Skip to content

Commit

Permalink
Support multiple NICs
Browse files Browse the repository at this point in the history
  • Loading branch information
mh61503891 committed Nov 30, 2015
1 parent b4e519c commit e38483e
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 106 deletions.
39 changes: 23 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ This module depends on following commands by using [chid_process](https://nodejs
- `wmic path Win32_NetworkAdapterConfiguration get *`
- `wmic path Win32_NetworkAdapter get *`
- darwin
- `route -n get -inet default`
- `route -n get -inet6 default`
- `netstat -rn -f inet`
- `netstat -rn -f inet6`
- linux
- `route -n -A inet`
- `route -n -A inet6`
- `netstat -rn -A inet`
- `netstat -rn -A inet6`

## Installation

Expand Down Expand Up @@ -44,9 +44,15 @@ route.collect(function(error, data) {
An example output:

```js
{ en0:
{ en4:
[ { family: 'IPv4', address: '192.168.1.1' },
{ family: 'IPv6', address: 'fe80::20b:a2ff:fede:2886%en0' } ] }
{ family: 'IPv6', address: 'fe80::20b:a2ff:fede:2886%en4' } ],
en0:
[ { family: 'IPv4', address: '192.168.1.1' },
{ family: 'IPv6', address: 'fe80::20b:a2ff:fede:2886%en0' } ],
en8:
[ { family: 'IPv4', address: '192.168.1.1' },
{ family: 'IPv6', address: 'fe80::20b:a2ff:fede:2886%en8' } ] }
```

#### Example 2
Expand All @@ -60,35 +66,36 @@ var os = require('os');
var route = require('default-network');
route.collect(function(error, data) {
names = Object.keys(data);
console.log(os.networkInterfaces()[name[0]]);
// names[0] is 'en4'
console.log(os.networkInterfaces()[names[0]]);
});
```

An example output:

```js
[ { address: '192.168.1.6',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: false },
{ address: 'fe80::3636:3bff:fece:d106',
[ { address: 'fe80::6a5b:35ff:fe96:cc05',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 4,
scopeid: 14,
internal: false },
{ address: '2001:a0ae:7c22:0:3636:3bff:fece:d106',
{ address: '2001:a0ae:7c22:0:6a5b:35ff:fe96:cc05',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 0,
internal: false },
{ address: '2001:a0ae:7c22:0:2994:aeb5:5973:5cd4',
{ address: '2001:a0ae:7c22:0:a8d1:fef3:2917:cd87',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 0,
internal: false },
{ address: '192.168.1.10',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: false } ]
```

Expand Down
72 changes: 41 additions & 31 deletions src/api-darwin.coffee
Original file line number Diff line number Diff line change
@@ -1,41 +1,51 @@
net = require('net')
exec = require('child_process').exec

getDefaultRoute = (family, callback) ->
exec "route -n get #{family} default", (error, stdout, stderr) ->
if not (family == '-inet' or family == '-inet6')
return callback(new Error("unsupported family option: #{family}"))
getDefaultNetwork = (command, callback) ->
exec command, (error, stdout, stderr) ->
return callback(error) if error?
return callback(new Error(stderr.trim())) if stderr.trim() != ''
defaultGateway = (stdout.match(/gateway:\s*(.+)\s*\n/) || [])[1]
defaultInterface = (stdout.match(/interface:\s*(.+)\s*\n/) || [])[1]
if not defaultGateway? || not defaultInterface?
return callback(new Error('defaultGateway or defaultInterface not found'))
if not net.isIP(defaultGateway)
return callback(new Error("defaultGateway not found: #{defaultGateway}"))
data = {
defaultGateway: defaultGateway
defaultInterface: defaultInterface
}
callback(error, data)
return callback(null, new Object) if stdout.trim() == ''
data = {}
stdout = stdout.trim()
for line in stdout.split('\n')
[defaultGateway, defaultInterface] = line.split(' ')
if not defaultGateway? || not defaultInterface?
return callback(new Error("parse error: #{stdout}"))
if not net.isIP(defaultGateway)
return callback(new Error("parse error: #{stdout}"))
data[defaultInterface] || = []
family = switch net.isIP(defaultGateway)
when 4 then 'IPv4'
when 6 then 'IPv6'
if not family?
return callback(new Error("invalid address: #{stdout}"))
data[defaultInterface].push {
family: family
address: defaultGateway
}
callback(null, data)

getDefaultNetworkByInet4 = (callback) ->
getDefaultNetwork "netstat -rn -f inet | awk '$3~/UG/ {print $2,$6;}'",
(error, data) ->
callback(error, data)

getDefaultNetworkByInet6 = (callback) ->
getDefaultNetwork "netstat -rn -f inet6 | awk '$3~/UG/ {print $2,$4;}'",
(error, data) ->
callback(error, data)

collect = (callback) ->
getDefaultRoute '-inet', (error4, data4) ->
getDefaultRoute '-inet6', (error6, data6) ->
data = {}
if data4? and not error4?
data[data4.defaultInterface] || = []
data[data4.defaultInterface].push {
family: 'IPv4'
address: data4.defaultGateway
}
if data6? and not error6?
data[data6.defaultInterface] || = []
data[data6.defaultInterface].push {
family: 'IPv6'
address: data6.defaultGateway
}
callback(null, data)
getDefaultNetworkByInet4 (error4, data4) ->
getDefaultNetworkByInet6 (error6, data6) ->
result = {}
for data in [data4, data6]
for iface, adapters of data
result[iface] || = []
result[iface].push(adapters...)
# collect() does not return errors
callback(null, result)

module.exports =
collect: collect
97 changes: 40 additions & 57 deletions src/api-linux.coffee
Original file line number Diff line number Diff line change
@@ -1,68 +1,51 @@
net = require('net')
exec = require('child_process').exec
async = require('async')

getRouteCommandPath = (callback) ->
paths = [
'route',
'/sbin/route' # for Debian
]
async.detect paths,
(path, callback) ->
exec "which #{path}", (error, stdout, stderr) ->
callback not error?
(path) ->
if not path?
error = new Error("route command not found: paths #{paths.join(', ')}")
return callback(error)
callback(null, path)

getDefaultRouteByInet4 = (path, callback) ->
exec "#{path} -n -A inet | awk '$4~/UG/ {print $2,$8;}'",
(error, stdout, stderr) ->
return callback(error) if error?
return callback(new Error(stderr.trim())) if stderr.trim() != ''
[defaultGateway, defaultInterface] = stdout.trim().split(' ')
getDefaultNetwork = (command, callback) ->
exec command, (error, stdout, stderr) ->
return callback(error) if error?
return callback(new Error(stderr.trim())) if stderr.trim() != ''
return callback(null, new Object) if stdout.trim() == ''
data = {}
stdout = stdout.trim()
for line in stdout.split('\n')
[defaultGateway, defaultInterface] = line.split(' ')
if not defaultGateway? || not defaultInterface?
return callback(new Error("UG not found"))
data = {
defaultGateway: defaultGateway
defaultInterface: defaultInterface
return callback(new Error("parse error: #{stdout}"))
if not net.isIP(defaultGateway)
return callback(new Error("parse error: #{stdout}"))
data[defaultInterface] || = []
family = switch net.isIP(defaultGateway)
when 4 then 'IPv4'
when 6 then 'IPv6'
if not family?
return callback(new Error("invalid address: #{stdout}"))
data[defaultInterface].push {
family: family
address: defaultGateway
}
callback(null, data)
callback(null, data)

getDefaultRouteByInet6 = (path, callback) ->
exec "#{path} -n -A inet6 | awk '$3~/UG/ {print $2,$7;}'",
(error, stdout, stderr) ->
return callback(error) if error?
return callback(new Error(stderr.trim())) if stderr.trim() != ''
[defaultGateway, defaultInterface] = stdout.trim().split(' ')
if not defaultGateway? || not defaultInterface?
return callback(new Error("UG not found"))
data = {
defaultGateway: defaultGateway
defaultInterface: defaultInterface
}
callback(null, data)
getDefaultNetworkByInet4 = (callback) ->
getDefaultNetwork "netstat -rn -A inet | awk '$4~/UG/ {print $2,$8;}'",
(error, data) ->
callback(error, data)

getDefaultNetworkByInet6 = (callback) ->
getDefaultNetwork "netstat -rn -A inet6 | awk '$4~/UG/ {print $2,$7;}'",
(error, data) ->
callback(error, data)

collect = (callback) ->
getRouteCommandPath (error, path) ->
getDefaultRouteByInet4 path, (error4, data4) ->
getDefaultRouteByInet6 path, (error6, data6) ->
data = {}
if data4?
data[data4.defaultInterface] || = []
data[data4.defaultInterface].push {
family: 'IPv4'
address: data4.defaultGateway
}
if data6?
data[data6.defaultInterface] || = []
data[data6.defaultInterface].push {
family: 'IPv6'
address: data6.defaultGateway
}
callback(null, data)
getDefaultNetworkByInet4 (error4, data4) ->
getDefaultNetworkByInet6 (error6, data6) ->
result = {}
for data in [data4, data6]
for iface, adapters of data
result[iface] || = []
result[iface].push(adapters...)
# collect() does not return errors
callback(null, result)

module.exports =
collect: collect
4 changes: 2 additions & 2 deletions src/api-win32.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ getDefaultNetwork = (callback) ->

collect = (callback) ->
getDefaultNetwork (error, data) ->
return callback null, {} if error?
callback(error, data)
return callback(null, {} ) if error?
callback(null, data)

module.exports =
collect: collect
2 changes: 2 additions & 0 deletions test/default-network.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ describe 'default-network', ->
before (done) ->
defaultNetwork.collect (error, result) ->
data = result
# console.log 'data', data
# console.log 'interfaces', os.networkInterfaces()
done(error)
it 'is an data object', ->
expect(data).to.be.an.any('object')
Expand Down

0 comments on commit e38483e

Please sign in to comment.