Node: `os.networkInterfaces` does not list all interfaces.

Created on 18 Jan 2015  路  18Comments  路  Source: nodejs/node

Adoption of joyent/node#9029.

os.networkInterfaces() does not list all interfaces, but only those that have addresses, excluding for example an unplugged eth0, which can be surprising.

This happens because os.networkInterfaces is actually implemented in terms of GetInterfaceAddresses which calls into uv_interface_addresses (which among other things filters out everything except AF_INET*) making networkInterfaces a bit of a misnomer for what is basically networkInterfaceAddresses.

Though os is at stability 4 already, this behavior can be a bit unexpected. Perhaps we could correct it somewhat without breaking the API, or at least document it. I can think of a few ways to work this out:

  • Leave the method as it is, but document the exceptional behavior in the docs, and leave it to a community module to solve this correctly; or
  • Alias it to os.networkInterfaceAddresses, thus reflecting GetInterfaceAddresses and uv_interface_addresses; or
  • Implement uv_interfaces and rebase os.networkInterfaces() on that and uv_interface_addresses, preserving the current behavior, but listing all interfaces when given a flag.
  • yes
  • os
  • v0.10, v0.12, v1.0.0
blocked feature request libuv os

Most helpful comment

As workaround, I used undocumented function findalldevs() in pcap npm package (uses binary libpcap library, which must be present on system). I am using live packet capture from pcap module anyway. As time of writing, npm version did not compile on my system, but git master did.

In this example, at least interface en4 is unplugged.

> const pcap = require('pcap');
undefined
> pcap.findalldevs()
[ { name: 'en0', addresses: [ <1 empty item>, [Object] ] },
  { name: 'awdl0', addresses: [ <1 empty item>, [Object] ] },
  { name: 'bridge0', addresses: [] },
  { name: 'en1', addresses: [] },
  { name: 'en2', addresses: [] },
  { name: 'p2p0', addresses: [] },
  { name: 'en4', addresses: [] },
  { name: 'lo0',
    addresses: [ <1 empty item>, [Object], [Object], [Object], [Object] ],
    flags: 'PCAP_IF_LOOPBACK' } ]

Also Cap looks usable. it still needs libpcap installed, but should work on Windows as well.
Edit: just converted my code to Cap as I need Windows support :)

Any other workaround besides pcap?, I tried npm network which uses wmic but opens a console to run the wmic command.

Why is so hard to have something like this, for node:

https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.networkinterface.getallnetworkinterfaces?view=netframework-4.7.2

All 18 comments

os.networkInterfaces({ all: true }) wouldn't be a breaking change, I'm +1 for that; not having the ability to list _all_ interfaces is a bit of a handicap for the platform

It would require a (tedious) update to libuv, however. Tedious because it needs to be applied to all platforms and because it's an API change. Whoever wants to pursue that, please file a libuv issue first so we can hash out the details.

+1 for { all: true } and similar approaches. It's unlikely for networkInterfaces to receive an object with this shape by accident. Conversely, trying to invoke the new behavior on node.js will still return a valid list of interfaces (with down interfaces missing as usual).

I believe libuv would only need a single addition (uv_interfaces and possibly uv_free_interfaces) without changes in existing code. The remaining job of meshing uv_interfaces and uv_interface_addresses together would be entirely done on the io.js bindings. I'll open an issue there and try a POC.

+1 for { all: true }. Until that, what workarounds could be used?

@piranna I don't believe there is a core workaround right now, unless there is an npm module somewhere.

I don't know of any npm module about this... :-(

This issue appears to be dormant and doesn't seem likely to get any traction any time soon because it depends on a significant feature appearing in libuv first. Would it be wrong-headed to close this and open something in nodejs/NG instead?

@Trott Nah, this is still valid IMO. It's the kind of thing that we would add.

Adding blocked label because this can't happen until libuv gets the required feature...

As workaround, I used undocumented function findalldevs() in pcap npm package (uses binary libpcap library, which must be present on system). I am using live packet capture from pcap module anyway. As time of writing, npm version did not compile on my system, but git master did.

In this example, at least interface en4 is unplugged.

> const pcap = require('pcap');
undefined
> pcap.findalldevs()
[ { name: 'en0', addresses: [ <1 empty item>, [Object] ] },
  { name: 'awdl0', addresses: [ <1 empty item>, [Object] ] },
  { name: 'bridge0', addresses: [] },
  { name: 'en1', addresses: [] },
  { name: 'en2', addresses: [] },
  { name: 'p2p0', addresses: [] },
  { name: 'en4', addresses: [] },
  { name: 'lo0',
    addresses: [ <1 empty item>, [Object], [Object], [Object], [Object] ],
    flags: 'PCAP_IF_LOOPBACK' } ]

Also Cap looks usable. it still needs libpcap installed, but should work on Windows as well.
Edit: just converted my code to Cap as I need Windows support :)

Are there any open tickets within libuv currently to keep track of? It would be nice to know if anyone is currently working on this problem.

There is https://github.com/libuv/libuv/issues/158. I don't think anyone is actively working on it though.

What's the current status on this? Is anyone working on this/it's libuv counterpart?

/cc @nodejs/libuv @cjihrig

@ryzokuken So there is this https://github.com/libuv/libuv/pull/219 old PR which has been superseded by this https://github.com/libuv/libuv/pull/1371 but unfortunately there has been no activity for almost a year now. It seems the implementation pretty much stalled.
Edit: ping'ed the author in the PR, let's see, maybe there is a chance.

The upstream PR seems to be stalled, and I attempted to close it. Is this still an issue? We could reformat it so that someone else picks it up.

As workaround, I used undocumented function findalldevs() in pcap npm package (uses binary libpcap library, which must be present on system). I am using live packet capture from pcap module anyway. As time of writing, npm version did not compile on my system, but git master did.

In this example, at least interface en4 is unplugged.

> const pcap = require('pcap');
undefined
> pcap.findalldevs()
[ { name: 'en0', addresses: [ <1 empty item>, [Object] ] },
  { name: 'awdl0', addresses: [ <1 empty item>, [Object] ] },
  { name: 'bridge0', addresses: [] },
  { name: 'en1', addresses: [] },
  { name: 'en2', addresses: [] },
  { name: 'p2p0', addresses: [] },
  { name: 'en4', addresses: [] },
  { name: 'lo0',
    addresses: [ <1 empty item>, [Object], [Object], [Object], [Object] ],
    flags: 'PCAP_IF_LOOPBACK' } ]

Also Cap looks usable. it still needs libpcap installed, but should work on Windows as well.
Edit: just converted my code to Cap as I need Windows support :)

Any other workaround besides pcap?, I tried npm network which uses wmic but opens a console to run the wmic command.

Why is so hard to have something like this, for node:

https://docs.microsoft.com/en-us/dotnet/api/system.net.networkinformation.networkinterface.getallnetworkinterfaces?view=netframework-4.7.2

5 years and it's still an issue. Workaround is to rely on another npm package or parse ipconfig / ifconfig (or any other network cmd) yourself.
Any better ideas?

It seems that no one's gone through the effort to properly land this in libuv?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fanjunzhi picture fanjunzhi  路  3Comments

willnwhite picture willnwhite  路  3Comments

cong88 picture cong88  路  3Comments

stevenvachon picture stevenvachon  路  3Comments

vsemozhetbyt picture vsemozhetbyt  路  3Comments