Added an implementation of iphlpapi.dll; most Get* functions
introduced through Win98 are included.
This commit is contained in:
parent
e15aadd58a
commit
38fa5ad1bc
10
configure.ac
10
configure.ac
|
@ -982,6 +982,7 @@ AC_CHECK_HEADERS(\
|
||||||
netinet/in.h \
|
netinet/in.h \
|
||||||
netinet/in_systm.h \
|
netinet/in_systm.h \
|
||||||
netinet/tcp.h \
|
netinet/tcp.h \
|
||||||
|
netinet/tcp_fsm.h \
|
||||||
pty.h \
|
pty.h \
|
||||||
pwd.h \
|
pwd.h \
|
||||||
regex.h \
|
regex.h \
|
||||||
|
@ -1039,7 +1040,7 @@ AC_CHECK_HEADERS(sys/mount.h sys/user.h,,,
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
#endif])
|
#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>
|
[#include <sys/types.h>
|
||||||
#if HAVE_SYS_SOCKET_H
|
#if HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
|
@ -1054,12 +1055,6 @@ AC_CHECK_HEADERS(netinet/ip.h,,,
|
||||||
# include <netinet/in_systm.h>
|
# include <netinet/in_systm.h>
|
||||||
#endif])
|
#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>])
|
AC_CHECK_HEADERS(ucontext.h,,,[#include <signal.h>])
|
||||||
|
|
||||||
dnl **** Check for IPX headers (currently Linux only) ****
|
dnl **** Check for IPX headers (currently Linux only) ****
|
||||||
|
@ -1402,6 +1397,7 @@ dlls/glu32/Makefile
|
||||||
dlls/icmp/Makefile
|
dlls/icmp/Makefile
|
||||||
dlls/imagehlp/Makefile
|
dlls/imagehlp/Makefile
|
||||||
dlls/imm32/Makefile
|
dlls/imm32/Makefile
|
||||||
|
dlls/iphlpapi/Makefile
|
||||||
dlls/kernel/Makefile
|
dlls/kernel/Makefile
|
||||||
dlls/kernel/tests/Makefile
|
dlls/kernel/tests/Makefile
|
||||||
dlls/lzexpand/Makefile
|
dlls/lzexpand/Makefile
|
||||||
|
|
|
@ -47,6 +47,7 @@ BASEDIRS = \
|
||||||
icmp \
|
icmp \
|
||||||
imagehlp \
|
imagehlp \
|
||||||
imm32 \
|
imm32 \
|
||||||
|
iphlpapi \
|
||||||
kernel \
|
kernel \
|
||||||
lzexpand \
|
lzexpand \
|
||||||
mapi32 \
|
mapi32 \
|
||||||
|
@ -226,6 +227,7 @@ all: \
|
||||||
imaadp32.acm$(DLLEXT) \
|
imaadp32.acm$(DLLEXT) \
|
||||||
imagehlp.dll$(DLLEXT) \
|
imagehlp.dll$(DLLEXT) \
|
||||||
imm32.dll$(DLLEXT) \
|
imm32.dll$(DLLEXT) \
|
||||||
|
iphlpapi.dll$(DLLEXT) \
|
||||||
joystick.drv$(DLLEXT) \
|
joystick.drv$(DLLEXT) \
|
||||||
kernel32.dll$(DLLEXT) \
|
kernel32.dll$(DLLEXT) \
|
||||||
lz32.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)
|
imm32.dll$(DLLEXT) imm.dll$(DLLEXT): imm32/imm32.dll$(DLLEXT)
|
||||||
$(RM) $@ && $(LN_S) 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)
|
joystick.drv$(DLLEXT): winmm/joystick/joystick.drv$(DLLEXT)
|
||||||
$(RM) $@ && $(LN_S) winmm/joystick/joystick.drv$(DLLEXT) $@
|
$(RM) $@ && $(LN_S) winmm/joystick/joystick.drv$(DLLEXT) $@
|
||||||
|
|
||||||
|
@ -688,6 +693,7 @@ IMPORT_LIBS = \
|
||||||
libicmp \
|
libicmp \
|
||||||
libimagehlp \
|
libimagehlp \
|
||||||
libimm32 \
|
libimm32 \
|
||||||
|
libiphlpapi \
|
||||||
libkernel32 \
|
libkernel32 \
|
||||||
liblz32 \
|
liblz32 \
|
||||||
libmapi32 \
|
libmapi32 \
|
||||||
|
@ -927,6 +933,11 @@ libimm32.def: imm32/imm32.spec.def
|
||||||
libimm32.a: imm32/imm32.spec.def
|
libimm32.a: imm32/imm32.spec.def
|
||||||
$(DLLTOOL) -k -l $@ -d 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
|
libkernel32.def: kernel/kernel32.spec.def
|
||||||
$(RM) $@ && $(LN_S) kernel/kernel32.spec.def $@
|
$(RM) $@ && $(LN_S) kernel/kernel32.spec.def $@
|
||||||
libkernel32.a: kernel/kernel32.spec.def
|
libkernel32.a: kernel/kernel32.spec.def
|
||||||
|
@ -1253,6 +1264,7 @@ glu32/glu32.spec.def: $(WINEBUILD)
|
||||||
icmp/icmp.spec.def: $(WINEBUILD)
|
icmp/icmp.spec.def: $(WINEBUILD)
|
||||||
imagehlp/imagehlp.spec.def: $(WINEBUILD)
|
imagehlp/imagehlp.spec.def: $(WINEBUILD)
|
||||||
imm32/imm32.spec.def: $(WINEBUILD)
|
imm32/imm32.spec.def: $(WINEBUILD)
|
||||||
|
iphlpapi/iphlpapi.spec.def: $(WINEBUILD)
|
||||||
kernel/kernel32.spec.def: $(WINEBUILD)
|
kernel/kernel32.spec.def: $(WINEBUILD)
|
||||||
lzexpand/lz32.spec.def: $(WINEBUILD)
|
lzexpand/lz32.spec.def: $(WINEBUILD)
|
||||||
mapi32/mapi32.spec.def: $(WINEBUILD)
|
mapi32/mapi32.spec.def: $(WINEBUILD)
|
||||||
|
@ -1354,6 +1366,7 @@ icmp/icmp.dll$(DLLEXT): icmp
|
||||||
msacm/imaadp32/imaadp32.acm$(DLLEXT): msacm/imaadp32
|
msacm/imaadp32/imaadp32.acm$(DLLEXT): msacm/imaadp32
|
||||||
imagehlp/imagehlp.dll$(DLLEXT): imagehlp
|
imagehlp/imagehlp.dll$(DLLEXT): imagehlp
|
||||||
imm32/imm32.dll$(DLLEXT): imm32
|
imm32/imm32.dll$(DLLEXT): imm32
|
||||||
|
iphlpapi/iphlpapi.dll$(DLLEXT): iphlpapi
|
||||||
winmm/joystick/joystick.drv$(DLLEXT): winmm/joystick
|
winmm/joystick/joystick.drv$(DLLEXT): winmm/joystick
|
||||||
kernel/kernel32.dll$(DLLEXT): kernel
|
kernel/kernel32.dll$(DLLEXT): kernel
|
||||||
lzexpand/lz32.dll$(DLLEXT): lzexpand
|
lzexpand/lz32.dll$(DLLEXT): lzexpand
|
||||||
|
@ -1470,6 +1483,7 @@ icmp/__install__: icmp.dll$(DLLEXT)
|
||||||
msacm/imaadp32/__install__: imaadp32.acm$(DLLEXT)
|
msacm/imaadp32/__install__: imaadp32.acm$(DLLEXT)
|
||||||
imagehlp/__install__: imagehlp.dll$(DLLEXT)
|
imagehlp/__install__: imagehlp.dll$(DLLEXT)
|
||||||
imm32/__install__: imm32.dll$(DLLEXT)
|
imm32/__install__: imm32.dll$(DLLEXT)
|
||||||
|
iphlpapi/__install__: iphlpapi.dll$(DLLEXT)
|
||||||
winmm/joystick/__install__: joystick.drv$(DLLEXT)
|
winmm/joystick/__install__: joystick.drv$(DLLEXT)
|
||||||
kernel/__install__: kernel32.dll$(DLLEXT)
|
kernel/__install__: kernel32.dll$(DLLEXT)
|
||||||
lzexpand/__install__: lz32.dll$(DLLEXT)
|
lzexpand/__install__: lz32.dll$(DLLEXT)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Makefile
|
||||||
|
iphlpapi.dll.dbg.c
|
||||||
|
iphlpapi.spec.c
|
|
@ -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:
|
|
@ -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;
|
||||||
|
}
|
|
@ -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_ */
|
|
@ -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
|
@ -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;
|
||||||
|
}
|
|
@ -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_ */
|
|
@ -68,6 +68,10 @@ WINDOWS_INCLUDES = \
|
||||||
initguid.h \
|
initguid.h \
|
||||||
instance.h \
|
instance.h \
|
||||||
ipexport.h \
|
ipexport.h \
|
||||||
|
iphlpapi.h \
|
||||||
|
ipifcons.h \
|
||||||
|
iprtrmib.h \
|
||||||
|
iptypes.h \
|
||||||
lm.h \
|
lm.h \
|
||||||
lmaccess.h \
|
lmaccess.h \
|
||||||
lmapibuf.h \
|
lmapibuf.h \
|
||||||
|
|
|
@ -335,12 +335,27 @@
|
||||||
/* Define to 1 if you have the <netinet/ip.h> header file. */
|
/* Define to 1 if you have the <netinet/ip.h> header file. */
|
||||||
#undef HAVE_NETINET_IP_H
|
#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. */
|
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||||
#undef HAVE_NETINET_TCP_H
|
#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. */
|
/* Define to 1 if you have the <net/if.h> header file. */
|
||||||
#undef HAVE_NET_IF_H
|
#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. */
|
/* Define to use glibc NPTL threading support. */
|
||||||
#undef HAVE_NPTL
|
#undef HAVE_NPTL
|
||||||
|
|
||||||
|
|
|
@ -96,4 +96,21 @@ typedef struct icmp_echo_reply ICMP_ECHO_REPLY, *PICMP_ECHO_REPLY;
|
||||||
#define IP_PENDING (IP_STATUS_BASE + 255)
|
#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 */
|
#endif /* __WINE_IPEXPORT_H */
|
||||||
|
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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_*/
|
Loading…
Reference in New Issue