draft: refactor project so it sits on top of a standalone app
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
Copyright (c) silverwind
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
# default-gateway
|
||||
[](https://www.npmjs.org/package/default-gateway) [](https://www.npmjs.org/package/default-gateway) [](https://travis-ci.org/silverwind/default-gateway)
|
||||
|
||||
> Get the default network gateway, cross-platform.
|
||||
|
||||
Obtains the machine's default gateway through `exec` calls to OS routing interfaces. On Linux and Android, the `ip` command must be available (usually provided by the `iproute2` package). On IBM i, the `db2util` command must be available (provided by the `db2util` package).
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm install default-gateway
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
const defaultGateway = require('default-gateway');
|
||||
|
||||
defaultGateway.v4().then(result => {
|
||||
// result = {gateway: '1.2.3.4', interface: 'en1'}
|
||||
});
|
||||
|
||||
defaultGateway.v6().then(result => {
|
||||
// result = {gateway: '2001:db8::1', interface: 'en2'}
|
||||
});
|
||||
|
||||
const result = defaultGateway.v4.sync();
|
||||
// result = {gateway: '1.2.3.4', interface: 'en1'}
|
||||
|
||||
const result = defaultGateway.v6.sync();
|
||||
// result = {gateway: '2001:db8::1', interface: 'en2'}
|
||||
```
|
||||
|
||||
## API
|
||||
### defaultGateway.v4()
|
||||
### defaultGateway.v6()
|
||||
### defaultGateway.v4.sync()
|
||||
### defaultGateway.v6.sync()
|
||||
|
||||
Returns: `result` *Object*
|
||||
- `gateway`: The IP address of the default gateway.
|
||||
- `interface`: The name of the interface. On Windows, this is the network adapter name.
|
||||
|
||||
The `.v{4,6}()` methods return a Promise while the `.v{4,6}.sync()` variants will return the result synchronously.
|
||||
|
||||
The `gateway` property will always be defined on success, while `interface` can be `null` if it cannot be determined. All methods reject/throw on unexpected conditions.
|
||||
|
||||
## License
|
||||
|
||||
© [silverwind](https://github.com/silverwind), distributed under BSD licence
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
|
||||
const net = require("net");
|
||||
const execa = require("execa");
|
||||
|
||||
const args = {
|
||||
v4: ["-4", "r"],
|
||||
v6: ["-6", "r"],
|
||||
};
|
||||
|
||||
const parse = stdout => {
|
||||
let result;
|
||||
|
||||
(stdout || "").trim().split("\n").some(line => {
|
||||
const results = /default via (.+?) dev (.+?)( |$)/.exec(line) || [];
|
||||
const gateway = results[1];
|
||||
const iface = results[2];
|
||||
if (gateway && net.isIP(gateway)) {
|
||||
result = {gateway, interface: (iface ? iface : null)};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return execa.stdout("ip", args[family]).then(stdout => {
|
||||
return parse(stdout);
|
||||
});
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const result = execa.sync("ip", args[family]);
|
||||
return parse(result.stdout);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("v4");
|
||||
module.exports.v6 = () => promise("v6");
|
||||
|
||||
module.exports.v4.sync = () => sync("v4");
|
||||
module.exports.v6.sync = () => sync("v6");
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
const net = require("net");
|
||||
const execa = require("execa");
|
||||
const dests = ["default", "0.0.0.0", "0.0.0.0/0", "::", "::/0"];
|
||||
|
||||
const args = {
|
||||
v4: ["-rn", "-f", "inet"],
|
||||
v6: ["-rn", "-f", "inet6"],
|
||||
};
|
||||
|
||||
const parse = (stdout, family) => {
|
||||
let result;
|
||||
|
||||
(stdout || "").trim().split("\n").some(line => {
|
||||
const results = line.split(/ +/) || [];
|
||||
const target = results[0];
|
||||
const gateway = results[1];
|
||||
const iface = results[family === "v4" ? 5 : 3];
|
||||
if (dests.indexOf(target) !== -1 && gateway && net.isIP(gateway)) {
|
||||
result = {gateway, interface: (iface ? iface : null)};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return execa.stdout("netstat", args[family]).then(stdout => {
|
||||
return parse(stdout, family);
|
||||
});
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const result = execa.sync("netstat", args[family]);
|
||||
return parse(result.stdout, family);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("v4");
|
||||
module.exports.v6 = () => promise("v6");
|
||||
|
||||
module.exports.v4.sync = () => sync("v4");
|
||||
module.exports.v6.sync = () => sync("v6");
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
const net = require("net");
|
||||
const execa = require("execa");
|
||||
const dests = ["default", "0.0.0.0", "0.0.0.0/0", "::", "::/0"];
|
||||
|
||||
const args = {
|
||||
v4: ["-rn", "-f", "inet"],
|
||||
v6: ["-rn", "-f", "inet6"],
|
||||
};
|
||||
|
||||
const parse = stdout => {
|
||||
let result;
|
||||
|
||||
(stdout || "").trim().split("\n").some(line => {
|
||||
const results = line.split(/ +/) || [];
|
||||
const target = results[0];
|
||||
const gateway = results[1];
|
||||
const iface = results[3];
|
||||
if (dests.indexOf(target) !== -1 && gateway && net.isIP(gateway)) {
|
||||
result = {gateway, interface: (iface ? iface : null)};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return execa.stdout("netstat", args[family]).then(stdout => {
|
||||
return parse(stdout);
|
||||
});
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const result = execa.sync("netstat", args[family]);
|
||||
return parse(result.stdout);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("v4");
|
||||
module.exports.v6 = () => promise("v6");
|
||||
|
||||
module.exports.v4.sync = () => sync("v4");
|
||||
module.exports.v6.sync = () => sync("v6");
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
|
||||
const execa = require("execa");
|
||||
|
||||
const db2util = "/QOpenSys/pkgs/bin/db2util";
|
||||
const sql = "select NEXT_HOP, LOCAL_BINDING_INTERFACE from QSYS2.NETSTAT_ROUTE_INFO where ROUTE_TYPE='DFTROUTE' and NEXT_HOP!='*DIRECT' and CONNECTION_TYPE=?";
|
||||
|
||||
const parse = stdout => {
|
||||
let result;
|
||||
try {
|
||||
const resultObj = JSON.parse(stdout);
|
||||
const gateway = resultObj.records[0].NEXT_HOP;
|
||||
const iface = resultObj.records[0].LOCAL_BINDING_INTERFACE;
|
||||
result = {gateway, iface};
|
||||
} catch (err) {}
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return execa.stdout(db2util, [sql, "-p", family, "-o", "json"]).then(stdout => parse(stdout));
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const {stdout} = execa.sync(db2util, [sql, "-p", family, "-o", "json"]);
|
||||
return parse(stdout);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("IPV4");
|
||||
module.exports.v6 = () => promise("IPV6");
|
||||
|
||||
module.exports.v4.sync = () => sync("IPV4");
|
||||
module.exports.v6.sync = () => sync("IPV6");
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
"use strict";
|
||||
|
||||
const os = require("os");
|
||||
const platform = os.platform();
|
||||
|
||||
if ([
|
||||
"android",
|
||||
"darwin",
|
||||
"freebsd",
|
||||
"linux",
|
||||
"openbsd",
|
||||
"sunos",
|
||||
"win32",
|
||||
"aix",
|
||||
].indexOf(platform) !== -1) {
|
||||
let file;
|
||||
if (platform === "aix") {
|
||||
// AIX `netstat` output is compatible with Solaris
|
||||
file = `${os.type() === "OS400" ? "ibmi" : "sunos"}.js`;
|
||||
} else {
|
||||
file = `${platform}.js`;
|
||||
}
|
||||
|
||||
const m = require(`./${file}`);
|
||||
module.exports.v4 = () => m.v4();
|
||||
module.exports.v6 = () => m.v6();
|
||||
module.exports.v4.sync = () => m.v4.sync();
|
||||
module.exports.v6.sync = () => m.v6.sync();
|
||||
} else {
|
||||
const unsupported = () => { throw new Error(`Unsupported Platform: ${platform}`); };
|
||||
module.exports.v4 = unsupported;
|
||||
module.exports.v6 = unsupported;
|
||||
module.exports.v4.sync = unsupported;
|
||||
module.exports.v6.sync = unsupported;
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
"use strict";
|
||||
|
||||
const net = require("net");
|
||||
const os = require("os");
|
||||
const execa = require("execa");
|
||||
|
||||
const args = {
|
||||
v4: ["-4", "r"],
|
||||
v6: ["-6", "r"],
|
||||
};
|
||||
|
||||
const parse = (stdout, family) => {
|
||||
let result;
|
||||
|
||||
(stdout || "").trim().split("\n").some(line => {
|
||||
const results = /default( via .+?)?( dev .+?)( |$)/.exec(line) || [];
|
||||
const gateway = (results[1] || "").substring(5);
|
||||
const iface = (results[2] || "").substring(5);
|
||||
if (gateway && net.isIP(gateway)) { // default via 1.2.3.4 dev en0
|
||||
result = {gateway, interface: (iface ? iface : null)};
|
||||
return true;
|
||||
} else if (iface && !gateway) { // default via dev en0
|
||||
const interfaces = os.networkInterfaces();
|
||||
const addresses = interfaces[iface];
|
||||
if (!addresses || !addresses.length) return;
|
||||
|
||||
addresses.some(addr => {
|
||||
if (addr.family.substring(2) === family && net.isIP(addr.address)) {
|
||||
result = {gateway: addr.address, interface: (iface ? iface : null)};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return execa.stdout("ip", args[family]).then(stdout => {
|
||||
return parse(stdout, family);
|
||||
});
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const result = execa.sync("ip", args[family]);
|
||||
return parse(result.stdout, family);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("v4");
|
||||
module.exports.v6 = () => promise("v6");
|
||||
|
||||
module.exports.v4.sync = () => sync("v4");
|
||||
module.exports.v6.sync = () => sync("v6");
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
const net = require("net");
|
||||
const execa = require("execa");
|
||||
const dests = ["default", "0.0.0.0", "0.0.0.0/0", "::", "::/0"];
|
||||
|
||||
const args = {
|
||||
v4: ["-rn", "-f", "inet"],
|
||||
v6: ["-rn", "-f", "inet6"],
|
||||
};
|
||||
|
||||
const parse = stdout => {
|
||||
let result;
|
||||
|
||||
(stdout || "").trim().split("\n").some(line => {
|
||||
const results = line.split(/ +/) || [];
|
||||
const target = results[0];
|
||||
const gateway = results[1];
|
||||
const iface = results[7];
|
||||
if (dests.indexOf(target) !== -1 && gateway && net.isIP(gateway)) {
|
||||
result = {gateway, interface: (iface ? iface : null)};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return execa.stdout("netstat", args[family]).then(stdout => {
|
||||
return parse(stdout);
|
||||
});
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const result = execa.sync("netstat", args[family]);
|
||||
return parse(result.stdout);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("v4");
|
||||
module.exports.v6 = () => promise("v6");
|
||||
|
||||
module.exports.v4.sync = () => sync("v4");
|
||||
module.exports.v6.sync = () => sync("v6");
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"_from": "default-gateway@^4.2.0",
|
||||
"_id": "default-gateway@4.2.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
|
||||
"_location": "/default-gateway",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "default-gateway@^4.2.0",
|
||||
"name": "default-gateway",
|
||||
"escapedName": "default-gateway",
|
||||
"rawSpec": "^4.2.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^4.2.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/internal-ip"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
|
||||
"_shasum": "167104c7500c2115f6dd69b0a536bb8ed720552b",
|
||||
"_spec": "default-gateway@^4.2.0",
|
||||
"_where": "O:\\zero\\zero.Web\\node_modules\\internal-ip",
|
||||
"author": {
|
||||
"name": "silverwind",
|
||||
"email": "me@silverwind.io"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/silverwind/default-gateway/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"execa": "^1.0.0",
|
||||
"ip-regex": "^2.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Get the default network gateway, cross-platform.",
|
||||
"devDependencies": {
|
||||
"eslint": "^5.15.1",
|
||||
"eslint-config-silverwind": "^2.1.0",
|
||||
"updates": "^7.2.0",
|
||||
"ver": "4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"android.js",
|
||||
"darwin.js",
|
||||
"freebsd.js",
|
||||
"linux.js",
|
||||
"openbsd.js",
|
||||
"sunos.js",
|
||||
"win32.js",
|
||||
"ibmi.js"
|
||||
],
|
||||
"homepage": "https://github.com/silverwind/default-gateway#readme",
|
||||
"keywords": [
|
||||
"default gateway",
|
||||
"network",
|
||||
"default",
|
||||
"gateway",
|
||||
"routing",
|
||||
"route"
|
||||
],
|
||||
"license": "BSD-2-Clause",
|
||||
"name": "default-gateway",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/silverwind/default-gateway.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "eslint *.js && node --pending-deprecation --trace-deprecation --throw-deprecation --trace-warnings test.js"
|
||||
},
|
||||
"version": "4.2.0"
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
const net = require("net");
|
||||
const execa = require("execa");
|
||||
const dests = ["default", "0.0.0.0", "0.0.0.0/0", "::", "::/0"];
|
||||
|
||||
const args = {
|
||||
v4: ["-rn", "-f", "inet"],
|
||||
v6: ["-rn", "-f", "inet6"],
|
||||
};
|
||||
|
||||
const parse = stdout => {
|
||||
let result;
|
||||
|
||||
(stdout || "").trim().split("\n").some(line => {
|
||||
const results = line.split(/ +/) || [];
|
||||
const target = results[0];
|
||||
const gateway = results[1];
|
||||
const iface = results[5];
|
||||
if (dests.indexOf(target) !== -1 && gateway && net.isIP(gateway)) {
|
||||
result = {gateway, interface: (iface ? iface : null)};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return execa.stdout("netstat", args[family]).then(stdout => {
|
||||
return parse(stdout);
|
||||
});
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const result = execa.sync("netstat", args[family]);
|
||||
return parse(result.stdout);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("v4");
|
||||
module.exports.v6 = () => promise("v6");
|
||||
|
||||
module.exports.v4.sync = () => sync("v4");
|
||||
module.exports.v6.sync = () => sync("v6");
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
"use strict";
|
||||
|
||||
const execa = require("execa");
|
||||
const ipRegex = require("ip-regex");
|
||||
|
||||
const gwArgs = "path Win32_NetworkAdapterConfiguration where IPEnabled=true get DefaultIPGateway,Index /format:table".split(" ");
|
||||
const ifArgs = "path Win32_NetworkAdapter get Index,NetConnectionID /format:table".split(" ");
|
||||
|
||||
const parse = (gwTable, ifTable, family) => {
|
||||
let gateway, gwid, result;
|
||||
|
||||
(gwTable || "").trim().split("\n").splice(1).some(line => {
|
||||
const results = line.trim().split(/} +/) || [];
|
||||
const gw = results[0];
|
||||
const id = results[1];
|
||||
gateway = (ipRegex[family]().exec((gw || "").trim()) || [])[0];
|
||||
if (gateway) {
|
||||
gwid = id;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
(ifTable || "").trim().split("\n").splice(1).some(line => {
|
||||
const i = line.indexOf(" ");
|
||||
const id = line.substr(0, i).trim();
|
||||
const name = line.substr(i + 1).trim();
|
||||
if (id === gwid) {
|
||||
result = {gateway, interface: name ? name : null};
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
throw new Error("Unable to determine default gateway");
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const spawnOpts = {
|
||||
windowsHide: true,
|
||||
};
|
||||
|
||||
const promise = family => {
|
||||
return Promise.all([
|
||||
execa.stdout("wmic", gwArgs, spawnOpts),
|
||||
execa.stdout("wmic", ifArgs, spawnOpts),
|
||||
]).then(results => {
|
||||
const gwTable = results[0];
|
||||
const ifTable = results[1];
|
||||
|
||||
return parse(gwTable, ifTable, family);
|
||||
});
|
||||
};
|
||||
|
||||
const sync = family => {
|
||||
const gwTable = execa.sync("wmic", gwArgs, spawnOpts).stdout;
|
||||
const ifTable = execa.sync("wmic", ifArgs, spawnOpts).stdout;
|
||||
|
||||
return parse(gwTable, ifTable, family);
|
||||
};
|
||||
|
||||
module.exports.v4 = () => promise("v4");
|
||||
module.exports.v6 = () => promise("v6");
|
||||
|
||||
module.exports.v4.sync = () => sync("v4");
|
||||
module.exports.v6.sync = () => sync("v6");
|
||||
Reference in New Issue
Block a user