aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRobert Pluim2019-11-15 11:11:30 +0100
committerRobert Pluim2019-11-26 08:46:13 +0100
commit650a514e996287106f9a9525b6f27068ec2a0cbf (patch)
tree188170aae76f32d894d8df1baa7f435fbfe99d88 /src
parent5c3d0cf7910afa6b3fbdba24ac5c5817f268eb0e (diff)
downloademacs-650a514e996287106f9a9525b6f27068ec2a0cbf.tar.gz
emacs-650a514e996287106f9a9525b6f27068ec2a0cbf.zip
Extend network-interface-list to return IPv6 and network info
Bug#38218 * src/process.c (Fnetwork_interface_list): Extend argument list to allow requesting full network info and/or IPv4/IPv6 info. (network_interface_list) [HAVE_GETIFADDRS]: Use getifaddrs to retrieve interface IP addresses. * src/process.h: Update prototype of network_interface_list. * src/w32.c (g_b_init_get_adapters_addresses): New init flag. (globals_of_w32): Initialize it. (GetAdaptersAddresses_Proc): New function typedef. (get_adapters_addresses): New wrapper function. (init_winsock): Load htonl and ntohl. (sys_htonl, sys_ntohl): New wrapper functions. (network_interface_list): Implement in terms of get_adapters_addresses. * nt/inc/sys/socket.h: Add sys_htonl and sys_ntohl prototypes. * etc/NEWS: Announce IPv4/IPv6 changes in network-interface-list. * doc/lispref/processes.texi (Misc Network): Document updated arglist and return values for network-interface-list.
Diffstat (limited to 'src')
-rw-r--r--src/process.c158
-rw-r--r--src/process.h2
-rw-r--r--src/w32.c244
3 files changed, 343 insertions, 61 deletions
diff --git a/src/process.c b/src/process.c
index 9158cfd347c..0f82682ae5f 100644
--- a/src/process.c
+++ b/src/process.c
@@ -4255,73 +4255,86 @@ usage: (make-network-process &rest ARGS) */)
4255} 4255}
4256 4256
4257 4257
4258#ifdef HAVE_NET_IF_H
4259 4258
4260#ifdef SIOCGIFCONF 4259#ifdef HAVE_GETIFADDRS
4261static Lisp_Object 4260static Lisp_Object
4262network_interface_list (void) 4261network_interface_list (bool full, unsigned short match)
4263{ 4262{
4264 struct ifconf ifconf; 4263 Lisp_Object res = Qnil;
4265 struct ifreq *ifreq; 4264 struct ifaddrs *ifap;
4266 void *buf = NULL;
4267 ptrdiff_t buf_size = 512;
4268 int s;
4269 Lisp_Object res;
4270 ptrdiff_t count;
4271 4265
4272 s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 4266 if (getifaddrs (&ifap) == -1)
4273 if (s < 0)
4274 return Qnil; 4267 return Qnil;
4275 count = SPECPDL_INDEX ();
4276 record_unwind_protect_int (close_file_unwind, s);
4277 4268
4278 do 4269 for (struct ifaddrs *it = ifap; it != NULL; it = it->ifa_next)
4279 { 4270 {
4280 buf = xpalloc (buf, &buf_size, 1, INT_MAX, 1); 4271 int len;
4281 ifconf.ifc_buf = buf; 4272 int addr_len;
4282 ifconf.ifc_len = buf_size; 4273 uint32_t *maskp;
4283 if (ioctl (s, SIOCGIFCONF, &ifconf)) 4274 uint32_t *addrp;
4284 { 4275 Lisp_Object elt = Qnil;
4285 emacs_close (s);
4286 xfree (buf);
4287 return Qnil;
4288 }
4289 }
4290 while (ifconf.ifc_len == buf_size);
4291
4292 res = unbind_to (count, Qnil);
4293 ifreq = ifconf.ifc_req;
4294 while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len)
4295 {
4296 struct ifreq *ifq = ifreq;
4297#ifdef HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN
4298#define SIZEOF_IFREQ(sif) \
4299 ((sif)->ifr_addr.sa_len < sizeof (struct sockaddr) \
4300 ? sizeof (*(sif)) : sizeof ((sif)->ifr_name) + (sif)->ifr_addr.sa_len)
4301 4276
4302 int len = SIZEOF_IFREQ (ifq); 4277 /* BSD can allegedly return interfaces with a NULL address. */
4303#else 4278 if (it->ifa_addr == NULL)
4304 int len = sizeof (*ifreq); 4279 continue;
4280 if (match && it->ifa_addr->sa_family != match)
4281 continue;
4282 if (it->ifa_addr->sa_family == AF_INET)
4283 {
4284 DECLARE_POINTER_ALIAS (sin1, struct sockaddr_in, it->ifa_netmask);
4285 maskp = (uint32_t *)&sin1->sin_addr;
4286 DECLARE_POINTER_ALIAS (sin2, struct sockaddr_in, it->ifa_addr);
4287 addrp = (uint32_t *)&sin2->sin_addr;
4288 len = sizeof (struct sockaddr_in);
4289 addr_len = 1;
4290 }
4291#ifdef AF_INET6
4292 else if (it->ifa_addr->sa_family == AF_INET6)
4293 {
4294 DECLARE_POINTER_ALIAS (sin6_1, struct sockaddr_in6, it->ifa_netmask);
4295 maskp = (uint32_t *) &sin6_1->sin6_addr;
4296 DECLARE_POINTER_ALIAS (sin6_2, struct sockaddr_in6, it->ifa_addr);
4297 addrp = (uint32_t *) &sin6_2->sin6_addr;
4298 len = sizeof (struct sockaddr_in6);
4299 addr_len = 4;
4300 }
4305#endif 4301#endif
4306 char namebuf[sizeof (ifq->ifr_name) + 1]; 4302 else
4307 ifreq = (struct ifreq *) ((char *) ifreq + len); 4303 continue;
4308 4304
4309 if (ifq->ifr_addr.sa_family != AF_INET) 4305 Lisp_Object addr = conv_sockaddr_to_lisp (it->ifa_addr, len);
4310 continue;
4311 4306
4312 memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name)); 4307 if (full)
4313 namebuf[sizeof (ifq->ifr_name)] = 0; 4308 {
4314 res = Fcons (Fcons (build_string (namebuf), 4309 elt = Fcons (conv_sockaddr_to_lisp (it->ifa_netmask, len), elt);
4315 conv_sockaddr_to_lisp (&ifq->ifr_addr, 4310 /* There is an it->ifa_broadaddr field, but its contents are
4316 sizeof (struct sockaddr))), 4311 unreliable, so always calculate the broadcast address from
4317 res); 4312 the address and the netmask. */
4313 int i;
4314 uint32_t mask;
4315 for (i = 0; i < addr_len; i++)
4316 {
4317 mask = maskp[i];
4318 maskp[i] = (addrp[i] & mask) | ~mask;
4319 }
4320 elt = Fcons (conv_sockaddr_to_lisp (it->ifa_netmask, len), elt);
4321 elt = Fcons (addr, elt);
4322 }
4323 else
4324 {
4325 elt = addr;
4326 }
4327 res = Fcons (Fcons (build_string (it->ifa_name), elt), res);
4318 } 4328 }
4329#ifdef HAVE_FREEIFADDRS
4330 freeifaddrs (ifap);
4331#endif
4319 4332
4320 xfree (buf);
4321 return res; 4333 return res;
4322} 4334}
4323#endif /* SIOCGIFCONF */ 4335#endif /* HAVE_GETIFADDRS */
4324 4336
4337#ifdef HAVE_NET_IF_H
4325#if defined (SIOCGIFADDR) || defined (SIOCGIFHWADDR) || defined (SIOCGIFFLAGS) 4338#if defined (SIOCGIFADDR) || defined (SIOCGIFHWADDR) || defined (SIOCGIFFLAGS)
4326 4339
4327struct ifflag_def { 4340struct ifflag_def {
@@ -4550,17 +4563,46 @@ network_interface_info (Lisp_Object ifname)
4550#endif /* defined (HAVE_NET_IF_H) */ 4563#endif /* defined (HAVE_NET_IF_H) */
4551 4564
4552DEFUN ("network-interface-list", Fnetwork_interface_list, 4565DEFUN ("network-interface-list", Fnetwork_interface_list,
4553 Snetwork_interface_list, 0, 0, 0, 4566 Snetwork_interface_list, 0, 2, 0,
4554 doc: /* Return an alist of all network interfaces and their network address. 4567 doc: /* Return an alist of all network interfaces and their network address.
4555Each element is a cons, the car of which is a string containing the 4568Each element is cons of the form (IFNAME . IP) where IFNAME is a
4556interface name, and the cdr is the network address in internal 4569string containing the interface name, and IP is the network address in
4557format; see the description of ADDRESS in `make-network-process'. 4570internal format; see the description of ADDRESS in
4571`make-network-process'. The interface name is not guaranteed to be
4572unique.
4573
4574Optional parameter FULL non-nil means return all IP address info for
4575each interface. Each element is then a list of the form
4576 (IFNAME IP BCAST MASK)
4577where IFNAME is the interface name, IP the IP address,
4578BCAST the broadcast address, and MASK the network mask.
4579
4580Optional parameter FAMILY controls the type of addresses to return.
4581The default of nil means both IPv4 and IPv6, symbol `ipv4' means IPv4
4582only, symbol `ipv6' means IPv6 only.
4583
4584See also `network-interface-info', which is limited to IPv4 only.
4558 4585
4559If the information is not available, return nil. */) 4586If the information is not available, return nil. */)
4560 (void) 4587 (Lisp_Object full, Lisp_Object family)
4561{ 4588{
4562#if (defined HAVE_NET_IF_H && defined SIOCGIFCONF) || defined WINDOWSNT 4589#if defined HAVE_GETIFADDRS || defined WINDOWSNT
4563 return network_interface_list (); 4590 unsigned short match;
4591 bool full_info = false;
4592
4593 if (! NILP (full))
4594 full_info = true;
4595 if (NILP (family))
4596 match = 0;
4597 else if (EQ (family, Qipv4))
4598 match = AF_INET;
4599#ifdef AF_INET6
4600 else if (EQ (family, Qipv6))
4601 match = AF_INET6;
4602#endif
4603 else
4604 error ("Unsupported address family");
4605 return network_interface_list (full_info, match);
4564#else 4606#else
4565 return Qnil; 4607 return Qnil;
4566#endif 4608#endif
diff --git a/src/process.h b/src/process.h
index 5e957c4298e..bf15317eb4f 100644
--- a/src/process.h
+++ b/src/process.h
@@ -291,7 +291,7 @@ extern void catch_child_signal (void);
291extern void restore_nofile_limit (void); 291extern void restore_nofile_limit (void);
292 292
293#ifdef WINDOWSNT 293#ifdef WINDOWSNT
294extern Lisp_Object network_interface_list (void); 294extern Lisp_Object network_interface_list (bool full, unsigned short match);
295extern Lisp_Object network_interface_info (Lisp_Object); 295extern Lisp_Object network_interface_info (Lisp_Object);
296#endif 296#endif
297 297
diff --git a/src/w32.c b/src/w32.c
index 26ea15d8910..76c226892a4 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -227,6 +227,8 @@ typedef struct _REPARSE_DATA_BUFFER {
227#undef connect 227#undef connect
228#undef htons 228#undef htons
229#undef ntohs 229#undef ntohs
230#undef htonl
231#undef ntohl
230#undef inet_addr 232#undef inet_addr
231#undef gethostname 233#undef gethostname
232#undef gethostbyname 234#undef gethostbyname
@@ -326,6 +328,7 @@ static BOOL g_b_init_set_file_security_a;
326static BOOL g_b_init_set_named_security_info_w; 328static BOOL g_b_init_set_named_security_info_w;
327static BOOL g_b_init_set_named_security_info_a; 329static BOOL g_b_init_set_named_security_info_a;
328static BOOL g_b_init_get_adapters_info; 330static BOOL g_b_init_get_adapters_info;
331static BOOL g_b_init_get_adapters_addresses;
329static BOOL g_b_init_reg_open_key_ex_w; 332static BOOL g_b_init_reg_open_key_ex_w;
330static BOOL g_b_init_reg_query_value_ex_w; 333static BOOL g_b_init_reg_query_value_ex_w;
331static BOOL g_b_init_expand_environment_strings_w; 334static BOOL g_b_init_expand_environment_strings_w;
@@ -503,6 +506,12 @@ typedef BOOL (WINAPI *IsValidSecurityDescriptor_Proc) (PSECURITY_DESCRIPTOR);
503typedef DWORD (WINAPI *GetAdaptersInfo_Proc) ( 506typedef DWORD (WINAPI *GetAdaptersInfo_Proc) (
504 PIP_ADAPTER_INFO pAdapterInfo, 507 PIP_ADAPTER_INFO pAdapterInfo,
505 PULONG pOutBufLen); 508 PULONG pOutBufLen);
509typedef DWORD (WINAPI *GetAdaptersAddresses_Proc) (
510 ULONG,
511 ULONG,
512 PVOID,
513 PIP_ADAPTER_ADDRESSES,
514 PULONG);
506 515
507int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int); 516int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int);
508int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL); 517int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL);
@@ -1368,6 +1377,31 @@ get_adapters_info (PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
1368 return s_pfn_Get_Adapters_Info (pAdapterInfo, pOutBufLen); 1377 return s_pfn_Get_Adapters_Info (pAdapterInfo, pOutBufLen);
1369} 1378}
1370 1379
1380static DWORD WINAPI
1381get_adapters_addresses (ULONG family, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen)
1382{
1383 static GetAdaptersAddresses_Proc s_pfn_Get_Adapters_Addresses = NULL;
1384 HMODULE hm_iphlpapi = NULL;
1385
1386 if (is_windows_9x () == TRUE)
1387 return ERROR_NOT_SUPPORTED;
1388
1389 if (g_b_init_get_adapters_addresses == 0)
1390 {
1391 g_b_init_get_adapters_addresses = 1;
1392 hm_iphlpapi = LoadLibrary ("Iphlpapi.dll");
1393 if (hm_iphlpapi)
1394 s_pfn_Get_Adapters_Addresses = (GetAdaptersAddresses_Proc)
1395 get_proc_addr (hm_iphlpapi, "GetAdaptersAddresses");
1396 }
1397 if (s_pfn_Get_Adapters_Addresses == NULL)
1398 return ERROR_NOT_SUPPORTED;
1399 ULONG flags = GAA_FLAG_SKIP_ANYCAST
1400 | GAA_FLAG_SKIP_MULTICAST
1401 | GAA_FLAG_SKIP_DNS_SERVER;
1402 return s_pfn_Get_Adapters_Addresses (family, flags, NULL, pAdapterAddresses, pOutBufLen);
1403}
1404
1371static LONG WINAPI 1405static LONG WINAPI
1372reg_open_key_ex_w (HKEY hkey, LPCWSTR lpSubKey, DWORD ulOptions, 1406reg_open_key_ex_w (HKEY hkey, LPCWSTR lpSubKey, DWORD ulOptions,
1373 REGSAM samDesired, PHKEY phkResult) 1407 REGSAM samDesired, PHKEY phkResult)
@@ -7414,6 +7448,8 @@ int (PASCAL *pfn_WSACleanup) (void);
7414 7448
7415u_short (PASCAL *pfn_htons) (u_short hostshort); 7449u_short (PASCAL *pfn_htons) (u_short hostshort);
7416u_short (PASCAL *pfn_ntohs) (u_short netshort); 7450u_short (PASCAL *pfn_ntohs) (u_short netshort);
7451u_long (PASCAL *pfn_htonl) (u_long hostlong);
7452u_long (PASCAL *pfn_ntohl) (u_long netlong);
7417unsigned long (PASCAL *pfn_inet_addr) (const char * cp); 7453unsigned long (PASCAL *pfn_inet_addr) (const char * cp);
7418int (PASCAL *pfn_gethostname) (char * name, int namelen); 7454int (PASCAL *pfn_gethostname) (char * name, int namelen);
7419struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); 7455struct hostent * (PASCAL *pfn_gethostbyname) (const char * name);
@@ -7504,6 +7540,8 @@ init_winsock (int load_now)
7504 LOAD_PROC (shutdown); 7540 LOAD_PROC (shutdown);
7505 LOAD_PROC (htons); 7541 LOAD_PROC (htons);
7506 LOAD_PROC (ntohs); 7542 LOAD_PROC (ntohs);
7543 LOAD_PROC (htonl);
7544 LOAD_PROC (ntohl);
7507 LOAD_PROC (inet_addr); 7545 LOAD_PROC (inet_addr);
7508 LOAD_PROC (gethostname); 7546 LOAD_PROC (gethostname);
7509 LOAD_PROC (gethostbyname); 7547 LOAD_PROC (gethostbyname);
@@ -7884,6 +7922,19 @@ sys_ntohs (u_short netshort)
7884 return (winsock_lib != NULL) ? 7922 return (winsock_lib != NULL) ?
7885 pfn_ntohs (netshort) : netshort; 7923 pfn_ntohs (netshort) : netshort;
7886} 7924}
7925u_long
7926sys_htonl (u_long hostlong)
7927{
7928 return (winsock_lib != NULL) ?
7929 pfn_htonl (hostlong) : hostlong;
7930}
7931
7932u_long
7933sys_ntohl (u_long netlong)
7934{
7935 return (winsock_lib != NULL) ?
7936 pfn_ntohl (netlong) : netlong;
7937}
7887 7938
7888unsigned long 7939unsigned long
7889sys_inet_addr (const char * cp) 7940sys_inet_addr (const char * cp)
@@ -9382,9 +9433,197 @@ network_interface_get_info (Lisp_Object ifname)
9382} 9433}
9383 9434
9384Lisp_Object 9435Lisp_Object
9385network_interface_list (void) 9436network_interface_list (bool full, unsigned short match)
9386{ 9437{
9387 return network_interface_get_info (Qnil); 9438 ULONG ainfo_len = sizeof (IP_ADAPTER_ADDRESSES);
9439 ULONG family = match;
9440 IP_ADAPTER_ADDRESSES *adapter, *ainfo = xmalloc (ainfo_len);
9441 DWORD retval = get_adapters_addresses (family, ainfo, &ainfo_len);
9442 Lisp_Object res = Qnil;
9443
9444 if (retval == ERROR_BUFFER_OVERFLOW)
9445 {
9446 ainfo = xrealloc (ainfo, ainfo_len);
9447 retval = get_adapters_addresses (family, ainfo, &ainfo_len);
9448 }
9449
9450 if (retval != ERROR_SUCCESS)
9451 {
9452 xfree (ainfo);
9453 return res;
9454 }
9455
9456 /* For the below, we need some winsock functions, so make sure
9457 the winsock DLL is loaded. If we cannot successfully load
9458 it, they will have no use of the information we provide,
9459 anyway, so punt. */
9460 if (!winsock_lib && !init_winsock (1))
9461 return res;
9462
9463 int eth_count = 0, tr_count = 0, fddi_count = 0, ppp_count = 0;
9464 int sl_count = 0, wlan_count = 0, lo_count = 0, ifx_count = 0;
9465 int tnl_count = 0;
9466 int if_num;
9467 char namebuf[MAX_ADAPTER_NAME_LENGTH + 4];
9468 static const char *ifmt[] = {
9469 "eth%d", "tr%d", "fddi%d", "ppp%d", "sl%d", "wlan%d",
9470 "lo%d", "ifx%d", "tunnel%d"
9471 };
9472 enum {
9473 NONE = -1,
9474 ETHERNET = 0,
9475 TOKENRING = 1,
9476 FDDI = 2,
9477 PPP = 3,
9478 SLIP = 4,
9479 WLAN = 5,
9480 LOOPBACK = 6,
9481 OTHER_IF = 7,
9482 TUNNEL = 8
9483 } ifmt_idx;
9484
9485 for (adapter = ainfo; adapter; adapter = adapter->Next)
9486 {
9487
9488 /* Present Unix-compatible interface names, instead of the
9489 Windows names, which are really GUIDs not readable by
9490 humans. */
9491
9492 switch (adapter->IfType)
9493 {
9494 case IF_TYPE_ETHERNET_CSMACD:
9495 ifmt_idx = ETHERNET;
9496 if_num = eth_count++;
9497 break;
9498 case IF_TYPE_ISO88025_TOKENRING:
9499 ifmt_idx = TOKENRING;
9500 if_num = tr_count++;
9501 break;
9502 case IF_TYPE_FDDI:
9503 ifmt_idx = FDDI;
9504 if_num = fddi_count++;
9505 break;
9506 case IF_TYPE_PPP:
9507 ifmt_idx = PPP;
9508 if_num = ppp_count++;
9509 break;
9510 case IF_TYPE_SLIP:
9511 ifmt_idx = SLIP;
9512 if_num = sl_count++;
9513 break;
9514 case IF_TYPE_IEEE80211:
9515 ifmt_idx = WLAN;
9516 if_num = wlan_count++;
9517 break;
9518 case IF_TYPE_SOFTWARE_LOOPBACK:
9519 ifmt_idx = LOOPBACK;
9520 if_num = lo_count++;
9521 break;
9522 case IF_TYPE_TUNNEL:
9523 ifmt_idx = TUNNEL;
9524 if_num = tnl_count++;
9525 break;
9526 default:
9527 ifmt_idx = OTHER_IF;
9528 if_num = ifx_count++;
9529 break;
9530 }
9531 sprintf (namebuf, ifmt[ifmt_idx], if_num);
9532
9533 IP_ADAPTER_UNICAST_ADDRESS *address;
9534 for (address = adapter->FirstUnicastAddress; address; address = address->Next)
9535 {
9536 int len;
9537 int addr_len;
9538 uint32_t *maskp;
9539 uint32_t *addrp;
9540 Lisp_Object elt = Qnil;
9541 struct sockaddr *ifa_addr = address->Address.lpSockaddr;
9542
9543 if (ifa_addr == NULL)
9544 continue;
9545 if (match && ifa_addr->sa_family != match)
9546 continue;
9547
9548 struct sockaddr_in ipv4;
9549#ifdef AF_INET6
9550 struct sockaddr_in6 ipv6;
9551#endif
9552 struct sockaddr *sin;
9553
9554 if (ifa_addr->sa_family == AF_INET)
9555 {
9556 ipv4.sin_family = AF_INET;
9557 ipv4.sin_port = 0;
9558 DECLARE_POINTER_ALIAS (sin_in, struct sockaddr_in, ifa_addr);
9559 addrp = (uint32_t *)&sin_in->sin_addr;
9560 maskp = (uint32_t *)&ipv4.sin_addr;
9561 sin = (struct sockaddr *)&ipv4;
9562 len = sizeof (struct sockaddr_in);
9563 addr_len = 1;
9564 }
9565#ifdef AF_INET6
9566 else if (ifa_addr->sa_family == AF_INET6)
9567 {
9568 ipv6.sin6_family = AF_INET6;
9569 ipv6.sin6_port = 0;
9570 DECLARE_POINTER_ALIAS (sin_in6, struct sockaddr_in6, ifa_addr);
9571 addrp = (uint32_t *)&sin_in6->sin6_addr;
9572 maskp = (uint32_t *)&ipv6.sin6_addr;
9573 sin = (struct sockaddr *)&ipv6;
9574 len = sizeof (struct sockaddr_in6);
9575 addr_len = 4;
9576 }
9577#endif
9578 else
9579 continue;
9580
9581 Lisp_Object addr = conv_sockaddr_to_lisp (ifa_addr, len);
9582
9583 if (full)
9584 {
9585 /* GetAdaptersAddress returns information in network
9586 byte order, so convert from host to network order
9587 when generating the netmask. */
9588 int i;
9589 ULONG numbits = address->OnLinkPrefixLength;
9590 for (i = 0; i < addr_len; i++)
9591 {
9592 if (numbits >= 32)
9593 {
9594 maskp[i] = -1U;
9595 numbits -= 32;
9596 }
9597 else if (numbits)
9598 {
9599 maskp[i] = sys_htonl (-1U << (32 - numbits));
9600 numbits = 0;
9601 }
9602 else
9603 {
9604 maskp[i] = 0;
9605 }
9606 }
9607 elt = Fcons (conv_sockaddr_to_lisp (sin, len), elt);
9608 uint32_t mask;
9609 for (i = 0; i < addr_len; i++)
9610 {
9611 mask = maskp[i];
9612 maskp[i] = (addrp[i] & mask) | ~mask;
9613
9614 }
9615 elt = Fcons (conv_sockaddr_to_lisp (sin, len), elt);
9616 elt = Fcons (addr, elt);
9617 }
9618 else
9619 {
9620 elt = addr;
9621 }
9622 res = Fcons (Fcons (build_string (namebuf), elt), res);
9623 }
9624 }
9625 xfree (ainfo);
9626 return res;
9388} 9627}
9389 9628
9390Lisp_Object 9629Lisp_Object
@@ -10099,6 +10338,7 @@ globals_of_w32 (void)
10099 g_b_init_set_named_security_info_w = 0; 10338 g_b_init_set_named_security_info_w = 0;
10100 g_b_init_set_named_security_info_a = 0; 10339 g_b_init_set_named_security_info_a = 0;
10101 g_b_init_get_adapters_info = 0; 10340 g_b_init_get_adapters_info = 0;
10341 g_b_init_get_adapters_addresses = 0;
10102 g_b_init_reg_open_key_ex_w = 0; 10342 g_b_init_reg_open_key_ex_w = 0;
10103 g_b_init_reg_query_value_ex_w = 0; 10343 g_b_init_reg_query_value_ex_w = 0;
10104 g_b_init_expand_environment_strings_w = 0; 10344 g_b_init_expand_environment_strings_w = 0;