mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 04:20:46 +00:00
Big merge in wine code. This merged version is far more complete than
the previous one. See notes and comments by me and the original author of iphlpapi_main.c, Juan Lang. svn path=/trunk/; revision=8194
This commit is contained in:
parent
d3a56d75eb
commit
a3ac53db3d
17 changed files with 4129 additions and 39 deletions
117
reactos/lib/iphlpapi/icmp.c
Normal file
117
reactos/lib/iphlpapi/icmp.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
# include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
# include <resolv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __REACTOS__
|
||||
# include <windows.h>
|
||||
# include <windef.h>
|
||||
# include <winbase.h>
|
||||
# include <net/miniport.h>
|
||||
# include <winsock2.h>
|
||||
# include <nspapi.h>
|
||||
# include <iptypes.h>
|
||||
# include "iphlpapiextra.h"
|
||||
#else
|
||||
# include "windef.h"
|
||||
# include "winbase.h"
|
||||
# include "winreg.h"
|
||||
#endif
|
||||
|
||||
#include "iphlpapi.h"
|
||||
#include "ifenum.h"
|
||||
#include "ipstats.h"
|
||||
#include "iphlp_res.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
STDCALL
|
||||
IcmpParseReplies(
|
||||
LPVOID ReplyBuffer,
|
||||
DWORD ReplySize
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
HANDLE STDCALL IcmpCreateFile(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL STDCALL IcmpCloseHandle(
|
||||
HANDLE IcmpHandle
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD STDCALL IcmpSendEcho(
|
||||
HANDLE IcmpHandle,
|
||||
IPAddr DestinationAddress,
|
||||
LPVOID RequestData,
|
||||
WORD RequestSize,
|
||||
PIP_OPTION_INFORMATION RequestOptions,
|
||||
LPVOID ReplyBuffer,
|
||||
DWORD ReplySize,
|
||||
DWORD Timeout
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
STDCALL
|
||||
IcmpSendEcho2(
|
||||
HANDLE IcmpHandle,
|
||||
HANDLE Event,
|
||||
FARPROC ApcRoutine,
|
||||
PVOID ApcContext,
|
||||
IPAddr DestinationAddress,
|
||||
LPVOID RequestData,
|
||||
WORD RequestSize,
|
||||
PIP_OPTION_INFORMATION RequestOptions,
|
||||
LPVOID ReplyBuffer,
|
||||
DWORD ReplySize,
|
||||
DWORD Timeout
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
142
reactos/lib/iphlpapi/ifenum.h
Normal file
142
reactos/lib/iphlpapi/ifenum.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* 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 <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "iprtrmib.h"
|
||||
|
||||
#define MAX_INTERFACE_PHYSADDR 8
|
||||
#define MAX_INTERFACE_DESCRIPTION 256
|
||||
|
||||
/* Call before using the functions in this module */
|
||||
void interfaceMapInit(void);
|
||||
/* Call to free resources allocated in interfaceMapInit() */
|
||||
void interfaceMapFree(void);
|
||||
|
||||
DWORD getNumInterfaces(void);
|
||||
DWORD 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 returned may have been allocated. It should be returned
|
||||
* by calling consumeInterfaceNmae.
|
||||
*/
|
||||
const char *getInterfaceNameByIndex(DWORD index);
|
||||
|
||||
/* consume the interface name provided by getInterfaceName. */
|
||||
|
||||
void consumeInterfaceName( const char *ifname );
|
||||
|
||||
/* 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_ */
|
723
reactos/lib/iphlpapi/ifenum_reactos.c
Normal file
723
reactos/lib/iphlpapi/ifenum_reactos.c
Normal file
|
@ -0,0 +1,723 @@
|
|||
/* Copyright (C) 2003 Art Yerkes
|
||||
* A reimplementation of ifenum.c by 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
|
||||
* - Our bretheren use IOCTL_TCP_QUERY_INFORMATION_EX to get information
|
||||
* from tcpip.sys and IOCTL_TCP_SET_INFORMATION_EX to set info (such as
|
||||
* the route table). These ioctls mirror WsControl exactly in usage.
|
||||
* - This iphlpapi does not rely on any reactos-only features.
|
||||
* - This implementation is meant to be largely correct. I am not, however,
|
||||
* paying any attention to performance. It can be done faster, and
|
||||
* someone should definately optimize this code when speed is more of a
|
||||
* priority than it is now.
|
||||
*
|
||||
* Edited implementation notes from the original -- Basically edited to add
|
||||
* information and prune things which are not accurate about this file.
|
||||
* 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.
|
||||
* FIXME:
|
||||
* - We don't support IPv6 addresses here yet -- I moved the upper edge
|
||||
* functions into iphlpv6.c (arty)
|
||||
*/
|
||||
|
||||
#include "ipprivate.h"
|
||||
#include "ifenum.h"
|
||||
|
||||
/* Globals */
|
||||
const PWCHAR TcpFileName = L"\\Device\\Tcp";
|
||||
|
||||
/* Functions */
|
||||
|
||||
void interfaceMapInit(void)
|
||||
{
|
||||
/* For now, nothing */
|
||||
}
|
||||
|
||||
void interfaceMapFree(void)
|
||||
{
|
||||
/* Ditto. */
|
||||
}
|
||||
|
||||
NTSTATUS openTcpFile(PHANDLE tcpFile) {
|
||||
UNICODE_STRING fileName;
|
||||
OBJECT_ATTRIBUTES objectAttributes;
|
||||
IO_STATUS_BLOCK ioStatusBlock;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("called.\n");
|
||||
|
||||
/* Shamelessly ripped from CreateFileW */
|
||||
RtlInitUnicodeString( &fileName, TcpFileName );
|
||||
|
||||
InitializeObjectAttributes( &objectAttributes,
|
||||
&fileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL );
|
||||
|
||||
status = NtCreateFile( tcpFile,
|
||||
SYNCHRONIZE | GENERIC_EXECUTE,
|
||||
&objectAttributes,
|
||||
&ioStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_OPEN_IF,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
0,
|
||||
0 );
|
||||
|
||||
/* String does not need to be freed: it points to the constant
|
||||
* string we provided */
|
||||
|
||||
TRACE("returning %08x\n", (int)status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void closeTcpFile( HANDLE h ) {
|
||||
TRACE("called.\n");
|
||||
NtClose( h );
|
||||
}
|
||||
|
||||
/* A generic thing-getting function which interacts in the right way with
|
||||
* TDI. This may seem oblique, but I'm using it to reduce code and hopefully
|
||||
* make this thing easier to debug.
|
||||
*
|
||||
* The things returned can be any of:
|
||||
* TDIEntityID
|
||||
* TDIObjectID
|
||||
* IFEntry
|
||||
* IPSNMPInfo
|
||||
* IPAddrEntry
|
||||
* IPInterfaceInfo
|
||||
*/
|
||||
NTSTATUS tdiGetSetOfThings( HANDLE tcpFile,
|
||||
DWORD toiClass,
|
||||
DWORD toiType,
|
||||
DWORD toiId,
|
||||
DWORD teiEntity,
|
||||
DWORD fixedPart,
|
||||
DWORD entrySize,
|
||||
PVOID *tdiEntitySet,
|
||||
PDWORD numEntries ) {
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
||||
PVOID entitySet = 0;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
DWORD allocationSizeForEntityArray = entrySize * MAX_TDI_ENTITIES,
|
||||
arraySize = entrySize * MAX_TDI_ENTITIES;
|
||||
|
||||
DPRINT("TdiGetSetOfThings(tcpFile %x,toiClass %x,toiType %x,toiId %x,"
|
||||
"teiEntity %x,fixedPart %d,entrySize %d)\n",
|
||||
(int)tcpFile,
|
||||
(int)toiClass,
|
||||
(int)toiType,
|
||||
(int)toiId,
|
||||
(int)teiEntity,
|
||||
(int)fixedPart,
|
||||
(int)entrySize );
|
||||
|
||||
req.ID.toi_class = toiClass;
|
||||
req.ID.toi_type = toiType;
|
||||
req.ID.toi_id = toiId;
|
||||
req.ID.toi_entity.tei_entity = teiEntity;
|
||||
|
||||
/* There's a subtle problem here...
|
||||
* If an interface is added at this exact instant, (as if by a PCMCIA
|
||||
* card insertion), the array will still not have enough entries after
|
||||
* have allocated it after the first DeviceIoControl call.
|
||||
*
|
||||
* We'll get around this by repeating until the number of interfaces
|
||||
* stabilizes.
|
||||
*/
|
||||
do {
|
||||
assert( !entitySet ); /* We must not have an entity set allocated */
|
||||
status = DeviceIoControl( tcpFile,
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX,
|
||||
&req,
|
||||
sizeof(req),
|
||||
0,
|
||||
0,
|
||||
&allocationSizeForEntityArray,
|
||||
NULL );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("TdiGetSetOfThings() => %08x\n", (int)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
arraySize = allocationSizeForEntityArray;
|
||||
entitySet = HeapAlloc( GetProcessHeap(), 0, arraySize );
|
||||
|
||||
if( !entitySet ) {
|
||||
status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
DPRINT("TdiGetSetOfThings() => %08x\n", (int)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = DeviceIoControl( tcpFile,
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX,
|
||||
&req,
|
||||
sizeof(req),
|
||||
entitySet,
|
||||
arraySize,
|
||||
&allocationSizeForEntityArray,
|
||||
NULL );
|
||||
|
||||
/* This is why we have the loop -- we might have added an adapter */
|
||||
if( arraySize == allocationSizeForEntityArray )
|
||||
break;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, entitySet );
|
||||
entitySet = 0;
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("TdiGetSetOfThings() => %08x\n", (int)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
DPRINT("TdiGetSetOfThings(): Array changed size: %d -> %d.\n",
|
||||
arraySize, allocationSizeForEntityArray );
|
||||
} while( TRUE ); /* We break if the array we received was the size we
|
||||
* expected. Therefore, we got here because it wasn't */
|
||||
|
||||
*numEntries = (arraySize - fixedPart) / entrySize;
|
||||
*tdiEntitySet = entitySet;
|
||||
|
||||
DPRINT("TdiGetSetOfThings() => Success: %d things @ %08x\n",
|
||||
(int)*numEntries, (int)entitySet);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID tdiFreeThingSet( PVOID things ) {
|
||||
HeapFree( GetProcessHeap(), 0, things );
|
||||
}
|
||||
|
||||
NTSTATUS tdiGetMibForIfEntity
|
||||
( HANDLE tcpFile, DWORD entityId, IFEntrySafelySized *entry ) {
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
DWORD returnSize;
|
||||
|
||||
DPRINT("TdiGetMibForIfEntity(tcpFile %x,entityId %x)\n",
|
||||
(int)tcpFile, (int)entityId);
|
||||
|
||||
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = IF_MIB_STATS_ID;
|
||||
req.ID.toi_entity.tei_entity = IF_ENTITY;
|
||||
req.ID.toi_entity.tei_instance = entityId;
|
||||
|
||||
status = DeviceIoControl( tcpFile,
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX,
|
||||
&req,
|
||||
sizeof(req),
|
||||
entry,
|
||||
sizeof(*entry),
|
||||
&returnSize,
|
||||
NULL );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
TRACE("failure: %08x\n", status);
|
||||
return status;
|
||||
} else TRACE("Success.\n");
|
||||
|
||||
DPRINT("TdiGetMibForIfEntity() => {\n"
|
||||
" if_index ....................... %x\n"
|
||||
" if_type ........................ %x\n"
|
||||
" if_mtu ......................... %d\n"
|
||||
" if_speed ....................... %x\n"
|
||||
" if_physaddrlen ................. %d\n"
|
||||
" if_physaddr .................... %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
" if_descr ....................... %s\n"
|
||||
"} status %08x\n",
|
||||
(int)entry->offset.ent.if_index,
|
||||
(int)entry->offset.ent.if_type,
|
||||
(int)entry->offset.ent.if_mtu,
|
||||
(int)entry->offset.ent.if_speed,
|
||||
(int)entry->offset.ent.if_physaddrlen,
|
||||
entry->offset.ent.if_physaddr[0] & 0xff,
|
||||
entry->offset.ent.if_physaddr[1] & 0xff,
|
||||
entry->offset.ent.if_physaddr[2] & 0xff,
|
||||
entry->offset.ent.if_physaddr[3] & 0xff,
|
||||
entry->offset.ent.if_physaddr[4] & 0xff,
|
||||
entry->offset.ent.if_physaddr[5] & 0xff,
|
||||
entry->offset.ent.if_descr,
|
||||
(int)status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile,
|
||||
TDIEntityID **entitySet,
|
||||
PDWORD numEntities ) {
|
||||
NTSTATUS status = tdiGetSetOfThings( tcpFile,
|
||||
INFO_CLASS_GENERIC,
|
||||
INFO_TYPE_PROVIDER,
|
||||
ENTITY_LIST_ID,
|
||||
GENERIC_ENTITY,
|
||||
0,
|
||||
sizeof(TDIEntityID),
|
||||
(PVOID *)entitySet,
|
||||
numEntities );
|
||||
if( NT_SUCCESS(status) ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; i < *numEntities; i++ ) {
|
||||
DPRINT("%-4d: %04x:%08x\n",
|
||||
i,
|
||||
(*entitySet)[i].tei_entity,
|
||||
(*entitySet)[i].tei_instance );
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static BOOL isInterface( TDIEntityID *if_maybe ) {
|
||||
return
|
||||
if_maybe->tei_entity == IF_ENTITY;
|
||||
}
|
||||
|
||||
static BOOL isLoopback( HANDLE tcpFile, TDIEntityID *loop_maybe ) {
|
||||
IFEntrySafelySized entryInfo;
|
||||
|
||||
tdiGetMibForIfEntity( tcpFile,
|
||||
loop_maybe->tei_instance,
|
||||
&entryInfo );
|
||||
|
||||
return !entryInfo.offset.ent.if_type ||
|
||||
entryInfo.offset.ent.if_type == IFENT_SOFTWARE_LOOPBACK;
|
||||
}
|
||||
|
||||
NTSTATUS tdiGetEntityType( HANDLE tcpFile, TDIEntityID *ent, PULONG type ) {
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
DWORD returnSize;
|
||||
|
||||
DPRINT("TdiGetEntityType(tcpFile %x,entityId %x)\n",
|
||||
(DWORD)tcpFile, ent->tei_instance);
|
||||
|
||||
req.ID.toi_class = INFO_CLASS_GENERIC;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = ENTITY_TYPE_ID;
|
||||
req.ID.toi_entity.tei_entity = ent->tei_entity;
|
||||
req.ID.toi_entity.tei_instance = ent->tei_instance;
|
||||
|
||||
status = DeviceIoControl( tcpFile,
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX,
|
||||
&req,
|
||||
sizeof(req),
|
||||
type,
|
||||
sizeof(*type),
|
||||
&returnSize,
|
||||
NULL );
|
||||
|
||||
DPRINT("TdiGetEntityType() => %08x %08x\n", *type, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static DWORD getNumInterfacesInt(BOOL onlyLoopback)
|
||||
{
|
||||
DWORD numEntities, numInterfaces = 0;
|
||||
TDIEntityID *entitySet;
|
||||
HANDLE tcpFile;
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
|
||||
status = openTcpFile( &tcpFile );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("getNumInterfaces: failed %08x\n", status );
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("getNumInterfaces: failed %08x\n", status );
|
||||
return 0;
|
||||
}
|
||||
|
||||
closeTcpFile( tcpFile );
|
||||
|
||||
for( i = 0; i < numEntities; i++ ) {
|
||||
if( isInterface( &entitySet[i] ) &&
|
||||
(!onlyLoopback || isLoopback( tcpFile, &entitySet[i] )) )
|
||||
numInterfaces++;
|
||||
}
|
||||
|
||||
DPRINT("getNumInterfaces: success: %d %d %08x\n",
|
||||
onlyLoopback, numInterfaces, status );
|
||||
|
||||
tdiFreeThingSet( entitySet );
|
||||
|
||||
return numInterfaces;
|
||||
}
|
||||
|
||||
DWORD getNumInterfaces(void)
|
||||
{
|
||||
return getNumInterfacesInt( FALSE );
|
||||
}
|
||||
|
||||
DWORD getNumNonLoopbackInterfaces(void)
|
||||
{
|
||||
return getNumInterfacesInt( TRUE );
|
||||
}
|
||||
|
||||
DWORD getNthInterfaceEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent ) {
|
||||
DWORD numEntities = 0;
|
||||
DWORD numInterfaces = 0;
|
||||
TDIEntityID *entitySet = 0;
|
||||
NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
|
||||
int i;
|
||||
|
||||
if( !NT_SUCCESS(status) )
|
||||
return status;
|
||||
|
||||
for( i = 0; i < numEntities; i++ ) {
|
||||
if( isInterface( &entitySet[i] ) ) {
|
||||
if( numInterfaces == index ) break;
|
||||
else numInterfaces++;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Index %d is entity #%d - %04x:%08x\n", index, i,
|
||||
entitySet[i].tei_entity, entitySet[i].tei_instance );
|
||||
|
||||
if( numInterfaces == index && i < numEntities ) {
|
||||
memcpy( ent, &entitySet[i], sizeof(*ent) );
|
||||
tdiFreeThingSet( entitySet );
|
||||
return STATUS_SUCCESS;
|
||||
} else {
|
||||
tdiFreeThingSet( entitySet );
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that the result of this operation must be freed later */
|
||||
|
||||
const char *getInterfaceNameByIndex(DWORD index)
|
||||
{
|
||||
TDIEntityID ent;
|
||||
IFEntrySafelySized entityInfo;
|
||||
HANDLE tcpFile = INVALID_HANDLE_VALUE;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
PCHAR interfaceName = 0;
|
||||
char simple_name_buf[100];
|
||||
char *adapter_name;
|
||||
|
||||
status = openTcpFile( &tcpFile );
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("failed %08x\n", status );
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = getNthInterfaceEntity( tcpFile, index, &ent );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("failed %08x\n", status );
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = tdiGetMibForIfEntity( tcpFile,
|
||||
ent.tei_instance,
|
||||
&entityInfo );
|
||||
if( NT_SUCCESS(status) ) {
|
||||
adapter_name = entityInfo.offset.ent.if_descr;
|
||||
} else {
|
||||
sprintf( simple_name_buf, "eth%x",
|
||||
(int)ent.tei_instance );
|
||||
adapter_name = simple_name_buf;
|
||||
}
|
||||
interfaceName = HeapAlloc( GetProcessHeap(), 0,
|
||||
strlen(adapter_name) + 1 );
|
||||
strcpy( interfaceName, adapter_name );
|
||||
|
||||
closeTcpFile( tcpFile );
|
||||
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
void consumeInterfaceName(const char *name) {
|
||||
HeapFree( GetProcessHeap(), 0, (char *)name );
|
||||
}
|
||||
|
||||
DWORD getInterfaceIndexByName(const char *name, PDWORD index)
|
||||
{
|
||||
DWORD ret = STATUS_SUCCESS;
|
||||
int numInterfaces = getNumInterfaces();
|
||||
const char *iname = 0;
|
||||
int i;
|
||||
HANDLE tcpFile;
|
||||
|
||||
ret = openTcpFile( &tcpFile );
|
||||
|
||||
if( !NT_SUCCESS(ret) ) {
|
||||
DPRINT("Failure: %08x\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for( i = 0; i < numInterfaces; i++ ) {
|
||||
iname = getInterfaceNameByIndex( i );
|
||||
if( !strcmp(iname, name) ) {
|
||||
*index = i;
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, (char *)iname );
|
||||
}
|
||||
|
||||
closeTcpFile( tcpFile );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *getInterfaceIndexTableInt( BOOL nonLoopbackOnly ) {
|
||||
HANDLE tcpFile;
|
||||
DWORD numInterfaces, curInterface = 0;
|
||||
int i;
|
||||
InterfaceIndexTable *ret;
|
||||
TDIEntityID *entitySet;
|
||||
DWORD numEntities;
|
||||
NTSTATUS status;
|
||||
|
||||
numInterfaces = getNumInterfaces();
|
||||
TRACE("getInterfaceIndexTable: numInterfaces: %d\n", numInterfaces);
|
||||
ret = (InterfaceIndexTable *)calloc(1,
|
||||
sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD));
|
||||
if (ret) {
|
||||
ret->numAllocated = numInterfaces;
|
||||
}
|
||||
|
||||
status = openTcpFile( &tcpFile );
|
||||
tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
|
||||
|
||||
for( i = 0; i < numEntities; i++ ) {
|
||||
if( isInterface( &entitySet[i] ) &&
|
||||
(!nonLoopbackOnly || !isLoopback( tcpFile, &entitySet[i] )) ) {
|
||||
ret->indexes[curInterface++] = entitySet[i].tei_instance;
|
||||
}
|
||||
}
|
||||
|
||||
tdiFreeThingSet( entitySet );
|
||||
closeTcpFile( tcpFile );
|
||||
ret->numIndexes = curInterface;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
InterfaceIndexTable *getInterfaceIndexTable(void) {
|
||||
return getInterfaceIndexTableInt( FALSE );
|
||||
}
|
||||
|
||||
InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void) {
|
||||
return getInterfaceIndexTableInt( TRUE );
|
||||
}
|
||||
|
||||
DWORD getInterfaceIPAddrByName(const char *name)
|
||||
{
|
||||
return INADDR_ANY;
|
||||
}
|
||||
|
||||
DWORD getInterfaceIPAddrByIndex(DWORD index)
|
||||
{
|
||||
return INADDR_ANY;
|
||||
}
|
||||
|
||||
DWORD getInterfaceBCastAddrByName(const char *name)
|
||||
{
|
||||
return INADDR_ANY;
|
||||
}
|
||||
|
||||
DWORD getInterfaceBCastAddrByIndex(DWORD index)
|
||||
{
|
||||
return INADDR_ANY;
|
||||
}
|
||||
|
||||
DWORD getInterfaceMaskByName(const char *name)
|
||||
{
|
||||
DWORD ret = INADDR_NONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD getInterfaceMaskByIndex(DWORD index)
|
||||
{
|
||||
DWORD ret = INADDR_NONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
|
||||
PDWORD type)
|
||||
{
|
||||
DWORD ret;
|
||||
DWORD addrLen;
|
||||
|
||||
if (!name || !len || !addr || !type)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (addrLen > *len) {
|
||||
ret = ERROR_INSUFFICIENT_BUFFER;
|
||||
*len = addrLen;
|
||||
}
|
||||
else {
|
||||
/* zero out remaining bytes for broken implementations */
|
||||
memset(addr + addrLen, 0, *len - addrLen);
|
||||
*len = addrLen;
|
||||
ret = NO_ERROR;
|
||||
}
|
||||
|
||||
ret = ERROR_NO_MORE_FILES;
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
*mtu = 0;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!name)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if (!status)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
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)
|
||||
{
|
||||
HANDLE tcpFile;
|
||||
NTSTATUS status = openTcpFile( &tcpFile );
|
||||
TDIEntityID entity;
|
||||
|
||||
DPRINT("Called.\n");
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("Failed: %08x\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = getNthInterfaceEntity( tcpFile, index, &entity );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
DPRINT("Failed: %08x\n", status);
|
||||
closeTcpFile( tcpFile );
|
||||
return status;
|
||||
}
|
||||
|
||||
status = tdiGetMibForIfEntity( tcpFile,
|
||||
entity.tei_instance,
|
||||
(IFEntrySafelySized *)
|
||||
&entry->wszName[MAX_INTERFACE_NAME_LEN] );
|
||||
|
||||
closeTcpFile( tcpFile );
|
||||
return status;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
12
reactos/lib/iphlpapi/iphlp_res.h
Normal file
12
reactos/lib/iphlpapi/iphlp_res.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef _IPHLP_RES_H
|
||||
#define _IPHLP_RES_H
|
||||
|
||||
typedef struct _IPHLP_RES_INFO {
|
||||
DWORD riCount;
|
||||
LPSOCKADDR riAddressList;
|
||||
} IPHLP_RES_INFO, *PIPHLP_RES_INFO;
|
||||
|
||||
PIPHLP_RES_INFO getResInfo();
|
||||
VOID disposeResInfo( PIPHLP_RES_INFO InfoPtr );
|
||||
|
||||
#endif/*_IPHLP_RES_H*/
|
|
@ -19,14 +19,14 @@ GetUdpTable=GetUdpTable@12
|
|||
FlushIpNetTable=FlushIpNetTable@4
|
||||
;IpHlpDllEntry
|
||||
;AllocateAndGetArpEntTableFromStack
|
||||
AllocateAndGetIfTableFromStack@16
|
||||
AllocateAndGetIpAddrTableFromStack@16
|
||||
AllocateAndGetIpForwardTableFromStack@16
|
||||
AllocateAndGetIpNetTableFromStack@16
|
||||
AllocateAndGetIfTableFromStack=AllocateAndGetIfTableFromStack@16
|
||||
AllocateAndGetIpAddrTableFromStack=AllocateAndGetIpAddrTableFromStack@16
|
||||
AllocateAndGetIpForwardTableFromStack=AllocateAndGetIpForwardTableFromStack@16
|
||||
AllocateAndGetIpNetTableFromStack=AllocateAndGetIpNetTableFromStack@16
|
||||
;AllocateAndGetTcpExTableFromStack
|
||||
AllocateAndGetTcpTableFromStack@16
|
||||
AllocateAndGetTcpTableFromStack=AllocateAndGetTcpTableFromStack@16
|
||||
;AllocateAndGetUdpExTableFromStack
|
||||
AllocateAndGetUdpTableFromStack@16
|
||||
AllocateAndGetUdpTableFromStack=AllocateAndGetUdpTableFromStack@16
|
||||
CreateIpNetEntry=CreateIpNetEntry@4
|
||||
CreateProxyArpEntry=CreateProxyArpEntry@12
|
||||
DeleteIPAddress=DeleteIPAddress@4
|
||||
|
|
2102
reactos/lib/iphlpapi/iphlpapi_main.c
Normal file
2102
reactos/lib/iphlpapi/iphlpapi_main.c
Normal file
File diff suppressed because it is too large
Load diff
11
reactos/lib/iphlpapi/iphlpapiextra.h
Normal file
11
reactos/lib/iphlpapi/iphlpapiextra.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef _IPHLPAPIEXTRA_H
|
||||
#define _IPHLPAPIEXTRA_H
|
||||
|
||||
#include <w32api.h>
|
||||
/* This is here until we switch to version 2.5 of the mingw headers */
|
||||
#if (__W32API_MAJOR_VERSION < 2 || __W32API_MINOR_VERSION < 5)
|
||||
BOOL WINAPI
|
||||
GetComputerNameExA(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
|
||||
#endif
|
||||
|
||||
#endif/*_IPHLPAPIEXTRA_H*/
|
91
reactos/lib/iphlpapi/iphlpv6.c
Normal file
91
reactos/lib/iphlpapi/iphlpv6.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
# include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
# include <resolv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __REACTOS__
|
||||
# include <windows.h>
|
||||
# include <windef.h>
|
||||
# include <winbase.h>
|
||||
# include <net/miniport.h>
|
||||
# include <winsock2.h>
|
||||
# include <nspapi.h>
|
||||
# include <iptypes.h>
|
||||
# include <ws2tcpip.h>
|
||||
# include "iphlpapiextra.h"
|
||||
#else
|
||||
# include "windef.h"
|
||||
# include "winbase.h"
|
||||
# include "winreg.h"
|
||||
#endif
|
||||
|
||||
#include "iphlpapi.h"
|
||||
#include "ifenum.h"
|
||||
#include "ipstats.h"
|
||||
#include "iphlp_res.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
HANDLE STDCALL Icmp6CreateFile(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
STDCALL
|
||||
Icmp6SendEcho2(
|
||||
HANDLE IcmpHandle,
|
||||
HANDLE Event,
|
||||
FARPROC ApcRoutine,
|
||||
PVOID ApcContext,
|
||||
struct sockaddr_in6 *SourceAddress,
|
||||
struct sockaddr_in6 *DestinationAddress,
|
||||
LPVOID RequestData,
|
||||
WORD RequestSize,
|
||||
PIP_OPTION_INFORMATION RequestOptions,
|
||||
LPVOID ReplyBuffer,
|
||||
DWORD ReplySize,
|
||||
DWORD Timeout
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
STDCALL
|
||||
Icmp6ParseReplies(
|
||||
LPVOID ReplyBuffer,
|
||||
DWORD ReplySize
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
|
@ -1,15 +1,92 @@
|
|||
#ifndef IPPRIVATE_H
|
||||
#define IPPRIVATE_H
|
||||
|
||||
typedef void (*EnumInterfacesFunc)( HANDLE RegHandle, PWCHAR InterfaceName,
|
||||
PVOID Data );
|
||||
typedef void (*EnumNameServersFunc)( PWCHAR InterfaceName, PWCHAR Server,
|
||||
PVOID Data );
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int NumServers;
|
||||
int CurrentName;
|
||||
PIP_ADDR_STRING AddrString;
|
||||
} NAME_SERVER_LIST_PRIVATE, *PNAME_SERVER_LIST_PRIVATE;
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
# include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
# include <resolv.h>
|
||||
#endif
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <rosrtl/string.h>
|
||||
#include <ntdll/rtl.h>
|
||||
#include <windows.h>
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <net/miniport.h>
|
||||
#include <winsock2.h>
|
||||
#include <nspapi.h>
|
||||
#include <iptypes.h>
|
||||
#include "iphlpapiextra.h"
|
||||
#include "ipregprivate.h"
|
||||
#include "iphlpapi.h"
|
||||
#include "ifenum.h"
|
||||
#include "ipstats.h"
|
||||
#include "iphlp_res.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
#undef TRACE
|
||||
#define TRACE(fmt,args...) DbgPrint("(%s:%d - %s) " fmt, __FILE__, __LINE__, __FUNCTION__, ## args)
|
||||
|
||||
#include "net/tdiinfo.h"
|
||||
#include "tcpioctl.h"
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#define ETH_ALEN 6
|
||||
#endif
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE (~0U)
|
||||
#endif
|
||||
|
||||
#ifndef IFENT_SOFTWARE_LOOPBACK
|
||||
#define IFENT_SOFTWARE_LOOPBACK 24 /* This is an SNMP constant from rfc1213 */
|
||||
#endif/*IFENT_SOFTWARE_LOOPBACK*/
|
||||
|
||||
#define INDEX_IS_LOOPBACK 0x00800000
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 0x20
|
||||
#endif/*IFNAMSIZ*/
|
||||
|
||||
#define TCP_REQUEST_QUERY_INFORMATION_INIT { { { 0 } } }
|
||||
|
||||
/* No caddr_t in reactos headers */
|
||||
typedef char *caddr_t;
|
||||
|
||||
typedef union _IFEntrySafelySized {
|
||||
PCHAR MaxSize[sizeof(DWORD) +
|
||||
sizeof(IFEntry) +
|
||||
MAX_ADAPTER_DESCRIPTION_LENGTH + 1];
|
||||
struct {
|
||||
DWORD ProperlyOffsetTheStructure;
|
||||
IFEntry ent;
|
||||
} offset;
|
||||
} IFEntrySafelySized;
|
||||
|
||||
/** Prototypes **/
|
||||
NTSTATUS openTcpFile(PHANDLE tcpFile);
|
||||
VOID closeTcpFile(HANDLE tcpFile);
|
||||
NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, TDIEntityID **entitySet,
|
||||
PDWORD numEntities );
|
||||
VOID tdiFreeThingSet( PVOID things );
|
||||
|
||||
#endif/*IPPRIVATE_H*/
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
|
||||
int GetLongestChildKeyName( HANDLE RegHandle );
|
||||
LONG OpenChildKeyRead( HANDLE RegHandle,
|
||||
PWCHAR ChildKeyName,
|
||||
PCHAR ChildKeyName,
|
||||
PHKEY ReturnHandle );
|
||||
PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n );
|
||||
void ConsumeChildKeyName( PWCHAR Name );
|
||||
PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName );
|
||||
void ConsumeRegValueString( PWCHAR NameServer );
|
||||
PCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n );
|
||||
void ConsumeChildKeyName( PCHAR Name );
|
||||
PCHAR QueryRegistryValueString( HANDLE RegHandle, PCHAR ValueName );
|
||||
void ConsumeRegValueString( PCHAR NameServer );
|
||||
|
||||
#endif/*IPREGPRIVATE_H*/
|
||||
|
|
108
reactos/lib/iphlpapi/ipstats.h
Normal file
108
reactos/lib/iphlpapi/ipstats.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* 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 <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.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);
|
||||
|
||||
/* Ditto above by index. */
|
||||
DWORD getInterfaceStatsByIndex(DWORD index, 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, DWORD family);
|
||||
|
||||
/* Gets TCP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is
|
||||
* NULL, NO_ERROR otherwise.
|
||||
*/
|
||||
DWORD getTCPStats(MIB_TCPSTATS *stats, DWORD family);
|
||||
|
||||
/* Gets UDP statistics into stats. Returns ERROR_INVALID_PARAMETER if stats is
|
||||
* NULL, NO_ERROR otherwise.
|
||||
*/
|
||||
DWORD getUDPStats(MIB_UDPSTATS *stats, DWORD family);
|
||||
|
||||
/* 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_ */
|
558
reactos/lib/iphlpapi/ipstats_reactos.c
Normal file
558
reactos/lib/iphlpapi/ipstats_reactos.c
Normal file
|
@ -0,0 +1,558 @@
|
|||
/* 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 "ipprivate.h"
|
||||
#include "ipstats.h"
|
||||
#include "ifenum.h"
|
||||
|
||||
#ifndef TCPS_ESTABLISHED
|
||||
# define TCPS_ESTABLISHED TCP_ESTABLISHED
|
||||
#endif
|
||||
#ifndef TCPS_SYN_SENT
|
||||
# define TCPS_SYN_SENT TCP_SYN_SENT
|
||||
#endif
|
||||
#ifndef TCPS_SYN_RECEIVED
|
||||
# define TCPS_SYN_RECEIVED TCP_SYN_RECV
|
||||
#endif
|
||||
#ifndef TCPS_FIN_WAIT_1
|
||||
# define TCPS_FIN_WAIT_1 TCP_FIN_WAIT1
|
||||
#endif
|
||||
#ifndef TCPS_FIN_WAIT_2
|
||||
# define TCPS_FIN_WAIT_2 TCP_FIN_WAIT2
|
||||
#endif
|
||||
#ifndef TCPS_TIME_WAIT
|
||||
# define TCPS_TIME_WAIT TCP_TIME_WAIT
|
||||
#endif
|
||||
#ifndef TCPS_CLOSED
|
||||
# define TCPS_CLOSED TCP_CLOSE
|
||||
#endif
|
||||
#ifndef TCPS_CLOSE_WAIT
|
||||
# define TCPS_CLOSE_WAIT TCP_CLOSE_WAIT
|
||||
#endif
|
||||
#ifndef TCPS_LAST_ACK
|
||||
# define TCPS_LAST_ACK TCP_LAST_ACK
|
||||
#endif
|
||||
#ifndef TCPS_LISTEN
|
||||
# define TCPS_LISTEN TCP_LISTEN
|
||||
#endif
|
||||
#ifndef TCPS_CLOSING
|
||||
# define TCPS_CLOSING TCP_CLOSING
|
||||
#endif
|
||||
|
||||
BOOL isIpEntity( HANDLE tcpFile, TDIEntityID *ent ) {
|
||||
DWORD entityType, returnedLen;
|
||||
NTSTATUS status;
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req;
|
||||
|
||||
req.ID.toi_class = INFO_CLASS_GENERIC;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = ENTITY_TYPE_ID;
|
||||
req.ID.toi_entity = *ent;
|
||||
|
||||
status =
|
||||
DeviceIoControl
|
||||
( tcpFile,
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX,
|
||||
&req,
|
||||
sizeof(req),
|
||||
&entityType,
|
||||
sizeof(entityType),
|
||||
&returnedLen,
|
||||
NULL );
|
||||
|
||||
DPRINT("Ent: %04x:d -> %04x\n",
|
||||
ent->tei_entity, ent->tei_instance, entityType );
|
||||
|
||||
return NT_SUCCESS(status) && entityType == CL_NL_IP;
|
||||
}
|
||||
|
||||
NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent ) {
|
||||
DWORD numEntities = 0;
|
||||
DWORD numRoutes = 0;
|
||||
TDIEntityID *entitySet = 0;
|
||||
NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
|
||||
int i;
|
||||
|
||||
if( !NT_SUCCESS(status) )
|
||||
return status;
|
||||
|
||||
for( i = 0; i < numEntities; i++ ) {
|
||||
if( isIpEntity( tcpFile, &entitySet[i] ) ) {
|
||||
DPRINT("Entity %d is an IP Entity\n", i);
|
||||
if( numRoutes == index ) break;
|
||||
else numRoutes++;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Index %d is entity #%d - %04x:%08x\n", index, i,
|
||||
entitySet[i].tei_entity, entitySet[i].tei_instance );
|
||||
|
||||
if( numRoutes == index && i < numEntities ) {
|
||||
memcpy( ent, &entitySet[i], sizeof(*ent) );
|
||||
tdiFreeThingSet( entitySet );
|
||||
return STATUS_SUCCESS;
|
||||
} else {
|
||||
tdiFreeThingSet( entitySet );
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS tdiGetMibForIpEntity
|
||||
( HANDLE tcpFile, TDIEntityID *ent, IPSNMPInfo *entry ) {
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
DWORD returnSize;
|
||||
|
||||
memset( entry, 0, sizeof( *entry ) );
|
||||
|
||||
DPRINT("TdiGetMibForIpEntity(tcpFile %x,entityId %x)\n",
|
||||
(DWORD)tcpFile, ent->tei_instance);
|
||||
|
||||
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = IP_MIB_STATS_ID;
|
||||
req.ID.toi_entity = *ent;
|
||||
|
||||
status = DeviceIoControl( tcpFile,
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX,
|
||||
&req,
|
||||
sizeof(req),
|
||||
entry,
|
||||
sizeof(*entry),
|
||||
&returnSize,
|
||||
NULL );
|
||||
|
||||
DPRINT("TdiGetMibForIpEntity() => {\n"
|
||||
" ipsi_forwarding ............ %d\n"
|
||||
" ipsi_defaultttl ............ %d\n"
|
||||
" ipsi_inreceives ............ %d\n"
|
||||
" ipsi_indelivers ............ %d\n"
|
||||
" ipsi_outrequests ........... %d\n"
|
||||
" ipsi_routingdiscards ....... %d\n"
|
||||
" ipsi_outdiscards ........... %d\n"
|
||||
" ipsi_outnoroutes ........... %d\n"
|
||||
" ipsi_numif ................. %d\n"
|
||||
" ipsi_numaddr ............... %d\n"
|
||||
" ipsi_numroutes ............. %d\n"
|
||||
"} status %08x\n",
|
||||
entry->ipsi_forwarding,
|
||||
entry->ipsi_defaultttl,
|
||||
entry->ipsi_inreceives,
|
||||
entry->ipsi_indelivers,
|
||||
entry->ipsi_outrequests,
|
||||
entry->ipsi_routingdiscards,
|
||||
entry->ipsi_outdiscards,
|
||||
entry->ipsi_outnoroutes,
|
||||
entry->ipsi_numif,
|
||||
entry->ipsi_numaddr,
|
||||
entry->ipsi_numroutes,
|
||||
status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS tdiGetRoutesForIpEntity
|
||||
( HANDLE tcpFile, TDIEntityID *ent, int numRoutes, IPRouteEntry *routes ) {
|
||||
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
DWORD returnSize;
|
||||
|
||||
DPRINT("TdiGetRoutesForIpEntity(tcpFile %x,entityId %x)\n",
|
||||
(DWORD)tcpFile, ent->tei_instance);
|
||||
|
||||
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||
req.ID.toi_id = IP_MIB_ROUTETABLE_ENTRY_ID;
|
||||
req.ID.toi_entity = *ent;
|
||||
|
||||
status = DeviceIoControl( tcpFile,
|
||||
IOCTL_TCP_QUERY_INFORMATION_EX,
|
||||
&req,
|
||||
sizeof(req),
|
||||
routes,
|
||||
sizeof(*routes) * numRoutes,
|
||||
&returnSize,
|
||||
NULL );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
|
||||
{
|
||||
if (!name)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
if (!entry)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
DWORD getInterfaceStatsByIndex(DWORD index, PMIB_IFROW entry)
|
||||
{
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
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, DWORD family)
|
||||
{
|
||||
if (!stats)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
DWORD getTCPStats(MIB_TCPSTATS *stats, DWORD family)
|
||||
{
|
||||
if (!stats)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
DWORD getUDPStats(MIB_UDPSTATS *stats, DWORD family)
|
||||
{
|
||||
if (!stats)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static DWORD getNumWithOneHeader(const char *filename)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD getNumRoutes(void)
|
||||
{
|
||||
DWORD numEntities, numRoutes = 0;
|
||||
TDIEntityID *entitySet;
|
||||
HANDLE tcpFile;
|
||||
int i;
|
||||
NTSTATUS status;
|
||||
|
||||
TRACE("called.\n");
|
||||
|
||||
status = openTcpFile( &tcpFile );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
TRACE("failure: %08x\n", (int)status );
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
|
||||
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
TRACE("failure: %08x\n", (int)status );
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 0; i < numEntities; i++ ) {
|
||||
if( isIpEntity( tcpFile, &entitySet[i] ) ) {
|
||||
IPSNMPInfo isnmp;
|
||||
memset( &isnmp, 0, sizeof( isnmp ) );
|
||||
status = tdiGetMibForIpEntity( tcpFile, &entitySet[i], &isnmp );
|
||||
if( !NT_SUCCESS(status) ) {
|
||||
tdiFreeThingSet( entitySet );
|
||||
return status;
|
||||
}
|
||||
numRoutes += isnmp.ipsi_numroutes;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("numRoutes: %d\n", (int)numRoutes);
|
||||
|
||||
closeTcpFile( tcpFile );
|
||||
|
||||
return numRoutes;
|
||||
}
|
||||
|
||||
VOID HexDump( PCHAR Data, DWORD Len ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; i < Len; i++ ) {
|
||||
if( !(i & 0xf) ) {
|
||||
if( i ) fprintf(stderr,"\n");
|
||||
fprintf(stderr,"%08x:", i);
|
||||
}
|
||||
fprintf( stderr, " %02x", Data[i] & 0xff );
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
|
||||
RouteTable *getRouteTable(void)
|
||||
{
|
||||
RouteTable *out_route_table;
|
||||
DWORD numRoutes = getNumRoutes(), routesAdded = 0;
|
||||
IPSNMPInfo snmpInfo;
|
||||
TDIEntityID ent;
|
||||
HANDLE tcpFile;
|
||||
NTSTATUS status = openTcpFile( &tcpFile );
|
||||
int i;
|
||||
|
||||
if( !NT_SUCCESS(status) )
|
||||
return 0;
|
||||
|
||||
out_route_table = HeapAlloc( GetProcessHeap(), 0,
|
||||
sizeof(RouteTable) +
|
||||
(sizeof(RouteEntry) * (numRoutes - 1)) );
|
||||
|
||||
out_route_table->numRoutes = numRoutes;
|
||||
|
||||
for( i = 0; routesAdded < numRoutes; i++ ) {
|
||||
int j;
|
||||
IPRouteEntry *route_set;
|
||||
|
||||
getNthIpEntity( tcpFile, i, &ent );
|
||||
tdiGetMibForIpEntity( tcpFile, &ent, &snmpInfo );
|
||||
route_set = HeapAlloc( GetProcessHeap(), 0,
|
||||
sizeof( IPRouteEntry ) *
|
||||
snmpInfo.ipsi_numroutes );
|
||||
|
||||
DPRINT( "%d routes in instance %d\n", snmpInfo.ipsi_numroutes, i );
|
||||
|
||||
if( !route_set ) {
|
||||
closeTcpFile( tcpFile );
|
||||
HeapFree( GetProcessHeap(), 0, out_route_table );
|
||||
return 0;
|
||||
}
|
||||
|
||||
tdiGetRoutesForIpEntity( tcpFile, &ent, numRoutes, route_set );
|
||||
|
||||
DPRINT("Route set returned\n");
|
||||
#if 0
|
||||
HexDump( route_set,
|
||||
sizeof( IPRouteEntry ) *
|
||||
snmpInfo.ipsi_numroutes );
|
||||
#endif
|
||||
|
||||
for( j = 0; j < snmpInfo.ipsi_numroutes; j++ ) {
|
||||
int routeNum = j + routesAdded;
|
||||
out_route_table->routes[routeNum].dest =
|
||||
route_set[j].ire_dest;
|
||||
out_route_table->routes[routeNum].mask =
|
||||
route_set[j].ire_mask;
|
||||
out_route_table->routes[routeNum].gateway =
|
||||
route_set[j].ire_gw;
|
||||
out_route_table->routes[routeNum].ifIndex =
|
||||
route_set[j].ire_index;
|
||||
out_route_table->routes[routeNum].metric =
|
||||
route_set[j].ire_metric;
|
||||
}
|
||||
|
||||
routesAdded += snmpInfo.ipsi_numroutes;
|
||||
}
|
||||
|
||||
return out_route_table;
|
||||
}
|
||||
|
||||
DWORD getNumArpEntries(void)
|
||||
{
|
||||
return getNumWithOneHeader("/proc/net/arp");
|
||||
}
|
||||
|
||||
PMIB_IPNETTABLE getArpTable(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -8,11 +8,13 @@ TARGET_NAME = iphlpapi
|
|||
|
||||
TARGET_BASE = 0x777c0000
|
||||
|
||||
TARGET_CFLAGS = -DUNICODE -D_UNICODE -D__USE_W32API -Wall -Werror
|
||||
TARGET_CFLAGS += -DYDEBUG -DUNICODE -D_UNICODE -D__USE_W32API -D__REACTOS__ -D_WIN32_WINNT=0x0500 -Wall
|
||||
#-Werror
|
||||
|
||||
TARGET_SDKLIBS = ntdll.a kernel32.a
|
||||
TARGET_SDKLIBS = ntdll.a kernel32.a ws2_32.a
|
||||
|
||||
TARGET_OBJECTS = $(TARGET_NAME).o registry.o
|
||||
TARGET_OBJECTS = iphlpapi_main.o icmp.o iphlpv6.o media.o registry.o \
|
||||
ifenum_reactos.o ipstats_reactos.o resinfo_reactos.o
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
|
|
59
reactos/lib/iphlpapi/media.c
Normal file
59
reactos/lib/iphlpapi/media.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
# include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
# include <resolv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __REACTOS__
|
||||
# include <windows.h>
|
||||
# include <windef.h>
|
||||
# include <winbase.h>
|
||||
# include <net/miniport.h>
|
||||
# include <winsock2.h>
|
||||
# include <nspapi.h>
|
||||
# include <iptypes.h>
|
||||
# include "iphlpapiextra.h"
|
||||
#else
|
||||
# include "windef.h"
|
||||
# include "winbase.h"
|
||||
# include "winreg.h"
|
||||
#endif
|
||||
|
||||
#include "iphlpapi.h"
|
||||
#include "ifenum.h"
|
||||
#include "ipstats.h"
|
||||
#include "iphlp_res.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD STDCALL DisableMediaSense(HANDLE *pHandle,OVERLAPPED *pOverLapped)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD STDCALL RestoreMediaSense(OVERLAPPED* pOverlapped,LPDWORD lpdwEnableCount)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return 0L;
|
||||
}
|
||||
|
36
reactos/lib/iphlpapi/merge-notes.txt
Normal file
36
reactos/lib/iphlpapi/merge-notes.txt
Normal file
|
@ -0,0 +1,36 @@
|
|||
GetAdaptersInfo --
|
||||
Wine uses: Software\\Wine\\Wine\\Config\\Network
|
||||
-- Wins support is todo so this part isn't so important.
|
||||
-- Overall, workable
|
||||
Wine uses ansi functions
|
||||
GetNetworkParams --
|
||||
-- Make workable interface for _res
|
||||
-- Wine based on real _res
|
||||
-- Reactos based on my enumerator funcs
|
||||
|
||||
ROUTE PRINT:
|
||||
|
||||
iphlpapi_main.c:137 - ppIfTable 0104bd80, bOrder 1, heap 0xa0000000, flags 0x00000001
|
||||
- AllocateAndGetIfTableFromStack
|
||||
iphlpapi_main.c:898 - pIfTable 0104bd00, pdwSize 0104bd00, bOrder 1
|
||||
- GetIfTable
|
||||
(tcpip/main.c:168)(TiCreateFileObject) No EA information in IRP.
|
||||
- We need a special case of no EA information to handle these ioctls in
|
||||
tcpip.sys
|
||||
iphlpapi_main.c:939 - returning 122
|
||||
iphlpapi_main.c:898 - pIfTable 0104bd00, pdwSize 0104bd00, bOrder 1
|
||||
- GetIfTable again
|
||||
(tcpip/main.c:168)(TiCreateFileObject) No EA information in IRP.
|
||||
(tcpip/main.c:168)(TiCreateFileObject) No EA information in IRP.
|
||||
getInterfaceIndexTable: numInterfaces: 0
|
||||
iphlpapi_main.c:939 - returning 0
|
||||
iphlpapi_main.c:149 - returning 0
|
||||
iphlpapi_main.c:213 - ppIpForwardTable 0104bd78, bOrder 1, heap 0xa0000000, flags 0x00000001
|
||||
- AllocateAndGetIpForwardTableFromStack
|
||||
iphlpapi_main.c:1151 - pIpForwardTable 00000000, pdwSize 0104bd00, bOrder 1
|
||||
- GetIpForwardTable
|
||||
iphlpapi_main.c:1214 - returning 122
|
||||
iphlpapi_main.c:1151 - pIpForwardTable a0001d68, pdwSize 0104bd00, bOrder 1
|
||||
- GetIpForwardTable again
|
||||
iphlpapi_main.c:1214 - returning 122
|
||||
iphlpapi_main.c:225 - returning 122
|
|
@ -10,7 +10,7 @@ int GetLongestChildKeyName( HANDLE RegHandle ) {
|
|||
LONG Status;
|
||||
DWORD MaxAdapterName;
|
||||
|
||||
Status = RegQueryInfoKeyW(RegHandle,
|
||||
Status = RegQueryInfoKeyA(RegHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -29,9 +29,9 @@ int GetLongestChildKeyName( HANDLE RegHandle ) {
|
|||
}
|
||||
|
||||
LONG OpenChildKeyRead( HANDLE RegHandle,
|
||||
PWCHAR ChildKeyName,
|
||||
PCHAR ChildKeyName,
|
||||
PHKEY ReturnHandle ) {
|
||||
return RegOpenKeyExW( RegHandle,
|
||||
return RegOpenKeyExA( RegHandle,
|
||||
ChildKeyName,
|
||||
0,
|
||||
KEY_READ,
|
||||
|
@ -42,10 +42,10 @@ LONG OpenChildKeyRead( HANDLE RegHandle,
|
|||
* Yields a malloced value that must be freed.
|
||||
*/
|
||||
|
||||
PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ) {
|
||||
PCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ) {
|
||||
LONG Status;
|
||||
int MaxAdapterName = GetLongestChildKeyName( RegHandle );
|
||||
PWCHAR Value;
|
||||
PCHAR Value;
|
||||
DWORD ValueLen;
|
||||
|
||||
if (MaxAdapterName == -1) {
|
||||
|
@ -54,8 +54,8 @@ PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ) {
|
|||
}
|
||||
|
||||
ValueLen = MaxAdapterName;
|
||||
Value = (PWCHAR)malloc( MaxAdapterName * sizeof(WCHAR) );
|
||||
Status = RegEnumKeyExW( RegHandle, n, Value, &ValueLen,
|
||||
Value = (PCHAR)HeapAlloc( GetProcessHeap(), 0, MaxAdapterName );
|
||||
Status = RegEnumKeyExA( RegHandle, n, Value, &ValueLen,
|
||||
NULL, NULL, NULL, NULL );
|
||||
if (Status != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
@ -65,27 +65,27 @@ PWCHAR GetNthChildKeyName( HANDLE RegHandle, DWORD n ) {
|
|||
}
|
||||
}
|
||||
|
||||
void ConsumeChildKeyName( PWCHAR Name ) {
|
||||
if (Name) free( Name );
|
||||
void ConsumeChildKeyName( PCHAR Name ) {
|
||||
if (Name) HeapFree( GetProcessHeap(), 0, Name );
|
||||
}
|
||||
|
||||
PWCHAR QueryRegistryValueString( HANDLE RegHandle, PWCHAR ValueName ) {
|
||||
PWCHAR Name;
|
||||
PCHAR QueryRegistryValueString( HANDLE RegHandle, PCHAR ValueName ) {
|
||||
PCHAR Name;
|
||||
DWORD ReturnedSize = 0;
|
||||
|
||||
if (RegQueryValueExW( RegHandle, ValueName, NULL, NULL, NULL,
|
||||
if (RegQueryValueExA( RegHandle, ValueName, NULL, NULL, NULL,
|
||||
&ReturnedSize ) != 0)
|
||||
return 0;
|
||||
else {
|
||||
Name = malloc( (ReturnedSize + 1) * sizeof(WCHAR) );
|
||||
RegQueryValueExW( RegHandle, ValueName, NULL, NULL, (PVOID)Name,
|
||||
RegQueryValueExA( RegHandle, ValueName, NULL, NULL, (PVOID)Name,
|
||||
&ReturnedSize );
|
||||
Name[ReturnedSize] = 0;
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
|
||||
void ConsumeRegValueString( PWCHAR Value ) {
|
||||
void ConsumeRegValueString( PCHAR Value ) {
|
||||
if (Value) free(Value);
|
||||
}
|
||||
|
||||
|
@ -93,8 +93,8 @@ PWCHAR *QueryRegistryValueStringMulti( HANDLE RegHandle, PWCHAR ValueName ) {
|
|||
return 0; /* FIXME if needed */
|
||||
}
|
||||
|
||||
void ConsumeRegValueStringMulti( PWCHAR *Value ) {
|
||||
PWCHAR *Orig = Value;
|
||||
void ConsumeRegValueStringMulti( PCHAR *Value ) {
|
||||
PCHAR *Orig = Value;
|
||||
if (Value) {
|
||||
while (*Value) {
|
||||
free(*Value);
|
||||
|
|
52
reactos/lib/iphlpapi/resinfo_reactos.c
Normal file
52
reactos/lib/iphlpapi/resinfo_reactos.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_NAMESER_H
|
||||
# include <arpa/nameser.h>
|
||||
#endif
|
||||
#ifdef HAVE_RESOLV_H
|
||||
# include <resolv.h>
|
||||
#endif
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
|
||||
#ifdef __REACTOS__
|
||||
# include <net/miniport.h> /* ULONGLONG */
|
||||
# include <winsock2.h> /* Enables NSPAPI */
|
||||
# include <nspapi.h> /* SOCKET_ADDRESS */
|
||||
# include <iptypes.h> /* IP_ADAPTER_ADDRESSES */
|
||||
#endif
|
||||
|
||||
#include "iphlpapi.h"
|
||||
#include "ifenum.h"
|
||||
#include "ipstats.h"
|
||||
#include "iphlp_res.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
PIPHLP_RES_INFO getResInfo() {
|
||||
PIPHLP_RES_INFO InfoPtr =
|
||||
(PIPHLP_RES_INFO)HeapAlloc( GetProcessHeap(), 0,
|
||||
sizeof(PIPHLP_RES_INFO) );
|
||||
if( InfoPtr ) {
|
||||
InfoPtr->riCount = 0;
|
||||
InfoPtr->riAddressList = (LPSOCKADDR)0;
|
||||
}
|
||||
|
||||
return InfoPtr;
|
||||
}
|
||||
|
||||
VOID disposeResInfo( PIPHLP_RES_INFO InfoPtr ) {
|
||||
HeapFree( GetProcessHeap(), 0, InfoPtr );
|
||||
}
|
Loading…
Reference in a new issue