Commit f776aea6 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

iphlpapi: Set gateway addresses in GetAdaptersAddresses.

parent 873be06c
...@@ -696,34 +696,82 @@ static char *debugstr_ipv6(const struct WS_sockaddr_in6 *sin, char *buf) ...@@ -696,34 +696,82 @@ static char *debugstr_ipv6(const struct WS_sockaddr_in6 *sin, char *buf)
return buf; return buf;
} }
static ULONG count_v4_gateways(DWORD index, PMIB_IPFORWARDTABLE routeTable)
{
DWORD i, num_gateways = 0;
for (i = 0; i < routeTable->dwNumEntries; i++)
{
if (routeTable->table[i].dwForwardIfIndex == index &&
routeTable->table[i].dwForwardType == MIB_IPROUTE_TYPE_INDIRECT)
num_gateways++;
}
return num_gateways;
}
static PMIB_IPFORWARDROW findIPv4Gateway(DWORD index,
PMIB_IPFORWARDTABLE routeTable)
{
DWORD i;
PMIB_IPFORWARDROW row = NULL;
for (i = 0; !row && i < routeTable->dwNumEntries; i++)
{
if (routeTable->table[i].dwForwardIfIndex == index &&
routeTable->table[i].dwForwardType == MIB_IPROUTE_TYPE_INDIRECT)
row = &routeTable->table[i];
}
return row;
}
static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADDRESSES *aa, ULONG *size) static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADDRESSES *aa, ULONG *size)
{ {
ULONG ret, i, num_v4addrs = 0, num_v6addrs = 0, total_size; ULONG ret, i, num_v4addrs = 0, num_v4_gateways = 0, num_v6addrs = 0, total_size;
DWORD *v4addrs = NULL; DWORD *v4addrs = NULL;
SOCKET_ADDRESS *v6addrs = NULL; SOCKET_ADDRESS *v6addrs = NULL;
PMIB_IPFORWARDTABLE routeTable = NULL;
if (family == AF_INET) if (family == AF_INET)
{
ret = AllocateAndGetIpForwardTableFromStack(&routeTable, FALSE,
GetProcessHeap(), 0);
if (!ret)
{
ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs); ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs);
num_v4_gateways = count_v4_gateways(index, routeTable);
}
}
else if (family == AF_INET6) else if (family == AF_INET6)
ret = v6addressesFromIndex(index, &v6addrs, &num_v6addrs); ret = v6addressesFromIndex(index, &v6addrs, &num_v6addrs);
else if (family == AF_UNSPEC) else if (family == AF_UNSPEC)
{ {
ret = AllocateAndGetIpForwardTableFromStack(&routeTable, FALSE,
GetProcessHeap(), 0);
if (!ret)
{
ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs); ret = v4addressesFromIndex(index, &v4addrs, &num_v4addrs);
num_v4_gateways = count_v4_gateways(index, routeTable);
if (!ret) if (!ret)
ret = v6addressesFromIndex(index, &v6addrs, &num_v6addrs); ret = v6addressesFromIndex(index, &v6addrs, &num_v6addrs);
} }
}
else else
{ {
FIXME("address family %u unsupported\n", family); FIXME("address family %u unsupported\n", family);
ret = ERROR_NO_DATA; ret = ERROR_NO_DATA;
} }
if (ret) return ret; if (ret)
{
HeapFree(GetProcessHeap(), 0, routeTable);
return ret;
}
total_size = sizeof(IP_ADAPTER_ADDRESSES); total_size = sizeof(IP_ADAPTER_ADDRESSES);
total_size += IF_NAMESIZE; total_size += IF_NAMESIZE;
total_size += IF_NAMESIZE * sizeof(WCHAR); total_size += IF_NAMESIZE * sizeof(WCHAR);
total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v4addrs; total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v4addrs;
total_size += sizeof(struct sockaddr_in) * num_v4addrs; total_size += sizeof(struct sockaddr_in) * num_v4addrs;
total_size += (sizeof(IP_ADAPTER_GATEWAY_ADDRESS) + sizeof(SOCKADDR_IN)) * num_v4_gateways;
total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v6addrs; total_size += sizeof(IP_ADAPTER_UNICAST_ADDRESS) * num_v6addrs;
total_size += sizeof(SOCKET_ADDRESS) * num_v6addrs; total_size += sizeof(SOCKET_ADDRESS) * num_v6addrs;
for (i = 0; i < num_v6addrs; i++) for (i = 0; i < num_v6addrs; i++)
...@@ -751,11 +799,44 @@ static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADD ...@@ -751,11 +799,44 @@ static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADD
TRACE("%s: %d IPv4 addresses, %d IPv6 addresses:\n", name, num_v4addrs, TRACE("%s: %d IPv4 addresses, %d IPv6 addresses:\n", name, num_v4addrs,
num_v6addrs); num_v6addrs);
if (num_v4_gateways)
{
PMIB_IPFORWARDROW adapterRow;
if ((adapterRow = findIPv4Gateway(index, routeTable)))
{
PIP_ADAPTER_GATEWAY_ADDRESS gw;
PSOCKADDR_IN sin;
for (gw = aa->FirstGatewayAddress; gw && gw->Next;
gw = gw->Next)
;
if (!gw)
{
gw = (PIP_ADAPTER_GATEWAY_ADDRESS)ptr;
aa->FirstGatewayAddress = gw;
}
else
{
gw->Next = (PIP_ADAPTER_GATEWAY_ADDRESS)ptr;
gw = gw->Next;
}
gw->u.s.Length = sizeof(IP_ADAPTER_GATEWAY_ADDRESS);
ptr += sizeof(IP_ADAPTER_GATEWAY_ADDRESS);
sin = (PSOCKADDR_IN)ptr;
sin->sin_family = AF_INET;
sin->sin_port = 0;
memcpy(&sin->sin_addr, &adapterRow->dwForwardNextHop,
sizeof(DWORD));
gw->Address.lpSockaddr = (LPSOCKADDR)sin;
gw->Address.iSockaddrLength = sizeof(SOCKADDR_IN);
ptr += sizeof(SOCKADDR_IN);
}
}
if (num_v4addrs) if (num_v4addrs)
{ {
IP_ADAPTER_UNICAST_ADDRESS *ua; IP_ADAPTER_UNICAST_ADDRESS *ua;
struct sockaddr_in *sa; struct sockaddr_in *sa;
aa->Flags |= IP_ADAPTER_IPV4_ENABLED; aa->Flags |= IP_ADAPTER_IPV4_ENABLED;
ua = aa->FirstUnicastAddress = (IP_ADAPTER_UNICAST_ADDRESS *)ptr; ua = aa->FirstUnicastAddress = (IP_ADAPTER_UNICAST_ADDRESS *)ptr;
for (i = 0; i < num_v4addrs; i++) for (i = 0; i < num_v4addrs; i++)
...@@ -834,6 +915,7 @@ static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADD ...@@ -834,6 +915,7 @@ static ULONG adapterAddressesFromIndex(ULONG family, DWORD index, IP_ADAPTER_ADD
else aa->OperStatus = IfOperStatusUnknown; else aa->OperStatus = IfOperStatusUnknown;
} }
*size = total_size; *size = total_size;
HeapFree(GetProcessHeap(), 0, routeTable);
HeapFree(GetProcessHeap(), 0, v6addrs); HeapFree(GetProcessHeap(), 0, v6addrs);
HeapFree(GetProcessHeap(), 0, v4addrs); HeapFree(GetProcessHeap(), 0, v4addrs);
return ERROR_SUCCESS; return ERROR_SUCCESS;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment