iphlpapi: Remove one IP address per interface restriction.
- remove restriction of one IP address per interface
- remove dead code, and make static functions that can be
- update comments and copyright notice
diff --git a/dlls/iphlpapi/ifenum.c b/dlls/iphlpapi/ifenum.c
index 0283d36..31b0532 100644
--- a/dlls/iphlpapi/ifenum.c
+++ b/dlls/iphlpapi/ifenum.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Juan Lang
+/* Copyright (C) 2003,2006 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -455,38 +455,7 @@
return ret;
}
-DWORD getInterfaceIPAddrByName(const char *name)
-{
- DWORD ret = INADDR_ANY;
-
- if (name) {
- int fd = socket(PF_INET, SOCK_DGRAM, 0);
-
- if (fd != -1) {
- struct ifreq ifr;
-
- lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
- if (ioctl(fd, SIOCGIFADDR, &ifr) == 0)
- memcpy(&ret, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
- close(fd);
- }
- }
- return ret;
-}
-
-DWORD getInterfaceIPAddrByIndex(DWORD index)
-{
- DWORD ret;
- const char *name = getInterfaceNameByIndex(index);
-
- if (name)
- ret = getInterfaceIPAddrByName(name);
- else
- ret = INADDR_ANY;
- return ret;
-}
-
-DWORD getInterfaceBCastAddrByName(const char *name)
+static DWORD getInterfaceBCastAddrByName(const char *name)
{
DWORD ret = INADDR_ANY;
@@ -505,19 +474,7 @@
return ret;
}
-DWORD getInterfaceBCastAddrByIndex(DWORD index)
-{
- DWORD ret;
- const char *name = getInterfaceNameByIndex(index);
-
- if (name)
- ret = getInterfaceBCastAddrByName(name);
- else
- ret = INADDR_ANY;
- return ret;
-}
-
-DWORD getInterfaceMaskByName(const char *name)
+static DWORD getInterfaceMaskByName(const char *name)
{
DWORD ret = INADDR_NONE;
@@ -536,18 +493,6 @@
return ret;
}
-DWORD getInterfaceMaskByIndex(DWORD index)
-{
- DWORD ret;
- const char *name = getInterfaceNameByIndex(index);
-
- if (name)
- ret = getInterfaceMaskByName(name);
- else
- ret = INADDR_NONE;
- return ret;
-}
-
#if defined (SIOCGIFHWADDR)
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
PDWORD type)
@@ -657,12 +602,16 @@
else {
struct arpreq arp;
struct sockaddr_in *saddr;
+ struct ifreq ifr;
+ /* get IP addr */
+ lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
+ ioctl(fd, SIOCGIFADDR, &ifr);
memset(&arp, 0, sizeof(struct arpreq));
arp.arp_pa.sa_family = AF_INET;
saddr = (struct sockaddr_in *)&arp; /* proto addr is first member */
saddr->sin_family = AF_INET;
- saddr->sin_addr.s_addr = getInterfaceIPAddrByName(name);
+ memcpy(&saddr->sin_addr.s_addr, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
if ((ioctl(fd, SIOCGARP, &arp)))
ret = ERROR_INVALID_DATA;
else {
@@ -793,7 +742,7 @@
return ERROR_INVALID_DATA;
}
-DWORD getInterfaceMtuByName(const char *name, PDWORD mtu)
+static DWORD getInterfaceMtuByName(const char *name, PDWORD mtu)
{
DWORD ret;
int fd;
@@ -825,17 +774,7 @@
return ret;
}
-DWORD getInterfaceMtuByIndex(DWORD index, PDWORD mtu)
-{
- const char *name = getInterfaceNameByIndex(index);
-
- if (name)
- return getInterfaceMtuByName(name, mtu);
- else
- return ERROR_INVALID_DATA;
-}
-
-DWORD getInterfaceStatusByName(const char *name, PDWORD status)
+static DWORD getInterfaceStatusByName(const char *name, PDWORD status)
{
DWORD ret;
int fd;
@@ -866,16 +805,6 @@
return ret;
}
-DWORD getInterfaceStatusByIndex(DWORD index, PDWORD status)
-{
- const char *name = getInterfaceNameByIndex(index);
-
- if (name)
- return getInterfaceStatusByName(name, status);
- else
- return ERROR_INVALID_DATA;
-}
-
DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
{
BYTE addr[MAX_INTERFACE_PHYSADDR];
@@ -927,6 +856,74 @@
return ERROR_INVALID_DATA;
}
+/* Enumerates the IP addresses in the system using SIOCGIFCONF, returning
+ * 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.
+ * Free ifc->ifc_buf using HeapFree.
+ * Returns NO_ERROR on success, something else on failure.
+ */
+static DWORD enumIPAddresses(PDWORD pcAddresses, struct ifconf *ifc)
+{
+ DWORD ret;
+ int fd;
+
+ fd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (fd != -1) {
+ int ioctlRet = 0;
+ DWORD guessedNumAddresses = 0, numAddresses = 0;
+ caddr_t ifPtr;
+
+ ret = NO_ERROR;
+ ifc->ifc_len = 0;
+ ifc->ifc_buf = NULL;
+ /* there is no way to know the interface count beforehand,
+ so we need to loop again and again upping our max each time
+ until returned < max */
+ do {
+ HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
+ if (guessedNumAddresses == 0)
+ guessedNumAddresses = INITIAL_INTERFACES_ASSUMED;
+ else
+ guessedNumAddresses *= 2;
+ ifc->ifc_len = sizeof(struct ifreq) * guessedNumAddresses;
+ ifc->ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc->ifc_len);
+ ioctlRet = ioctl(fd, SIOCGIFCONF, ifc);
+ } while (ioctlRet == 0 &&
+ ifc->ifc_len == (sizeof(struct ifreq) * guessedNumAddresses));
+
+ if (ioctlRet == 0) {
+ ifPtr = ifc->ifc_buf;
+ while (ifPtr && ifPtr < ifc->ifc_buf + ifc->ifc_len) {
+ numAddresses++;
+ ifPtr += ifreq_len((struct ifreq *)ifPtr);
+ }
+ }
+ else
+ ret = ERROR_INVALID_PARAMETER; /* FIXME: map from errno to Win32 */
+ if (!ret)
+ *pcAddresses = numAddresses;
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
+ ifc->ifc_buf = NULL;
+ }
+ close(fd);
+ }
+ else
+ ret = ERROR_NO_SYSTEM_RESOURCES;
+ return ret;
+}
+
+DWORD getNumIPAddresses(void)
+{
+ DWORD numAddresses = 0;
+ struct ifconf ifc;
+
+ if (!enumIPAddresses(&numAddresses, &ifc))
+ HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
+ return numAddresses;
+}
+
DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
{
DWORD ret;
@@ -935,84 +932,50 @@
ret = ERROR_INVALID_PARAMETER;
else
{
- int fd;
+ DWORD numAddresses = 0;
+ struct ifconf ifc;
- fd = socket(PF_INET, SOCK_DGRAM, 0);
- if (fd != -1) {
- int ioctlRet;
- DWORD guessedNumAddresses, numAddresses;
- struct ifconf ifc;
- caddr_t ifPtr;
+ ret = enumIPAddresses(&numAddresses, &ifc);
+ if (!ret)
+ {
+ *ppIpAddrTable = HeapAlloc(heap, flags, sizeof(MIB_IPADDRTABLE) +
+ (numAddresses - 1) * sizeof(MIB_IPADDRROW));
+ if (*ppIpAddrTable) {
+ DWORD i = 0, bcast;
+ caddr_t ifPtr;
- guessedNumAddresses = 0;
- ioctlRet = 0;
- memset(&ifc, 0, sizeof(ifc));
- /* there is no way to know the interface count beforehand,
- so we need to loop again and again upping our max each time
- until returned < max */
- do {
- if (guessedNumAddresses == 0)
- guessedNumAddresses = INITIAL_INTERFACES_ASSUMED;
- else
- guessedNumAddresses *= 2;
- HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
- ifc.ifc_len = sizeof(struct ifreq) * guessedNumAddresses;
- ifc.ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc.ifc_len);
- ioctlRet = ioctl(fd, SIOCGIFCONF, &ifc);
- } while (ioctlRet == 0 &&
- ifc.ifc_len == (sizeof(struct ifreq) * guessedNumAddresses));
-
- if (ioctlRet == 0) {
- numAddresses = 0;
+ ret = NO_ERROR;
+ (*ppIpAddrTable)->dwNumEntries = numAddresses;
ifPtr = ifc.ifc_buf;
- while (ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
- numAddresses++;
- ifPtr += ifreq_len((struct ifreq *)ifPtr);
+ while (!ret && ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
+ struct ifreq *ifr = (struct ifreq *)ifPtr;
+
+ ret = getInterfaceIndexByName(ifr->ifr_name,
+ &(*ppIpAddrTable)->table[i].dwIndex);
+ 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;
+ ifPtr += ifreq_len(ifr);
+ i++;
}
- *ppIpAddrTable = HeapAlloc(heap, flags, sizeof(MIB_IPADDRTABLE) +
- (numAddresses - 1) * sizeof(MIB_IPADDRROW));
- if (*ppIpAddrTable) {
- DWORD i = 0, bcast;
-
- ret = NO_ERROR;
- (*ppIpAddrTable)->dwNumEntries = numAddresses;
- ifPtr = ifc.ifc_buf;
- while (!ret && ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
- struct ifreq *ifr = (struct ifreq *)ifPtr;
-
- ret = getInterfaceIndexByName(ifr->ifr_name,
- &(*ppIpAddrTable)->table[i].dwIndex);
- (*ppIpAddrTable)->table[i].dwAddr =
- getInterfaceIPAddrByIndex((*ppIpAddrTable)->table[i].dwIndex);
- (*ppIpAddrTable)->table[i].dwMask =
- getInterfaceMaskByIndex((*ppIpAddrTable)->table[i].dwIndex);
- /* 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 = getInterfaceBCastAddrByIndex(
- (*ppIpAddrTable)->table[i].dwIndex);
- (*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;
- ifPtr += ifreq_len(ifr);
- i++;
- }
- }
- else
- ret = ERROR_OUTOFMEMORY;
}
else
- ret = ERROR_INVALID_PARAMETER;
+ ret = ERROR_OUTOFMEMORY;
HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
- close(fd);
}
- else
- ret = ERROR_NO_SYSTEM_RESOURCES;
}
return ret;
}