Skip to content

Commit e219e50

Browse files
committed
os: expose broadcast address in os.networkInterfaces()
Not using the correct broadcast address in applications can cause disasterous results. Rather than letting the programmer guess at the broadcast address and try to derive it correctly, allow him to query the system instead for the correctly configured state. Fixes: #23437 Depends-on: libuv/libuv#2033
1 parent be346d9 commit e219e50

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

doc/api/os.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ The properties available on the assigned network address object include:
259259

260260
* `address` {string} The assigned IPv4 or IPv6 address
261261
* `netmask` {string} The IPv4 or IPv6 network mask
262+
* `broadcast` {string} The IPv4 or IPv6 broadcast address (not available
263+
on all interface types)
262264
* `family` {string} Either `IPv4` or `IPv6`
263265
* `mac` {string} The MAC address of the network interface
264266
* `internal` {boolean} `true` if the network interface is a loopback or
@@ -294,6 +296,7 @@ The properties available on the assigned network address object include:
294296
{
295297
address: '192.168.1.108',
296298
netmask: '255.255.255.0',
299+
broadcast: '192.168.1.255',
297300
family: 'IPv4',
298301
mac: '01:02:03:0a:0b:0c',
299302
internal: false,

src/env.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct PackageConfig {
127127
V(args_string, "args") \
128128
V(async, "async") \
129129
V(async_ids_stack_string, "async_ids_stack") \
130+
V(broadcast_string, "broadcast") \
130131
V(buffer_string, "buffer") \
131132
V(bytes_string, "bytes") \
132133
V(bytes_parsed_string, "bytesParsed") \

src/node_os.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
237237
int count, i;
238238
char ip[INET6_ADDRSTRLEN];
239239
char netmask[INET6_ADDRSTRLEN];
240+
char broadcast[INET6_ADDRSTRLEN];
240241
char mac[18];
241242
Local<Object> ret, o;
242243
Local<String> name, family;
@@ -296,11 +297,24 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
296297
family = env->unknown_string();
297298
}
298299

300+
if (interfaces[i].broadcast.broadcast4.sin_family == AF_INET) {
301+
uv_ip4_name(&interfaces[i].broadcast.broadcast4, broadcast,
302+
sizeof(broadcast));
303+
} else if (interfaces[i].broadcast.broadcast4.sin_family == AF_INET6) {
304+
uv_ip6_name(&interfaces[i].broadcast.broadcast6, broadcast,
305+
sizeof(broadcast));
306+
} else {
307+
broadcast[0] = '\0';
308+
}
309+
299310
o = Object::New(env->isolate());
300311
o->Set(env->address_string(), OneByteString(env->isolate(), ip));
301312
o->Set(env->netmask_string(), OneByteString(env->isolate(), netmask));
302313
o->Set(env->family_string(), family);
303314
o->Set(env->mac_string(), FIXED_ONE_BYTE_STRING(env->isolate(), mac));
315+
if (broadcast[0]) {
316+
o->Set(env->broadcast_string(), OneByteString(env->isolate(), broadcast));
317+
}
304318

305319
if (interfaces[i].address.address4.sin_family == AF_INET6) {
306320
uint32_t scopeid = interfaces[i].address.address6.sin6_scope_id;
@@ -450,6 +464,11 @@ void Initialize(Local<Object> target,
450464
Local<Value> unused,
451465
Local<Context> context) {
452466
Environment* env = Environment::GetCurrent(context);
467+
const struct sockaddr_in6 allhosts_in6 = {
468+
AF_INET6, 0, 0, IN6ADDR_ALLHOSTS_GROUP, 0,
469+
};
470+
static char allhosts_str[INET6_ADDRSTRLEN];
471+
453472
env->SetMethod(target, "getHostname", GetHostname);
454473
env->SetMethod(target, "getLoadAvg", GetLoadAvg);
455474
env->SetMethod(target, "getUptime", GetUptime);
@@ -465,6 +484,10 @@ void Initialize(Local<Object> target,
465484
env->SetMethod(target, "getPriority", GetPriority);
466485
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "isBigEndian"),
467486
Boolean::New(env->isolate(), IsBigEndian()));
487+
488+
uv_ip6_name(&allhosts_in6, allhosts_str, sizeof(allhosts_str));
489+
NODE_DEFINE_STRING_CONSTANT(target, STRINGIFY_(IN6ADDR_ALLHOSTS_GROUP),
490+
allhosts_str);
468491
}
469492

470493
} // namespace os

0 commit comments

Comments
 (0)