Package: emacs;
Reported by: Robert Pluim <rpluim <at> gmail.com>
Date: Fri, 15 Nov 2019 10:14:02 UTC
Severity: normal
Tags: fixed
Fixed in version 27.1
Done: Robert Pluim <rpluim <at> gmail.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 38218 in the body.
You can then email your comments to 38218 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Fri, 15 Nov 2019 10:14:02 GMT) Full text and rfc822 format available.Message #3 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Robert Pluim <rpluim <at> gmail.com> To: bug-gnu-emacs <at> gnu.org Subject: network-interface-list only returns IPv4 addresses Date: Fri, 15 Nov 2019 11:13:03 +0100
The current (2019-11-15) implementation of network-interface-list only supports returning IPv4 addresses, it should return IPv6 addresses as well (where possible).
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Fri, 15 Nov 2019 10:19:01 GMT) Full text and rfc822 format available.Message #6 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Robert Pluim <rpluim <at> gmail.com> To: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Fri, 15 Nov 2019 11:18:41 +0100
[Message part 1 (text/plain, inline)]
>>>>> On Fri, 15 Nov 2019 11:13:03 +0100, Robert Pluim <rpluim <at> gmail.com> said: Robert> The current (2019-11-15) implementation of network-interface-list only Robert> supports returning IPv4 addresses, it should return IPv6 addresses as Robert> well (where possible). The following has been tested on macOS 10.14, Fedora 30, and mingw64 running on Windows 10.
[0001-Extend-network-interface-list-to-return-IPv6-and-net.patch (text/x-patch, inline)]
From 5eb703f8ed12af8205bf8cd5ba99baa5137a5dfa Mon Sep 17 00:00:00 2001 From: Robert Pluim <rpluim <at> gmail.com> Date: Fri, 15 Nov 2019 11:11:30 +0100 Subject: [PATCH] Extend network-interface-list to return IPv6 and network info To: emacs-devel <at> gnu.org 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. --- doc/lispref/processes.texi | 29 ++++- etc/NEWS | 5 + nt/inc/sys/socket.h | 4 + src/process.c | 158 +++++++++++++++--------- src/process.h | 2 +- src/w32.c | 244 ++++++++++++++++++++++++++++++++++++- 6 files changed, 375 insertions(+), 67 deletions(-) diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi index 5caf0a2426..63383efb70 100644 --- a/doc/lispref/processes.texi +++ b/doc/lispref/processes.texi @@ -2971,12 +2971,27 @@ Misc Network on network connections. Note that they are supported only on some systems. -@defun network-interface-list -This function returns a list describing the network interfaces -of the machine you are using. The value is an alist whose -elements have the form @code{(@var{name} . @var{address})}. -@var{address} has the same form as the @var{local-address} -and @var{remote-address} arguments to @code{make-network-process}. +@defun network-interface-list &optional full family +This function returns a list describing the network interfaces of the +machine you are using. The value is an alist whose elements have the +form @code{(@var{ifname} . @var{address})}. @var{ifname} is a string +naming the interface, @var{address} has the same form as the +@var{local-address} and @var{remote-address} arguments to +@code{make-network-process}, i.e. a vector of integers. By default +both IPv4 and IPv6 addresses are returned if possible. + +Optional argument @var{full} non-@code{nil} means to instead return a +list of one or more elements of the form @w{@code{(@var{ifname} +@var{addr} @var{bcast} @var{netmask})}}. @var{ifname} is a non-unique +string naming the interface. @var{addr}, @var{bcast}, and +@var{netmask} are vectors of integers detailing the IP address, +broadcast address, and network mask. + +Optional argument @var{family} specified as symbol @code{ipv4} or +@code{ipv6} restricts the returned information to IPv4 and IPv6 +addresses respectively, independently of the value of @var{full}. +Speficying @code{ipv6} when IPv6 support is not available will result +in an error being signaled. @end defun @defun network-interface-info ifname @@ -2996,6 +3011,8 @@ Misc Network @item flags The current flags of the interface. @end table + +Note that this function returns only IPv4 information. @end defun @defun format-network-address address &optional omit-port diff --git a/etc/NEWS b/etc/NEWS index 485d2b1fdf..d73db73c9e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -234,6 +234,11 @@ To get the old, less-secure behavior, you can set the ** New function 'network-lookup-address-info'. This does IPv4 and/or IPv6 address lookups on hostnames. ++++ +** 'network-interface-list' can now return IPv4 and IPv6 addresses. +IPv4 and IPv6 addresses are now returned by default if available, +optionally including netmask/broadcast address information. + --- ** Control of the threshold for using the 'distant-foreground' color. The threshold for color distance below which the 'distant-foreground' diff --git a/nt/inc/sys/socket.h b/nt/inc/sys/socket.h index 6d26ff907e..0f3943b453 100644 --- a/nt/inc/sys/socket.h +++ b/nt/inc/sys/socket.h @@ -92,6 +92,8 @@ #define bind sys_bind #define connect sys_connect #define htons sys_htons #define ntohs sys_ntohs +#define htonl sys_htonl +#define ntohl sys_ntohl #define inet_addr sys_inet_addr #define gethostname sys_gethostname #define gethostbyname sys_gethostbyname @@ -112,6 +114,8 @@ #define freeaddrinfo sys_freeaddrinfo int sys_connect (int s, const struct sockaddr *addr, int namelen); u_short sys_htons (u_short hostshort); u_short sys_ntohs (u_short netshort); +u_long sys_htonl (u_long hostlong); +u_long sys_ntohl (u_long netlong); unsigned long sys_inet_addr (const char * cp); int sys_gethostname (char * name, int namelen); struct hostent * sys_gethostbyname (const char * name); diff --git a/src/process.c b/src/process.c index 9158cfd347..0f82682ae5 100644 --- a/src/process.c +++ b/src/process.c @@ -4255,73 +4255,86 @@ DEFUN ("make-network-process", Fmake_network_process, Smake_network_process, } -#ifdef HAVE_NET_IF_H -#ifdef SIOCGIFCONF +#ifdef HAVE_GETIFADDRS static Lisp_Object -network_interface_list (void) +network_interface_list (bool full, unsigned short match) { - struct ifconf ifconf; - struct ifreq *ifreq; - void *buf = NULL; - ptrdiff_t buf_size = 512; - int s; - Lisp_Object res; - ptrdiff_t count; + Lisp_Object res = Qnil; + struct ifaddrs *ifap; - s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (s < 0) + if (getifaddrs (&ifap) == -1) return Qnil; - count = SPECPDL_INDEX (); - record_unwind_protect_int (close_file_unwind, s); - do + for (struct ifaddrs *it = ifap; it != NULL; it = it->ifa_next) { - buf = xpalloc (buf, &buf_size, 1, INT_MAX, 1); - ifconf.ifc_buf = buf; - ifconf.ifc_len = buf_size; - if (ioctl (s, SIOCGIFCONF, &ifconf)) - { - emacs_close (s); - xfree (buf); - return Qnil; - } - } - while (ifconf.ifc_len == buf_size); - - res = unbind_to (count, Qnil); - ifreq = ifconf.ifc_req; - while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) - { - struct ifreq *ifq = ifreq; -#ifdef HAVE_STRUCT_IFREQ_IFR_ADDR_SA_LEN -#define SIZEOF_IFREQ(sif) \ - ((sif)->ifr_addr.sa_len < sizeof (struct sockaddr) \ - ? sizeof (*(sif)) : sizeof ((sif)->ifr_name) + (sif)->ifr_addr.sa_len) + int len; + int addr_len; + uint32_t *maskp; + uint32_t *addrp; + Lisp_Object elt = Qnil; - int len = SIZEOF_IFREQ (ifq); -#else - int len = sizeof (*ifreq); + /* BSD can allegedly return interfaces with a NULL address. */ + if (it->ifa_addr == NULL) + continue; + if (match && it->ifa_addr->sa_family != match) + continue; + if (it->ifa_addr->sa_family == AF_INET) + { + DECLARE_POINTER_ALIAS (sin1, struct sockaddr_in, it->ifa_netmask); + maskp = (uint32_t *)&sin1->sin_addr; + DECLARE_POINTER_ALIAS (sin2, struct sockaddr_in, it->ifa_addr); + addrp = (uint32_t *)&sin2->sin_addr; + len = sizeof (struct sockaddr_in); + addr_len = 1; + } +#ifdef AF_INET6 + else if (it->ifa_addr->sa_family == AF_INET6) + { + DECLARE_POINTER_ALIAS (sin6_1, struct sockaddr_in6, it->ifa_netmask); + maskp = (uint32_t *) &sin6_1->sin6_addr; + DECLARE_POINTER_ALIAS (sin6_2, struct sockaddr_in6, it->ifa_addr); + addrp = (uint32_t *) &sin6_2->sin6_addr; + len = sizeof (struct sockaddr_in6); + addr_len = 4; + } #endif - char namebuf[sizeof (ifq->ifr_name) + 1]; - ifreq = (struct ifreq *) ((char *) ifreq + len); + else + continue; - if (ifq->ifr_addr.sa_family != AF_INET) - continue; + Lisp_Object addr = conv_sockaddr_to_lisp (it->ifa_addr, len); - memcpy (namebuf, ifq->ifr_name, sizeof (ifq->ifr_name)); - namebuf[sizeof (ifq->ifr_name)] = 0; - res = Fcons (Fcons (build_string (namebuf), - conv_sockaddr_to_lisp (&ifq->ifr_addr, - sizeof (struct sockaddr))), - res); + if (full) + { + elt = Fcons (conv_sockaddr_to_lisp (it->ifa_netmask, len), elt); + /* There is an it->ifa_broadaddr field, but its contents are + unreliable, so always calculate the broadcast address from + the address and the netmask. */ + int i; + uint32_t mask; + for (i = 0; i < addr_len; i++) + { + mask = maskp[i]; + maskp[i] = (addrp[i] & mask) | ~mask; + } + elt = Fcons (conv_sockaddr_to_lisp (it->ifa_netmask, len), elt); + elt = Fcons (addr, elt); + } + else + { + elt = addr; + } + res = Fcons (Fcons (build_string (it->ifa_name), elt), res); } +#ifdef HAVE_FREEIFADDRS + freeifaddrs (ifap); +#endif - xfree (buf); return res; } -#endif /* SIOCGIFCONF */ +#endif /* HAVE_GETIFADDRS */ +#ifdef HAVE_NET_IF_H #if defined (SIOCGIFADDR) || defined (SIOCGIFHWADDR) || defined (SIOCGIFFLAGS) struct ifflag_def { @@ -4550,17 +4563,46 @@ network_interface_info (Lisp_Object ifname) #endif /* defined (HAVE_NET_IF_H) */ DEFUN ("network-interface-list", Fnetwork_interface_list, - Snetwork_interface_list, 0, 0, 0, + Snetwork_interface_list, 0, 2, 0, doc: /* Return an alist of all network interfaces and their network address. -Each element is a cons, the car of which is a string containing the -interface name, and the cdr is the network address in internal -format; see the description of ADDRESS in `make-network-process'. +Each element is cons of the form (IFNAME . IP) where IFNAME is a +string containing the interface name, and IP is the network address in +internal format; see the description of ADDRESS in +`make-network-process'. The interface name is not guaranteed to be +unique. + +Optional parameter FULL non-nil means return all IP address info for +each interface. Each element is then a list of the form + (IFNAME IP BCAST MASK) +where IFNAME is the interface name, IP the IP address, +BCAST the broadcast address, and MASK the network mask. + +Optional parameter FAMILY controls the type of addresses to return. +The default of nil means both IPv4 and IPv6, symbol `ipv4' means IPv4 +only, symbol `ipv6' means IPv6 only. + +See also `network-interface-info', which is limited to IPv4 only. If the information is not available, return nil. */) - (void) + (Lisp_Object full, Lisp_Object family) { -#if (defined HAVE_NET_IF_H && defined SIOCGIFCONF) || defined WINDOWSNT - return network_interface_list (); +#if defined HAVE_GETIFADDRS || defined WINDOWSNT + unsigned short match; + bool full_info = false; + + if (! NILP (full)) + full_info = true; + if (NILP (family)) + match = 0; + else if (EQ (family, Qipv4)) + match = AF_INET; +#ifdef AF_INET6 + else if (EQ (family, Qipv6)) + match = AF_INET6; +#endif + else + error ("Unsupported address family"); + return network_interface_list (full_info, match); #else return Qnil; #endif diff --git a/src/process.h b/src/process.h index 5e957c4298..bf15317eb4 100644 --- a/src/process.h +++ b/src/process.h @@ -291,7 +291,7 @@ pset_gnutls_cred_type (struct Lisp_Process *p, Lisp_Object val) extern void restore_nofile_limit (void); #ifdef WINDOWSNT -extern Lisp_Object network_interface_list (void); +extern Lisp_Object network_interface_list (bool full, unsigned short match); extern Lisp_Object network_interface_info (Lisp_Object); #endif diff --git a/src/w32.c b/src/w32.c index 26ea15d891..76c226892a 100644 --- a/src/w32.c +++ b/src/w32.c @@ -227,6 +227,8 @@ #define FSCTL_GET_REPARSE_POINT \ #undef connect #undef htons #undef ntohs +#undef htonl +#undef ntohl #undef inet_addr #undef gethostname #undef gethostbyname @@ -326,6 +328,7 @@ #define FSCTL_GET_REPARSE_POINT \ static BOOL g_b_init_set_named_security_info_w; static BOOL g_b_init_set_named_security_info_a; static BOOL g_b_init_get_adapters_info; +static BOOL g_b_init_get_adapters_addresses; static BOOL g_b_init_reg_open_key_ex_w; static BOOL g_b_init_reg_query_value_ex_w; static BOOL g_b_init_expand_environment_strings_w; @@ -503,6 +506,12 @@ #define FSCTL_GET_REPARSE_POINT \ typedef DWORD (WINAPI *GetAdaptersInfo_Proc) ( PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen); +typedef DWORD (WINAPI *GetAdaptersAddresses_Proc) ( + ULONG, + ULONG, + PVOID, + PIP_ADAPTER_ADDRESSES, + PULONG); int (WINAPI *pMultiByteToWideChar)(UINT,DWORD,LPCSTR,int,LPWSTR,int); int (WINAPI *pWideCharToMultiByte)(UINT,DWORD,LPCWSTR,int,LPSTR,int,LPCSTR,LPBOOL); @@ -1368,6 +1377,31 @@ get_adapters_info (PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) return s_pfn_Get_Adapters_Info (pAdapterInfo, pOutBufLen); } +static DWORD WINAPI +get_adapters_addresses (ULONG family, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen) +{ + static GetAdaptersAddresses_Proc s_pfn_Get_Adapters_Addresses = NULL; + HMODULE hm_iphlpapi = NULL; + + if (is_windows_9x () == TRUE) + return ERROR_NOT_SUPPORTED; + + if (g_b_init_get_adapters_addresses == 0) + { + g_b_init_get_adapters_addresses = 1; + hm_iphlpapi = LoadLibrary ("Iphlpapi.dll"); + if (hm_iphlpapi) + s_pfn_Get_Adapters_Addresses = (GetAdaptersAddresses_Proc) + get_proc_addr (hm_iphlpapi, "GetAdaptersAddresses"); + } + if (s_pfn_Get_Adapters_Addresses == NULL) + return ERROR_NOT_SUPPORTED; + ULONG flags = GAA_FLAG_SKIP_ANYCAST + | GAA_FLAG_SKIP_MULTICAST + | GAA_FLAG_SKIP_DNS_SERVER; + return s_pfn_Get_Adapters_Addresses (family, flags, NULL, pAdapterAddresses, pOutBufLen); +} + static LONG WINAPI reg_open_key_ex_w (HKEY hkey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) @@ -7414,6 +7448,8 @@ int (PASCAL *pfn_WSACleanup) (void); u_short (PASCAL *pfn_htons) (u_short hostshort); u_short (PASCAL *pfn_ntohs) (u_short netshort); +u_long (PASCAL *pfn_htonl) (u_long hostlong); +u_long (PASCAL *pfn_ntohl) (u_long netlong); unsigned long (PASCAL *pfn_inet_addr) (const char * cp); int (PASCAL *pfn_gethostname) (char * name, int namelen); struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); @@ -7504,6 +7540,8 @@ #define LOAD_PROC(fn) \ LOAD_PROC (shutdown); LOAD_PROC (htons); LOAD_PROC (ntohs); + LOAD_PROC (htonl); + LOAD_PROC (ntohl); LOAD_PROC (inet_addr); LOAD_PROC (gethostname); LOAD_PROC (gethostbyname); @@ -7884,6 +7922,19 @@ sys_ntohs (u_short netshort) return (winsock_lib != NULL) ? pfn_ntohs (netshort) : netshort; } +u_long +sys_htonl (u_long hostlong) +{ + return (winsock_lib != NULL) ? + pfn_htonl (hostlong) : hostlong; +} + +u_long +sys_ntohl (u_long netlong) +{ + return (winsock_lib != NULL) ? + pfn_ntohl (netlong) : netlong; +} unsigned long sys_inet_addr (const char * cp) @@ -9382,9 +9433,197 @@ network_interface_get_info (Lisp_Object ifname) } Lisp_Object -network_interface_list (void) +network_interface_list (bool full, unsigned short match) { - return network_interface_get_info (Qnil); + ULONG ainfo_len = sizeof (IP_ADAPTER_ADDRESSES); + ULONG family = match; + IP_ADAPTER_ADDRESSES *adapter, *ainfo = xmalloc (ainfo_len); + DWORD retval = get_adapters_addresses (family, ainfo, &ainfo_len); + Lisp_Object res = Qnil; + + if (retval == ERROR_BUFFER_OVERFLOW) + { + ainfo = xrealloc (ainfo, ainfo_len); + retval = get_adapters_addresses (family, ainfo, &ainfo_len); + } + + if (retval != ERROR_SUCCESS) + { + xfree (ainfo); + return res; + } + + /* For the below, we need some winsock functions, so make sure + the winsock DLL is loaded. If we cannot successfully load + it, they will have no use of the information we provide, + anyway, so punt. */ + if (!winsock_lib && !init_winsock (1)) + return res; + + int eth_count = 0, tr_count = 0, fddi_count = 0, ppp_count = 0; + int sl_count = 0, wlan_count = 0, lo_count = 0, ifx_count = 0; + int tnl_count = 0; + int if_num; + char namebuf[MAX_ADAPTER_NAME_LENGTH + 4]; + static const char *ifmt[] = { + "eth%d", "tr%d", "fddi%d", "ppp%d", "sl%d", "wlan%d", + "lo%d", "ifx%d", "tunnel%d" + }; + enum { + NONE = -1, + ETHERNET = 0, + TOKENRING = 1, + FDDI = 2, + PPP = 3, + SLIP = 4, + WLAN = 5, + LOOPBACK = 6, + OTHER_IF = 7, + TUNNEL = 8 + } ifmt_idx; + + for (adapter = ainfo; adapter; adapter = adapter->Next) + { + + /* Present Unix-compatible interface names, instead of the + Windows names, which are really GUIDs not readable by + humans. */ + + switch (adapter->IfType) + { + case IF_TYPE_ETHERNET_CSMACD: + ifmt_idx = ETHERNET; + if_num = eth_count++; + break; + case IF_TYPE_ISO88025_TOKENRING: + ifmt_idx = TOKENRING; + if_num = tr_count++; + break; + case IF_TYPE_FDDI: + ifmt_idx = FDDI; + if_num = fddi_count++; + break; + case IF_TYPE_PPP: + ifmt_idx = PPP; + if_num = ppp_count++; + break; + case IF_TYPE_SLIP: + ifmt_idx = SLIP; + if_num = sl_count++; + break; + case IF_TYPE_IEEE80211: + ifmt_idx = WLAN; + if_num = wlan_count++; + break; + case IF_TYPE_SOFTWARE_LOOPBACK: + ifmt_idx = LOOPBACK; + if_num = lo_count++; + break; + case IF_TYPE_TUNNEL: + ifmt_idx = TUNNEL; + if_num = tnl_count++; + break; + default: + ifmt_idx = OTHER_IF; + if_num = ifx_count++; + break; + } + sprintf (namebuf, ifmt[ifmt_idx], if_num); + + IP_ADAPTER_UNICAST_ADDRESS *address; + for (address = adapter->FirstUnicastAddress; address; address = address->Next) + { + int len; + int addr_len; + uint32_t *maskp; + uint32_t *addrp; + Lisp_Object elt = Qnil; + struct sockaddr *ifa_addr = address->Address.lpSockaddr; + + if (ifa_addr == NULL) + continue; + if (match && ifa_addr->sa_family != match) + continue; + + struct sockaddr_in ipv4; +#ifdef AF_INET6 + struct sockaddr_in6 ipv6; +#endif + struct sockaddr *sin; + + if (ifa_addr->sa_family == AF_INET) + { + ipv4.sin_family = AF_INET; + ipv4.sin_port = 0; + DECLARE_POINTER_ALIAS (sin_in, struct sockaddr_in, ifa_addr); + addrp = (uint32_t *)&sin_in->sin_addr; + maskp = (uint32_t *)&ipv4.sin_addr; + sin = (struct sockaddr *)&ipv4; + len = sizeof (struct sockaddr_in); + addr_len = 1; + } +#ifdef AF_INET6 + else if (ifa_addr->sa_family == AF_INET6) + { + ipv6.sin6_family = AF_INET6; + ipv6.sin6_port = 0; + DECLARE_POINTER_ALIAS (sin_in6, struct sockaddr_in6, ifa_addr); + addrp = (uint32_t *)&sin_in6->sin6_addr; + maskp = (uint32_t *)&ipv6.sin6_addr; + sin = (struct sockaddr *)&ipv6; + len = sizeof (struct sockaddr_in6); + addr_len = 4; + } +#endif + else + continue; + + Lisp_Object addr = conv_sockaddr_to_lisp (ifa_addr, len); + + if (full) + { + /* GetAdaptersAddress returns information in network + byte order, so convert from host to network order + when generating the netmask. */ + int i; + ULONG numbits = address->OnLinkPrefixLength; + for (i = 0; i < addr_len; i++) + { + if (numbits >= 32) + { + maskp[i] = -1U; + numbits -= 32; + } + else if (numbits) + { + maskp[i] = sys_htonl (-1U << (32 - numbits)); + numbits = 0; + } + else + { + maskp[i] = 0; + } + } + elt = Fcons (conv_sockaddr_to_lisp (sin, len), elt); + uint32_t mask; + for (i = 0; i < addr_len; i++) + { + mask = maskp[i]; + maskp[i] = (addrp[i] & mask) | ~mask; + + } + elt = Fcons (conv_sockaddr_to_lisp (sin, len), elt); + elt = Fcons (addr, elt); + } + else + { + elt = addr; + } + res = Fcons (Fcons (build_string (namebuf), elt), res); + } + } + xfree (ainfo); + return res; } Lisp_Object @@ -10099,6 +10338,7 @@ globals_of_w32 (void) g_b_init_set_named_security_info_w = 0; g_b_init_set_named_security_info_a = 0; g_b_init_get_adapters_info = 0; + g_b_init_get_adapters_addresses = 0; g_b_init_reg_open_key_ex_w = 0; g_b_init_reg_query_value_ex_w = 0; g_b_init_expand_environment_strings_w = 0; -- 2.23.0
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Sat, 16 Nov 2019 05:18:01 GMT) Full text and rfc822 format available.Message #9 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Lars Ingebrigtsen <larsi <at> gnus.org> To: Robert Pluim <rpluim <at> gmail.com> Cc: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Sat, 16 Nov 2019 06:17:10 +0100
Robert Pluim <rpluim <at> gmail.com> writes: > +Optional argument @var{full} non-@code{nil} means to instead return a > +list of one or more elements of the form @w{@code{(@var{ifname} > +@var{addr} @var{bcast} @var{netmask})}}. @var{ifname} is a non-unique > +string naming the interface. @var{addr}, @var{bcast}, and > +@var{netmask} are vectors of integers detailing the IP address, > +broadcast address, and network mask. I think it might make sense to include an example output from the function here to make it clearer what the string bit is, in particular. I've otherwise just skimmed the patch (and not tried it), but it makes sense to me. -- (domestic pets only, the antidote for overdose, milk.) bloggy blog: http://lars.ingebrigtsen.no
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Sun, 17 Nov 2019 20:51:01 GMT) Full text and rfc822 format available.Message #12 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Robert Pluim <rpluim <at> gmail.com> To: Lars Ingebrigtsen <larsi <at> gnus.org> Cc: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Sun, 17 Nov 2019 21:50:00 +0100
>>>>> On Sat, 16 Nov 2019 06:17:10 +0100, Lars Ingebrigtsen <larsi <at> gnus.org> said: Lars> Robert Pluim <rpluim <at> gmail.com> writes: >> +Optional argument @var{full} non-@code{nil} means to instead return a >> +list of one or more elements of the form @w{@code{(@var{ifname} >> +@var{addr} @var{bcast} @var{netmask})}}. @var{ifname} is a non-unique >> +string naming the interface. @var{addr}, @var{bcast}, and >> +@var{netmask} are vectors of integers detailing the IP address, >> +broadcast address, and network mask. Lars> I think it might make sense to include an example output from the Lars> function here to make it clearer what the string bit is, in particular. Sure. Lars> I've otherwise just skimmed the patch (and not tried it), but it makes Lars> sense to me. Iʼll just push and wait for the screams then. (Eli, thatʼs a joke). Robert
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Tue, 26 Nov 2019 08:39:01 GMT) Full text and rfc822 format available.Message #15 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Robert Pluim <rpluim <at> gmail.com> To: Lars Ingebrigtsen <larsi <at> gnus.org> Cc: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Tue, 26 Nov 2019 09:37:53 +0100
tags 38218 fixed close 38218 27.1 quit >>>>> On Sun, 17 Nov 2019 21:50:00 +0100, Robert Pluim <rpluim <at> gmail.com> said: >>>>> On Sat, 16 Nov 2019 06:17:10 +0100, Lars Ingebrigtsen <larsi <at> gnus.org> said: Lars> I've otherwise just skimmed the patch (and not tried it), but it makes Lars> sense to me. Robert> Iʼll just push and wait for the screams then. (Eli, thatʼs a joke). Iʼve now pushed it. Closing. Committed as 650a514e99
Robert Pluim <rpluim <at> gmail.com>
to control <at> debbugs.gnu.org
.
(Tue, 26 Nov 2019 08:39:01 GMT) Full text and rfc822 format available.Robert Pluim <rpluim <at> gmail.com>
to control <at> debbugs.gnu.org
.
(Tue, 26 Nov 2019 08:39:02 GMT) Full text and rfc822 format available.bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Tue, 26 Nov 2019 17:18:01 GMT) Full text and rfc822 format available.Message #22 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: Robert Pluim <rpluim <at> gmail.com> Cc: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Tue, 26 Nov 2019 19:17:49 +0200
> From: Robert Pluim <rpluim <at> gmail.com> > Date: Tue, 26 Nov 2019 09:37:53 +0100 > Cc: 38218 <at> debbugs.gnu.org > > Robert> Iʼll just push and wait for the screams then. (Eli, thatʼs a joke). > > Iʼve now pushed it. It needed a bit of tweaking for mingw.org's MinGW, so that it would work on XP. However, after making the changes, one test from nsm-tests.el fails here: 127.1/0 No such host is known. 127.1/0 No such host is known. Test nsm-check-local-subnet-ipv4 backtrace: signal(ert-test-failed (((should (eq nil (nsm-should-check "127.1") ert-fail(((should (eq nil (nsm-should-check "127.1"))) :form (eq ni (if (unwind-protect (setq value-44 (apply fn-42 args-43)) (setq for (let (form-description-46) (if (unwind-protect (setq value-44 (appl (let ((value-44 'ert-form-evaluation-aborted-45)) (let (form-descri (let* ((fn-42 #'eq) (args-43 (condition-case err (let ((signal-hook (let ((nsm-trust-local-network t)) (let* ((fn-37 #'eq) (args-38 (co (let ((local-ip '[172 26 128 160 0]) (mask '[255 255 255 0 0]) (wro (closure (t) nil (let ((local-ip '[172 26 128 160 0]) (mask '[255 2 ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-tes ert-run-test(#s(ert-test :name nsm-check-local-subnet-ipv4 :documen ert-run-or-rerun-test(#s(ert--stats :selector (not (tag :unstable)) ert-run-tests((not (tag :unstable)) #f(compiled-function (event-typ ert-run-tests-batch((not (tag :unstable))) ert-run-tests-batch-and-exit((not (tag :unstable))) eval((ert-run-tests-batch-and-exit '(not (tag :unstable))) t) command-line-1((#("-L" 0 2 (charset cp862)) #(";." 0 2 (charset cp8 command-line() normal-top-level() Test nsm-check-local-subnet-ipv4 condition: (ert-test-failed ((should (eq nil (nsm-should-check "127.1"))) :form (eq nil t) :value nil)) FAILED 1/2 nsm-check-local-subnet-ipv4 (4.656250 sec) Does it work for you in your MinGW build? If so, could you eyeball the code I added/modified in w32.c to see if I goofed somewhere? Thanks.
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Tue, 26 Nov 2019 18:11:02 GMT) Full text and rfc822 format available.Message #25 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Robert Pluim <rpluim <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Tue, 26 Nov 2019 19:10:04 +0100
[Message part 1 (text/plain, inline)]
>>>>> On Tue, 26 Nov 2019 19:17:49 +0200, Eli Zaretskii <eliz <at> gnu.org> said: Eli> It needed a bit of tweaking for mingw.org's MinGW, so that it would Eli> work on XP. However, after making the changes, one test from Eli> nsm-tests.el fails here: Thanks for that Eli> 127.1/0 No such host is known. Eli> 127.1/0 No such host is known. Eli> Test nsm-check-local-subnet-ipv4 backtrace: Eli> signal(ert-test-failed (((should (eq nil (nsm-should-check "127.1") Eli> ert-fail(((should (eq nil (nsm-should-check "127.1"))) :form (eq ni Eli> (if (unwind-protect (setq value-44 (apply fn-42 args-43)) (setq for Eli> (let (form-description-46) (if (unwind-protect (setq value-44 (appl Eli> (let ((value-44 'ert-form-evaluation-aborted-45)) (let (form-descri Eli> (let* ((fn-42 #'eq) (args-43 (condition-case err (let ((signal-hook Eli> (let ((nsm-trust-local-network t)) (let* ((fn-37 #'eq) (args-38 (co Eli> (let ((local-ip '[172 26 128 160 0]) (mask '[255 255 255 0 0]) (wro Eli> (closure (t) nil (let ((local-ip '[172 26 128 160 0]) (mask '[255 2 Eli> ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-tes Eli> ert-run-test(#s(ert-test :name nsm-check-local-subnet-ipv4 :documen Eli> ert-run-or-rerun-test(#s(ert--stats :selector (not (tag :unstable)) Eli> ert-run-tests((not (tag :unstable)) #f(compiled-function (event-typ Eli> ert-run-tests-batch((not (tag :unstable))) Eli> ert-run-tests-batch-and-exit((not (tag :unstable))) Eli> eval((ert-run-tests-batch-and-exit '(not (tag :unstable))) t) Eli> command-line-1((#("-L" 0 2 (charset cp862)) #(";." 0 2 (charset cp8 Eli> command-line() Eli> normal-top-level() Eli> Test nsm-check-local-subnet-ipv4 condition: Eli> (ert-test-failed Eli> ((should Eli> (eq nil Eli> (nsm-should-check "127.1"))) Eli> :form Eli> (eq nil t) Eli> :value nil)) Eli> FAILED 1/2 nsm-check-local-subnet-ipv4 (4.656250 sec) Eek. mingw (or winsock) doesnʼt support getaddrinfo("127.1",...), although getaddrinfo("127.0.0.1",...) seems to work. This fixes it for me:
[0001-Use-127.0.0.1-in-nsm-tests.patch (text/x-patch, inline)]
From e441c874ac7e7a0c7724af85ebf2d1678aea3a88 Mon Sep 17 00:00:00 2001 From: Robert Pluim <rpluim <at> gmail.com> Date: Tue, 26 Nov 2019 19:07:42 +0100 Subject: [PATCH] Use 127.0.0.1 in nsm-tests To: emacs-devel <at> gnu.org Winsock doesn't like "127.1" * test/lisp/net/nsm-tests.el (nsm-check-local-subnet-ipv4): Spell numeric localhost as "127.0.0.1" instead of "127.1". --- test/lisp/net/nsm-tests.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lisp/net/nsm-tests.el b/test/lisp/net/nsm-tests.el index 8e52568d71..97edcca80d 100644 --- a/test/lisp/net/nsm-tests.el +++ b/test/lisp/net/nsm-tests.el @@ -42,11 +42,11 @@ nsm-check-local-subnet-ipv4 (should-error (nsm-network-same-subnet local-ip wrong-length-mask remote-ip-yes)) (should (eq nil (nsm-network-same-subnet local-ip wrong-mask remote-ip-yes))) (should (eq t (nsm-should-check "google.com"))) - (should (eq t (nsm-should-check "127.1"))) + (should (eq t (nsm-should-check "127.0.0.1"))) (should (eq t (nsm-should-check "localhost"))) (let ((nsm-trust-local-network t)) (should (eq t (nsm-should-check "google.com"))) - (should (eq nil (nsm-should-check "127.1"))) + (should (eq nil (nsm-should-check "127.0.0.1"))) (should (eq nil (nsm-should-check "localhost")))))) (defun nsm-ipv6-is-available () -- 2.24.0.155.gd9f6f3b619
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Tue, 26 Nov 2019 18:24:02 GMT) Full text and rfc822 format available.Message #28 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: Robert Pluim <rpluim <at> gmail.com> Cc: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Tue, 26 Nov 2019 20:23:30 +0200
> From: Robert Pluim <rpluim <at> gmail.com> > Cc: 38218 <at> debbugs.gnu.org > Date: Tue, 26 Nov 2019 19:10:04 +0100 > > Eli> It needed a bit of tweaking for mingw.org's MinGW, so that it would > Eli> work on XP. However, after making the changes, one test from > Eli> nsm-tests.el fails here: > > Thanks for that Thanks for reviewing it. > Eli> Test nsm-check-local-subnet-ipv4 condition: > Eli> (ert-test-failed > Eli> ((should > Eli> (eq nil > Eli> (nsm-should-check "127.1"))) > Eli> :form > Eli> (eq nil t) > Eli> :value nil)) > Eli> FAILED 1/2 nsm-check-local-subnet-ipv4 (4.656250 sec) > > Eek. mingw (or winsock) doesnʼt support getaddrinfo("127.1",...), > although getaddrinfo("127.0.0.1",...) seems to work. This fixes it for me: For me as well, thanks.
bug-gnu-emacs <at> gnu.org
:bug#38218
; Package emacs
.
(Tue, 26 Nov 2019 18:30:02 GMT) Full text and rfc822 format available.Message #31 received at 38218 <at> debbugs.gnu.org (full text, mbox):
From: Robert Pluim <rpluim <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 38218 <at> debbugs.gnu.org Subject: Re: bug#38218: network-interface-list only returns IPv4 addresses Date: Tue, 26 Nov 2019 19:29:36 +0100
>>>>> On Tue, 26 Nov 2019 20:23:30 +0200, Eli Zaretskii <eliz <at> gnu.org> said: >> From: Robert Pluim <rpluim <at> gmail.com> >> Cc: 38218 <at> debbugs.gnu.org >> Date: Tue, 26 Nov 2019 19:10:04 +0100 >> Eli> It needed a bit of tweaking for mingw.org's MinGW, so that it would Eli> work on XP. However, after making the changes, one test from Eli> nsm-tests.el fails here: >> >> Thanks for that Eli> Thanks for reviewing it. Thanks for writing it. The Windows handling of IP prefixes is weird, to say the least. Eli> Test nsm-check-local-subnet-ipv4 condition: Eli> (ert-test-failed Eli> ((should Eli> (eq nil Eli> (nsm-should-check "127.1"))) Eli> :form Eli> (eq nil t) Eli> :value nil)) Eli> FAILED 1/2 nsm-check-local-subnet-ipv4 (4.656250 sec) >> >> Eek. mingw (or winsock) doesnʼt support getaddrinfo("127.1",...), >> although getaddrinfo("127.0.0.1",...) seems to work. This fixes it for me: Eli> For me as well, thanks. Pushed as 95e218af14. Thanks Robert
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Wed, 25 Dec 2019 12:24:04 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.