diff options
| author | Eli Zaretskii | 2013-10-16 18:44:02 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-10-16 18:44:02 +0300 |
| commit | 3dffe395916c0c075c1609c41e553d9f8e3690ea (patch) | |
| tree | eeaa2e377b897148fee2ed764c9e0fbb786dc9e1 /src | |
| parent | b911a94d7993508f8a53360a4be4651de30ea301 (diff) | |
| download | emacs-3dffe395916c0c075c1609c41e553d9f8e3690ea.tar.gz emacs-3dffe395916c0c075c1609c41e553d9f8e3690ea.zip | |
Implement network-interface-* functions for MS-Windows (bug #15610).
src/w32.c (network_interface_get_info, network_interface_list)
(network_interface_info): New functions.
(GetAdaptersInfo_Proc): New typedef.
(get_adapters_info): New wrapper function.
(globals_of_w32): Initialize g_b_init_get_adapters_info.
src/process.h (network_interface_list, network_interface_info): New
prototypes.
src/process.c (conv_sockaddr_to_lisp): Now externally-visible.
(Fnetwork_interface_list, Fnetwork_interface_info): Define for
all systems. Return non-nil for systems that HAVE_NET_IF_H and
for WINDOWSNT. Doc fix.
(syms_of_process): Defsubr Snetwork_interface_list and
Snetwork_interface_info unconditionally.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 16 | ||||
| -rw-r--r-- | src/process.c | 56 | ||||
| -rw-r--r-- | src/process.h | 4 | ||||
| -rw-r--r-- | src/w32.c | 292 |
4 files changed, 349 insertions, 19 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 4874187b3c0..3b419af9e32 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,21 @@ | |||
| 1 | 2013-10-16 Eli Zaretskii <eliz@gnu.org> | 1 | 2013-10-16 Eli Zaretskii <eliz@gnu.org> |
| 2 | 2 | ||
| 3 | * w32.c (network_interface_get_info, network_interface_list) | ||
| 4 | (network_interface_info): New functions. (Bug#15610) | ||
| 5 | (GetAdaptersInfo_Proc): New typedef. | ||
| 6 | (get_adapters_info): New wrapper function. | ||
| 7 | (globals_of_w32): Initialize g_b_init_get_adapters_info. | ||
| 8 | |||
| 9 | * process.h (network_interface_list, network_interface_info): New | ||
| 10 | prototypes. | ||
| 11 | |||
| 12 | * process.c (conv_sockaddr_to_lisp): Now externally-visible. | ||
| 13 | (Fnetwork_interface_list, Fnetwork_interface_info): Define for | ||
| 14 | all systems. Return non-nil for systems that HAVE_NET_IF_H and | ||
| 15 | for WINDOWSNT. Doc fix. | ||
| 16 | (syms_of_process): Defsubr Snetwork_interface_list and | ||
| 17 | Snetwork_interface_info unconditionally. | ||
| 18 | |||
| 3 | * menu.c (have_boxes): Fix redundant simulation of radio buttons | 19 | * menu.c (have_boxes): Fix redundant simulation of radio buttons |
| 4 | in NS GUI sessions. (Bug#15629) | 20 | in NS GUI sessions. (Bug#15629) |
| 5 | 21 | ||
diff --git a/src/process.c b/src/process.c index 2ed8a690193..cf9d5e265e1 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1958,7 +1958,7 @@ create_pty (Lisp_Object process) | |||
| 1958 | /* Convert an internal struct sockaddr to a lisp object (vector or string). | 1958 | /* Convert an internal struct sockaddr to a lisp object (vector or string). |
| 1959 | The address family of sa is not included in the result. */ | 1959 | The address family of sa is not included in the result. */ |
| 1960 | 1960 | ||
| 1961 | static Lisp_Object | 1961 | Lisp_Object |
| 1962 | conv_sockaddr_to_lisp (struct sockaddr *sa, int len) | 1962 | conv_sockaddr_to_lisp (struct sockaddr *sa, int len) |
| 1963 | { | 1963 | { |
| 1964 | Lisp_Object address; | 1964 | Lisp_Object address; |
| @@ -3504,16 +3504,45 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3504 | } | 3504 | } |
| 3505 | 3505 | ||
| 3506 | 3506 | ||
| 3507 | #if defined (HAVE_NET_IF_H) | ||
| 3508 | |||
| 3509 | #ifdef SIOCGIFCONF | ||
| 3510 | DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0, | 3507 | DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0, |
| 3511 | doc: /* Return an alist of all network interfaces and their network address. | 3508 | doc: /* Return an alist of all network interfaces and their network address. |
| 3512 | Each element is a cons, the car of which is a string containing the | 3509 | Each element is a cons, the car of which is a string containing the |
| 3513 | interface name, and the cdr is the network address in internal | 3510 | interface name, and the cdr is the network address in internal |
| 3514 | format; see the description of ADDRESS in `make-network-process'. */) | 3511 | format; see the description of ADDRESS in `make-network-process'. |
| 3512 | |||
| 3513 | If the information is not available, return nil. */) | ||
| 3515 | (void) | 3514 | (void) |
| 3516 | { | 3515 | { |
| 3516 | #if (defined (HAVE_NET_IF_H) && defined (SIOCGIFCONF)) || defined (WINDOWSNT) | ||
| 3517 | return network_interface_list (); | ||
| 3518 | #else | ||
| 3519 | return Qnil; | ||
| 3520 | #endif | ||
| 3521 | } | ||
| 3522 | |||
| 3523 | DEFUN ("network-interface-info", Fnetwork_interface_info, Snetwork_interface_info, 1, 1, 0, | ||
| 3524 | doc: /* Return information about network interface named IFNAME. | ||
| 3525 | The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS), | ||
| 3526 | where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address, | ||
| 3527 | NETMASK is the layer 3 network mask, HWADDR is the layer 2 address, and | ||
| 3528 | FLAGS is the current flags of the interface. | ||
| 3529 | |||
| 3530 | Data that is unavailable is returned as nil. */) | ||
| 3531 | (Lisp_Object ifname) | ||
| 3532 | { | ||
| 3533 | #if (defined (HAVE_NET_IF_H) && (defined (SIOCGIFADDR) || defined (SIOCGIFHWADDR) || defined (SIOCGIFFLAGS))) || defined (WINDOWSNT) | ||
| 3534 | return network_interface_info (ifname); | ||
| 3535 | #else | ||
| 3536 | return Qnil; | ||
| 3537 | #endif | ||
| 3538 | } | ||
| 3539 | |||
| 3540 | #if defined (HAVE_NET_IF_H) | ||
| 3541 | |||
| 3542 | #ifdef SIOCGIFCONF | ||
| 3543 | Lisp_Object | ||
| 3544 | network_interface_list (void) | ||
| 3545 | { | ||
| 3517 | struct ifconf ifconf; | 3546 | struct ifconf ifconf; |
| 3518 | struct ifreq *ifreq; | 3547 | struct ifreq *ifreq; |
| 3519 | void *buf = NULL; | 3548 | void *buf = NULL; |
| @@ -3654,13 +3683,8 @@ static const struct ifflag_def ifflag_table[] = { | |||
| 3654 | { 0, 0 } | 3683 | { 0, 0 } |
| 3655 | }; | 3684 | }; |
| 3656 | 3685 | ||
| 3657 | DEFUN ("network-interface-info", Fnetwork_interface_info, Snetwork_interface_info, 1, 1, 0, | 3686 | Lisp_Object |
| 3658 | doc: /* Return information about network interface named IFNAME. | 3687 | network_interface_info (Lisp_Object ifname) |
| 3659 | The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS), | ||
| 3660 | where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address, | ||
| 3661 | NETMASK is the layer 3 network mask, HWADDR is the layer 2 address, and | ||
| 3662 | FLAGS is the current flags of the interface. */) | ||
| 3663 | (Lisp_Object ifname) | ||
| 3664 | { | 3688 | { |
| 3665 | struct ifreq rq; | 3689 | struct ifreq rq; |
| 3666 | Lisp_Object res = Qnil; | 3690 | Lisp_Object res = Qnil; |
| @@ -3802,7 +3826,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3802 | 3826 | ||
| 3803 | return unbind_to (count, any ? res : Qnil); | 3827 | return unbind_to (count, any ? res : Qnil); |
| 3804 | } | 3828 | } |
| 3805 | #endif | 3829 | #endif /* !SIOCGIFADDR && !SIOCGIFHWADDR && !SIOCGIFFLAGS */ |
| 3806 | #endif /* defined (HAVE_NET_IF_H) */ | 3830 | #endif /* defined (HAVE_NET_IF_H) */ |
| 3807 | 3831 | ||
| 3808 | /* Turn off input and output for process PROC. */ | 3832 | /* Turn off input and output for process PROC. */ |
| @@ -7293,14 +7317,8 @@ The variable takes effect when `start-process' is called. */); | |||
| 7293 | defsubr (&Sset_network_process_option); | 7317 | defsubr (&Sset_network_process_option); |
| 7294 | defsubr (&Smake_network_process); | 7318 | defsubr (&Smake_network_process); |
| 7295 | defsubr (&Sformat_network_address); | 7319 | defsubr (&Sformat_network_address); |
| 7296 | #if defined (HAVE_NET_IF_H) | ||
| 7297 | #ifdef SIOCGIFCONF | ||
| 7298 | defsubr (&Snetwork_interface_list); | 7320 | defsubr (&Snetwork_interface_list); |
| 7299 | #endif | ||
| 7300 | #if defined (SIOCGIFADDR) || defined (SIOCGIFHWADDR) || defined (SIOCGIFFLAGS) | ||
| 7301 | defsubr (&Snetwork_interface_info); | 7321 | defsubr (&Snetwork_interface_info); |
| 7302 | #endif | ||
| 7303 | #endif /* defined (HAVE_NET_IF_H) */ | ||
| 7304 | #ifdef DATAGRAM_SOCKETS | 7322 | #ifdef DATAGRAM_SOCKETS |
| 7305 | defsubr (&Sprocess_datagram_address); | 7323 | defsubr (&Sprocess_datagram_address); |
| 7306 | defsubr (&Sset_process_datagram_address); | 7324 | defsubr (&Sset_process_datagram_address); |
diff --git a/src/process.h b/src/process.h index a9b15f03da4..163066f025f 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -240,4 +240,8 @@ extern void delete_write_fd (int fd); | |||
| 240 | extern void catch_child_signal (void); | 240 | extern void catch_child_signal (void); |
| 241 | #endif | 241 | #endif |
| 242 | 242 | ||
| 243 | extern Lisp_Object network_interface_list (void); | ||
| 244 | extern Lisp_Object network_interface_info (Lisp_Object); | ||
| 245 | |||
| 246 | |||
| 243 | INLINE_HEADER_END | 247 | INLINE_HEADER_END |
| @@ -218,6 +218,8 @@ typedef struct _REPARSE_DATA_BUFFER { | |||
| 218 | #undef recvfrom | 218 | #undef recvfrom |
| 219 | #undef sendto | 219 | #undef sendto |
| 220 | 220 | ||
| 221 | #include <iphlpapi.h> /* should be after winsock2.h */ | ||
| 222 | |||
| 221 | #include "w32.h" | 223 | #include "w32.h" |
| 222 | #include <dirent.h> | 224 | #include <dirent.h> |
| 223 | #include "w32common.h" | 225 | #include "w32common.h" |
| @@ -296,6 +298,7 @@ static BOOL g_b_init_convert_sd_to_sddl; | |||
| 296 | static BOOL g_b_init_convert_sddl_to_sd; | 298 | static BOOL g_b_init_convert_sddl_to_sd; |
| 297 | static BOOL g_b_init_is_valid_security_descriptor; | 299 | static BOOL g_b_init_is_valid_security_descriptor; |
| 298 | static BOOL g_b_init_set_file_security; | 300 | static BOOL g_b_init_set_file_security; |
| 301 | static BOOL g_b_init_get_adapters_info; | ||
| 299 | 302 | ||
| 300 | /* | 303 | /* |
| 301 | BEGIN: Wrapper functions around OpenProcessToken | 304 | BEGIN: Wrapper functions around OpenProcessToken |
| @@ -438,6 +441,9 @@ typedef BOOL (WINAPI *ConvertSecurityDescriptorToStringSecurityDescriptor_Proc) | |||
| 438 | LPTSTR *StringSecurityDescriptor, | 441 | LPTSTR *StringSecurityDescriptor, |
| 439 | PULONG StringSecurityDescriptorLen); | 442 | PULONG StringSecurityDescriptorLen); |
| 440 | typedef BOOL (WINAPI *IsValidSecurityDescriptor_Proc) (PSECURITY_DESCRIPTOR); | 443 | typedef BOOL (WINAPI *IsValidSecurityDescriptor_Proc) (PSECURITY_DESCRIPTOR); |
| 444 | typedef DWORD (WINAPI *GetAdaptersInfo_Proc) ( | ||
| 445 | PIP_ADAPTER_INFO pAdapterInfo, | ||
| 446 | PULONG pOutBufLen); | ||
| 441 | 447 | ||
| 442 | /* ** A utility function ** */ | 448 | /* ** A utility function ** */ |
| 443 | static BOOL | 449 | static BOOL |
| @@ -1130,6 +1136,28 @@ convert_sddl_to_sd (LPCTSTR StringSecurityDescriptor, | |||
| 1130 | return retval; | 1136 | return retval; |
| 1131 | } | 1137 | } |
| 1132 | 1138 | ||
| 1139 | static DWORD WINAPI | ||
| 1140 | get_adapters_info (PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) | ||
| 1141 | { | ||
| 1142 | static GetAdaptersInfo_Proc s_pfn_Get_Adapters_Info = NULL; | ||
| 1143 | HMODULE hm_iphlpapi = NULL; | ||
| 1144 | |||
| 1145 | if (is_windows_9x () == TRUE) | ||
| 1146 | return ERROR_NOT_SUPPORTED; | ||
| 1147 | |||
| 1148 | if (g_b_init_get_adapters_info == 0) | ||
| 1149 | { | ||
| 1150 | g_b_init_get_adapters_info = 1; | ||
| 1151 | hm_iphlpapi = LoadLibrary ("Iphlpapi.dll"); | ||
| 1152 | if (hm_iphlpapi) | ||
| 1153 | s_pfn_Get_Adapters_Info = (GetAdaptersInfo_Proc) | ||
| 1154 | GetProcAddress (hm_iphlpapi, "GetAdaptersInfo"); | ||
| 1155 | } | ||
| 1156 | if (s_pfn_Get_Adapters_Info == NULL) | ||
| 1157 | return ERROR_NOT_SUPPORTED; | ||
| 1158 | return s_pfn_Get_Adapters_Info (pAdapterInfo, pOutBufLen); | ||
| 1159 | } | ||
| 1160 | |||
| 1133 | 1161 | ||
| 1134 | 1162 | ||
| 1135 | /* Return 1 if P is a valid pointer to an object of size SIZE. Return | 1163 | /* Return 1 if P is a valid pointer to an object of size SIZE. Return |
| @@ -7434,6 +7462,269 @@ sys_write (int fd, const void * buffer, unsigned int count) | |||
| 7434 | return nchars; | 7462 | return nchars; |
| 7435 | } | 7463 | } |
| 7436 | 7464 | ||
| 7465 | |||
| 7466 | /* Emulation of SIOCGIFCONF and getifaddrs, see process.c. */ | ||
| 7467 | |||
| 7468 | extern Lisp_Object conv_sockaddr_to_lisp (struct sockaddr *, int); | ||
| 7469 | |||
| 7470 | /* Return information about network interface IFNAME, or about all | ||
| 7471 | interfaces (if IFNAME is nil). */ | ||
| 7472 | static Lisp_Object | ||
| 7473 | network_interface_get_info (Lisp_Object ifname) | ||
| 7474 | { | ||
| 7475 | ULONG ainfo_len = sizeof (IP_ADAPTER_INFO); | ||
| 7476 | IP_ADAPTER_INFO *adapter, *ainfo = xmalloc (ainfo_len); | ||
| 7477 | DWORD retval = get_adapters_info (ainfo, &ainfo_len); | ||
| 7478 | Lisp_Object res = Qnil; | ||
| 7479 | |||
| 7480 | if (retval == ERROR_BUFFER_OVERFLOW) | ||
| 7481 | { | ||
| 7482 | ainfo = xrealloc (ainfo, ainfo_len); | ||
| 7483 | retval = get_adapters_info (ainfo, &ainfo_len); | ||
| 7484 | } | ||
| 7485 | |||
| 7486 | if (retval == ERROR_SUCCESS) | ||
| 7487 | { | ||
| 7488 | int eth_count = 0, tr_count = 0, fddi_count = 0, ppp_count = 0; | ||
| 7489 | int sl_count = 0, wlan_count = 0, lo_count = 0, ifx_count = 0; | ||
| 7490 | int if_num; | ||
| 7491 | struct sockaddr_in sa; | ||
| 7492 | |||
| 7493 | /* For the below, we need some winsock functions, so make sure | ||
| 7494 | the winsock DLL is loaded. If we cannot successfully load | ||
| 7495 | it, they will have no use of the information we provide, | ||
| 7496 | anyway, so punt. */ | ||
| 7497 | if (!winsock_lib && !init_winsock (1)) | ||
| 7498 | goto done; | ||
| 7499 | |||
| 7500 | for (adapter = ainfo; adapter; adapter = adapter->Next) | ||
| 7501 | { | ||
| 7502 | char namebuf[MAX_ADAPTER_NAME_LENGTH + 4]; | ||
| 7503 | u_long ip_addr; | ||
| 7504 | /* Present Unix-compatible interface names, instead of the | ||
| 7505 | Windows names, which are really GUIDs not readable by | ||
| 7506 | humans. */ | ||
| 7507 | static const char *ifmt[] = { | ||
| 7508 | "eth%d", "tr%d", "fddi%d", "ppp%d", "sl%d", "wlan%d", | ||
| 7509 | "lo", "ifx%d" | ||
| 7510 | }; | ||
| 7511 | enum { | ||
| 7512 | NONE = -1, | ||
| 7513 | ETHERNET = 0, | ||
| 7514 | TOKENRING = 1, | ||
| 7515 | FDDI = 2, | ||
| 7516 | PPP = 3, | ||
| 7517 | SLIP = 4, | ||
| 7518 | WLAN = 5, | ||
| 7519 | LOOPBACK = 6, | ||
| 7520 | OTHER_IF = 7 | ||
| 7521 | } ifmt_idx; | ||
| 7522 | |||
| 7523 | switch (adapter->Type) | ||
| 7524 | { | ||
| 7525 | case MIB_IF_TYPE_ETHERNET: | ||
| 7526 | /* Windows before Vista reports wireless adapters as | ||
| 7527 | Ethernet. Work around by looking at the Description | ||
| 7528 | string. */ | ||
| 7529 | if (strstr (adapter->Description, "Wireless ")) | ||
| 7530 | { | ||
| 7531 | ifmt_idx = WLAN; | ||
| 7532 | if_num = wlan_count++; | ||
| 7533 | } | ||
| 7534 | else | ||
| 7535 | { | ||
| 7536 | ifmt_idx = ETHERNET; | ||
| 7537 | if_num = eth_count++; | ||
| 7538 | } | ||
| 7539 | break; | ||
| 7540 | case MIB_IF_TYPE_TOKENRING: | ||
| 7541 | ifmt_idx = TOKENRING; | ||
| 7542 | if_num = tr_count++; | ||
| 7543 | break; | ||
| 7544 | case MIB_IF_TYPE_FDDI: | ||
| 7545 | ifmt_idx = FDDI; | ||
| 7546 | if_num = fddi_count++; | ||
| 7547 | break; | ||
| 7548 | case MIB_IF_TYPE_PPP: | ||
| 7549 | ifmt_idx = PPP; | ||
| 7550 | if_num = ppp_count++; | ||
| 7551 | break; | ||
| 7552 | case MIB_IF_TYPE_SLIP: | ||
| 7553 | ifmt_idx = SLIP; | ||
| 7554 | if_num = sl_count++; | ||
| 7555 | break; | ||
| 7556 | case IF_TYPE_IEEE80211: | ||
| 7557 | ifmt_idx = WLAN; | ||
| 7558 | if_num = wlan_count++; | ||
| 7559 | break; | ||
| 7560 | case MIB_IF_TYPE_LOOPBACK: | ||
| 7561 | if (lo_count < 0) | ||
| 7562 | { | ||
| 7563 | ifmt_idx = LOOPBACK; | ||
| 7564 | if_num = lo_count++; | ||
| 7565 | } | ||
| 7566 | else | ||
| 7567 | ifmt_idx = NONE; | ||
| 7568 | break; | ||
| 7569 | default: | ||
| 7570 | ifmt_idx = OTHER_IF; | ||
| 7571 | if_num = ifx_count++; | ||
| 7572 | break; | ||
| 7573 | } | ||
| 7574 | if (ifmt_idx == NONE) | ||
| 7575 | continue; | ||
| 7576 | sprintf (namebuf, ifmt[ifmt_idx], if_num); | ||
| 7577 | |||
| 7578 | sa.sin_family = AF_INET; | ||
| 7579 | ip_addr = sys_inet_addr (adapter->IpAddressList.IpAddress.String); | ||
| 7580 | if (ip_addr == INADDR_NONE) | ||
| 7581 | { | ||
| 7582 | /* Bogus address, skip this interface. */ | ||
| 7583 | continue; | ||
| 7584 | } | ||
| 7585 | sa.sin_addr.s_addr = ip_addr; | ||
| 7586 | sa.sin_port = 0; | ||
| 7587 | if (NILP (ifname)) | ||
| 7588 | res = Fcons (Fcons (build_string (namebuf), | ||
| 7589 | conv_sockaddr_to_lisp ((struct sockaddr*) &sa, | ||
| 7590 | sizeof (struct sockaddr))), | ||
| 7591 | res); | ||
| 7592 | else if (strcmp (namebuf, SSDATA (ifname)) == 0) | ||
| 7593 | { | ||
| 7594 | Lisp_Object hwaddr = Fmake_vector (make_number (6), Qnil); | ||
| 7595 | register struct Lisp_Vector *p = XVECTOR (hwaddr); | ||
| 7596 | Lisp_Object flags = Qnil; | ||
| 7597 | int n; | ||
| 7598 | u_long net_mask; | ||
| 7599 | |||
| 7600 | /* Flags. We guess most of them by type, since the | ||
| 7601 | Windows flags are different and hard to get by. */ | ||
| 7602 | flags = Fcons (intern ("up"), flags); | ||
| 7603 | if (ifmt_idx == ETHERNET || ifmt_idx == WLAN) | ||
| 7604 | { | ||
| 7605 | flags = Fcons (intern ("broadcast"), flags); | ||
| 7606 | flags = Fcons (intern ("multicast"), flags); | ||
| 7607 | } | ||
| 7608 | flags = Fcons (intern ("running"), flags); | ||
| 7609 | if (ifmt_idx == PPP) | ||
| 7610 | { | ||
| 7611 | flags = Fcons (intern ("pointopoint"), flags); | ||
| 7612 | flags = Fcons (intern ("noarp"), flags); | ||
| 7613 | } | ||
| 7614 | if (adapter->HaveWins) | ||
| 7615 | flags = Fcons (intern ("WINS"), flags); | ||
| 7616 | if (adapter->DhcpEnabled) | ||
| 7617 | flags = Fcons (intern ("dynamic"), flags); | ||
| 7618 | |||
| 7619 | res = Fcons (flags, res); | ||
| 7620 | |||
| 7621 | /* Hardware address and its family. */ | ||
| 7622 | for (n = 0; n < adapter->AddressLength; n++) | ||
| 7623 | p->u.contents[n] = make_number ((int) adapter->Address[n]); | ||
| 7624 | /* Windows does not support AF_LINK or AF_PACKET family | ||
| 7625 | of addresses. Use an arbitrary family number that is | ||
| 7626 | identical to what GNU/Linux returns. */ | ||
| 7627 | res = Fcons (Fcons (make_number (1), hwaddr), res); | ||
| 7628 | |||
| 7629 | /* Network mask. */ | ||
| 7630 | sa.sin_family = AF_INET; | ||
| 7631 | net_mask = sys_inet_addr (adapter->IpAddressList.IpMask.String); | ||
| 7632 | if (net_mask != INADDR_NONE) | ||
| 7633 | { | ||
| 7634 | sa.sin_addr.s_addr = net_mask; | ||
| 7635 | sa.sin_port = 0; | ||
| 7636 | res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, | ||
| 7637 | sizeof (struct sockaddr)), | ||
| 7638 | res); | ||
| 7639 | } | ||
| 7640 | else | ||
| 7641 | res = Fcons (Qnil, res); | ||
| 7642 | |||
| 7643 | sa.sin_family = AF_INET; | ||
| 7644 | if (ip_addr != INADDR_NONE) | ||
| 7645 | { | ||
| 7646 | /* Broadcast address is only reported by | ||
| 7647 | GetAdaptersAddresses, which is of limited | ||
| 7648 | availability. Generate it on our own. */ | ||
| 7649 | u_long bcast_addr = (ip_addr & net_mask) | ~net_mask; | ||
| 7650 | |||
| 7651 | sa.sin_addr.s_addr = bcast_addr; | ||
| 7652 | sa.sin_port = 0; | ||
| 7653 | res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, | ||
| 7654 | sizeof (struct sockaddr)), | ||
| 7655 | res); | ||
| 7656 | |||
| 7657 | /* IP address. */ | ||
| 7658 | sa.sin_addr.s_addr = ip_addr; | ||
| 7659 | sa.sin_port = 0; | ||
| 7660 | res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, | ||
| 7661 | sizeof (struct sockaddr)), | ||
| 7662 | res); | ||
| 7663 | } | ||
| 7664 | else | ||
| 7665 | res = Fcons (Qnil, Fcons (Qnil, res)); | ||
| 7666 | } | ||
| 7667 | } | ||
| 7668 | /* GetAdaptersInfo is documented to not report loopback | ||
| 7669 | interfaces, so we generate one out of thin air. */ | ||
| 7670 | if (!lo_count) | ||
| 7671 | { | ||
| 7672 | sa.sin_family = AF_INET; | ||
| 7673 | sa.sin_port = 0; | ||
| 7674 | if (NILP (ifname)) | ||
| 7675 | { | ||
| 7676 | sa.sin_addr.s_addr = sys_inet_addr ("127.0.0.1"); | ||
| 7677 | res = Fcons (Fcons (build_string ("lo"), | ||
| 7678 | conv_sockaddr_to_lisp ((struct sockaddr*) &sa, | ||
| 7679 | sizeof (struct sockaddr))), | ||
| 7680 | res); | ||
| 7681 | } | ||
| 7682 | else if (strcmp (SSDATA (ifname), "lo") == 0) | ||
| 7683 | { | ||
| 7684 | res = Fcons (Fcons (intern ("running"), | ||
| 7685 | Fcons (intern ("loopback"), | ||
| 7686 | Fcons (intern ("up"), Qnil))), Qnil); | ||
| 7687 | /* 772 is what 3 different GNU/Linux systems report for | ||
| 7688 | the loopback interface. */ | ||
| 7689 | res = Fcons (Fcons (make_number (772), | ||
| 7690 | Fmake_vector (make_number (6), | ||
| 7691 | make_number (0))), | ||
| 7692 | res); | ||
| 7693 | sa.sin_addr.s_addr = sys_inet_addr ("255.0.0.0"); | ||
| 7694 | res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, | ||
| 7695 | sizeof (struct sockaddr)), | ||
| 7696 | res); | ||
| 7697 | sa.sin_addr.s_addr = sys_inet_addr ("0.0.0.0"); | ||
| 7698 | res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, | ||
| 7699 | sizeof (struct sockaddr)), | ||
| 7700 | res); | ||
| 7701 | sa.sin_addr.s_addr = sys_inet_addr ("127.0.0.1"); | ||
| 7702 | res = Fcons (conv_sockaddr_to_lisp ((struct sockaddr *) &sa, | ||
| 7703 | sizeof (struct sockaddr)), | ||
| 7704 | res); | ||
| 7705 | } | ||
| 7706 | |||
| 7707 | } | ||
| 7708 | } | ||
| 7709 | |||
| 7710 | done: | ||
| 7711 | xfree (ainfo); | ||
| 7712 | return res; | ||
| 7713 | } | ||
| 7714 | |||
| 7715 | Lisp_Object | ||
| 7716 | network_interface_list (void) | ||
| 7717 | { | ||
| 7718 | return network_interface_get_info (Qnil); | ||
| 7719 | } | ||
| 7720 | |||
| 7721 | Lisp_Object | ||
| 7722 | network_interface_info (Lisp_Object ifname) | ||
| 7723 | { | ||
| 7724 | return network_interface_get_info (ifname); | ||
| 7725 | } | ||
| 7726 | |||
| 7727 | |||
| 7437 | /* The Windows CRT functions are "optimized for speed", so they don't | 7728 | /* The Windows CRT functions are "optimized for speed", so they don't |
| 7438 | check for timezone and DST changes if they were last called less | 7729 | check for timezone and DST changes if they were last called less |
| 7439 | than 1 minute ago (see http://support.microsoft.com/kb/821231). So | 7730 | than 1 minute ago (see http://support.microsoft.com/kb/821231). So |
| @@ -7735,6 +8026,7 @@ globals_of_w32 (void) | |||
| 7735 | g_b_init_convert_sddl_to_sd = 0; | 8026 | g_b_init_convert_sddl_to_sd = 0; |
| 7736 | g_b_init_is_valid_security_descriptor = 0; | 8027 | g_b_init_is_valid_security_descriptor = 0; |
| 7737 | g_b_init_set_file_security = 0; | 8028 | g_b_init_set_file_security = 0; |
| 8029 | g_b_init_get_adapters_info = 0; | ||
| 7738 | num_of_processors = 0; | 8030 | num_of_processors = 0; |
| 7739 | /* The following sets a handler for shutdown notifications for | 8031 | /* The following sets a handler for shutdown notifications for |
| 7740 | console apps. This actually applies to Emacs in both console and | 8032 | console apps. This actually applies to Emacs in both console and |