iphlpapi: Reimplement interface enumeration.
Implement interface enumeration based on if_nameindex, based on a suggestion by Michael Ost
This commit is contained in:
parent
d4c62162e9
commit
540dca3259
|
@ -15,22 +15,6 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
* Implementation notes
|
* Implementation notes
|
||||||
* Interface index fun:
|
|
||||||
* - Windows may rely on an index being cleared in the topmost 8 bits in some
|
|
||||||
* APIs; see GetFriendlyIfIndex and the mention of "backward compatible"
|
|
||||||
* indexes. It isn't clear which APIs might fail with non-backward-compatible
|
|
||||||
* indexes, but I'll keep them bits clear just in case.
|
|
||||||
* - Even though if_nametoindex and if_indextoname seem to be pretty portable,
|
|
||||||
* Linux, at any rate, uses the same interface index for all virtual
|
|
||||||
* interfaces of a real interface as well as for the real interface itself.
|
|
||||||
* If I used the Linux index as my index, this would break my statement that
|
|
||||||
* an index is a key, and that an interface has 0 or 1 IP addresses.
|
|
||||||
* If that behavior were consistent across UNIXen (I don't know), it could
|
|
||||||
* help me implement multiple IP addresses more in the Windows way.
|
|
||||||
* I used to assert I could not use UNIX interface indexes as my iphlpapi
|
|
||||||
* indexes due to restrictions in netapi32 and wsock32, but I have removed
|
|
||||||
* those restrictions, so using if_nametoindex and if_indextoname rather
|
|
||||||
* than my current mess would probably be better.
|
|
||||||
* FIXME:
|
* FIXME:
|
||||||
* - I don't support IPv6 addresses here, since SIOCGIFCONF can't return them
|
* - I don't support IPv6 addresses here, since SIOCGIFCONF can't return them
|
||||||
*
|
*
|
||||||
|
@ -121,69 +105,8 @@
|
||||||
|
|
||||||
#define INDEX_IS_LOOPBACK 0x00800000
|
#define INDEX_IS_LOOPBACK 0x00800000
|
||||||
|
|
||||||
/* Type declarations */
|
|
||||||
|
|
||||||
typedef struct _InterfaceNameMapEntry {
|
|
||||||
char name[IFNAMSIZ];
|
|
||||||
BOOL inUse;
|
|
||||||
BOOL usedLastPass;
|
|
||||||
} InterfaceNameMapEntry;
|
|
||||||
|
|
||||||
typedef struct _InterfaceNameMap {
|
|
||||||
DWORD numInterfaces;
|
|
||||||
DWORD nextAvailable;
|
|
||||||
DWORD numAllocated;
|
|
||||||
InterfaceNameMapEntry table[1];
|
|
||||||
} InterfaceNameMap;
|
|
||||||
|
|
||||||
/* Global variables */
|
|
||||||
|
|
||||||
static CRITICAL_SECTION mapCS;
|
|
||||||
static InterfaceNameMap *gNonLoopbackInterfaceMap = NULL;
|
|
||||||
static InterfaceNameMap *gLoopbackInterfaceMap = NULL;
|
|
||||||
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
|
||||||
void interfaceMapInit(void)
|
|
||||||
{
|
|
||||||
InitializeCriticalSection(&mapCS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void interfaceMapFree(void)
|
|
||||||
{
|
|
||||||
DeleteCriticalSection(&mapCS);
|
|
||||||
HeapFree(GetProcessHeap(), 0, gNonLoopbackInterfaceMap);
|
|
||||||
HeapFree(GetProcessHeap(), 0, gLoopbackInterfaceMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sizes the passed-in map to have enough space for numInterfaces interfaces.
|
|
||||||
* If map is NULL, allocates a new map. If it is not, may reallocate the
|
|
||||||
* existing map and return a map of increased size. Returns the allocated map,
|
|
||||||
* or NULL if it could not allocate a map of the requested size.
|
|
||||||
*/
|
|
||||||
static InterfaceNameMap *sizeMap(InterfaceNameMap *map, DWORD numInterfaces)
|
|
||||||
{
|
|
||||||
if (!map) {
|
|
||||||
numInterfaces = max(numInterfaces, INITIAL_INTERFACES_ASSUMED);
|
|
||||||
map = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
|
||||||
sizeof(InterfaceNameMap) +
|
|
||||||
(numInterfaces - 1) * sizeof(InterfaceNameMapEntry));
|
|
||||||
if (map)
|
|
||||||
map->numAllocated = numInterfaces;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (map->numAllocated < numInterfaces) {
|
|
||||||
map = HeapReAlloc(GetProcessHeap(), 0, map,
|
|
||||||
sizeof(InterfaceNameMap) +
|
|
||||||
(numInterfaces - 1) * sizeof(InterfaceNameMapEntry));
|
|
||||||
if (map)
|
|
||||||
memset(&map->table[map->numAllocated], 0,
|
|
||||||
(numInterfaces - map->numAllocated) * sizeof(InterfaceNameMapEntry));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int isLoopbackInterface(int fd, const char *name)
|
static int isLoopbackInterface(int fd, const char *name)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -198,243 +121,96 @@ static int isLoopbackInterface(int fd, const char *name)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void countInterfaces(int fd, caddr_t buf, size_t len)
|
/* The comments say MAX_ADAPTER_NAME is required, but really only IF_NAMESIZE
|
||||||
{
|
* bytes are necessary.
|
||||||
caddr_t ifPtr = buf;
|
|
||||||
DWORD numNonLoopbackInterfaces = 0, numLoopbackInterfaces = 0;
|
|
||||||
|
|
||||||
while (ifPtr && ifPtr < buf + len) {
|
|
||||||
struct ifreq *ifr = (struct ifreq *)ifPtr;
|
|
||||||
|
|
||||||
if (isLoopbackInterface(fd, ifr->ifr_name))
|
|
||||||
numLoopbackInterfaces++;
|
|
||||||
else
|
|
||||||
numNonLoopbackInterfaces++;
|
|
||||||
ifPtr += ifreq_len(ifr);
|
|
||||||
}
|
|
||||||
gNonLoopbackInterfaceMap = sizeMap(gNonLoopbackInterfaceMap,
|
|
||||||
numNonLoopbackInterfaces);
|
|
||||||
gLoopbackInterfaceMap = sizeMap(gLoopbackInterfaceMap,
|
|
||||||
numLoopbackInterfaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stores the name in the given map, and increments the map's numInterfaces
|
|
||||||
* member if stored successfully. Will store in the same slot as previously if
|
|
||||||
* usedLastPass is set, otherwise will store in a new slot.
|
|
||||||
* Assumes map and name are not NULL, and the usedLastPass flag is set
|
|
||||||
* correctly for each entry in the map, and that map->numInterfaces <
|
|
||||||
* map->numAllocated.
|
|
||||||
* FIXME: this is kind of expensive, doing a linear scan of the map with a
|
|
||||||
* string comparison of each entry to find the old slot.
|
|
||||||
*/
|
*/
|
||||||
static void storeInterfaceInMap(InterfaceNameMap *map, const char *name)
|
char *getInterfaceNameByIndex(DWORD index, char *name)
|
||||||
{
|
{
|
||||||
if (map && name) {
|
return if_indextoname(index, name);
|
||||||
DWORD ndx;
|
|
||||||
BOOL stored = FALSE;
|
|
||||||
|
|
||||||
/* look for previous slot, mark in use if so */
|
|
||||||
for (ndx = 0; !stored && ndx < map->nextAvailable; ndx++) {
|
|
||||||
if (map->table[ndx].usedLastPass && !strncmp(map->table[ndx].name, name,
|
|
||||||
sizeof(map->table[ndx].name))) {
|
|
||||||
map->table[ndx].inUse = TRUE;
|
|
||||||
stored = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* look for new slot */
|
|
||||||
for (ndx = 0; !stored && ndx < map->numAllocated; ndx++) {
|
|
||||||
if (!map->table[ndx].inUse) {
|
|
||||||
lstrcpynA(map->table[ndx].name, name, IFNAMSIZ);
|
|
||||||
map->table[ndx].inUse = TRUE;
|
|
||||||
stored = TRUE;
|
|
||||||
if (ndx >= map->nextAvailable)
|
|
||||||
map->nextAvailable = ndx + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stored)
|
|
||||||
map->numInterfaces++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sets all used entries' usedLastPass flag to their inUse flag, clears
|
|
||||||
* their inUse flag, and clears their numInterfaces member.
|
|
||||||
*/
|
|
||||||
static void markOldInterfaces(InterfaceNameMap *map)
|
|
||||||
{
|
|
||||||
if (map) {
|
|
||||||
DWORD ndx;
|
|
||||||
|
|
||||||
map->numInterfaces = 0;
|
|
||||||
for (ndx = 0; ndx < map->nextAvailable; ndx++) {
|
|
||||||
map->table[ndx].usedLastPass = map->table[ndx].inUse;
|
|
||||||
map->table[ndx].inUse = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void classifyInterfaces(int fd, caddr_t buf, size_t len)
|
|
||||||
{
|
|
||||||
caddr_t ifPtr = buf;
|
|
||||||
|
|
||||||
markOldInterfaces(gNonLoopbackInterfaceMap);
|
|
||||||
markOldInterfaces(gLoopbackInterfaceMap);
|
|
||||||
while (ifPtr && ifPtr < buf + len) {
|
|
||||||
struct ifreq *ifr = (struct ifreq *)ifPtr;
|
|
||||||
|
|
||||||
if (ifr->ifr_addr.sa_family == AF_INET) {
|
|
||||||
if (isLoopbackInterface(fd, ifr->ifr_name))
|
|
||||||
storeInterfaceInMap(gLoopbackInterfaceMap, ifr->ifr_name);
|
|
||||||
else
|
|
||||||
storeInterfaceInMap(gNonLoopbackInterfaceMap, ifr->ifr_name);
|
|
||||||
}
|
|
||||||
ifPtr += ifreq_len(ifr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enumerateInterfaces(void)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
fd = socket(PF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (fd != -1) {
|
|
||||||
int ret, guessedNumInterfaces;
|
|
||||||
struct ifconf ifc;
|
|
||||||
|
|
||||||
/* try to avoid silly heap action by starting with the right size buffer */
|
|
||||||
guessedNumInterfaces = 0;
|
|
||||||
if (gNonLoopbackInterfaceMap)
|
|
||||||
guessedNumInterfaces += gNonLoopbackInterfaceMap->numInterfaces;
|
|
||||||
if (gLoopbackInterfaceMap)
|
|
||||||
guessedNumInterfaces += gLoopbackInterfaceMap->numInterfaces;
|
|
||||||
|
|
||||||
ret = 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 (guessedNumInterfaces == 0)
|
|
||||||
guessedNumInterfaces = INITIAL_INTERFACES_ASSUMED;
|
|
||||||
else
|
|
||||||
guessedNumInterfaces *= 2;
|
|
||||||
HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
|
|
||||||
ifc.ifc_len = sizeof(struct ifreq) * guessedNumInterfaces;
|
|
||||||
ifc.ifc_buf = HeapAlloc(GetProcessHeap(), 0, ifc.ifc_len);
|
|
||||||
ret = ioctl(fd, SIOCGIFCONF, &ifc);
|
|
||||||
} while (ret == 0 &&
|
|
||||||
ifc.ifc_len == (sizeof(struct ifreq) * guessedNumInterfaces));
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
EnterCriticalSection(&mapCS);
|
|
||||||
countInterfaces(fd, ifc.ifc_buf, ifc.ifc_len);
|
|
||||||
classifyInterfaces(fd, ifc.ifc_buf, ifc.ifc_len);
|
|
||||||
LeaveCriticalSection(&mapCS);
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, ifc.ifc_buf);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD getNumNonLoopbackInterfaces(void)
|
|
||||||
{
|
|
||||||
enumerateInterfaces();
|
|
||||||
return gNonLoopbackInterfaceMap ? gNonLoopbackInterfaceMap->numInterfaces : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD getNumInterfaces(void)
|
|
||||||
{
|
|
||||||
DWORD ret = getNumNonLoopbackInterfaces();
|
|
||||||
|
|
||||||
ret += gLoopbackInterfaceMap ? gLoopbackInterfaceMap->numInterfaces : 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *getInterfaceNameByIndex(DWORD index)
|
|
||||||
{
|
|
||||||
DWORD realIndex;
|
|
||||||
InterfaceNameMap *map;
|
|
||||||
const char *ret = NULL;
|
|
||||||
|
|
||||||
EnterCriticalSection(&mapCS);
|
|
||||||
if (index & INDEX_IS_LOOPBACK) {
|
|
||||||
realIndex = index ^ INDEX_IS_LOOPBACK;
|
|
||||||
map = gLoopbackInterfaceMap;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
realIndex = index;
|
|
||||||
map = gNonLoopbackInterfaceMap;
|
|
||||||
}
|
|
||||||
if (map && realIndex < map->nextAvailable)
|
|
||||||
ret = map->table[realIndex].name;
|
|
||||||
LeaveCriticalSection(&mapCS);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD getInterfaceIndexByName(const char *name, PDWORD index)
|
DWORD getInterfaceIndexByName(const char *name, PDWORD index)
|
||||||
{
|
{
|
||||||
DWORD ndx, ret;
|
DWORD ret;
|
||||||
BOOL found = FALSE;
|
unsigned int idx;
|
||||||
|
|
||||||
if (!name)
|
if (!name)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
if (!index)
|
if (!index)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
idx = if_nametoindex(name);
|
||||||
EnterCriticalSection(&mapCS);
|
if (idx) {
|
||||||
for (ndx = 0; !found && gNonLoopbackInterfaceMap &&
|
*index = idx;
|
||||||
ndx < gNonLoopbackInterfaceMap->nextAvailable; ndx++)
|
|
||||||
if (!strncmp(gNonLoopbackInterfaceMap->table[ndx].name, name, IFNAMSIZ)) {
|
|
||||||
found = TRUE;
|
|
||||||
*index = ndx;
|
|
||||||
}
|
|
||||||
for (ndx = 0; !found && gLoopbackInterfaceMap &&
|
|
||||||
ndx < gLoopbackInterfaceMap->nextAvailable; ndx++)
|
|
||||||
if (!strncmp(gLoopbackInterfaceMap->table[ndx].name, name, IFNAMSIZ)) {
|
|
||||||
found = TRUE;
|
|
||||||
*index = ndx | INDEX_IS_LOOPBACK;
|
|
||||||
}
|
|
||||||
LeaveCriticalSection(&mapCS);
|
|
||||||
if (found)
|
|
||||||
ret = NO_ERROR;
|
ret = NO_ERROR;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ret = ERROR_INVALID_DATA;
|
ret = ERROR_INVALID_DATA;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addMapEntriesToIndexTable(InterfaceIndexTable *table,
|
DWORD getNumNonLoopbackInterfaces(void)
|
||||||
const InterfaceNameMap *map)
|
|
||||||
{
|
{
|
||||||
if (table && map) {
|
DWORD numInterfaces;
|
||||||
DWORD ndx;
|
int fd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
for (ndx = 0; ndx < map->nextAvailable &&
|
if (fd != -1) {
|
||||||
table->numIndexes < table->numAllocated; ndx++)
|
struct if_nameindex *indexes = if_nameindex();
|
||||||
if (map->table[ndx].inUse) {
|
|
||||||
DWORD externalNdx = ndx;
|
|
||||||
|
|
||||||
if (map == gLoopbackInterfaceMap)
|
if (indexes) {
|
||||||
externalNdx |= INDEX_IS_LOOPBACK;
|
struct if_nameindex *p;
|
||||||
table->indexes[table->numIndexes++] = externalNdx;
|
|
||||||
}
|
for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
|
||||||
|
if (!isLoopbackInterface(fd, p->if_name))
|
||||||
|
numInterfaces++;
|
||||||
|
if_freenameindex(indexes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
numInterfaces = 0;
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
numInterfaces = 0;
|
||||||
|
return numInterfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD getNumInterfaces(void)
|
||||||
|
{
|
||||||
|
DWORD numInterfaces;
|
||||||
|
struct if_nameindex *indexes = if_nameindex();
|
||||||
|
|
||||||
|
if (indexes) {
|
||||||
|
struct if_nameindex *p;
|
||||||
|
|
||||||
|
for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
|
||||||
|
numInterfaces++;
|
||||||
|
if_freenameindex(indexes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
numInterfaces = 0;
|
||||||
|
return numInterfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
InterfaceIndexTable *getInterfaceIndexTable(void)
|
InterfaceIndexTable *getInterfaceIndexTable(void)
|
||||||
{
|
{
|
||||||
DWORD numInterfaces;
|
DWORD numInterfaces;
|
||||||
InterfaceIndexTable *ret;
|
InterfaceIndexTable *ret;
|
||||||
|
struct if_nameindex *indexes = if_nameindex();
|
||||||
EnterCriticalSection(&mapCS);
|
|
||||||
numInterfaces = getNumInterfaces();
|
if (indexes) {
|
||||||
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
struct if_nameindex *p;
|
||||||
sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
|
||||||
if (ret) {
|
for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
|
||||||
ret->numAllocated = numInterfaces;
|
numInterfaces++;
|
||||||
addMapEntriesToIndexTable(ret, gNonLoopbackInterfaceMap);
|
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
addMapEntriesToIndexTable(ret, gLoopbackInterfaceMap);
|
sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
||||||
|
if (ret) {
|
||||||
|
for (p = indexes; p && p->if_name; p++)
|
||||||
|
ret->indexes[ret->numIndexes++] = p->if_index;
|
||||||
|
}
|
||||||
|
if_freenameindex(indexes);
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&mapCS);
|
else
|
||||||
|
ret = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,16 +218,32 @@ InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void)
|
||||||
{
|
{
|
||||||
DWORD numInterfaces;
|
DWORD numInterfaces;
|
||||||
InterfaceIndexTable *ret;
|
InterfaceIndexTable *ret;
|
||||||
|
int fd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
EnterCriticalSection(&mapCS);
|
if (fd != -1) {
|
||||||
numInterfaces = getNumNonLoopbackInterfaces();
|
struct if_nameindex *indexes = if_nameindex();
|
||||||
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
|
||||||
sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
if (indexes) {
|
||||||
if (ret) {
|
struct if_nameindex *p;
|
||||||
ret->numAllocated = numInterfaces;
|
|
||||||
addMapEntriesToIndexTable(ret, gNonLoopbackInterfaceMap);
|
for (p = indexes, numInterfaces = 0; p && p->if_name; p++)
|
||||||
|
if (!isLoopbackInterface(fd, p->if_name))
|
||||||
|
numInterfaces++;
|
||||||
|
ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
||||||
|
if (ret) {
|
||||||
|
for (p = indexes; p && p->if_name; p++)
|
||||||
|
if (!isLoopbackInterface(fd, p->if_name))
|
||||||
|
ret->indexes[ret->numIndexes++] = p->if_index;
|
||||||
|
}
|
||||||
|
if_freenameindex(indexes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ret = NULL;
|
||||||
|
close(fd);
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&mapCS);
|
else
|
||||||
|
ret = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,7 +526,8 @@ 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)
|
||||||
{
|
{
|
||||||
const char *name = getInterfaceNameByIndex(index);
|
char nameBuf[IF_NAMESIZE];
|
||||||
|
char *name = getInterfaceNameByIndex(index, nameBuf);
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
return getInterfacePhysicalByName(name, len, addr, type);
|
return getInterfacePhysicalByName(name, len, addr, type);
|
||||||
|
@ -848,7 +641,8 @@ DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
|
||||||
|
|
||||||
DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
|
DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
|
||||||
{
|
{
|
||||||
const char *name = getInterfaceNameByIndex(index);
|
char nameBuf[IF_NAMESIZE];
|
||||||
|
char *name = getInterfaceNameByIndex(index, nameBuf);
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
return getInterfaceEntryByName(name, entry);
|
return getInterfaceEntryByName(name, entry);
|
||||||
|
|
|
@ -42,20 +42,12 @@
|
||||||
#define MAX_INTERFACE_PHYSADDR 8
|
#define MAX_INTERFACE_PHYSADDR 8
|
||||||
#define MAX_INTERFACE_DESCRIPTION 256
|
#define MAX_INTERFACE_DESCRIPTION 256
|
||||||
|
|
||||||
/* Call before using the functions in this module */
|
|
||||||
void interfaceMapInit(void);
|
|
||||||
/* Call to free resources allocated in interfaceMapInit() */
|
|
||||||
void interfaceMapFree(void);
|
|
||||||
|
|
||||||
DWORD getNumInterfaces(void);
|
DWORD getNumInterfaces(void);
|
||||||
DWORD getNumNonLoopbackInterfaces(void);
|
DWORD getNumNonLoopbackInterfaces(void);
|
||||||
|
|
||||||
/* A table of interface indexes, see get*InterfaceTable(). Ignore numAllocated,
|
/* A table of interface indexes, see get*InterfaceTable(). */
|
||||||
* it's used during the creation of the table.
|
|
||||||
*/
|
|
||||||
typedef struct _InterfaceIndexTable {
|
typedef struct _InterfaceIndexTable {
|
||||||
DWORD numIndexes;
|
DWORD numIndexes;
|
||||||
DWORD numAllocated;
|
|
||||||
DWORD indexes[1];
|
DWORD indexes[1];
|
||||||
} InterfaceIndexTable;
|
} InterfaceIndexTable;
|
||||||
|
|
||||||
|
@ -70,10 +62,10 @@ InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void);
|
||||||
/* ByName/ByIndex versions of various getter functions. */
|
/* ByName/ByIndex versions of various getter functions. */
|
||||||
|
|
||||||
/* can be used as quick check to see if you've got a valid index, returns NULL
|
/* can be used as quick check to see if you've got a valid index, returns NULL
|
||||||
* if not. The buffer's only valid till the next call, so copy it right away
|
* if not. Overwrites your buffer, which should be at least of size
|
||||||
* if you care.
|
* MAX_ADAPTER_NAME.
|
||||||
*/
|
*/
|
||||||
const char *getInterfaceNameByIndex(DWORD index);
|
char *getInterfaceNameByIndex(DWORD index, char *name);
|
||||||
|
|
||||||
/* Fills index with the index of name, if found. Returns
|
/* Fills index with the index of name, if found. Returns
|
||||||
* ERROR_INVALID_PARAMETER if name or index is NULL, ERROR_INVALID_DATA if name
|
* ERROR_INVALID_PARAMETER if name or index is NULL, ERROR_INVALID_DATA if name
|
||||||
|
|
|
@ -55,11 +55,9 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
switch (fdwReason) {
|
switch (fdwReason) {
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
DisableThreadLibraryCalls( hinstDLL );
|
DisableThreadLibraryCalls( hinstDLL );
|
||||||
interfaceMapInit();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
interfaceMapFree();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -714,9 +712,7 @@ DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
|
||||||
BOOL firstIPAddr = TRUE;
|
BOOL firstIPAddr = TRUE;
|
||||||
|
|
||||||
/* on Win98 this is left empty, but whatever */
|
/* on Win98 this is left empty, but whatever */
|
||||||
lstrcpynA(ptr->AdapterName,
|
getInterfaceNameByIndex(table->indexes[ndx], ptr->AdapterName);
|
||||||
getInterfaceNameByIndex(table->indexes[ndx]),
|
|
||||||
MAX_ADAPTER_NAME_LENGTH+1);
|
|
||||||
getInterfacePhysicalByIndex(table->indexes[ndx], &addrLen,
|
getInterfacePhysicalByIndex(table->indexes[ndx], &addrLen,
|
||||||
ptr->Address, &type);
|
ptr->Address, &type);
|
||||||
/* MS defines address length and type as UINT in some places and
|
/* MS defines address length and type as UINT in some places and
|
||||||
|
@ -929,13 +925,14 @@ DWORD WINAPI GetIcmpStatistics(PMIB_ICMP pStats)
|
||||||
DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow)
|
DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow)
|
||||||
{
|
{
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
const char *name;
|
char nameBuf[MAX_ADAPTER_NAME];
|
||||||
|
char *name;
|
||||||
|
|
||||||
TRACE("pIfRow %p\n", pIfRow);
|
TRACE("pIfRow %p\n", pIfRow);
|
||||||
if (!pIfRow)
|
if (!pIfRow)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
name = getInterfaceNameByIndex(pIfRow->dwIndex);
|
name = getInterfaceNameByIndex(pIfRow->dwIndex, nameBuf);
|
||||||
if (name) {
|
if (name) {
|
||||||
ret = getInterfaceEntryByName(name, pIfRow);
|
ret = getInterfaceEntryByName(name, pIfRow);
|
||||||
if (ret == NO_ERROR)
|
if (ret == NO_ERROR)
|
||||||
|
@ -1044,6 +1041,9 @@ DWORD WINAPI GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder)
|
||||||
* RETURNS
|
* RETURNS
|
||||||
* Success: NO_ERROR
|
* Success: NO_ERROR
|
||||||
* Failure: error code from winerror.h
|
* Failure: error code from winerror.h
|
||||||
|
*
|
||||||
|
* BUGS
|
||||||
|
* MSDN states this should return non-loopback interfaces only.
|
||||||
*/
|
*/
|
||||||
DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen)
|
DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen)
|
||||||
{
|
{
|
||||||
|
@ -1073,6 +1073,7 @@ DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
DWORD ndx;
|
DWORD ndx;
|
||||||
|
char nameBuf[MAX_ADAPTER_NAME];
|
||||||
|
|
||||||
*dwOutBufLen = size;
|
*dwOutBufLen = size;
|
||||||
pIfTable->NumAdapters = 0;
|
pIfTable->NumAdapters = 0;
|
||||||
|
@ -1081,7 +1082,7 @@ DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen)
|
||||||
WCHAR *assigner;
|
WCHAR *assigner;
|
||||||
|
|
||||||
pIfTable->Adapter[ndx].Index = table->indexes[ndx];
|
pIfTable->Adapter[ndx].Index = table->indexes[ndx];
|
||||||
name = getInterfaceNameByIndex(table->indexes[ndx]);
|
name = getInterfaceNameByIndex(table->indexes[ndx], nameBuf);
|
||||||
for (walker = name, assigner = pIfTable->Adapter[ndx].Name;
|
for (walker = name, assigner = pIfTable->Adapter[ndx].Name;
|
||||||
walker && *walker &&
|
walker && *walker &&
|
||||||
assigner - pIfTable->Adapter[ndx].Name < MAX_ADAPTER_NAME - 1;
|
assigner - pIfTable->Adapter[ndx].Name < MAX_ADAPTER_NAME - 1;
|
||||||
|
|
Loading…
Reference in New Issue