iphlpapi: Implement GetAdaptersAddresses for IPv6 addresses.
This commit is contained in:
parent
00fb356990
commit
e3c0e30db1
|
@ -6064,6 +6064,20 @@ fi
|
|||
done
|
||||
|
||||
|
||||
for ac_header in ifaddrs.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "ifaddrs.h" "ac_cv_header_ifaddrs_h" "#include <sys/types.h>
|
||||
"
|
||||
if test "x$ac_cv_header_ifaddrs_h" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_IFADDRS_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
for ac_header in ucontext.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "ucontext.h" "ac_cv_header_ucontext_h" "#include <signal.h>
|
||||
|
|
|
@ -556,6 +556,8 @@ AC_CHECK_HEADERS([resolv.h],,,
|
|||
# include <arpa/nameser.h>
|
||||
#endif])
|
||||
|
||||
AC_CHECK_HEADERS([ifaddrs.h],,,[#include <sys/types.h>])
|
||||
|
||||
AC_CHECK_HEADERS(ucontext.h,,,[#include <signal.h>])
|
||||
|
||||
AC_CHECK_HEADERS([sys/thr.h],,,
|
||||
|
|
|
@ -87,7 +87,12 @@
|
|||
#include <net/if_types.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include "ifenum.h"
|
||||
#include "ws2ipdef.h"
|
||||
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
#define ifreq_len(ifr) \
|
||||
|
@ -788,6 +793,76 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_IFADDRS_H
|
||||
ULONG v6addressesFromIndex(DWORD index, SOCKET_ADDRESS **addrs, ULONG *num_addrs)
|
||||
{
|
||||
struct ifaddrs *ifa;
|
||||
ULONG ret;
|
||||
|
||||
if (!getifaddrs(&ifa))
|
||||
{
|
||||
struct ifaddrs *p;
|
||||
ULONG n;
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
getInterfaceNameByIndex(index, name);
|
||||
for (p = ifa, n = 0; p; p = p->ifa_next)
|
||||
if (p->ifa_addr->sa_family == AF_INET6 && !strcmp(name, p->ifa_name))
|
||||
n++;
|
||||
if (n)
|
||||
{
|
||||
*addrs = HeapAlloc(GetProcessHeap(), 0, n * (sizeof(SOCKET_ADDRESS) +
|
||||
sizeof(struct WS_sockaddr_in6)));
|
||||
if (*addrs)
|
||||
{
|
||||
struct WS_sockaddr_in6 *next_addr = (struct WS_sockaddr_in6 *)(
|
||||
(BYTE *)*addrs + n * sizeof(SOCKET_ADDRESS));
|
||||
|
||||
for (p = ifa, n = 0; p; p = p->ifa_next)
|
||||
{
|
||||
if (p->ifa_addr->sa_family == AF_INET6 && !strcmp(name, p->ifa_name))
|
||||
{
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)p->ifa_addr;
|
||||
|
||||
next_addr->sin6_family = WS_AF_INET6;
|
||||
next_addr->sin6_port = addr->sin6_port;
|
||||
next_addr->sin6_flowinfo = addr->sin6_flowinfo;
|
||||
memcpy(&next_addr->sin6_addr, &addr->sin6_addr,
|
||||
sizeof(next_addr->sin6_addr));
|
||||
next_addr->sin6_scope_id = addr->sin6_scope_id;
|
||||
(*addrs)[n].lpSockaddr = (LPSOCKADDR)next_addr;
|
||||
(*addrs)[n].iSockaddrLength = sizeof(struct WS_sockaddr_in6);
|
||||
next_addr++;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
*num_addrs = n;
|
||||
ret = ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
ret = ERROR_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
*addrs = NULL;
|
||||
*num_addrs = 0;
|
||||
ret = ERROR_SUCCESS;
|
||||
}
|
||||
freeifaddrs(ifa);
|
||||
}
|
||||
else
|
||||
ret = ERROR_NO_DATA;
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
ULONG v6addressesFromIndex(DWORD index, SOCKET_ADDRESS **addrs, ULONG *num_addrs)
|
||||
{
|
||||
*addrs = NULL;
|
||||
*num_addrs = 0;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *toIPAddressString(unsigned int addr, char string[16])
|
||||
{
|
||||
if (string) {
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "iprtrmib.h"
|
||||
#define USE_WS_PREFIX
|
||||
#include "winsock2.h"
|
||||
|
||||
#define MAX_INTERFACE_PHYSADDR 8
|
||||
#define MAX_INTERFACE_DESCRIPTION 256
|
||||
|
@ -105,6 +107,11 @@ DWORD getNumIPAddresses(void);
|
|||
*/
|
||||
DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags);
|
||||
|
||||
/* Returns the IPv6 addresses for a particular interface index.
|
||||
* Returns NO_ERROR on success, something else on failure.
|
||||
*/
|
||||
ULONG v6addressesFromIndex(DWORD index, SOCKET_ADDRESS **addrs, ULONG *num_addrs);
|
||||
|
||||
/* Converts the network-order bytes in addr to a printable string. Returns
|
||||
* string.
|
||||
*/
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "winreg.h"
|
||||
#define USE_WS_PREFIX
|
||||
#include "winsock2.h"
|
||||
#include "ws2ipdef.h"
|
||||
#include "iphlpapi.h"
|
||||
#include "ifenum.h"
|
||||
#include "ipstats.h"
|
||||
|
@ -634,22 +635,23 @@ static ULONG v4addressesFromIndex(DWORD index, DWORD **addrs, ULONG *num_addrs)
|
|||
|
||||
static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADDRESSES *aa, ULONG *size)
|
||||
{
|
||||
ULONG ret, i, num_v4addrs = 0, total_size;
|
||||
ULONG ret, i, num_v4addrs = 0, num_v6addrs = 0, total_size;
|
||||
DWORD *v4addrs = NULL;
|
||||
SOCKET_ADDRESS *v6addrs = NULL;
|
||||
|
||||
if (family == AF_INET)
|
||||
ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs);
|
||||
else if (family == AF_INET6)
|
||||
ret = v6addressesFromIndex(index, &v6addrs, &num_v6addrs);
|
||||
else if (family == AF_UNSPEC)
|
||||
{
|
||||
WARN("no support for IPv6 addresses\n");
|
||||
ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs);
|
||||
if (!ret)
|
||||
ret = v6addressesFromIndex(index, &v6addrs, &num_v6addrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (family == AF_INET6)
|
||||
FIXME("no support for IPv6 addresses\n");
|
||||
else
|
||||
FIXME("address family %u unsupported\n", family);
|
||||
FIXME("address family %u unsupported\n", family);
|
||||
ret = ERROR_NO_DATA;
|
||||
}
|
||||
if (ret) return ret;
|
||||
|
@ -659,6 +661,10 @@ static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADD
|
|||
total_size += IF_NAMESIZE * sizeof(WCHAR);
|
||||
total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v4addrs;
|
||||
total_size += sizeof(struct sockaddr_in) * num_v4addrs;
|
||||
total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v6addrs;
|
||||
total_size += sizeof(SOCKET_ADDRESS) * num_v6addrs;
|
||||
for (i = 0; i < num_v6addrs; i++)
|
||||
total_size += v6addrs[i].iSockaddrLength;
|
||||
|
||||
if (aa && *size >= total_size)
|
||||
{
|
||||
|
@ -706,6 +712,37 @@ static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADD
|
|||
}
|
||||
}
|
||||
}
|
||||
if (num_v6addrs)
|
||||
{
|
||||
IP_ADAPTER_UNICAST_ADDRESS *ua;
|
||||
struct WS_sockaddr_in6 *sa;
|
||||
|
||||
if (aa->FirstUnicastAddress)
|
||||
{
|
||||
for (ua = aa->FirstUnicastAddress; ua->Next; ua = ua->Next)
|
||||
;
|
||||
ua->Next = (IP_ADAPTER_UNICAST_ADDRESS *)ptr;
|
||||
}
|
||||
else
|
||||
ua = aa->FirstUnicastAddress = (IP_ADAPTER_UNICAST_ADDRESS *)ptr;
|
||||
for (i = 0; i < num_v6addrs; i++)
|
||||
{
|
||||
memset(ua, 0, sizeof(IP_ADAPTER_UNICAST_ADDRESS));
|
||||
ua->u.s.Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
||||
ua->Address.iSockaddrLength = v6addrs[i].iSockaddrLength;
|
||||
ua->Address.lpSockaddr = (SOCKADDR *)((char *)ua + ua->u.s.Length);
|
||||
|
||||
sa = (struct WS_sockaddr_in6 *)ua->Address.lpSockaddr;
|
||||
memcpy(sa, v6addrs[i].lpSockaddr, sizeof(*sa));
|
||||
|
||||
ptr += ua->u.s.Length + ua->Address.iSockaddrLength;
|
||||
if (i < num_v6addrs - 1)
|
||||
{
|
||||
ua->Next = (IP_ADAPTER_UNICAST_ADDRESS *)ptr;
|
||||
ua = ua->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buflen = MAX_INTERFACE_PHYSADDR;
|
||||
getInterfacePhysicalByIndex(index, &buflen, aa->PhysicalAddress, &type);
|
||||
|
@ -720,6 +757,7 @@ static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADD
|
|||
else aa->OperStatus = IfOperStatusUnknown;
|
||||
}
|
||||
*size = total_size;
|
||||
HeapFree(GetProcessHeap(), 0, v6addrs);
|
||||
HeapFree(GetProcessHeap(), 0, v4addrs);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -255,6 +255,9 @@
|
|||
/* Define to 1 if you have the <ieeefp.h> header file. */
|
||||
#undef HAVE_IEEEFP_H
|
||||
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#undef HAVE_IFADDRS_H
|
||||
|
||||
/* Define to 1 if you have the <inet/mib2.h> header file. */
|
||||
#undef HAVE_INET_MIB2_H
|
||||
|
||||
|
|
Loading…
Reference in New Issue