Commit 201cdcc4 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

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
parent b825b8ba
/* Copyright (C) 2003 Juan Lang /* Copyright (C) 2003,2006 Juan Lang
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -455,38 +455,7 @@ InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void) ...@@ -455,38 +455,7 @@ InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void)
return ret; return ret;
} }
DWORD getInterfaceIPAddrByName(const char *name) static DWORD getInterfaceBCastAddrByName(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)
{ {
DWORD ret = INADDR_ANY; DWORD ret = INADDR_ANY;
...@@ -505,19 +474,7 @@ DWORD getInterfaceBCastAddrByName(const char *name) ...@@ -505,19 +474,7 @@ DWORD getInterfaceBCastAddrByName(const char *name)
return ret; return ret;
} }
DWORD getInterfaceBCastAddrByIndex(DWORD index) static DWORD getInterfaceMaskByName(const char *name)
{
DWORD ret;
const char *name = getInterfaceNameByIndex(index);
if (name)
ret = getInterfaceBCastAddrByName(name);
else
ret = INADDR_ANY;
return ret;
}
DWORD getInterfaceMaskByName(const char *name)
{ {
DWORD ret = INADDR_NONE; DWORD ret = INADDR_NONE;
...@@ -536,18 +493,6 @@ DWORD getInterfaceMaskByName(const char *name) ...@@ -536,18 +493,6 @@ DWORD getInterfaceMaskByName(const char *name)
return ret; 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) #if defined (SIOCGIFHWADDR)
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
PDWORD type) PDWORD type)
...@@ -657,12 +602,16 @@ DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, ...@@ -657,12 +602,16 @@ DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
else { else {
struct arpreq arp; struct arpreq arp;
struct sockaddr_in *saddr; 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)); memset(&arp, 0, sizeof(struct arpreq));
arp.arp_pa.sa_family = AF_INET; arp.arp_pa.sa_family = AF_INET;
saddr = (struct sockaddr_in *)&arp; /* proto addr is first member */ saddr = (struct sockaddr_in *)&arp; /* proto addr is first member */
saddr->sin_family = AF_INET; 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))) if ((ioctl(fd, SIOCGARP, &arp)))
ret = ERROR_INVALID_DATA; ret = ERROR_INVALID_DATA;
else { else {
...@@ -793,7 +742,7 @@ DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr, ...@@ -793,7 +742,7 @@ DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr,
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
} }
DWORD getInterfaceMtuByName(const char *name, PDWORD mtu) static DWORD getInterfaceMtuByName(const char *name, PDWORD mtu)
{ {
DWORD ret; DWORD ret;
int fd; int fd;
...@@ -825,17 +774,7 @@ DWORD getInterfaceMtuByName(const char *name, PDWORD mtu) ...@@ -825,17 +774,7 @@ DWORD getInterfaceMtuByName(const char *name, PDWORD mtu)
return ret; return ret;
} }
DWORD getInterfaceMtuByIndex(DWORD index, PDWORD mtu) static DWORD getInterfaceStatusByName(const char *name, PDWORD status)
{
const char *name = getInterfaceNameByIndex(index);
if (name)
return getInterfaceMtuByName(name, mtu);
else
return ERROR_INVALID_DATA;
}
DWORD getInterfaceStatusByName(const char *name, PDWORD status)
{ {
DWORD ret; DWORD ret;
int fd; int fd;
...@@ -866,16 +805,6 @@ DWORD getInterfaceStatusByName(const char *name, PDWORD status) ...@@ -866,16 +805,6 @@ DWORD getInterfaceStatusByName(const char *name, PDWORD status)
return ret; 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) DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
{ {
BYTE addr[MAX_INTERFACE_PHYSADDR]; BYTE addr[MAX_INTERFACE_PHYSADDR];
...@@ -927,52 +856,93 @@ DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry) ...@@ -927,52 +856,93 @@ DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
return ERROR_INVALID_DATA; return ERROR_INVALID_DATA;
} }
DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags) /* 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; DWORD ret;
if (!ppIpAddrTable)
ret = ERROR_INVALID_PARAMETER;
else
{
int fd; int fd;
fd = socket(PF_INET, SOCK_DGRAM, 0); fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd != -1) { if (fd != -1) {
int ioctlRet; int ioctlRet = 0;
DWORD guessedNumAddresses, numAddresses; DWORD guessedNumAddresses = 0, numAddresses = 0;
struct ifconf ifc;
caddr_t ifPtr; caddr_t ifPtr;
guessedNumAddresses = 0; ret = NO_ERROR;
ioctlRet = 0; ifc->ifc_len = 0;
memset(&ifc, 0, sizeof(ifc)); ifc->ifc_buf = NULL;
/* there is no way to know the interface count beforehand, /* there is no way to know the interface count beforehand,
so we need to loop again and again upping our max each time so we need to loop again and again upping our max each time
until returned < max */ until returned < max */
do { do {
HeapFree(GetProcessHeap(), 0, ifc->ifc_buf);
if (guessedNumAddresses == 0) if (guessedNumAddresses == 0)
guessedNumAddresses = INITIAL_INTERFACES_ASSUMED; guessedNumAddresses = INITIAL_INTERFACES_ASSUMED;
else else
guessedNumAddresses *= 2; guessedNumAddresses *= 2;
HeapFree(GetProcessHeap(), 0, ifc.ifc_buf); ifc->ifc_len = sizeof(struct ifreq) * guessedNumAddresses;
ifc.ifc_len = sizeof(struct ifreq) * guessedNumAddresses; ifc->ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc->ifc_len);
ifc.ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc.ifc_len); ioctlRet = ioctl(fd, SIOCGIFCONF, ifc);
ioctlRet = ioctl(fd, SIOCGIFCONF, &ifc);
} while (ioctlRet == 0 && } while (ioctlRet == 0 &&
ifc.ifc_len == (sizeof(struct ifreq) * guessedNumAddresses)); ifc->ifc_len == (sizeof(struct ifreq) * guessedNumAddresses));
if (ioctlRet == 0) { if (ioctlRet == 0) {
numAddresses = 0; ifPtr = ifc->ifc_buf;
ifPtr = ifc.ifc_buf; while (ifPtr && ifPtr < ifc->ifc_buf + ifc->ifc_len) {
while (ifPtr && ifPtr < ifc.ifc_buf + ifc.ifc_len) {
numAddresses++; numAddresses++;
ifPtr += ifreq_len((struct ifreq *)ifPtr); 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;
if (!ppIpAddrTable)
ret = ERROR_INVALID_PARAMETER;
else
{
DWORD numAddresses = 0;
struct ifconf ifc;
ret = enumIPAddresses(&numAddresses, &ifc);
if (!ret)
{
*ppIpAddrTable = HeapAlloc(heap, flags, sizeof(MIB_IPADDRTABLE) + *ppIpAddrTable = HeapAlloc(heap, flags, sizeof(MIB_IPADDRTABLE) +
(numAddresses - 1) * sizeof(MIB_IPADDRROW)); (numAddresses - 1) * sizeof(MIB_IPADDRROW));
if (*ppIpAddrTable) { if (*ppIpAddrTable) {
DWORD i = 0, bcast; DWORD i = 0, bcast;
caddr_t ifPtr;
ret = NO_ERROR; ret = NO_ERROR;
(*ppIpAddrTable)->dwNumEntries = numAddresses; (*ppIpAddrTable)->dwNumEntries = numAddresses;
...@@ -982,16 +952,15 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags) ...@@ -982,16 +952,15 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
ret = getInterfaceIndexByName(ifr->ifr_name, ret = getInterfaceIndexByName(ifr->ifr_name,
&(*ppIpAddrTable)->table[i].dwIndex); &(*ppIpAddrTable)->table[i].dwIndex);
(*ppIpAddrTable)->table[i].dwAddr = memcpy(&(*ppIpAddrTable)->table[i].dwAddr, ifr->ifr_addr.sa_data + 2,
getInterfaceIPAddrByIndex((*ppIpAddrTable)->table[i].dwIndex); sizeof(DWORD));
(*ppIpAddrTable)->table[i].dwMask = (*ppIpAddrTable)->table[i].dwMask =
getInterfaceMaskByIndex((*ppIpAddrTable)->table[i].dwIndex); getInterfaceMaskByName(ifr->ifr_name);
/* the dwBCastAddr member isn't the broadcast address, it indicates /* the dwBCastAddr member isn't the broadcast address, it indicates
* whether the interface uses the 1's broadcast address (1) or the * whether the interface uses the 1's broadcast address (1) or the
* 0's broadcast address (0). * 0's broadcast address (0).
*/ */
bcast = getInterfaceBCastAddrByIndex( bcast = getInterfaceBCastAddrByName(ifr->ifr_name);
(*ppIpAddrTable)->table[i].dwIndex);
(*ppIpAddrTable)->table[i].dwBCastAddr = (*ppIpAddrTable)->table[i].dwBCastAddr =
(bcast & (*ppIpAddrTable)->table[i].dwMask) ? 1 : 0; (bcast & (*ppIpAddrTable)->table[i].dwMask) ? 1 : 0;
/* FIXME: hardcoded reasm size, not sure where to get it */ /* FIXME: hardcoded reasm size, not sure where to get it */
...@@ -1005,14 +974,8 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags) ...@@ -1005,14 +974,8 @@ DWORD getIPAddrTable(PMIB_IPADDRTABLE *ppIpAddrTable, HANDLE heap, DWORD flags)
} }
else else
ret = ERROR_OUTOFMEMORY; ret = ERROR_OUTOFMEMORY;
}
else
ret = ERROR_INVALID_PARAMETER;
HeapFree(GetProcessHeap(), 0, ifc.ifc_buf); HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
close(fd);
} }
else
ret = ERROR_NO_SYSTEM_RESOURCES;
} }
return ret; return ret;
} }
......
/* ifenum.h /* ifenum.h
* Copyright (C) 2003 Juan Lang * Copyright (C) 2003,2006 Juan Lang
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -81,16 +81,6 @@ const char *getInterfaceNameByIndex(DWORD index); ...@@ -81,16 +81,6 @@ const char *getInterfaceNameByIndex(DWORD index);
*/ */
DWORD getInterfaceIndexByName(const char *name, PDWORD index); DWORD getInterfaceIndexByName(const char *name, PDWORD index);
/* This bunch returns IP addresses, and INADDR_ANY or INADDR_NONE if not found,
* appropriately depending on the f/n.
*/
DWORD getInterfaceIPAddrByName(const char *name);
DWORD getInterfaceIPAddrByIndex(DWORD index);
DWORD getInterfaceMaskByName(const char *name);
DWORD getInterfaceMaskByIndex(DWORD index);
DWORD getInterfaceBCastAddrByName(const char *name);
DWORD getInterfaceBCastAddrByIndex(DWORD index);
/* Gets a few physical charactersistics of a device: MAC addr len, MAC addr, /* Gets a few physical charactersistics of a device: MAC addr len, MAC addr,
* and type as one of the MIB_IF_TYPEs. * and type as one of the MIB_IF_TYPEs.
* len's in-out: on in, needs to say how many bytes are available in addr, * len's in-out: on in, needs to say how many bytes are available in addr,
...@@ -109,14 +99,6 @@ DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr, ...@@ -109,14 +99,6 @@ DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr, DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr,
PDWORD type); PDWORD type);
/* Get the operational status as a (MIB_)IF_OPER_STATUS type.
*/
DWORD getInterfaceStatusByName(const char *name, PDWORD status);
DWORD getInterfaceStatusByIndex(DWORD index, PDWORD status);
DWORD getInterfaceMtuByName(const char *name, PDWORD mtu);
DWORD getInterfaceMtuByIndex(DWORD index, PDWORD mtu);
/* Fills in the MIB_IFROW by name/index. Doesn't fill in interface statistics, /* Fills in the MIB_IFROW by name/index. Doesn't fill in interface statistics,
* see ipstats.h for that. * see ipstats.h for that.
* Returns ERROR_INVALID_PARAMETER if name or entry is NULL, ERROR_INVALID_DATA * Returns ERROR_INVALID_PARAMETER if name or entry is NULL, ERROR_INVALID_DATA
...@@ -125,6 +107,8 @@ DWORD getInterfaceMtuByIndex(DWORD index, PDWORD mtu); ...@@ -125,6 +107,8 @@ DWORD getInterfaceMtuByIndex(DWORD index, PDWORD mtu);
DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry); DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry);
DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry); DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry);
DWORD getNumIPAddresses(void);
/* Gets the configured IP addresses for the system, and sets *ppIpAddrTable to /* Gets the configured IP addresses for the system, and sets *ppIpAddrTable to
* a table of them allocated from heap, or NULL if out of memory. Returns * a table of them allocated from heap, or NULL if out of memory. Returns
* NO_ERROR on success, something else on failure. Note there may be more than * NO_ERROR on success, something else on failure. Note there may be more than
......
/* /*
* iphlpapi dll implementation * iphlpapi dll implementation
* *
* Copyright (C) 2003 Juan Lang * Copyright (C) 2003,2006 Juan Lang
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -618,6 +618,7 @@ DWORD WINAPI FlushIpNetTable(DWORD dwIfIndex) ...@@ -618,6 +618,7 @@ DWORD WINAPI FlushIpNetTable(DWORD dwIfIndex)
DWORD WINAPI GetAdapterIndex(LPWSTR AdapterName, PULONG IfIndex) DWORD WINAPI GetAdapterIndex(LPWSTR AdapterName, PULONG IfIndex)
{ {
FIXME("(AdapterName %p, IfIndex %p): stub\n", AdapterName, IfIndex); FIXME("(AdapterName %p, IfIndex %p): stub\n", AdapterName, IfIndex);
/* FIXME: implement using getInterfaceIndexByName */
return ERROR_NOT_SUPPORTED; return ERROR_NOT_SUPPORTED;
} }
...@@ -646,22 +647,34 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) ...@@ -646,22 +647,34 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
DWORD numNonLoopbackInterfaces = getNumNonLoopbackInterfaces(); DWORD numNonLoopbackInterfaces = getNumNonLoopbackInterfaces();
if (numNonLoopbackInterfaces > 0) { if (numNonLoopbackInterfaces > 0) {
/* this calculation assumes only one address in the IP_ADDR_STRING lists. DWORD numIPAddresses = getNumIPAddresses();
that's okay, because: ULONG size;
- we don't get multiple addresses per adapter anyway
- we don't know about per-adapter gateways
- DHCP and WINS servers can have max one entry per list */
ULONG size = sizeof(IP_ADAPTER_INFO) * numNonLoopbackInterfaces;
/* This may slightly overestimate the amount of space needed, because
* the IP addresses include the loopback address, but it's easier
* to make sure there's more than enough space than to make sure there's
* precisely enough space.
*/
size = sizeof(IP_ADAPTER_INFO) * numNonLoopbackInterfaces;
if (numIPAddresses > numNonLoopbackInterfaces)
size += (numIPAddresses - numNonLoopbackInterfaces) *
sizeof(IP_ADDR_STRING);
if (!pAdapterInfo || *pOutBufLen < size) { if (!pAdapterInfo || *pOutBufLen < size) {
*pOutBufLen = size; *pOutBufLen = size;
ret = ERROR_BUFFER_OVERFLOW; ret = ERROR_BUFFER_OVERFLOW;
} }
else { else {
InterfaceIndexTable *table = getNonLoopbackInterfaceIndexTable(); InterfaceIndexTable *table = NULL;
PMIB_IPADDRTABLE ipAddrTable = NULL;
ret = getIPAddrTable(&ipAddrTable, GetProcessHeap(), 0);
if (!ret)
table = getNonLoopbackInterfaceIndexTable();
if (table) { if (table) {
size = sizeof(IP_ADAPTER_INFO) * table->numIndexes; size = sizeof(IP_ADAPTER_INFO) * table->numIndexes;
if (ipAddrTable->dwNumEntries > numNonLoopbackInterfaces)
size += (ipAddrTable->dwNumEntries - numNonLoopbackInterfaces) *
sizeof(IP_ADDR_STRING);
if (*pOutBufLen < size) { if (*pOutBufLen < size) {
*pOutBufLen = size; *pOutBufLen = size;
ret = ERROR_INSUFFICIENT_BUFFER; ret = ERROR_INSUFFICIENT_BUFFER;
...@@ -671,10 +684,13 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) ...@@ -671,10 +684,13 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
HKEY hKey; HKEY hKey;
BOOL winsEnabled = FALSE; BOOL winsEnabled = FALSE;
IP_ADDRESS_STRING primaryWINS, secondaryWINS; IP_ADDRESS_STRING primaryWINS, secondaryWINS;
PIP_ADDR_STRING nextIPAddr = (PIP_ADDR_STRING)((LPBYTE)pAdapterInfo
+ numNonLoopbackInterfaces * sizeof(IP_ADAPTER_INFO));
memset(pAdapterInfo, 0, size); memset(pAdapterInfo, 0, size);
/* @@ Wine registry key: HKCU\Software\Wine\Network */ /* @@ Wine registry key: HKCU\Software\Wine\Network */
if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Network", &hKey) == ERROR_SUCCESS) { if (RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Network",
&hKey) == ERROR_SUCCESS) {
DWORD size = sizeof(primaryWINS.String); DWORD size = sizeof(primaryWINS.String);
unsigned long addr; unsigned long addr;
...@@ -693,7 +709,9 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) ...@@ -693,7 +709,9 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
} }
for (ndx = 0; ndx < table->numIndexes; ndx++) { for (ndx = 0; ndx < table->numIndexes; ndx++) {
PIP_ADAPTER_INFO ptr = &pAdapterInfo[ndx]; PIP_ADAPTER_INFO ptr = &pAdapterInfo[ndx];
DWORD addrLen = sizeof(ptr->Address), type; DWORD addrLen = sizeof(ptr->Address), type, i;
PIP_ADDR_STRING currentIPAddr = &ptr->IpAddressList;
BOOL firstIPAddr = TRUE;
/* on Win98 this is left empty, but whatever */ /* on Win98 this is left empty, but whatever */
lstrcpynA(ptr->AdapterName, lstrcpynA(ptr->AdapterName,
...@@ -707,10 +725,26 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) ...@@ -707,10 +725,26 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
ptr->AddressLength = addrLen; ptr->AddressLength = addrLen;
ptr->Type = type; ptr->Type = type;
ptr->Index = table->indexes[ndx]; ptr->Index = table->indexes[ndx];
toIPAddressString(getInterfaceIPAddrByIndex(table->indexes[ndx]), for (i = 0; i < ipAddrTable->dwNumEntries; i++) {
if (ipAddrTable->table[i].dwIndex == ptr->Index) {
if (firstIPAddr) {
toIPAddressString(ipAddrTable->table[i].dwAddr,
ptr->IpAddressList.IpAddress.String); ptr->IpAddressList.IpAddress.String);
toIPAddressString(getInterfaceMaskByIndex(table->indexes[ndx]), toIPAddressString(ipAddrTable->table[i].dwBCastAddr,
ptr->IpAddressList.IpMask.String); ptr->IpAddressList.IpMask.String);
firstIPAddr = FALSE;
}
else {
currentIPAddr->Next = nextIPAddr;
currentIPAddr = nextIPAddr;
toIPAddressString(ipAddrTable->table[i].dwAddr,
currentIPAddr->IpAddress.String);
toIPAddressString(ipAddrTable->table[i].dwBCastAddr,
currentIPAddr->IpMask.String);
nextIPAddr++;
}
}
}
if (winsEnabled) { if (winsEnabled) {
ptr->HaveWins = TRUE; ptr->HaveWins = TRUE;
memcpy(ptr->PrimaryWinsServer.IpAddress.String, memcpy(ptr->PrimaryWinsServer.IpAddress.String,
...@@ -729,6 +763,8 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) ...@@ -729,6 +763,8 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
} }
else else
ret = ERROR_OUTOFMEMORY; ret = ERROR_OUTOFMEMORY;
if (ipAddrTable)
HeapFree(GetProcessHeap(), 0, ipAddrTable);
} }
} }
else else
...@@ -1038,6 +1074,7 @@ DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen) ...@@ -1038,6 +1074,7 @@ DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen)
else { else {
DWORD ndx; DWORD ndx;
*dwOutBufLen = size;
pIfTable->NumAdapters = 0; pIfTable->NumAdapters = 0;
for (ndx = 0; ndx < table->numIndexes; ndx++) { for (ndx = 0; ndx < table->numIndexes; ndx++) {
const char *walker, *name; const char *walker, *name;
...@@ -1791,7 +1828,7 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd ...@@ -1791,7 +1828,7 @@ DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAdd
DWORD WINAPI SetIfEntry(PMIB_IFROW pIfRow) DWORD WINAPI SetIfEntry(PMIB_IFROW pIfRow)
{ {
FIXME("(pIfRow %p): stub\n", pIfRow); FIXME("(pIfRow %p): stub\n", pIfRow);
/* this is supposed to set an administratively interface up or down. /* this is supposed to set an interface administratively up or down.
Could do SIOCSIFFLAGS and set/clear IFF_UP, but, not sure I want to, and Could do SIOCSIFFLAGS and set/clear IFF_UP, but, not sure I want to, and
this sort of down is indistinguishable from other sorts of down (e.g. no this sort of down is indistinguishable from other sorts of down (e.g. no
link). */ link). */
......
/* Copyright (C) 2003 Juan Lang /* Copyright (C) 2003,2006 Juan Lang
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
......
/* ipstats.h /* ipstats.h
* Copyright (C) 2003 Juan Lang * Copyright (C) 2003,2006 Juan Lang
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
......
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