Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
os.getNetworkInterfaces()
Browse files Browse the repository at this point in the history
  • Loading branch information
ry committed Mar 16, 2011
1 parent 6111c17 commit 19e5351
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 2 deletions.
13 changes: 12 additions & 1 deletion doc/api/os.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,15 @@ Example inspection of os.cpus:
nice: 1480,
sys: 34920,
idle: 1072572010,
irq: 30 } } ]
irq: 30 } } ]

### os.getNetworkInterfaces()

Get a list of network interfaces:

{ lo: { ip: '127.0.0.1', internal: true, ip6: '::1' },
eth0: { ip6: 'fe80::f2de:f1ff:fe19:ae7', internal: false },
wlan0: { ip: '10.0.1.118', internal: false, ip6: 'fe80::226:c7ff:fe7d:1602' },
vboxnet0: {} }


1 change: 1 addition & 0 deletions lib/os.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ exports.totalmem = binding.getTotalMem;
exports.cpus = binding.getCPUs;
exports.type = binding.getOSType;
exports.release = binding.getOSRelease;
exports.getNetworkInterfaces = binding.getInterfaceAddresses;
7 changes: 7 additions & 0 deletions src/node_os.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ static Handle<Value> GetLoadAvg(const Arguments& args) {
return scope.Close(loads);
}


static Handle<Value> GetInterfaceAddresses(const Arguments& args) {
return Platform::GetInterfaceAddresses();
}


#ifdef __MINGW32__
static Handle<Value> OpenOSHandle(const Arguments& args) {
HandleScope scope;
Expand All @@ -186,6 +192,7 @@ void OS::Initialize(v8::Handle<v8::Object> target) {
NODE_SET_METHOD(target, "getCPUs", GetCPUInfo);
NODE_SET_METHOD(target, "getOSType", GetOSType);
NODE_SET_METHOD(target, "getOSRelease", GetOSRelease);
NODE_SET_METHOD(target, "getInterfaceAddresses", GetInterfaceAddresses);

#ifdef __MINGW32__
NODE_SET_METHOD(target, "openOSHandle", OpenOSHandle);
Expand Down
1 change: 1 addition & 0 deletions src/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Platform {
return adjusted ? GetUptimeImpl() - prog_start_time : GetUptimeImpl();
}
static int GetLoadAvg(v8::Local<v8::Array> *loads);
static v8::Handle<v8::Value> GetInterfaceAddresses();
private:
static double GetUptimeImpl();
static double prog_start_time;
Expand Down
6 changes: 6 additions & 0 deletions src/platform_cygwin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,10 @@ int Platform::GetLoadAvg(Local<Array> *loads) {
}


Handle<Value> Platform::GetInterfaceAddresses() {
HandleScope scope;
return scope.Close(Object::New());
}


} // namespace node
6 changes: 6 additions & 0 deletions src/platform_darwin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,10 @@ int Platform::GetLoadAvg(Local<Array> *loads) {
return 0;
}


Handle<Value> Platform::GetInterfaceAddresses() {
HandleScope scope;
return scope.Close(Object::New());
}

} // namespace node
6 changes: 6 additions & 0 deletions src/platform_freebsd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,10 @@ int Platform::GetLoadAvg(Local<Array> *loads) {
return 0;
}


Handle<Value> Platform::GetInterfaceAddresses() {

This comment has been minimized.

Copy link
@kennyb

kennyb Mar 18, 2011

this won't compile on mac without having the v8 namespace:

v8::Handle Platform::GetInterfaceAddresses() {

(btw, I don't know why, seeing as there is "using namespace v8;")

thanks!

HandleScope scope;
return scope.Close(Object::New());
}

} // namespace node
81 changes: 81 additions & 0 deletions src/platform_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@
#include <stdlib.h> // free
#include <string.h> // strdup

/* GetInterfaceAddresses */
#include <arpa/inet.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <net/if.h>

#if HAVE_MONOTONIC_CLOCK
#include <time.h>
#endif
Expand Down Expand Up @@ -295,4 +303,77 @@ int Platform::GetLoadAvg(Local<Array> *loads) {
return 0;
}


bool IsInternal(struct ifaddrs* addr) {
return addr->ifa_flags & IFF_UP &&
addr->ifa_flags & IFF_RUNNING &&
addr->ifa_flags & IFF_LOOPBACK;
}


Handle<Value> Platform::GetInterfaceAddresses() {
HandleScope scope;

struct ::ifaddrs *addrs;

int r = getifaddrs(&addrs);

if (r != 0) {
return ThrowException(ErrnoException(errno, "getifaddrs"));
}

struct ::ifaddrs *addr;

Local<Object> a = Object::New();

for (addr = addrs;
addr;
addr = addr->ifa_next) {
Local<String> name = String::New(addr->ifa_name);
Local<Object> info;

if (a->Has(name)) {
info = a->Get(name)->ToObject();
} else {
info = Object::New();
a->Set(name, info);
}

struct sockaddr *address = addr->ifa_addr;
char ip[INET6_ADDRSTRLEN];

switch (address->sa_family) {
case AF_INET6: {
struct sockaddr_in6 *a6 = (struct sockaddr_in6*)address;
inet_ntop(AF_INET6, &(a6->sin6_addr), ip, INET6_ADDRSTRLEN);
info->Set(String::New("ip6"), String::New(ip));
if (addr->ifa_flags) {
info->Set(String::New("internal"),
IsInternal(addr) ? True() : False());
}
break;
}

case AF_INET: {
struct sockaddr_in *a4 = (struct sockaddr_in*)address;
inet_ntop(AF_INET, &(a4->sin_addr), ip, INET6_ADDRSTRLEN);
info->Set(String::New("ip"), String::New(ip));
if (addr->ifa_flags) {
info->Set(String::New("internal"),
IsInternal(addr) ? True() : False());
}
break;
}

default:
assert(0);
}
}

freeifaddrs(addrs);

return scope.Close(a);
}


} // namespace node
7 changes: 7 additions & 0 deletions src/platform_openbsd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,11 @@ int Platform::GetLoadAvg(Local<Array> *loads) {
return 0;
}


Handle<Value> Platform::GetInterfaceAddresses() {
HandleScope scope;
return scope.Close(Object::New());
}


} // namespace node
6 changes: 6 additions & 0 deletions src/platform_sunos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,11 @@ int Platform::GetLoadAvg(Local<Array> *loads) {
}


Handle<Value> Platform::GetInterfaceAddresses() {
HandleScope scope;
return scope.Close(Object::New());
}


} // namespace node

7 changes: 7 additions & 0 deletions src/platform_win32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,11 @@ int Platform::GetLoadAvg(Local<Array> *loads) {
return -1;
}


Handle<Value> Platform::GetInterfaceAddresses() {
HandleScope scope;
return scope.Close(Object::New());
}


} // namespace node
11 changes: 10 additions & 1 deletion test/simple/test-os.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,13 @@ assert.ok(os.freemem() > 0);
assert.ok(os.totalmem() > 0);
assert.ok(os.cpus().length > 0);
assert.ok(os.type().length > 0);
assert.ok(os.release().length > 0);
assert.ok(os.release().length > 0);


var interfaces = os.getNetworkInterfaces();
console.error(interfaces);
switch (process.platform) {
case 'linux':
assert.equal('127.0.0.1', interfaces.lo.ip);
break;
}

2 comments on commit 19e5351

@mscdex
Copy link

@mscdex mscdex commented on 19e5351 Mar 17, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the code for linux should work for the other platforms as well (except mingw). The only thing that might need to be changed to work for all posix platforms is that according to Apple's/BSD's manpage for getifaddrs, <net/if.h> must be included before <ifaddrs.h>.

Also, how about a less wordy function name on the JS side? Something like ifaces()?

@ry
Copy link
Author

@ry ry commented on 19e5351 Mar 17, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes should mostly work without changes.
less wordy - sure

Please sign in to comment.