iphlpapi: Implement retrieving IPv4 addresses using getifaddrs, when available.
This commit is contained in:
parent
b4c3fcd17a
commit
25b014b6e7
|
@ -670,6 +670,102 @@ DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD getIPAddrRowByName(PMIB_IPADDRROW ipAddrRow, const char *ifName,
|
||||||
|
const struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
DWORD ret, bcast;
|
||||||
|
|
||||||
|
ret = getInterfaceIndexByName(ifName, &ipAddrRow->dwIndex);
|
||||||
|
memcpy(&ipAddrRow->dwAddr, sa->sa_data + 2, sizeof(DWORD));
|
||||||
|
ipAddrRow->dwMask = getInterfaceMaskByName(ifName);
|
||||||
|
/* the dwBCastAddr member isn't the broadcast address, it indicates whether
|
||||||
|
* the interface uses the 1's broadcast address (1) or the 0's broadcast
|
||||||
|
* address (0).
|
||||||
|
*/
|
||||||
|
bcast = getInterfaceBCastAddrByName(ifName);
|
||||||
|
ipAddrRow->dwBCastAddr = (bcast & ipAddrRow->dwMask) ? 1 : 0;
|
||||||
|
/* FIXME: hardcoded reasm size, not sure where to get it */
|
||||||
|
ipAddrRow->dwReasmSize = 65535;
|
||||||
|
ipAddrRow->unused1 = 0;
|
||||||
|
ipAddrRow->wType = 0;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_IFADDRS_H
|
||||||
|
|
||||||
|
/* Counts the IPv4 addresses in the system using the return value from
|
||||||
|
* getifaddrs, returning the count.
|
||||||
|
*/
|
||||||
|
static DWORD countIPv4Addresses(struct ifaddrs *ifa)
|
||||||
|
{
|
||||||
|
DWORD numAddresses = 0;
|
||||||
|
|
||||||
|
for (; ifa; ifa = ifa->ifa_next)
|
||||||
|
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET)
|
||||||
|
numAddresses++;
|
||||||
|
return numAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD getNumIPAddresses(void)
|
||||||
|
{
|
||||||
|
DWORD numAddresses = 0;
|
||||||
|
struct ifaddrs *ifa;
|
||||||
|
|
||||||
|
if (!getifaddrs(&ifa))
|
||||||
|
{
|
||||||
|
numAddresses = countIPv4Addresses(ifa);
|
||||||
|
freeifaddrs(ifa);
|
||||||
|
}
|
||||||
|
return numAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
|
||||||
|
{
|
||||||
|
DWORD ret;
|
||||||
|
|
||||||
|
if (!ppIpAddrTable)
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct ifaddrs *ifa;
|
||||||
|
|
||||||
|
if (!getifaddrs(&ifa))
|
||||||
|
{
|
||||||
|
DWORD size = sizeof(MIB_IPADDRTABLE);
|
||||||
|
DWORD numAddresses = countIPv4Addresses(ifa);
|
||||||
|
|
||||||
|
if (numAddresses > 1)
|
||||||
|
size += (numAddresses - 1) * sizeof(MIB_IPADDRROW);
|
||||||
|
*ppIpAddrTable = HeapAlloc(heap, flags, size);
|
||||||
|
if (*ppIpAddrTable)
|
||||||
|
{
|
||||||
|
DWORD i = 0;
|
||||||
|
struct ifaddrs *ifp;
|
||||||
|
|
||||||
|
ret = NO_ERROR;
|
||||||
|
(*ppIpAddrTable)->dwNumEntries = numAddresses;
|
||||||
|
for (ifp = ifa; !ret && ifp; ifp = ifp->ifa_next)
|
||||||
|
{
|
||||||
|
if (!ifp->ifa_addr || ifp->ifa_addr->sa_family != AF_INET)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = getIPAddrRowByName(&(*ppIpAddrTable)->table[i], ifp->ifa_name,
|
||||||
|
ifp->ifa_addr);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = ERROR_OUTOFMEMORY;
|
||||||
|
freeifaddrs(ifa);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
/* Enumerates the IP addresses in the system using SIOCGIFCONF, returning
|
/* Enumerates the IP addresses in the system using SIOCGIFCONF, returning
|
||||||
* the count to you in *pcAddresses. It also returns to you the struct ifconf
|
* the count to you in *pcAddresses. It also returns to you the struct ifconf
|
||||||
* used by the call to ioctl, so that you may process the addresses further.
|
* used by the call to ioctl, so that you may process the addresses further.
|
||||||
|
@ -763,7 +859,7 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
|
||||||
size += (numAddresses - 1) * sizeof(MIB_IPADDRROW);
|
size += (numAddresses - 1) * sizeof(MIB_IPADDRROW);
|
||||||
*ppIpAddrTable = HeapAlloc(heap, flags, size);
|
*ppIpAddrTable = HeapAlloc(heap, flags, size);
|
||||||
if (*ppIpAddrTable) {
|
if (*ppIpAddrTable) {
|
||||||
DWORD i = 0, bcast;
|
DWORD i = 0;
|
||||||
caddr_t ifPtr;
|
caddr_t ifPtr;
|
||||||
|
|
||||||
ret = NO_ERROR;
|
ret = NO_ERROR;
|
||||||
|
@ -777,24 +873,8 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
|
||||||
if (ifr->ifr_addr.sa_family != AF_INET)
|
if (ifr->ifr_addr.sa_family != AF_INET)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = getInterfaceIndexByName(ifr->ifr_name,
|
ret = getIPAddrRowByName(&(*ppIpAddrTable)->table[i], ifr->ifr_name,
|
||||||
&(*ppIpAddrTable)->table[i].dwIndex);
|
&ifr->ifr_addr);
|
||||||
memcpy(&(*ppIpAddrTable)->table[i].dwAddr, ifr->ifr_addr.sa_data + 2,
|
|
||||||
sizeof(DWORD));
|
|
||||||
(*ppIpAddrTable)->table[i].dwMask =
|
|
||||||
getInterfaceMaskByName(ifr->ifr_name);
|
|
||||||
/* the dwBCastAddr member isn't the broadcast address, it indicates
|
|
||||||
* whether the interface uses the 1's broadcast address (1) or the
|
|
||||||
* 0's broadcast address (0).
|
|
||||||
*/
|
|
||||||
bcast = getInterfaceBCastAddrByName(ifr->ifr_name);
|
|
||||||
(*ppIpAddrTable)->table[i].dwBCastAddr =
|
|
||||||
(bcast & (*ppIpAddrTable)->table[i].dwMask) ? 1 : 0;
|
|
||||||
/* FIXME: hardcoded reasm size, not sure where to get it */
|
|
||||||
(*ppIpAddrTable)->table[i].dwReasmSize = 65535;
|
|
||||||
|
|
||||||
(*ppIpAddrTable)->table[i].unused1 = 0;
|
|
||||||
(*ppIpAddrTable)->table[i].wType = 0;
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -806,6 +886,8 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IFADDRS_H
|
#ifdef HAVE_IFADDRS_H
|
||||||
ULONG v6addressesFromIndex(DWORD index, SOCKET_ADDRESS **addrs, ULONG *num_addrs)
|
ULONG v6addressesFromIndex(DWORD index, SOCKET_ADDRESS **addrs, ULONG *num_addrs)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue