Added an implementation of iphlpapi.dll; most Get* functions

introduced through Win98 are included.
This commit is contained in:
Juan Lang 2003-05-13 03:32:20 +00:00 committed by Alexandre Julliard
parent e15aadd58a
commit 38fa5ad1bc
18 changed files with 4114 additions and 67 deletions

72
configure vendored

File diff suppressed because one or more lines are too long

View File

@ -982,6 +982,7 @@ AC_CHECK_HEADERS(\
netinet/in.h \
netinet/in_systm.h \
netinet/tcp.h \
netinet/tcp_fsm.h \
pty.h \
pwd.h \
regex.h \
@ -1039,7 +1040,7 @@ AC_CHECK_HEADERS(sys/mount.h sys/user.h,,,
# include <sys/param.h>
#endif])
AC_CHECK_HEADERS(net/if.h,,,
AC_CHECK_HEADERS([net/if.h net/if_arp.h net/if_dl.h net/if_types.h net/route.h resolv.h],,,
[#include <sys/types.h>
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
@ -1054,12 +1055,6 @@ AC_CHECK_HEADERS(netinet/ip.h,,,
# include <netinet/in_systm.h>
#endif])
AC_CHECK_HEADERS(resolv.h,,,
[#include <sys/types.h>
#if HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif])
AC_CHECK_HEADERS(ucontext.h,,,[#include <signal.h>])
dnl **** Check for IPX headers (currently Linux only) ****
@ -1402,6 +1397,7 @@ dlls/glu32/Makefile
dlls/icmp/Makefile
dlls/imagehlp/Makefile
dlls/imm32/Makefile
dlls/iphlpapi/Makefile
dlls/kernel/Makefile
dlls/kernel/tests/Makefile
dlls/lzexpand/Makefile

View File

@ -47,6 +47,7 @@ BASEDIRS = \
icmp \
imagehlp \
imm32 \
iphlpapi \
kernel \
lzexpand \
mapi32 \
@ -226,6 +227,7 @@ all: \
imaadp32.acm$(DLLEXT) \
imagehlp.dll$(DLLEXT) \
imm32.dll$(DLLEXT) \
iphlpapi.dll$(DLLEXT) \
joystick.drv$(DLLEXT) \
kernel32.dll$(DLLEXT) \
lz32.dll$(DLLEXT) \
@ -415,6 +417,9 @@ imagehlp.dll$(DLLEXT): imagehlp/imagehlp.dll$(DLLEXT)
imm32.dll$(DLLEXT) imm.dll$(DLLEXT): imm32/imm32.dll$(DLLEXT)
$(RM) $@ && $(LN_S) imm32/imm32.dll$(DLLEXT) $@
iphlpapi.dll$(DLLEXT): iphlpapi/iphlpapi.dll$(DLLEXT)
$(RM) $@ && $(LN_S) iphlpapi/iphlpapi.dll$(DLLEXT) $@
joystick.drv$(DLLEXT): winmm/joystick/joystick.drv$(DLLEXT)
$(RM) $@ && $(LN_S) winmm/joystick/joystick.drv$(DLLEXT) $@
@ -688,6 +693,7 @@ IMPORT_LIBS = \
libicmp \
libimagehlp \
libimm32 \
libiphlpapi \
libkernel32 \
liblz32 \
libmapi32 \
@ -927,6 +933,11 @@ libimm32.def: imm32/imm32.spec.def
libimm32.a: imm32/imm32.spec.def
$(DLLTOOL) -k -l $@ -d imm32/imm32.spec.def
libiphlpapi.def: iphlpapi/iphlpapi.spec.def
$(RM) $@ && $(LN_S) iphlpapi/iphlpapi.spec.def $@
libiphlpapi.a: iphlpapi/iphlpapi.spec.def
$(DLLTOOL) -k -l $@ -d iphlpapi/iphlpapi.spec.def
libkernel32.def: kernel/kernel32.spec.def
$(RM) $@ && $(LN_S) kernel/kernel32.spec.def $@
libkernel32.a: kernel/kernel32.spec.def
@ -1253,6 +1264,7 @@ glu32/glu32.spec.def: $(WINEBUILD)
icmp/icmp.spec.def: $(WINEBUILD)
imagehlp/imagehlp.spec.def: $(WINEBUILD)
imm32/imm32.spec.def: $(WINEBUILD)
iphlpapi/iphlpapi.spec.def: $(WINEBUILD)
kernel/kernel32.spec.def: $(WINEBUILD)
lzexpand/lz32.spec.def: $(WINEBUILD)
mapi32/mapi32.spec.def: $(WINEBUILD)
@ -1354,6 +1366,7 @@ icmp/icmp.dll$(DLLEXT): icmp
msacm/imaadp32/imaadp32.acm$(DLLEXT): msacm/imaadp32
imagehlp/imagehlp.dll$(DLLEXT): imagehlp
imm32/imm32.dll$(DLLEXT): imm32
iphlpapi/iphlpapi.dll$(DLLEXT): iphlpapi
winmm/joystick/joystick.drv$(DLLEXT): winmm/joystick
kernel/kernel32.dll$(DLLEXT): kernel
lzexpand/lz32.dll$(DLLEXT): lzexpand
@ -1470,6 +1483,7 @@ icmp/__install__: icmp.dll$(DLLEXT)
msacm/imaadp32/__install__: imaadp32.acm$(DLLEXT)
imagehlp/__install__: imagehlp.dll$(DLLEXT)
imm32/__install__: imm32.dll$(DLLEXT)
iphlpapi/__install__: iphlpapi.dll$(DLLEXT)
winmm/joystick/__install__: joystick.drv$(DLLEXT)
kernel/__install__: kernel32.dll$(DLLEXT)
lzexpand/__install__: lz32.dll$(DLLEXT)

3
dlls/iphlpapi/.cvsignore Normal file
View File

@ -0,0 +1,3 @@
Makefile
iphlpapi.dll.dbg.c
iphlpapi.spec.c

18
dlls/iphlpapi/Makefile.in Normal file
View File

@ -0,0 +1,18 @@
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = iphlpapi.dll
IMPORTS = kernel32
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
ifenum.c \
iphlpapi_main.c \
ipstats.c
@MAKE_DLL_RULES@
### Dependencies:

912
dlls/iphlpapi/ifenum.c Normal file
View File

@ -0,0 +1,912 @@
/* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* 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.
* But here's a problem with doing so:
* - Netbios() has a concept of an LAN adapter number (LANA), which is an 8-bit
* number in the range 0-254, inclusive. The MSDN pages for Netbios() says
* the original Netbios() spec allowed only 0 or 1 to be used, though "new"
* applications should enumerate available adapters rather than assuming 0
* is the default adapter.
* I'm concerned that some old application might depend on being able to get
* "the" MAC address of a machine by opening LANA 0 and getting its MAC
* address. This also implies LANA 0 should correspond to a non-loopback
* interface.
* On Linux, the if_nametoindex index is 1-based, and "lo" typically has
* index 1.
* I could make netapi32 do its own LANA map, independent of my index
* assignment, but it seems simpler just to assign 0-based indexes and put
* non-loopback adapters first, so the first 255 indexes (!) on a system will
* automatically map to LANA numbers without difficulty.
* - One more argument for doing it this way, if you don't buy the Netbios()
* argument: WsControl() (in wsock32) uses the same index to refer to an IP
* address and an interface. If I assigned multiple IP addresses to an
* interface, wsock32 would have to maintain a table of IP addresses with its
* own indexing scheme. No thanks.
*
* There are three implemened methods for determining the MAC address of an
* interface:
* - a specific IOCTL (Linux)
* - looking in the ARP cache (at least Solaris)
* - using the sysctl interface (FreeBSD and MacOSX)
* Solaris and some others have SIOCGENADDR, but I haven't gotten that to work
* on the Solaris boxes at SourceForge's compile farm, whereas SIOCGARP does.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_NET_IF_H
#include <net/if.h>
#endif
#if HAVE_NET_IF_ARP_H
#include <net/if_arp.h>
#endif
#if HAVE_NET_ROUTE_H
#include <net/route.h>
#endif
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#if HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#if HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#if HAVE_NET_IF_DL_H
#include <net/if_dl.h>
#endif
#if HAVE_NET_IF_TYPES_H
#include <net/if_types.h>
#endif
#include "winbase.h"
#include "iprtrmib.h"
#include "ifenum.h"
#if HAVE_STRUCT_SOCKADDR_SA_LEN
#define ifreq_len(ifr) \
max(sizeof(struct ifreq), sizeof((ifr)->ifr_name)+(ifr)->ifr_addr.sa_len)
#else
#define ifreq_len(ifr) sizeof(struct ifreq)
#endif
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef INADDR_NONE
#define INADDR_NONE (~0U)
#endif
#define INITIAL_INTERFACES_ASSUMED 4
#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 InterfaceNameMap *gNonLoopbackInterfaceMap = NULL;
static InterfaceNameMap *gLoopbackInterfaceMap = NULL;
/* Functions */
/* 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.
*/
InterfaceNameMap *sizeMap(InterfaceNameMap *map, DWORD numInterfaces)
{
if (!map) {
numInterfaces = max(numInterfaces, INITIAL_INTERFACES_ASSUMED);
map = (InterfaceNameMap *)calloc(1, sizeof(InterfaceNameMap) +
(numInterfaces - 1) * sizeof(InterfaceNameMapEntry));
if (map)
map->numAllocated = numInterfaces;
}
else {
if (map->numAllocated < numInterfaces) {
map = (InterfaceNameMap *)realloc(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)
{
int ret = 0;
if (name) {
struct ifreq ifr;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ] = '\0';
if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
ret = ifr.ifr_flags & IFF_LOOPBACK;
}
return ret;
}
static void countInterfaces(int fd, caddr_t buf, size_t len)
{
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)
{
if (map && 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) {
strncpy(map->table[ndx].name, name, IFNAMSIZ);
map->table[ndx].name[IFNAMSIZ] = '\0';
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 (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;
if (ifc.ifc_buf)
free(ifc.ifc_buf);
ifc.ifc_len = sizeof(struct ifreq) * guessedNumInterfaces;
ifc.ifc_buf = (char *)malloc(ifc.ifc_len);
ret = ioctl(fd, SIOCGIFCONF, &ifc);
} while (ret == 0 &&
ifc.ifc_len == (sizeof(struct ifreq) * guessedNumInterfaces));
if (ret == 0) {
countInterfaces(fd, ifc.ifc_buf, ifc.ifc_len);
classifyInterfaces(fd, ifc.ifc_buf, ifc.ifc_len);
}
if (ifc.ifc_buf)
free(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;
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;
return ret;
}
DWORD getInterfaceIndexByName(const char *name, PDWORD index)
{
DWORD ndx;
BOOL found = FALSE;
if (!name)
return ERROR_INVALID_PARAMETER;
if (!index)
return ERROR_INVALID_PARAMETER;
for (ndx = 0; !found && gNonLoopbackInterfaceMap &&
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;
}
if (found)
return NO_ERROR;
else
return ERROR_INVALID_DATA;
}
static void addMapEntriesToIndexTable(InterfaceIndexTable *table,
const InterfaceNameMap *map)
{
if (table && map) {
DWORD ndx;
for (ndx = 0; ndx < map->nextAvailable &&
table->numIndexes < table->numAllocated; ndx++)
if (map->table[ndx].inUse) {
DWORD externalNdx = ndx;
if (map == gLoopbackInterfaceMap)
externalNdx |= INDEX_IS_LOOPBACK;
table->indexes[table->numIndexes++] = externalNdx;
}
}
}
InterfaceIndexTable *getInterfaceIndexTable(void)
{
DWORD numInterfaces = getNumInterfaces();
InterfaceIndexTable *ret = (InterfaceIndexTable *)calloc(1,
sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
if (ret) {
ret->numAllocated = numInterfaces;
addMapEntriesToIndexTable(ret, gNonLoopbackInterfaceMap);
addMapEntriesToIndexTable(ret, gLoopbackInterfaceMap);
}
return ret;
}
InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void)
{
DWORD numInterfaces = getNumNonLoopbackInterfaces();
InterfaceIndexTable *ret = (InterfaceIndexTable *)calloc(1,
sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
if (ret) {
ret->numAllocated = numInterfaces;
addMapEntriesToIndexTable(ret, gNonLoopbackInterfaceMap);
}
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;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ] = '\0';
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;
if (name) {
int fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd != -1) {
struct ifreq ifr;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ] = '\0';
if (ioctl(fd, SIOCGIFBRDADDR, &ifr) == 0)
memcpy(&ret, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
close(fd);
}
}
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)
{
DWORD ret = INADDR_NONE;
if (name) {
int fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd != -1) {
struct ifreq ifr;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ] = '\0';
if (ioctl(fd, SIOCGIFNETMASK, &ifr) == 0)
memcpy(&ret, ifr.ifr_addr.sa_data + 2, sizeof(DWORD));
close(fd);
}
}
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)
{
DWORD ret;
int fd;
if (!name || !len || !addr || !type)
return ERROR_INVALID_PARAMETER;
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd != -1) {
struct ifreq ifr;
memset(&ifr, 0, sizeof(struct ifreq));
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ] = '\0';
if ((ioctl(fd, SIOCGIFHWADDR, &ifr)))
ret = ERROR_INVALID_DATA;
else {
int addrLen;
switch (ifr.ifr_hwaddr.sa_family)
{
case ARPHRD_LOOPBACK:
addrLen = 0;
*type = MIB_IF_TYPE_LOOPBACK;
break;
case ARPHRD_ETHER:
addrLen = ETH_ALEN;
*type = MIB_IF_TYPE_ETHERNET;
break;
case ARPHRD_FDDI:
addrLen = ETH_ALEN;
*type = MIB_IF_TYPE_FDDI;
break;
case ARPHRD_IEEE802: /* 802.2 Ethernet && Token Ring, guess TR? */
addrLen = ETH_ALEN;
*type = MIB_IF_TYPE_TOKENRING;
break;
case ARPHRD_IEEE802_TR: /* also Token Ring? */
addrLen = ETH_ALEN;
*type = MIB_IF_TYPE_TOKENRING;
break;
case ARPHRD_SLIP:
addrLen = 0;
*type = MIB_IF_TYPE_SLIP;
break;
case ARPHRD_PPP:
addrLen = 0;
*type = MIB_IF_TYPE_PPP;
break;
default:
addrLen = min(MAX_INTERFACE_PHYSADDR, sizeof(ifr.ifr_hwaddr.sa_data));
*type = MIB_IF_TYPE_OTHER;
}
if (addrLen > *len) {
ret = ERROR_INSUFFICIENT_BUFFER;
*len = addrLen;
}
else {
if (addrLen > 0)
memcpy(addr, ifr.ifr_hwaddr.sa_data, addrLen);
/* zero out remaining bytes for broken implementations */
memset(addr + addrLen, 0, *len - addrLen);
*len = addrLen;
ret = NO_ERROR;
}
}
close(fd);
}
else
ret = ERROR_NO_MORE_FILES;
return ret;
}
#elif defined (SIOCGARP)
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
PDWORD type)
{
DWORD ret;
int fd;
if (!name || !len || !addr || !type)
return ERROR_INVALID_PARAMETER;
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd != -1) {
if (isLoopbackInterface(fd, name)) {
*type = MIB_IF_TYPE_LOOPBACK;
memset(addr, 0, *len);
*len = 0;
}
else {
struct arpreq arp;
struct sockaddr_in *saddr;
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 = getInterfaceAddrByName(name);
if ((ioctl(fd, SIOCGARP, &arp)))
ret = ERROR_INVALID_DATA;
else {
/* FIXME: heh: who said it was ethernet? */
int addrLen = ETH_ALEN;
if (addrLen > *len) {
ret = ERROR_INSUFFICIENT_BUFFER;
*len = addrLen;
}
else {
if (addrLen > 0)
memcpy(addr, &arp.arp_ha.sa_data[0], addrLen);
/* zero out remaining bytes for broken implementations */
memset(addr + addrLen, 0, *len - addrLen);
*len = addrLen;
*type = MIB_IF_TYPE_ETHERNET;
ret = NO_ERROR;
}
}
}
else
ret = ERROR_NO_MORE_FILES;
}
return ret;
}
#elif defined (HAVE_SYS_SYSCTL_H) && defined (HAVE_NET_IF_DL_H)
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
PDWORD type)
{
DWORD ret;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
u_char *p, *buf;
size_t mibLen;
int mib[] = { CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0 };
int addrLen;
BOOL found = FALSE;
if (!name || !len || !addr || !type)
return ERROR_INVALID_PARAMETER;
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
return ERROR_NO_MORE_FILES;
buf = (u_char *)malloc(mibLen);
if (!buf)
return ERROR_NOT_ENOUGH_MEMORY;
if (sysctl(mib, 6, buf, &mibLen, NULL, 0) < 0) {
free(buf);
return ERROR_NO_MORE_FILES;
}
ret = ERROR_INVALID_DATA;
for (p = buf; !found && p < buf + mibLen; p += ifm->ifm_msglen) {
ifm = (struct if_msghdr *)p;
sdl = (struct sockaddr_dl *)(ifm + 1);
if (ifm->ifm_type != RTM_IFINFO || (ifm->ifm_addrs & RTA_IFP) == 0)
continue;
if (sdl->sdl_family != AF_LINK || sdl->sdl_nlen == 0 ||
memcmp(sdl->sdl_data, name, max(sdl->sdl_nlen, strlen(name))) != 0)
continue;
found = TRUE;
addrLen = min(MAX_INTERFACE_PHYSADDR, sdl->sdl_alen);
if (addrLen > *len) {
ret = ERROR_INSUFFICIENT_BUFFER;
*len = addrLen;
}
else {
if (addrLen > 0)
memcpy(addr, LLADDR(sdl), addrLen);
/* zero out remaining bytes for broken implementations */
memset(addr + addrLen, 0, *len - addrLen);
*len = addrLen;
#if defined(HAVE_NET_IF_TYPES_H)
switch (sdl->sdl_type)
{
case IFT_ETHER:
*type = MIB_IF_TYPE_ETHERNET;
break;
case IFT_FDDI:
*type = MIB_IF_TYPE_FDDI;
break;
case IFT_ISO88024: /* Token Bus */
*type = MIB_IF_TYPE_TOKENRING;
break;
case IFT_ISO88025: /* Token Ring */
*type = MIB_IF_TYPE_TOKENRING;
break;
case IFT_PPP:
*type = MIB_IF_TYPE_PPP;
break;
case IFT_SLIP:
*type = MIB_IF_TYPE_SLIP;
break;
case IFT_LOOP:
*type = MIB_IF_TYPE_LOOPBACK;
break;
default:
*type = MIB_IF_TYPE_OTHER;
}
#else
/* default if we don't know */
*type = MIB_IF_TYPE_ETHERNET;
#endif
ret = NO_ERROR;
}
}
free(buf);
return ret;
}
#endif
DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr,
PDWORD type)
{
const char *name = getInterfaceNameByIndex(index);
if (name)
return getInterfacePhysicalByName(name, len, addr, type);
else
return ERROR_INVALID_DATA;
}
DWORD getInterfaceMtuByName(const char *name, PDWORD mtu)
{
DWORD ret;
int fd;
if (!name)
return ERROR_INVALID_PARAMETER;
if (!mtu)
return ERROR_INVALID_PARAMETER;
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd != -1) {
struct ifreq ifr;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ] = '\0';
if ((ioctl(fd, SIOCGIFMTU, &ifr)))
ret = ERROR_INVALID_DATA;
else {
*mtu = ifr.ifr_mtu;
ret = NO_ERROR;
}
}
else
ret = ERROR_NO_MORE_FILES;
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)
{
DWORD ret;
int fd;
if (!name)
return ERROR_INVALID_PARAMETER;
if (!status)
return ERROR_INVALID_PARAMETER;
fd = socket(PF_INET, SOCK_DGRAM, 0);
if (fd != -1) {
struct ifreq ifr;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ifr.ifr_name[IFNAMSIZ] = '\0';
if ((ioctl(fd, SIOCGIFFLAGS, &ifr)))
ret = ERROR_INVALID_DATA;
else {
if (ifr.ifr_flags & IFF_UP)
*status = MIB_IF_OPER_STATUS_OPERATIONAL;
else
*status = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
ret = NO_ERROR;
}
}
else
ret = ERROR_NO_MORE_FILES;
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];
DWORD ret, len = sizeof(addr), type;
if (!name)
return ERROR_INVALID_PARAMETER;
if (!entry)
return ERROR_INVALID_PARAMETER;
if (getInterfacePhysicalByName(name, &len, addr, &type) == NO_ERROR) {
WCHAR *assigner;
const char *walker;
memset(entry, 0, sizeof(MIB_IFROW));
for (assigner = entry->wszName, walker = name; *walker;
walker++, assigner++)
*assigner = *walker;
*assigner = 0;
getInterfaceIndexByName(name, &entry->dwIndex);
entry->dwPhysAddrLen = len;
memcpy(entry->bPhysAddr, addr, len);
memset(entry->bPhysAddr + len, 0, sizeof(entry->bPhysAddr) - len);
entry->dwType = type;
/* FIXME: how to calculate real speed? */
getInterfaceMtuByName(name, &entry->dwMtu);
/* lie, there's no "administratively down" here */
entry->dwAdminStatus = MIB_IF_ADMIN_STATUS_UP;
getInterfaceStatusByName(name, &entry->dwOperStatus);
/* punt on dwLastChange? */
entry->dwDescrLen = min(strlen(name), MAX_INTERFACE_DESCRIPTION - 1);
memcpy(entry->bDescr, name, entry->dwDescrLen);
entry->bDescr[entry->dwDescrLen] = '\0';
entry->dwDescrLen++;
ret = NO_ERROR;
}
else
ret = ERROR_INVALID_DATA;
return ret;
}
DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
{
const char *name = getInterfaceNameByIndex(index);
if (name)
return getInterfaceEntryByName(name, entry);
else
return ERROR_INVALID_DATA;
}
char *toIPAddressString(unsigned int addr, char string[16])
{
if (string) {
struct in_addr iAddr;
iAddr.s_addr = addr;
/* extra-anal, just to make auditors happy */
strncpy(string, inet_ntoa(iAddr), 16);
string[16] = '\0';
}
return string;
}

130
dlls/iphlpapi/ifenum.h Normal file
View File

@ -0,0 +1,130 @@
/* ifenum.h
* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This module implements functions shared by DLLs that need to enumerate
* network interfaces and addresses. It's meant to hide some problematic
* defines like socket(), as well as provide only one file
* that needs to be ported to implement these functions on different platforms,
* since the Windows API provides multiple ways to get at this info.
*
* Like Windows, it uses a numeric index to identify an interface uniquely.
* As implemented, an interface represents a UNIX network interface, virtual
* or real, and thus can have 0 or 1 IP addresses associated with it. (This
* only supports IPv4.)
* The indexes returned are not guaranteed to be contiguous, so don't call
* getNumInterfaces() and assume the values [0,getNumInterfaces() - 1] will be
* valid indexes; use getInterfaceIndexTable() instead. Non-loopback
* interfaces have lower index values than loopback interfaces, in order to
* make the indexes somewhat reusable as Netbios LANA numbers. See ifenum.c
* for more detail on this.
*
* See also the companion file, ipstats.h, for functions related to getting
* statistics.
*/
#ifndef WINE_IFENUM_H_
#define WINE_IFENUM_H_
#include "windef.h"
#include "iprtrmib.h"
#define MAX_INTERFACE_PHYSADDR 8
#define MAX_INTERFACE_DESCRIPTION 256
DWORD getNumInterfaces(void);
DWORD getNumNonLoopbackInterfaces(void);
/* A table of interface indexes, see get*InterfaceTable(). Ignore numAllocated,
* it's used during the creation of the table.
*/
typedef struct _InterfaceIndexTable {
DWORD numIndexes;
DWORD numAllocated;
DWORD indexes[1];
} InterfaceIndexTable;
/* Returns a table with all known interface indexes, or NULL if one could not
* be allocated. free() the returned table.
*/
InterfaceIndexTable *getInterfaceIndexTable(void);
/* Like getInterfaceIndexTable, but filters out loopback interfaces. */
InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void);
/* ByName/ByIndex versions of various getter functions. */
/* 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 you care.
*/
const char *getInterfaceNameByIndex(DWORD index);
/* Fills index with the index of name, if found. Returns
* ERROR_INVALID_PARAMETER if name or index is NULL, ERROR_INVALID_DATA if name
* is not found, and NO_ERROR on success.
*/
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,
* 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,
* which to be safe should be MAX_INTERFACE_PHYSADDR. On out, it's how many
* bytes were set, or how many were required if addr isn't big enough.
* Returns ERROR_INVALID_PARAMETER if name, len, addr, or type is NULL.
* Returns ERROR_INVALID_DATA if name/index isn't valid.
* Returns ERROR_INSUFFICIENT_BUFFER if addr isn't large enough for the
* physical address; *len will contain the required size.
* May return other errors, e.g. ERROR_OUTOFMEMORY or ERROR_NO_MORE_FILES,
* if internal errors occur.
* Returns NO_ERROR on success.
*/
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
PDWORD type);
DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr,
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,
* see ipstats.h for that.
* Returns ERROR_INVALID_PARAMETER if name or entry is NULL, ERROR_INVALID_DATA
* if name/index isn't valid, and NO_ERROR otherwise.
*/
DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry);
DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry);
/* Converts the network-order bytes in addr to a printable string. Returns
* string.
*/
char *toIPAddressString(unsigned int addr, char string[16]);
#endif /* ndef WINE_IFENUM_H_ */

117
dlls/iphlpapi/iphlpapi.spec Normal file
View File

@ -0,0 +1,117 @@
@ stdcall AddIPAddress( long long long ptr ptr )
@ stub AllocateAndGetArpEntTableFromStack
@ stub AllocateAndGetIfTableFromStack
@ stub AllocateAndGetIpAddrTableFromStack
@ stub AllocateAndGetIpForwardTableFromStack
@ stub AllocateAndGetIpNetTableFromStack
@ stub AllocateAndGetTcpTableFromStack
@ stub AllocateAndGetUdpTableFromStack
@ stdcall CreateIpForwardEntry( ptr )
@ stdcall CreateIpNetEntry( ptr )
@ stdcall CreateProxyArpEntry( long long long )
@ stdcall DeleteIPAddress( long )
@ stdcall DeleteIpForwardEntry( ptr )
@ stdcall DeleteIpNetEntry( ptr )
@ stdcall DeleteProxyArpEntry( long long long )
@ stdcall EnableRouter( ptr ptr )
@ stdcall FlushIpNetTable( long )
@ stub FlushIpNetTableFromStack
@ stdcall GetAdapterIndex( wstr ptr )
@ stub GetAdapterOrderMap
@ stdcall GetAdaptersInfo( ptr ptr )
@ stdcall GetBestInterface( long ptr )
@ stub GetBestInterfaceFromStack
@ stdcall GetBestRoute( long long long )
@ stub GetBestRouteFromStack
@ stdcall GetFriendlyIfIndex( long )
@ stdcall GetIcmpStatistics( ptr )
@ stub GetIcmpStatsFromStack
@ stdcall GetIfEntry( ptr )
@ stub GetIfEntryFromStack
@ stdcall GetIfTable( ptr ptr long )
@ stub GetIfTableFromStack
@ stub GetIgmpList
@ stdcall GetInterfaceInfo( ptr ptr )
@ stdcall GetIpAddrTable( ptr ptr long )
@ stub GetIpAddrTableFromStack
@ stdcall GetIpForwardTable( ptr ptr long )
@ stub GetIpForwardTableFromStack
@ stdcall GetIpNetTable( ptr ptr long )
@ stub GetIpNetTableFromStack
@ stdcall GetIpStatistics( ptr )
@ stub GetIpStatsFromStack
@ stdcall GetNetworkParams( ptr ptr )
@ stdcall GetNumberOfInterfaces( ptr )
@ stdcall GetPerAdapterInfo( long ptr ptr )
@ stdcall GetRTTAndHopCount( long ptr long ptr )
@ stdcall GetTcpStatistics( ptr )
@ stub GetTcpStatsFromStack
@ stdcall GetTcpTable( ptr ptr long )
@ stub GetTcpTableFromStack
@ stdcall GetUdpStatistics( ptr )
@ stub GetUdpStatsFromStack
@ stdcall GetUdpTable( ptr ptr long )
@ stub GetUdpTableFromStack
@ stdcall GetUniDirectionalAdapterInfo( ptr ptr )
@ stub InternalCreateIpForwardEntry
@ stub InternalCreateIpNetEntry
@ stub InternalDeleteIpForwardEntry
@ stub InternalDeleteIpNetEntry
@ stub InternalGetIfTable
@ stub InternalGetIpAddrTable
@ stub InternalGetIpForwardTable
@ stub InternalGetIpNetTable
@ stub InternalGetTcpTable
@ stub InternalGetUdpTable
@ stub InternalSetIfEntry
@ stub InternalSetIpForwardEntry
@ stub InternalSetIpNetEntry
@ stub InternalSetIpStats
@ stub InternalSetTcpEntry
@ stdcall IpReleaseAddress( ptr )
@ stdcall IpRenewAddress( ptr )
@ stub IsLocalAddress
@ stub NTPTimeToNTFileTime
@ stub NTTimeToNTPTime
@ stub NhGetGuidFromInterfaceName
@ stub NhGetInterfaceNameFromGuid
@ stub NhpAllocateAndGetInterfaceInfoFromStack
@ stub NhpGetInterfaceIndexFromStack
@ stdcall NotifyAddrChange( ptr ptr )
@ stdcall NotifyRouteChange( ptr ptr )
@ stub NotifyRouteChangeEx
@ stub _PfAddFiltersToInterface@24
@ stub _PfAddGlobalFilterToInterface@8
@ stub _PfBindInterfaceToIPAddress@12
@ stub _PfBindInterfaceToIndex@16
@ stub _PfCreateInterface@24
@ stub _PfDeleteInterface@4
@ stub _PfDeleteLog@0
@ stub _PfGetInterfaceStatistics@16
@ stub _PfMakeLog@4
@ stub _PfRebindFilters@8
@ stub _PfRemoveFilterHandles@12
@ stub _PfRemoveFiltersFromInterface@20
@ stub _PfRemoveGlobalFilterFromInterface@8
@ stub _PfSetLogBuffer@28
@ stub _PfTestPacket@20
@ stub _PfUnBindInterface@4
@ stdcall SendARP( long long ptr ptr )
@ stub SetAdapterIpAddress
@ stub SetBlockRoutes
@ stdcall SetIfEntry( ptr )
@ stub SetIfEntryToStack
@ stdcall SetIpForwardEntry( ptr )
@ stub SetIpForwardEntryToStack
@ stub SetIpMultihopRouteEntryToStack
@ stdcall SetIpNetEntry( ptr )
@ stub SetIpNetEntryToStack
@ stub SetIpRouteEntryToStack
@ stdcall SetIpStatistics( ptr )
@ stub SetIpStatsToStack
@ stdcall SetIpTTL( long )
@ stub SetProxyArpEntryToStack
@ stub SetRouteWithRef
@ stdcall SetTcpEntry( ptr )
@ stub SetTcpEntryToStack
@ stdcall UnenableRouter( ptr ptr )

File diff suppressed because it is too large Load Diff

829
dlls/iphlpapi/ipstats.c Normal file
View File

@ -0,0 +1,829 @@
/* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This file implements statistics getting using the /proc filesystem exported
* by Linux, and maybe other OSes.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if HAVE_NET_IF_H
#include <net/if.h>
#endif
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#if HAVE_NETINET_TCP_FSM_H
#include <netinet/tcp_fsm.h>
#endif
#include "winbase.h"
#include "iprtrmib.h"
#include "ifenum.h"
#include "ipstats.h"
DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
{
FILE *fp;
if (!name)
return ERROR_INVALID_PARAMETER;
if (!entry)
return ERROR_INVALID_PARAMETER;
/* get interface stats from /proc/net/dev, no error if can't
no inUnknownProtos, outNUcastPkts, outQLen */
fp = fopen("/proc/net/dev", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
int nameLen = strlen(name), nameFound = 0;
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && !nameFound) {
while (*ptr && isspace(*ptr))
ptr++;
if (strncasecmp(ptr, name, nameLen) == 0 && *(ptr + nameLen) == ':')
nameFound = 1;
else
ptr = fgets(buf, sizeof(buf), fp);
}
if (nameFound) {
char *endPtr;
ptr += nameLen + 1;
if (ptr && *ptr) {
entry->dwInOctets = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwInUcastPkts = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwInErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwInDiscards = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 10); /* skip */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 10); /* skip */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 10); /* skip */
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwInNUcastPkts = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwOutOctets = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwOutUcastPkts = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwOutErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
entry->dwOutDiscards = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
}
fclose(fp);
}
return NO_ERROR;
}
DWORD getICMPStats(MIB_ICMP *stats)
{
FILE *fp;
if (!stats)
return ERROR_INVALID_PARAMETER;
memset(stats, 0, sizeof(MIB_ICMP));
/* get most of these stats from /proc/net/snmp, no error if can't */
fp = fopen("/proc/net/snmp", "r");
if (fp) {
const char hdr[] = "Icmp:";
char buf[512] = { 0 }, *ptr;
do {
ptr = fgets(buf, sizeof(buf), fp);
} while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
if (ptr) {
/* last line was a header, get another */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
char *endPtr;
ptr += sizeof(hdr);
if (ptr && *ptr) {
stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
}
}
fclose(fp);
}
return NO_ERROR;
}
DWORD getIPStats(PMIB_IPSTATS stats)
{
FILE *fp;
if (!stats)
return ERROR_INVALID_PARAMETER;
memset(stats, 0, sizeof(MIB_IPSTATS));
stats->dwNumIf = stats->dwNumAddr = getNumInterfaces();
stats->dwNumRoutes = getNumRoutes();
/* get most of these stats from /proc/net/snmp, no error if can't */
fp = fopen("/proc/net/snmp", "r");
if (fp) {
const char hdr[] = "Ip:";
char buf[512] = { 0 }, *ptr;
do {
ptr = fgets(buf, sizeof(buf), fp);
} while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
if (ptr) {
/* last line was a header, get another */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
char *endPtr;
ptr += sizeof(hdr);
if (ptr && *ptr) {
stats->dwForwarding = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwDefaultTTL = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInReceives = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInHdrErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInAddrErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwForwDatagrams = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInUnknownProtos = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInDiscards = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInDelivers = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwOutRequests = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwOutDiscards = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwOutNoRoutes = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwReasmTimeout = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwReasmReqds = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwReasmOks = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwReasmFails = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwFragOks = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwFragFails = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwFragCreates = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
/* hmm, no routingDiscards */
}
}
fclose(fp);
}
return NO_ERROR;
}
DWORD getTCPStats(MIB_TCPSTATS *stats)
{
FILE *fp;
if (!stats)
return ERROR_INVALID_PARAMETER;
memset(stats, 0, sizeof(MIB_TCPSTATS));
/* get from /proc/net/snmp, no error if can't */
fp = fopen("/proc/net/snmp", "r");
if (fp) {
const char hdr[] = "Tcp:";
char buf[512] = { 0 }, *ptr;
do {
ptr = fgets(buf, sizeof(buf), fp);
} while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
if (ptr) {
/* last line was a header, get another */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
char *endPtr;
ptr += sizeof(hdr);
if (ptr && *ptr) {
stats->dwRtoAlgorithm = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwRtoMin = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwRtoMin = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwMaxConn = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwActiveOpens = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwPassiveOpens = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwAttemptFails = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwEstabResets = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwCurrEstab = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInSegs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwOutSegs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwRetransSegs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInErrs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwOutRsts = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
stats->dwNumConns = getNumTcpEntries();
}
}
fclose(fp);
}
return NO_ERROR;
}
DWORD getUDPStats(MIB_UDPSTATS *stats)
{
FILE *fp;
if (!stats)
return ERROR_INVALID_PARAMETER;
memset(stats, 0, sizeof(MIB_UDPSTATS));
/* get from /proc/net/snmp, no error if can't */
fp = fopen("/proc/net/snmp", "r");
if (fp) {
const char hdr[] = "Udp:";
char buf[512] = { 0 }, *ptr;
do {
ptr = fgets(buf, sizeof(buf), fp);
} while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
if (ptr) {
/* last line was a header, get another */
ptr = fgets(buf, sizeof(buf), fp);
if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
char *endPtr;
ptr += sizeof(hdr);
if (ptr && *ptr) {
stats->dwInDatagrams = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwNoPorts = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwInErrors = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwOutDatagrams = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
if (ptr && *ptr) {
stats->dwNumAddrs = strtoul(ptr, &endPtr, 10);
ptr = endPtr;
}
}
}
fclose(fp);
}
return NO_ERROR;
}
static DWORD getNumWithOneHeader(const char *filename)
{
FILE *fp;
int ret = 0;
fp = fopen(filename, "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
do {
ptr = fgets(buf, sizeof(buf), fp);
if (ptr)
ret++;
} while (ptr);
}
fclose(fp);
}
return ret;
}
DWORD getNumRoutes(void)
{
return getNumWithOneHeader("/proc/net/route");
}
RouteTable *getRouteTable(void)
{
DWORD numRoutes = getNumRoutes();
RouteTable *ret;
ret = (RouteTable *)calloc(1, sizeof(RouteTable) +
(numRoutes - 1) * sizeof(RouteEntry));
if (ret) {
FILE *fp;
/* get from /proc/net/route, no error if can't */
fp = fopen("/proc/net/route", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->numRoutes < numRoutes) {
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
DWORD index;
while (!isspace(*ptr))
ptr++;
*ptr = '\0';
ptr++;
if (getInterfaceIndexByName(buf, &index) == NO_ERROR) {
char *endPtr;
ret->routes[ret->numRoutes].ifIndex = index;
if (*ptr) {
ret->routes[ret->numRoutes].dest = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
ret->routes[ret->numRoutes].gateway = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* flags, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* refcount, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* use, skip */
ptr = endPtr;
}
if (ptr && *ptr) {
ret->routes[ret->numRoutes].metric = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
ret->routes[ret->numRoutes].mask = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
ret->numRoutes++;
}
}
}
fclose(fp);
}
}
return ret;
}
DWORD getNumArpEntries(void)
{
return getNumWithOneHeader("/proc/net/arp");
}
PMIB_IPNETTABLE getArpTable(void)
{
DWORD numEntries = getNumArpEntries();
PMIB_IPNETTABLE ret;
ret = (PMIB_IPNETTABLE)calloc(1, sizeof(MIB_IPNETTABLE) +
(numEntries - 1) * sizeof(MIB_IPNETROW));
if (ret) {
FILE *fp;
/* get from /proc/net/arp, no error if can't */
fp = fopen("/proc/net/arp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->dwNumEntries < numEntries) {
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
if (ptr && *ptr) {
ret->table[ret->dwNumEntries].dwAddr = strtoul(ptr, &endPtr, 16);
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* hw type (skip) */
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* flags (skip) */
ptr = endPtr;
}
/* FIXME: maybe this comes from flags? */
ret->table[ret->dwNumEntries].dwType = MIB_IPNET_TYPE_DYNAMIC;
while (ptr && *ptr && isspace(*ptr))
ptr++;
while (ptr && *ptr && !isspace(*ptr)) {
DWORD byte = strtoul(ptr, &endPtr, 16);
if (endPtr && *endPtr) {
endPtr++;
ret->table[ret->dwNumEntries].bPhysAddr[
ret->table[ret->dwNumEntries].dwPhysAddrLen++] = byte & 0x0ff;
}
ptr = endPtr;
}
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* mask (skip) */
ptr = endPtr;
}
getInterfaceIndexByName(ptr, &ret->table[ret->dwNumEntries].dwIndex);
ret->dwNumEntries++;
}
}
fclose(fp);
}
}
return ret;
}
DWORD getNumUdpEntries(void)
{
return getNumWithOneHeader("/proc/net/udp");
}
PMIB_UDPTABLE getUdpTable(void)
{
DWORD numEntries = getNumUdpEntries();
PMIB_UDPTABLE ret;
ret = (PMIB_UDPTABLE)calloc(1, sizeof(MIB_UDPTABLE) +
(numEntries - 1) * sizeof(MIB_UDPROW));
if (ret) {
FILE *fp;
/* get from /proc/net/udp, no error if can't */
fp = fopen("/proc/net/udp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->dwNumEntries < numEntries) {
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
if (ptr && *ptr) {
strtoul(ptr, &endPtr, 16); /* skip */
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
ret->dwNumEntries++;
}
}
fclose(fp);
}
}
return ret;
}
DWORD getNumTcpEntries(void)
{
return getNumWithOneHeader("/proc/net/tcp");
}
PMIB_TCPTABLE getTcpTable(void)
{
DWORD numEntries = getNumTcpEntries();
PMIB_TCPTABLE ret;
ret = (PMIB_TCPTABLE)calloc(1, sizeof(MIB_TCPTABLE) +
(numEntries - 1) * sizeof(MIB_TCPROW));
if (ret) {
FILE *fp;
/* get from /proc/net/tcp, no error if can't */
fp = fopen("/proc/net/tcp", "r");
if (fp) {
char buf[512] = { 0 }, *ptr;
/* skip header line */
ptr = fgets(buf, sizeof(buf), fp);
while (ptr && ret->dwNumEntries < numEntries) {
ptr = fgets(buf, sizeof(buf), fp);
if (ptr) {
char *endPtr;
while (ptr && *ptr && *ptr != ':')
ptr++;
if (ptr && *ptr)
ptr++;
if (ptr && *ptr) {
ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ret->table[ret->dwNumEntries].dwRemoteAddr = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
ptr++;
ret->table[ret->dwNumEntries].dwRemotePort = strtoul(ptr, &endPtr,
16);
ptr = endPtr;
}
if (ptr && *ptr) {
DWORD state = strtoul(ptr, &endPtr, 16);
#if HAVE_NETINET_TCP_H
switch (state)
{
case TCP_ESTABLISHED:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_ESTAB;
break;
case TCP_SYN_SENT:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_SYN_SENT;
break;
case TCP_SYN_RECV:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_SYN_RCVD;
break;
case TCP_FIN_WAIT1:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_FIN_WAIT1;
break;
case TCP_FIN_WAIT2:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_FIN_WAIT2;
break;
case TCP_TIME_WAIT:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_TIME_WAIT;
break;
case TCP_CLOSE:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_CLOSED;
break;
case TCP_CLOSE_WAIT:
ret->table[ret->dwNumEntries].dwState =
MIB_TCP_STATE_CLOSE_WAIT;
break;
case TCP_LAST_ACK:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_LAST_ACK;
break;
case TCP_LISTEN:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_LISTEN;
break;
case TCP_CLOSING:
ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_CLOSING;
break;
}
#endif
ptr = endPtr;
}
ret->dwNumEntries++;
}
}
fclose(fp);
}
}
return ret;
}

102
dlls/iphlpapi/ipstats.h Normal file
View File

@ -0,0 +1,102 @@
/* ipstats.h
* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This module implements functions shared by DLLs that need to get network-
* related statistics. It's meant to hide some platform-specificisms, and
* share code that was previously duplicated.
*/
#ifndef WINE_IPSTATS_H_
#define WINE_IPSTATS_H_
#include "windef.h"
#include "iprtrmib.h"
/* Fills in entry's interface stats, using name to find them.
* Returns ERROR_INVALID_PARAMETER if name or entry is NULL, NO_ERROR otherwise.
*/
DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry);
/* Gets ICMP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is
* NULL, NO_ERROR otherwise.
*/
DWORD getICMPStats(MIB_ICMP *stats);
/* Gets IP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is
* NULL, NO_ERROR otherwise.
*/
DWORD getIPStats(PMIB_IPSTATS stats);
/* Gets TCP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is
* NULL, NO_ERROR otherwise.
*/
DWORD getTCPStats(MIB_TCPSTATS *stats);
/* Gets UDP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is
* NULL, NO_ERROR otherwise.
*/
DWORD getUDPStats(MIB_UDPSTATS *stats);
/* Route table functions */
DWORD getNumRoutes(void);
/* Minimalist route entry, only has the fields I can actually fill in. How
* these map to the different windows route data structures is up to you.
*/
typedef struct _RouteEntry {
DWORD dest;
DWORD mask;
DWORD gateway;
DWORD ifIndex;
DWORD metric;
} RouteEntry;
typedef struct _RouteTable {
DWORD numRoutes;
RouteEntry routes[1];
} RouteTable;
/* Allocates and returns to you the route table, or NULL if it can't allocate
* enough memory. free() the returned table.
*/
RouteTable *getRouteTable(void);
/* Returns the number of entries in the arp table. */
DWORD getNumArpEntries(void);
/* Allocates and returns to you the arp table, or NULL if it can't allocate
* enough memory. free() the returned table.
*/
PMIB_IPNETTABLE getArpTable(void);
/* Returns the number of entries in the UDP state table. */
DWORD getNumUdpEntries(void);
/* Allocates and returns to you the UDP state table, or NULL if it can't
* allocate enough memory. free() the returned table.
*/
PMIB_UDPTABLE getUdpTable(void);
/* Returns the number of entries in the TCP state table. */
DWORD getNumTcpEntries(void);
/* Allocates and returns to you the TCP state table, or NULL if it can't
* allocate enough memory. free() the returned table.
*/
PMIB_TCPTABLE getTcpTable(void);
#endif /* ndef WINE_IPSTATS_H_ */

View File

@ -68,6 +68,10 @@ WINDOWS_INCLUDES = \
initguid.h \
instance.h \
ipexport.h \
iphlpapi.h \
ipifcons.h \
iprtrmib.h \
iptypes.h \
lm.h \
lmaccess.h \
lmapibuf.h \

View File

@ -335,12 +335,27 @@
/* Define to 1 if you have the <netinet/ip.h> header file. */
#undef HAVE_NETINET_IP_H
/* Define to 1 if you have the <netinet/tcp_fsm.h> header file. */
#undef HAVE_NETINET_TCP_FSM_H
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
/* Define to 1 if you have the <net/if_arp.h> header file. */
#undef HAVE_NET_IF_ARP_H
/* Define to 1 if you have the <net/if_dl.h> header file. */
#undef HAVE_NET_IF_DL_H
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define to 1 if you have the <net/if_types.h> header file. */
#undef HAVE_NET_IF_TYPES_H
/* Define to 1 if you have the <net/route.h> header file. */
#undef HAVE_NET_ROUTE_H
/* Define to use glibc NPTL threading support. */
#undef HAVE_NPTL

View File

@ -96,4 +96,21 @@ typedef struct icmp_echo_reply ICMP_ECHO_REPLY, *PICMP_ECHO_REPLY;
#define IP_PENDING (IP_STATUS_BASE + 255)
#define MAX_ADAPTER_NAME 128
typedef struct _IP_ADAPTER_INDEX_MAP {
ULONG Index;
WCHAR Name[MAX_ADAPTER_NAME];
} IP_ADAPTER_INDEX_MAP, *PIP_ADAPTER_INDEX_MAP;
typedef struct _IP_INTERFACE_INFO {
LONG NumAdapters;
IP_ADAPTER_INDEX_MAP Adapter[1];
} IP_INTERFACE_INFO,*PIP_INTERFACE_INFO;
typedef struct _IP_UNIDIRECTIONAL_ADAPTER_ADDRESS {
ULONG NumAdapters;
IPAddr Address[1];
} IP_UNIDIRECTIONAL_ADAPTER_ADDRESS, *PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS;
#endif /* __WINE_IPEXPORT_H */

138
include/iphlpapi.h Normal file
View File

@ -0,0 +1,138 @@
/* WINE iphlpapi.h
* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef WINE_IPHLPAPI_H__
#define WINE_IPHLPAPI_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <iprtrmib.h>
#include <ipexport.h>
#include <iptypes.h>
DWORD WINAPI GetNumberOfInterfaces(PDWORD pdwNumIf);
DWORD WINAPI GetIfEntry(PMIB_IFROW pIfRow);
DWORD WINAPI GetIfTable(PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder);
DWORD WINAPI GetIpAddrTable(PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize,
BOOL bOrder);
DWORD WINAPI GetIpNetTable(PMIB_IPNETTABLE pIpNetTable, PULONG pdwSize,
BOOL bOrder);
DWORD WINAPI GetIpForwardTable(PMIB_IPFORWARDTABLE pIpForwardTable,
PULONG pdwSize, BOOL bOrder);
DWORD WINAPI GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder);
DWORD WINAPI GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder);
DWORD WINAPI GetIpStatistics(PMIB_IPSTATS pStats);
DWORD WINAPI GetIpStatisticsEx(PMIB_IPSTATS pStats, DWORD dwFamily);
DWORD WINAPI GetIcmpStatistics(PMIB_ICMP pStats);
DWORD WINAPI GetTcpStatistics(PMIB_TCPSTATS pStats);
DWORD WINAPI GetTcpStatisticsEx(PMIB_TCPSTATS pStats, DWORD dwFamily);
DWORD WINAPI GetUdpStatistics(PMIB_UDPSTATS pStats);
DWORD WINAPI GetUdpStatisticsEx(PMIB_UDPSTATS pStats, DWORD dwFamily);
DWORD WINAPI SetIfEntry(PMIB_IFROW pIfRow);
DWORD WINAPI CreateIpForwardEntry(PMIB_IPFORWARDROW pRoute);
DWORD WINAPI SetIpForwardEntry(PMIB_IPFORWARDROW pRoute);
DWORD WINAPI DeleteIpForwardEntry(PMIB_IPFORWARDROW pRoute);
DWORD WINAPI SetIpStatistics(PMIB_IPSTATS pIpStats);
DWORD WINAPI SetIpTTL(UINT nTTL);
DWORD WINAPI CreateIpNetEntry(PMIB_IPNETROW pArpEntry);
DWORD WINAPI SetIpNetEntry(PMIB_IPNETROW pArpEntry);
DWORD WINAPI DeleteIpNetEntry(PMIB_IPNETROW pArpEntry);
DWORD WINAPI FlushIpNetTable(DWORD dwIfIndex);
DWORD WINAPI CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask,
DWORD dwIfIndex);
DWORD WINAPI DeleteProxyArpEntry(DWORD dwAddress, DWORD dwMask,
DWORD dwIfIndex);
DWORD WINAPI SetTcpEntry(PMIB_TCPROW pTcpRow);
DWORD WINAPI GetInterfaceInfo(PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen);
DWORD WINAPI GetUniDirectionalAdapterInfo(
PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen);
DWORD WINAPI GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex);
DWORD WINAPI GetBestRoute(DWORD dwDestAddr, DWORD dwSourceAddr,
PMIB_IPFORWARDROW pBestRoute);
DWORD WINAPI NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped);
DWORD WINAPI NotifyRouteChange(PHANDLE Handle, LPOVERLAPPED overlapped);
DWORD WINAPI GetAdapterIndex(IN LPWSTR AdapterName, OUT PULONG IfIndex);
DWORD WINAPI AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex,
PULONG NTEContext, PULONG NTEInstance);
DWORD WINAPI DeleteIPAddress(ULONG NTEContext);
DWORD WINAPI GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen);
DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
DWORD WINAPI GetPerAdapterInfo(ULONG IfIndex,
PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen);
DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo);
DWORD WINAPI IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo);
DWORD WINAPI SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr,
PULONG PhyAddrLen);
BOOL WINAPI GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount,
ULONG MaxHops, PULONG RTT);
DWORD WINAPI GetFriendlyIfIndex(DWORD IfIndex);
DWORD WINAPI EnableRouter(HANDLE* pHandle, OVERLAPPED* pOverlapped);
DWORD WINAPI UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount);
#ifdef __cplusplus
}
#endif
#endif /* WINE_IPHLPAPI_H__ */

40
include/ipifcons.h Normal file
View File

@ -0,0 +1,40 @@
/* WINE ipifcons.h
* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef WINE_IPIFCONS_H__
#define WINE_IPIFCONS_H__
#define MIB_IF_TYPE_OTHER 1
#define MIB_IF_TYPE_ETHERNET 6
#define MIB_IF_TYPE_TOKENRING 9
#define MIB_IF_TYPE_FDDI 15
#define MIB_IF_TYPE_PPP 23
#define MIB_IF_TYPE_LOOPBACK 24
#define MIB_IF_TYPE_SLIP 28
#define MIB_IF_ADMIN_STATUS_UP 1
#define MIB_IF_ADMIN_STATUS_DOWN 2
#define MIB_IF_ADMIN_STATUS_TESTING 3
#define MIB_IF_OPER_STATUS_NON_OPERATIONAL 0
#define MIB_IF_OPER_STATUS_UNREACHABLE 1
#define MIB_IF_OPER_STATUS_DISCONNECTED 2
#define MIB_IF_OPER_STATUS_CONNECTING 3
#define MIB_IF_OPER_STATUS_CONNECTED 4
#define MIB_IF_OPER_STATUS_OPERATIONAL 5
#endif /* WINE_ROUTING_IPIFCONS_H__ */

276
include/iprtrmib.h Normal file
View File

@ -0,0 +1,276 @@
/* WINE iprtrmib.h
* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef WINE_IPRTRMIB_H__
#define WINE_IPRTRMIB_H__
#define MAX_INTERFACE_NAME_LEN 256
#include <ipifcons.h>
#define MAXLEN_IFDESCR 256
#define MAXLEN_PHYSADDR 8
typedef struct _MIB_IFROW
{
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
DWORD dwIndex;
DWORD dwType;
DWORD dwMtu;
DWORD dwSpeed;
DWORD dwPhysAddrLen;
BYTE bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
DWORD dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets;
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets;
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
BYTE bDescr[MAXLEN_IFDESCR];
} MIB_IFROW,*PMIB_IFROW;
typedef struct _MIB_IFTABLE
{
DWORD dwNumEntries;
MIB_IFROW table[1];
} MIB_IFTABLE, *PMIB_IFTABLE;
typedef struct _MIBICMPSTATS
{
DWORD dwMsgs;
DWORD dwErrors;
DWORD dwDestUnreachs;
DWORD dwTimeExcds;
DWORD dwParmProbs;
DWORD dwSrcQuenchs;
DWORD dwRedirects;
DWORD dwEchos;
DWORD dwEchoReps;
DWORD dwTimestamps;
DWORD dwTimestampReps;
DWORD dwAddrMasks;
DWORD dwAddrMaskReps;
} MIBICMPSTATS;
typedef struct _MIBICMPINFO
{
MIBICMPSTATS icmpInStats;
MIBICMPSTATS icmpOutStats;
} MIBICMPINFO;
typedef struct _MIB_ICMP
{
MIBICMPINFO stats;
} MIB_ICMP,*PMIB_ICMP;
typedef struct _MIB_UDPSTATS
{
DWORD dwInDatagrams;
DWORD dwNoPorts;
DWORD dwInErrors;
DWORD dwOutDatagrams;
DWORD dwNumAddrs;
} MIB_UDPSTATS,*PMIB_UDPSTATS;
typedef struct _MIB_UDPROW
{
DWORD dwLocalAddr;
DWORD dwLocalPort;
} MIB_UDPROW, *PMIB_UDPROW;
typedef struct _MIB_UDPTABLE
{
DWORD dwNumEntries;
MIB_UDPROW table[1];
} MIB_UDPTABLE, *PMIB_UDPTABLE;
typedef struct _MIB_TCPSTATS
{
DWORD dwRtoAlgorithm;
DWORD dwRtoMin;
DWORD dwRtoMax;
DWORD dwMaxConn;
DWORD dwActiveOpens;
DWORD dwPassiveOpens;
DWORD dwAttemptFails;
DWORD dwEstabResets;
DWORD dwCurrEstab;
DWORD dwInSegs;
DWORD dwOutSegs;
DWORD dwRetransSegs;
DWORD dwInErrs;
DWORD dwOutRsts;
DWORD dwNumConns;
} MIB_TCPSTATS, *PMIB_TCPSTATS;
typedef struct _MIB_TCPROW
{
DWORD dwState;
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwRemoteAddr;
DWORD dwRemotePort;
} MIB_TCPROW, *PMIB_TCPROW;
#define MIB_TCP_STATE_CLOSED 1
#define MIB_TCP_STATE_LISTEN 2
#define MIB_TCP_STATE_SYN_SENT 3
#define MIB_TCP_STATE_SYN_RCVD 4
#define MIB_TCP_STATE_ESTAB 5
#define MIB_TCP_STATE_FIN_WAIT1 6
#define MIB_TCP_STATE_FIN_WAIT2 7
#define MIB_TCP_STATE_CLOSE_WAIT 8
#define MIB_TCP_STATE_CLOSING 9
#define MIB_TCP_STATE_LAST_ACK 10
#define MIB_TCP_STATE_TIME_WAIT 11
#define MIB_TCP_STATE_DELETE_TCB 12
typedef struct _MIB_TCPTABLE
{
DWORD dwNumEntries;
MIB_TCPROW table[1];
} MIB_TCPTABLE, *PMIB_TCPTABLE;
typedef struct _MIB_IPSTATS
{
DWORD dwForwarding;
DWORD dwDefaultTTL;
DWORD dwInReceives;
DWORD dwInHdrErrors;
DWORD dwInAddrErrors;
DWORD dwForwDatagrams;
DWORD dwInUnknownProtos;
DWORD dwInDiscards;
DWORD dwInDelivers;
DWORD dwOutRequests;
DWORD dwRoutingDiscards;
DWORD dwOutDiscards;
DWORD dwOutNoRoutes;
DWORD dwReasmTimeout;
DWORD dwReasmReqds;
DWORD dwReasmOks;
DWORD dwReasmFails;
DWORD dwFragOks;
DWORD dwFragFails;
DWORD dwFragCreates;
DWORD dwNumIf;
DWORD dwNumAddr;
DWORD dwNumRoutes;
} MIB_IPSTATS, *PMIB_IPSTATS;
typedef struct _MIB_IPADDRROW
{
DWORD dwAddr;
DWORD dwIndex;
DWORD dwMask;
DWORD dwBCastAddr;
DWORD dwReasmSize;
unsigned short unused1;
unsigned short wType;
} MIB_IPADDRROW, *PMIB_IPADDRROW;
typedef struct _MIB_IPADDRTABLE
{
DWORD dwNumEntries;
MIB_IPADDRROW table[1];
} MIB_IPADDRTABLE, *PMIB_IPADDRTABLE;
typedef struct _MIB_IPFORWARDNUMBER
{
DWORD dwValue;
}MIB_IPFORWARDNUMBER,*PMIB_IPFORWARDNUMBER;
typedef struct _MIB_IPFORWARDROW
{
DWORD dwForwardDest;
DWORD dwForwardMask;
DWORD dwForwardPolicy;
DWORD dwForwardNextHop;
DWORD dwForwardIfIndex;
DWORD dwForwardType;
DWORD dwForwardProto;
DWORD dwForwardAge;
DWORD dwForwardNextHopAS;
DWORD dwForwardMetric1;
DWORD dwForwardMetric2;
DWORD dwForwardMetric3;
DWORD dwForwardMetric4;
DWORD dwForwardMetric5;
}MIB_IPFORWARDROW, *PMIB_IPFORWARDROW;
#define MIB_IPROUTE_TYPE_OTHER 1
#define MIB_IPROUTE_TYPE_INVALID 2
#define MIB_IPROUTE_TYPE_DIRECT 3
#define MIB_IPROUTE_TYPE_INDIRECT 4
#define MIB_IPPROTO_OTHER 1
#define MIB_IPPROTO_LOCAL 2
#define MIB_IPPROTO_NETMGMT 3
#define MIB_IPPROTO_ICMP 4
#define MIB_IPPROTO_EGP 5
#define MIB_IPPROTO_GGP 6
#define MIB_IPPROTO_HELLO 7
#define MIB_IPPROTO_RIP 8
#define MIB_IPPROTO_IS_IS 9
#define MIB_IPPROTO_ES_IS 10
#define MIB_IPPROTO_CISCO 11
#define MIB_IPPROTO_BBN 12
#define MIB_IPPROTO_OSPF 13
#define MIB_IPPROTO_BGP 14
#define MIB_IPPROTO_NT_AUTOSTATIC 10002
#define MIB_IPPROTO_NT_STATIC 10006
#define MIB_IPPROTO_NT_STATIC_NON_DOD 10007
typedef struct _MIB_IPFORWARDTABLE
{
DWORD dwNumEntries;
MIB_IPFORWARDROW table[1];
} MIB_IPFORWARDTABLE, *PMIB_IPFORWARDTABLE;
typedef struct _MIB_IPNETROW
{
DWORD dwIndex;
DWORD dwPhysAddrLen;
BYTE bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAddr;
DWORD dwType;
} MIB_IPNETROW, *PMIB_IPNETROW;
#define MIB_IPNET_TYPE_OTHER 1
#define MIB_IPNET_TYPE_INVALID 2
#define MIB_IPNET_TYPE_DYNAMIC 3
#define MIB_IPNET_TYPE_STATIC 4
typedef struct _MIB_IPNETTABLE
{
DWORD dwNumEntries;
MIB_IPNETROW table[1];
} MIB_IPNETTABLE, *PMIB_IPNETTABLE;
#endif /* WINE_IPRTRMIB_H__ */

87
include/iptypes.h Normal file
View File

@ -0,0 +1,87 @@
/* WINE iptypes.h
* Copyright (C) 2003 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef WINE_IPTYPES_H_
#define WINE_IPTYPES_H_
#include <time.h>
#define MAX_ADAPTER_DESCRIPTION_LENGTH 128
#define MAX_ADAPTER_NAME_LENGTH 256
#define MAX_ADAPTER_ADDRESS_LENGTH 8
#define MAX_HOSTNAME_LEN 128
#define MAX_DOMAIN_NAME_LEN 128
#define MAX_SCOPE_ID_LEN 256
#define BROADCAST_NODETYPE 1
#define PEER_TO_PEER_NODETYPE 2
#define MIXED_NODETYPE 4
#define HYBRID_NODETYPE 8
typedef struct {
char String[4 * 4];
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
typedef struct _IP_ADDR_STRING {
struct _IP_ADDR_STRING* Next;
IP_ADDRESS_STRING IpAddress;
IP_MASK_STRING IpMask;
DWORD Context;
} IP_ADDR_STRING, *PIP_ADDR_STRING;
typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO* Next;
DWORD ComboIndex;
char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
UINT AddressLength;
BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD Index;
UINT Type;
UINT DhcpEnabled;
PIP_ADDR_STRING CurrentIpAddress;
IP_ADDR_STRING IpAddressList;
IP_ADDR_STRING GatewayList;
IP_ADDR_STRING DhcpServer;
BOOL HaveWins;
IP_ADDR_STRING PrimaryWinsServer;
IP_ADDR_STRING SecondaryWinsServer;
time_t LeaseObtained;
time_t LeaseExpires;
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;
typedef struct _IP_PER_ADAPTER_INFO {
UINT AutoconfigEnabled;
UINT AutoconfigActive;
PIP_ADDR_STRING CurrentDnsServer;
IP_ADDR_STRING DnsServerList;
} IP_PER_ADAPTER_INFO, *PIP_PER_ADAPTER_INFO;
typedef struct {
char HostName[MAX_HOSTNAME_LEN + 4] ;
char DomainName[MAX_DOMAIN_NAME_LEN + 4];
PIP_ADDR_STRING CurrentDnsServer;
IP_ADDR_STRING DnsServerList;
UINT NodeType;
char ScopeId[MAX_SCOPE_ID_LEN + 4];
UINT EnableRouting;
UINT EnableProxy;
UINT EnableDns;
} FIXED_INFO, *PFIXED_INFO;
#endif /* WINE_IPTYPES_H_*/