diff options
Diffstat (limited to 'winsup/cygwin/fhandler_procnet.cc')
-rw-r--r-- | winsup/cygwin/fhandler_procnet.cc | 211 |
1 files changed, 27 insertions, 184 deletions
diff --git a/winsup/cygwin/fhandler_procnet.cc b/winsup/cygwin/fhandler_procnet.cc index 28fc2b2bf..8201a0d1d 100644 --- a/winsup/cygwin/fhandler_procnet.cc +++ b/winsup/cygwin/fhandler_procnet.cc @@ -29,11 +29,10 @@ details. */ #include <dirent.h> #include <stdio.h> #include <stdlib.h> -#include <wchar.h> -#ifndef GAA_FLAG_INCLUDE_ALL_INTERFACES -#define GAA_FLAG_INCLUDE_ALL_INTERFACES 0x0100 -#endif +extern "C" int ip_addr_prefix (PIP_ADAPTER_UNICAST_ADDRESS pua, + PIP_ADAPTER_PREFIX pap); +bool get_adapters_addresses (PIP_ADAPTER_ADDRESSES *pa0, ULONG family); static const int PROCNET_IFINET6 = 2; @@ -70,12 +69,8 @@ fhandler_procnet::exists () { if (i == PROCNET_IFINET6) { - ULONG size; - if (GetAdaptersAddresses (AF_INET6, - GAA_FLAG_INCLUDE_PREFIX - | GAA_FLAG_INCLUDE_ALL_INTERFACES, - NULL, NULL, &size) - != ERROR_BUFFER_OVERFLOW) + if (!wincap.has_gaa_prefixes () + || !get_adapters_addresses (NULL, AF_INET6)) return 0; } fileid = i; @@ -129,12 +124,8 @@ fhandler_procnet::readdir (DIR *dir, dirent *de) goto out; if (dir->__d_position == PROCNET_IFINET6) { - ULONG size; - if (GetAdaptersAddresses (AF_INET6, - GAA_FLAG_INCLUDE_PREFIX - | GAA_FLAG_INCLUDE_ALL_INTERFACES, - NULL, NULL, &size) - != ERROR_BUFFER_OVERFLOW) + if (!wincap.has_gaa_prefixes () + || !get_adapters_addresses (NULL, AF_INET6)) goto out; } strcpy (de->d_name, process_listing[dir->__d_position++]); @@ -247,92 +238,30 @@ fhandler_procnet::fill_filebuf () return true; } -static int in6_are_prefix_equal(struct in6_addr *, struct in6_addr *, int); - -/* Vista: unicast address has additional OnLinkPrefixLength member. */ -typedef struct _IP_ADAPTER_UNICAST_ADDRESS_VISTA { - _ANONYMOUS_UNION union { - ULONGLONG Alignment; - _ANONYMOUS_UNION struct { - ULONG Length; - DWORD Flags; - } DUMMYSTRUCTNAME; - } DUMMYUNIONNAME; - struct _IP_ADAPTER_UNICAST_ADDRESS_VISTA *Next; - SOCKET_ADDRESS Address; - - IP_PREFIX_ORIGIN PrefixOrigin; - IP_SUFFIX_ORIGIN SuffixOrigin; - IP_DAD_STATE DadState; - - ULONG ValidLifetime; - ULONG PreferredLifetime; - ULONG LeaseLifetime; - unsigned char OnLinkPrefixLength; -} IP_ADAPTER_UNICAST_ADDRESS_VISTA, *PIP_ADAPTER_UNICAST_ADDRESS_VISTA; - -int -prefix (PIP_ADAPTER_UNICAST_ADDRESS pua, PIP_ADAPTER_PREFIX pap) -{ - if (wincap.has_gaa_on_link_prefix ()) - return (int) ((PIP_ADAPTER_UNICAST_ADDRESS_VISTA) pua)->OnLinkPrefixLength; - /* Prior to Vista, the loopback prefix is erroneously set to 0 instead - of to 128. So just fake it here... */ - if (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) - pua->Address.lpSockaddr)->sin6_addr)) - return 128; - /* XP prior to service pack 1 has no prefixes linked list. Let's fake. */ - if (!wincap.has_gaa_prefixes ()) - return 64; - for ( ; pap; pap = pap->Next) - if (in6_are_prefix_equal ( - &((struct sockaddr_in6 *) pua->Address.lpSockaddr)->sin6_addr, - &((struct sockaddr_in6 *) pap->Address.lpSockaddr)->sin6_addr, - pap->PrefixLength)) - return pap->PrefixLength; - return 0; -} - static _off64_t format_procnet_ifinet6 (char *&filebuf) { PIP_ADAPTER_ADDRESSES pa0 = NULL, pap; PIP_ADAPTER_UNICAST_ADDRESS pua; - ULONG ret, size = 0, alloclen; + ULONG alloclen; + if (!wincap.has_gaa_prefixes ()) + return 0; _off64_t filesize = 0; - do - { - ret = GetAdaptersAddresses (AF_INET6, GAA_FLAG_INCLUDE_PREFIX - | GAA_FLAG_INCLUDE_ALL_INTERFACES, - NULL, pa0, &size); - if (ret == ERROR_BUFFER_OVERFLOW) - { - if (pa0) - free (pa0); - pa0 = (PIP_ADAPTER_ADDRESSES) malloc (size); - } - } - while (ret == ERROR_BUFFER_OVERFLOW); - if (ret != ERROR_SUCCESS) - { - if (pa0) - free (pa0); - return 0; - } + if (!get_adapters_addresses (&pa0, AF_INET6)) + goto out; alloclen = 0; for (pap = pa0; pap; pap = pap->Next) - { - ULONG namelen = wcslen (pap->FriendlyName); - for (pua = pap->FirstUnicastAddress; pua; pua = pua->Next) - alloclen += 60 + namelen; - } + for (pua = pap->FirstUnicastAddress; pua; pua = pua->Next) + alloclen += 100; + if (!alloclen) + goto out; filebuf = (char *) crealloc (filebuf, alloclen); - filesize = 0; + if (!filebuf) + goto out; for (pap = pa0; pap; pap = pap->Next) for (pua = pap->FirstUnicastAddress; pua; pua = pua->Next) { - ULONG namelen = wcslen (pap->FriendlyName); struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) pua->Address.lpSockaddr; for (int i = 0; i < 8; ++i) @@ -341,103 +270,17 @@ format_procnet_ifinet6 (char *&filebuf) ntohs (sin6->sin6_addr.s6_addr16[i])); filebuf[filesize++] = ' '; filesize += __small_sprintf (filebuf + filesize, - "%02x %02x %02x %02x ", - pap->Ipv6IfIndex, - prefix (pua, pap->FirstPrefix), + "%02x %02x %02x %02x %s\n", + pap->IfIndex ?: pap->Ipv6IfIndex, + ip_addr_prefix (pua, pap->FirstPrefix), ((struct sockaddr_in6 *) pua->Address.lpSockaddr)->sin6_scope_id, - pua->DadState); - filesize += sys_wcstombs (filebuf + filesize, alloclen - filesize, - pap->FriendlyName, namelen); - filebuf[filesize++] = '\n'; + pua->DadState, + pap->AdapterName); } - if (!filesize) - filebuf[filesize++] = '\n'; - return filesize; -} -/* The below function has been taken from OpenBSD's src/sys/netinet6/in6.c. */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Copyright (c) 1982, 1986, 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)in.c 8.2 (Berkeley) 11/15/93 - */ - -static int -in6_are_prefix_equal(struct in6_addr *p1, struct in6_addr *p2, int len) -{ - int bytelen, bitlen; - - /* sanity check */ - if (0 > len || len > 128) - return 0; - - bytelen = len / 8; - bitlen = len % 8; - - if (memcmp (&p1->s6_addr, &p2->s6_addr, bytelen)) - return 0; - /* len == 128 is ok because bitlen == 0 then */ - if (bitlen != 0 && - p1->s6_addr[bytelen] >> (8 - bitlen) != - p2->s6_addr[bytelen] >> (8 - bitlen)) - return 0; - - return 1; +out: + if (pa0) + free (pa0); + return filesize; } - |