2004-02-15 07:17:00 +00:00
|
|
|
/* 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)
|
|
|
|
*/
|
2004-02-25 07:41:50 +00:00
|
|
|
#include "iphlpapi_private.h"
|
2004-02-15 07:17:00 +00:00
|
|
|
#include "ifenum.h"
|
2005-06-20 21:49:00 +00:00
|
|
|
#include <assert.h>
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2006-09-22 08:10:11 +00:00
|
|
|
//#define NDEBUG
|
2005-06-20 21:49:00 +00:00
|
|
|
#include "debug.h"
|
2005-06-20 20:20:40 +00:00
|
|
|
|
2004-02-15 07:17:00 +00:00
|
|
|
/* Globals */
|
|
|
|
const PWCHAR TcpFileName = L"\\Device\\Tcp";
|
|
|
|
|
|
|
|
/* Functions */
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
/* I'm a bit skittish about maintaining this info in memory, as I'd rather
|
|
|
|
* not add any mutex or critical section blockers to these functions. I've
|
|
|
|
* encountered far too many windows functions that contribute to deadlock
|
|
|
|
* by not announcing themselves. */
|
2004-02-15 07:17:00 +00:00
|
|
|
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,
|
2004-02-25 20:29:15 +00:00
|
|
|
&fileName,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2004-02-25 21:41:31 +00:00
|
|
|
status = ZwCreateFile( tcpFile,
|
2005-04-17 08:00:01 +00:00
|
|
|
SYNCHRONIZE | GENERIC_EXECUTE |
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
2004-02-25 20:29:15 +00:00
|
|
|
&objectAttributes,
|
|
|
|
&ioStatusBlock,
|
|
|
|
NULL,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
FILE_OPEN_IF,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT,
|
|
|
|
0,
|
|
|
|
0 );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
/* String does not need to be freed: it points to the constant
|
|
|
|
* string we provided */
|
|
|
|
|
2005-11-27 11:29:07 +00:00
|
|
|
if (!NT_SUCCESS(status)) {
|
|
|
|
DPRINT1("openTcpFile for <%wZ> failed: 0x%lx\n", &fileName, status);
|
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
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,
|
2004-02-25 20:29:15 +00:00
|
|
|
DWORD toiClass,
|
|
|
|
DWORD toiType,
|
|
|
|
DWORD toiId,
|
|
|
|
DWORD teiEntity,
|
2006-09-22 08:10:11 +00:00
|
|
|
DWORD teiInstance,
|
2004-02-25 20:29:15 +00:00
|
|
|
DWORD fixedPart,
|
|
|
|
DWORD entrySize,
|
|
|
|
PVOID *tdiEntitySet,
|
|
|
|
PDWORD numEntries ) {
|
2004-02-15 07:17:00 +00:00
|
|
|
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
|
|
|
PVOID entitySet = 0;
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
DWORD allocationSizeForEntityArray = entrySize * MAX_TDI_ENTITIES,
|
2004-02-25 20:29:15 +00:00
|
|
|
arraySize = entrySize * MAX_TDI_ENTITIES;
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2005-05-24 21:04:44 +00:00
|
|
|
TRACE("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 );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
req.ID.toi_class = toiClass;
|
|
|
|
req.ID.toi_type = toiType;
|
|
|
|
req.ID.toi_id = toiId;
|
|
|
|
req.ID.toi_entity.tei_entity = teiEntity;
|
2006-09-22 08:10:11 +00:00
|
|
|
req.ID.toi_entity.tei_instance = teiInstance;
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
/* 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 {
|
2005-06-20 21:49:00 +00:00
|
|
|
assert( !entitySet ); /* We must not have an entity set allocated */
|
2004-02-25 20:29:15 +00:00
|
|
|
status = DeviceIoControl( tcpFile,
|
|
|
|
IOCTL_TCP_QUERY_INFORMATION_EX,
|
|
|
|
&req,
|
|
|
|
sizeof(req),
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&allocationSizeForEntityArray,
|
|
|
|
NULL );
|
2004-11-26 00:32:59 +00:00
|
|
|
|
2006-09-22 08:10:11 +00:00
|
|
|
if(!NT_SUCCESS(status))
|
2005-09-23 03:50:03 +00:00
|
|
|
{
|
|
|
|
DPRINT("IOCTL Failed\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
2004-02-25 20:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2005-09-23 03:50:03 +00:00
|
|
|
if(!status)
|
|
|
|
{
|
|
|
|
DPRINT("IOCTL Failed\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
2004-02-25 20:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("TdiGetSetOfThings(): Array changed size: %d -> %d.\n",
|
|
|
|
arraySize, allocationSizeForEntityArray );
|
2004-02-15 07:17:00 +00:00
|
|
|
} while( TRUE ); /* We break if the array we received was the size we
|
2004-02-25 20:29:15 +00:00
|
|
|
* expected. Therefore, we got here because it wasn't */
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
*numEntries = (arraySize - fixedPart) / entrySize;
|
|
|
|
*tdiEntitySet = entitySet;
|
|
|
|
|
|
|
|
DPRINT("TdiGetSetOfThings() => Success: %d things @ %08x\n",
|
2004-02-25 20:29:15 +00:00
|
|
|
(int)*numEntries, (int)entitySet);
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID tdiFreeThingSet( PVOID things ) {
|
|
|
|
HeapFree( GetProcessHeap(), 0, things );
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS tdiGetMibForIfEntity
|
2004-02-25 07:41:50 +00:00
|
|
|
( HANDLE tcpFile, TDIEntityID *ent, IFEntrySafelySized *entry ) {
|
2004-02-15 07:17:00 +00:00
|
|
|
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
DWORD returnSize;
|
|
|
|
|
|
|
|
DPRINT("TdiGetMibForIfEntity(tcpFile %x,entityId %x)\n",
|
2004-02-25 20:29:15 +00:00
|
|
|
(int)tcpFile, (int)ent->tei_instance);
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
|
|
|
req.ID.toi_type = INFO_TYPE_PROVIDER;
|
|
|
|
req.ID.toi_id = IF_MIB_STATS_ID;
|
2004-02-25 07:41:50 +00:00
|
|
|
req.ID.toi_entity = *ent;
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
status = DeviceIoControl( tcpFile,
|
2004-02-25 20:29:15 +00:00
|
|
|
IOCTL_TCP_QUERY_INFORMATION_EX,
|
|
|
|
&req,
|
|
|
|
sizeof(req),
|
|
|
|
entry,
|
|
|
|
sizeof(*entry),
|
|
|
|
&returnSize,
|
|
|
|
NULL );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2005-09-23 03:50:03 +00:00
|
|
|
if(!status)
|
|
|
|
{
|
|
|
|
DPRINT("IOCTL Failed\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
DPRINT("TdiGetMibForIfEntity() => {\n"
|
2004-02-25 20:29:15 +00:00
|
|
|
" if_index ....................... %x\n"
|
|
|
|
" if_type ........................ %x\n"
|
|
|
|
" if_mtu ......................... %d\n"
|
|
|
|
" if_speed ....................... %x\n"
|
|
|
|
" if_physaddrlen ................. %d\n",
|
|
|
|
entry->ent.if_index,
|
|
|
|
entry->ent.if_type,
|
|
|
|
entry->ent.if_mtu,
|
|
|
|
entry->ent.if_speed,
|
|
|
|
entry->ent.if_physaddrlen);
|
2006-06-21 03:30:54 +00:00
|
|
|
DPRINT(" if_physaddr .................... %02x:%02x:%02x:%02x:%02x:%02x\n"
|
2004-02-25 20:29:15 +00:00
|
|
|
" if_descr ....................... %s\n",
|
|
|
|
entry->ent.if_physaddr[0] & 0xff,
|
|
|
|
entry->ent.if_physaddr[1] & 0xff,
|
|
|
|
entry->ent.if_physaddr[2] & 0xff,
|
|
|
|
entry->ent.if_physaddr[3] & 0xff,
|
|
|
|
entry->ent.if_physaddr[4] & 0xff,
|
|
|
|
entry->ent.if_physaddr[5] & 0xff,
|
|
|
|
entry->ent.if_descr);
|
2004-02-25 07:41:50 +00:00
|
|
|
DPRINT("} status %08x\n",status);
|
2004-02-25 20:29:15 +00:00
|
|
|
|
2004-02-15 07:17:00 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile,
|
2004-02-25 20:29:15 +00:00
|
|
|
TDIEntityID **entitySet,
|
|
|
|
PDWORD numEntities ) {
|
2004-02-15 07:17:00 +00:00
|
|
|
NTSTATUS status = tdiGetSetOfThings( tcpFile,
|
2004-02-25 20:29:15 +00:00
|
|
|
INFO_CLASS_GENERIC,
|
|
|
|
INFO_TYPE_PROVIDER,
|
|
|
|
ENTITY_LIST_ID,
|
|
|
|
GENERIC_ENTITY,
|
2006-09-22 08:10:11 +00:00
|
|
|
0,
|
2004-02-25 20:29:15 +00:00
|
|
|
0,
|
|
|
|
sizeof(TDIEntityID),
|
|
|
|
(PVOID *)entitySet,
|
|
|
|
numEntities );
|
2004-02-15 07:17:00 +00:00
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for( i = 0; i < *numEntities; i++ ) {
|
|
|
|
DPRINT("%-4d: %04x:%08x\n",
|
|
|
|
i,
|
|
|
|
(*entitySet)[i].tei_entity,
|
|
|
|
(*entitySet)[i].tei_instance );
|
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2006-09-22 08:10:11 +00:00
|
|
|
BOOL isInterface( TDIEntityID *if_maybe ) {
|
2004-02-15 07:17:00 +00:00
|
|
|
return
|
2004-02-25 20:29:15 +00:00
|
|
|
if_maybe->tei_entity == IF_ENTITY;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL isLoopback( HANDLE tcpFile, TDIEntityID *loop_maybe ) {
|
|
|
|
IFEntrySafelySized entryInfo;
|
2005-09-22 20:36:07 +00:00
|
|
|
NTSTATUS status;
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2005-09-22 20:36:07 +00:00
|
|
|
status = tdiGetMibForIfEntity( tcpFile,
|
|
|
|
loop_maybe,
|
|
|
|
&entryInfo );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2005-09-22 20:36:07 +00:00
|
|
|
return NT_SUCCESS(status) && (!entryInfo.ent.if_type ||
|
|
|
|
entryInfo.ent.if_type == IFENT_SOFTWARE_LOOPBACK);
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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",
|
2004-02-25 20:29:15 +00:00
|
|
|
(DWORD)tcpFile, ent->tei_instance);
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
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,
|
2004-02-25 20:29:15 +00:00
|
|
|
IOCTL_TCP_QUERY_INFORMATION_EX,
|
|
|
|
&req,
|
|
|
|
sizeof(req),
|
|
|
|
type,
|
|
|
|
sizeof(*type),
|
|
|
|
&returnSize,
|
|
|
|
NULL );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
DPRINT("TdiGetEntityType() => %08x %08x\n", *type, status);
|
|
|
|
|
2005-09-23 03:50:03 +00:00
|
|
|
return (status ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2006-09-22 08:10:11 +00:00
|
|
|
BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ) {
|
|
|
|
TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
DWORD returnSize, type;
|
|
|
|
|
|
|
|
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 = AT_ENTITY;
|
|
|
|
req.ID.toi_entity.tei_instance = arp_maybe->tei_instance;
|
|
|
|
|
|
|
|
status = DeviceIoControl( tcpFile,
|
|
|
|
IOCTL_TCP_QUERY_INFORMATION_EX,
|
|
|
|
&req,
|
|
|
|
sizeof(req),
|
|
|
|
&type,
|
|
|
|
sizeof(type),
|
|
|
|
&returnSize,
|
|
|
|
NULL );
|
|
|
|
|
|
|
|
if( !NT_SUCCESS(status) ) return FALSE;
|
|
|
|
return type == AT_ENTITY;
|
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
|
2004-02-25 20:29:15 +00:00
|
|
|
IFInfo **infoSet,
|
|
|
|
PDWORD numInterfaces ) {
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD numEntities;
|
|
|
|
TDIEntityID *entIDSet = 0;
|
|
|
|
NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entIDSet, &numEntities );
|
|
|
|
IFInfo *infoSetInt = 0;
|
|
|
|
BOOL interfaceInfoComplete;
|
|
|
|
int curInterf = 0, i;
|
|
|
|
|
2005-11-27 11:29:07 +00:00
|
|
|
if (!NT_SUCCESS(status)) {
|
|
|
|
DPRINT1("getInterfaceInfoSet: tdiGetEntityIDSet() failed: 0x%lx\n", status);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
infoSetInt = HeapAlloc( GetProcessHeap(), 0,
|
|
|
|
sizeof(IFInfo) * numEntities );
|
2004-02-25 07:41:50 +00:00
|
|
|
|
|
|
|
if( infoSetInt ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
for( i = 0; i < numEntities; i++ ) {
|
|
|
|
if( isInterface( &entIDSet[i] ) ) {
|
2005-09-25 04:55:16 +00:00
|
|
|
infoSetInt[curInterf].entity_id = entIDSet[i];
|
2004-02-25 20:29:15 +00:00
|
|
|
status = tdiGetMibForIfEntity
|
|
|
|
( tcpFile,
|
|
|
|
&entIDSet[i],
|
|
|
|
&infoSetInt[curInterf].if_info );
|
2004-03-05 04:50:01 +00:00
|
|
|
DPRINT("tdiGetMibForIfEntity: %08x\n", status);
|
2004-02-25 20:29:15 +00:00
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
DWORD numAddrs;
|
|
|
|
IPAddrEntry *addrs;
|
|
|
|
TDIEntityID ip_ent;
|
2005-07-13 02:02:08 +00:00
|
|
|
int j;
|
2004-02-25 20:29:15 +00:00
|
|
|
|
|
|
|
interfaceInfoComplete = FALSE;
|
2004-03-05 04:50:01 +00:00
|
|
|
status = getNthIpEntity( tcpFile, 0, &ip_ent );
|
|
|
|
if( NT_SUCCESS(status) )
|
|
|
|
status = tdiGetIpAddrsForIpEntity
|
|
|
|
( tcpFile, &ip_ent, &addrs, &numAddrs );
|
2005-07-13 02:02:08 +00:00
|
|
|
for( j = 0; j < numAddrs && NT_SUCCESS(status); j++ ) {
|
|
|
|
DPRINT("ADDR %d: index %d (target %d)\n", j, addrs[j].iae_index, infoSetInt[curInterf].if_info.ent.if_index);
|
|
|
|
if( addrs[j].iae_index ==
|
2004-03-05 04:50:01 +00:00
|
|
|
infoSetInt[curInterf].if_info.ent.if_index ) {
|
|
|
|
memcpy( &infoSetInt[curInterf].ip_addr,
|
2005-07-13 02:02:08 +00:00
|
|
|
&addrs[j],
|
|
|
|
sizeof( addrs[j] ) );
|
2004-03-05 04:50:01 +00:00
|
|
|
curInterf++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-02-25 20:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
|
2005-09-22 20:36:07 +00:00
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
*infoSet = infoSetInt;
|
|
|
|
*numInterfaces = curInterf;
|
|
|
|
} else {
|
|
|
|
HeapFree(GetProcessHeap(), 0, infoSetInt);
|
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
|
2005-09-22 20:36:07 +00:00
|
|
|
return status;
|
|
|
|
} else {
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
}
|
|
|
|
|
2004-06-21 02:21:16 +00:00
|
|
|
static DWORD getNumInterfacesInt(BOOL onlyNonLoopback)
|
2004-02-15 07:17:00 +00:00
|
|
|
{
|
|
|
|
DWORD numEntities, numInterfaces = 0;
|
|
|
|
TDIEntityID *entitySet;
|
|
|
|
HANDLE tcpFile;
|
|
|
|
NTSTATUS status;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
status = openTcpFile( &tcpFile );
|
|
|
|
|
|
|
|
if( !NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
DPRINT("getNumInterfaces: failed %08x\n", status );
|
|
|
|
return 0;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
|
|
|
|
|
|
|
|
if( !NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
DPRINT("getNumInterfaces: failed %08x\n", status );
|
|
|
|
return 0;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for( i = 0; i < numEntities; i++ ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
if( isInterface( &entitySet[i] ) &&
|
2004-06-21 02:21:16 +00:00
|
|
|
(!onlyNonLoopback ||
|
|
|
|
(onlyNonLoopback && !isLoopback( tcpFile, &entitySet[i] ))) )
|
2004-02-25 20:29:15 +00:00
|
|
|
numInterfaces++;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("getNumInterfaces: success: %d %d %08x\n",
|
2005-04-08 17:24:30 +00:00
|
|
|
onlyNonLoopback, numInterfaces, status );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2005-09-23 03:50:03 +00:00
|
|
|
closeTcpFile( tcpFile );
|
|
|
|
|
2004-02-15 07:17:00 +00:00
|
|
|
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) )
|
2004-02-25 20:29:15 +00:00
|
|
|
return status;
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
for( i = 0; i < numEntities; i++ ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
if( isInterface( &entitySet[i] ) ) {
|
|
|
|
if( numInterfaces == index ) break;
|
|
|
|
else numInterfaces++;
|
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Index %d is entity #%d - %04x:%08x\n", index, i,
|
2004-02-25 20:29:15 +00:00
|
|
|
entitySet[i].tei_entity, entitySet[i].tei_instance );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
if( numInterfaces == index && i < numEntities ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
memcpy( ent, &entitySet[i], sizeof(*ent) );
|
|
|
|
tdiFreeThingSet( entitySet );
|
|
|
|
return STATUS_SUCCESS;
|
2004-02-15 07:17:00 +00:00
|
|
|
} else {
|
2004-02-25 20:29:15 +00:00
|
|
|
tdiFreeThingSet( entitySet );
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
|
|
|
|
NTSTATUS getInterfaceInfoByIndex( HANDLE tcpFile, DWORD index, IFInfo *info ) {
|
|
|
|
IFInfo *ifInfo;
|
|
|
|
DWORD numInterfaces;
|
|
|
|
NTSTATUS status = getInterfaceInfoSet( tcpFile, &ifInfo, &numInterfaces );
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) )
|
2004-02-25 20:29:15 +00:00
|
|
|
for( i = 0; i < numInterfaces; i++ ) {
|
|
|
|
if( ifInfo[i].if_info.ent.if_index == index ) {
|
|
|
|
memcpy( info, &ifInfo[i], sizeof(*info) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
|
|
|
|
if( NT_SUCCESS(status) )
|
2004-02-25 20:29:15 +00:00
|
|
|
return i < numInterfaces ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
2004-02-25 07:41:50 +00:00
|
|
|
else
|
2004-02-25 20:29:15 +00:00
|
|
|
return status;
|
2004-02-25 07:41:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS getInterfaceInfoByName( HANDLE tcpFile, char *name, IFInfo *info ) {
|
|
|
|
IFInfo *ifInfo;
|
|
|
|
DWORD numInterfaces;
|
|
|
|
int i;
|
|
|
|
NTSTATUS status = getInterfaceInfoSet( tcpFile, &ifInfo, &numInterfaces );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) )
|
2004-02-25 20:29:15 +00:00
|
|
|
for( i = 0; i < numInterfaces; i++ ) {
|
|
|
|
if( !strcmp(ifInfo[i].if_info.ent.if_descr, name) ) {
|
|
|
|
memcpy( info, &ifInfo[i], sizeof(*info) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
|
|
|
|
if( NT_SUCCESS(status) )
|
2004-02-25 20:29:15 +00:00
|
|
|
return i < numInterfaces ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
2004-02-25 07:41:50 +00:00
|
|
|
else
|
2004-02-25 20:29:15 +00:00
|
|
|
return status;
|
2004-02-25 07:41:50 +00:00
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
/* Note that the result of this operation must be freed later */
|
|
|
|
|
|
|
|
const char *getInterfaceNameByIndex(DWORD index)
|
|
|
|
{
|
2004-02-25 07:41:50 +00:00
|
|
|
IFInfo ifInfo;
|
|
|
|
HANDLE tcpFile;
|
|
|
|
char *interfaceName = 0, *adapter_name = 0;
|
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
status = getInterfaceInfoByIndex( tcpFile, index, &ifInfo );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
adapter_name = ifInfo.if_info.ent.if_descr;
|
|
|
|
|
|
|
|
interfaceName = HeapAlloc( GetProcessHeap(), 0,
|
|
|
|
strlen(adapter_name) + 1 );
|
|
|
|
strcpy( interfaceName, adapter_name );
|
|
|
|
|
|
|
|
closeTcpFile( tcpFile );
|
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return interfaceName;
|
|
|
|
}
|
|
|
|
|
|
|
|
void consumeInterfaceName(const char *name) {
|
|
|
|
HeapFree( GetProcessHeap(), 0, (char *)name );
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfaceIndexByName(const char *name, PDWORD index)
|
|
|
|
{
|
2004-02-25 07:41:50 +00:00
|
|
|
IFInfo ifInfo;
|
2004-02-15 07:17:00 +00:00
|
|
|
HANDLE tcpFile;
|
2004-02-25 07:41:50 +00:00
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
status = getInterfaceInfoByName( tcpFile, (char *)name, &ifInfo );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
*index = ifInfo.if_info.ent.if_index;
|
|
|
|
closeTcpFile( tcpFile );
|
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
return status;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
InterfaceIndexTable *getInterfaceIndexTableInt( BOOL nonLoopbackOnly ) {
|
|
|
|
DWORD numInterfaces, curInterface = 0;
|
|
|
|
int i;
|
2004-02-25 07:41:50 +00:00
|
|
|
IFInfo *ifInfo;
|
|
|
|
InterfaceIndexTable *ret = 0;
|
|
|
|
HANDLE tcpFile;
|
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
status = getInterfaceInfoSet( tcpFile, &ifInfo, &numInterfaces );
|
|
|
|
|
2004-03-05 04:50:01 +00:00
|
|
|
DPRINT("InterfaceInfoSet: %08x, %04x:%08x\n",
|
|
|
|
status,
|
|
|
|
ifInfo->entity_id.tei_entity,
|
|
|
|
ifInfo->entity_id.tei_instance);
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
ret = (InterfaceIndexTable *)
|
|
|
|
calloc(1,
|
|
|
|
sizeof(InterfaceIndexTable) +
|
|
|
|
(numInterfaces - 1) * sizeof(DWORD));
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
ret->numAllocated = numInterfaces;
|
2004-03-05 04:50:01 +00:00
|
|
|
DPRINT("NumInterfaces = %d\n", numInterfaces);
|
2004-02-25 20:29:15 +00:00
|
|
|
|
|
|
|
for( i = 0; i < numInterfaces; i++ ) {
|
2004-03-05 04:50:01 +00:00
|
|
|
DPRINT("Examining interface %d\n", i);
|
2004-02-25 20:29:15 +00:00
|
|
|
if( !nonLoopbackOnly ||
|
|
|
|
!isLoopback( tcpFile, &ifInfo[i].entity_id ) ) {
|
2004-03-05 04:50:01 +00:00
|
|
|
DPRINT("Interface %d matches (%d)\n", i, curInterface);
|
2004-02-25 20:29:15 +00:00
|
|
|
ret->indexes[curInterface++] =
|
|
|
|
ifInfo[i].if_info.ent.if_index;
|
|
|
|
}
|
2004-03-05 04:50:01 +00:00
|
|
|
}
|
2004-02-25 20:29:15 +00:00
|
|
|
|
|
|
|
ret->numIndexes = curInterface;
|
|
|
|
}
|
|
|
|
|
|
|
|
tdiFreeThingSet( ifInfo );
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
closeTcpFile( tcpFile );
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
2004-02-25 20:29:15 +00:00
|
|
|
|
2004-02-15 07:17:00 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
InterfaceIndexTable *getInterfaceIndexTable(void) {
|
|
|
|
return getInterfaceIndexTableInt( FALSE );
|
|
|
|
}
|
|
|
|
|
|
|
|
InterfaceIndexTable *getNonLoopbackInterfaceIndexTable(void) {
|
|
|
|
return getInterfaceIndexTableInt( TRUE );
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfaceIPAddrByName(const char *name)
|
|
|
|
{
|
|
|
|
return INADDR_ANY;
|
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
NTSTATUS getIPAddrEntryForIf(HANDLE tcpFile,
|
2004-02-25 20:29:15 +00:00
|
|
|
char *name,
|
|
|
|
DWORD index,
|
|
|
|
IFInfo *ifInfo) {
|
2004-02-25 07:41:50 +00:00
|
|
|
NTSTATUS status =
|
2004-02-25 20:29:15 +00:00
|
|
|
name ?
|
|
|
|
getInterfaceInfoByName( tcpFile, name, ifInfo ) :
|
|
|
|
getInterfaceInfoByIndex( tcpFile, index, ifInfo );
|
2005-11-27 11:29:07 +00:00
|
|
|
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
|
|
DPRINT1("getIPAddrEntryForIf returning %lx\n", status);
|
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
return status;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD getAddrByIndexOrName( char *name, DWORD index, IPHLPAddrType addrType ) {
|
|
|
|
IFInfo ifInfo;
|
|
|
|
HANDLE tcpFile = INVALID_HANDLE_VALUE;
|
|
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
|
|
DWORD addrOut = INADDR_ANY;
|
|
|
|
|
|
|
|
status = openTcpFile( &tcpFile );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
status = getIPAddrEntryForIf( tcpFile, name, index, &ifInfo );
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
switch( addrType ) {
|
|
|
|
case IPAAddr: addrOut = ifInfo.ip_addr.iae_addr; break;
|
|
|
|
case IPABcast: addrOut = ifInfo.ip_addr.iae_bcastaddr; break;
|
|
|
|
case IPAMask: addrOut = ifInfo.ip_addr.iae_mask; break;
|
|
|
|
case IFMtu: addrOut = ifInfo.if_info.ent.if_mtu; break;
|
|
|
|
case IFStatus: addrOut = ifInfo.if_info.ent.if_operstatus; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closeTcpFile( &tcpFile );
|
2004-02-25 07:41:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return addrOut;
|
2004-02-25 20:29:15 +00:00
|
|
|
}
|
2004-02-25 07:41:50 +00:00
|
|
|
|
|
|
|
DWORD getInterfaceIPAddrByIndex(DWORD index) {
|
|
|
|
return getAddrByIndexOrName( 0, index, IPAAddr );
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD getInterfaceBCastAddrByName(const char *name) {
|
|
|
|
return getAddrByIndexOrName( (char *)name, 0, IPABcast );
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD getInterfaceBCastAddrByIndex(DWORD index) {
|
|
|
|
return getAddrByIndexOrName( 0, index, IPABcast );
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD getInterfaceMaskByName(const char *name) {
|
|
|
|
return getAddrByIndexOrName( (char *)name, 0, IPAMask );
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfaceMaskByIndex(DWORD index) {
|
|
|
|
return getAddrByIndexOrName( 0, index, IPAMask );
|
|
|
|
}
|
|
|
|
|
|
|
|
void getInterfacePhysicalFromInfo( IFInfo *info,
|
2004-02-25 20:29:15 +00:00
|
|
|
PDWORD len, PBYTE addr, PDWORD type ) {
|
2004-02-25 07:41:50 +00:00
|
|
|
*len = info->if_info.ent.if_physaddrlen;
|
|
|
|
memcpy( addr, info->if_info.ent.if_physaddr, *len );
|
|
|
|
*type = info->if_info.ent.if_type;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfacePhysicalByName(const char *name, PDWORD len, PBYTE addr,
|
2004-02-25 20:29:15 +00:00
|
|
|
PDWORD type)
|
2004-02-15 07:17:00 +00:00
|
|
|
{
|
2004-02-25 07:41:50 +00:00
|
|
|
HANDLE tcpFile;
|
|
|
|
IFInfo info;
|
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
status = getInterfaceInfoByName( tcpFile, (char *)name, &info );
|
|
|
|
if( NT_SUCCESS(status) )
|
|
|
|
getInterfacePhysicalFromInfo( &info, len, addr, type );
|
|
|
|
closeTcpFile( tcpFile );
|
2004-02-25 07:41:50 +00:00
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
return status;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfacePhysicalByIndex(DWORD index, PDWORD len, PBYTE addr,
|
|
|
|
PDWORD type)
|
|
|
|
{
|
2004-02-25 07:41:50 +00:00
|
|
|
HANDLE tcpFile;
|
|
|
|
IFInfo info;
|
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
status = getInterfaceInfoByIndex( tcpFile, index, &info );
|
|
|
|
if( NT_SUCCESS(status) )
|
|
|
|
getInterfacePhysicalFromInfo( &info, len, addr, type );
|
|
|
|
closeTcpFile( tcpFile );
|
2004-02-25 07:41:50 +00:00
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
return status;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD getInterfaceMtuByName(const char *name, PDWORD mtu) {
|
|
|
|
*mtu = getAddrByIndexOrName( (char *)name, 0, IFMtu );
|
|
|
|
return STATUS_SUCCESS;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD getInterfaceMtuByIndex(DWORD index, PDWORD mtu) {
|
|
|
|
*mtu = getAddrByIndexOrName( 0, index, IFMtu );
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2004-02-15 07:17:00 +00:00
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
DWORD getInterfaceStatusByName(const char *name, PDWORD status) {
|
|
|
|
*status = getAddrByIndexOrName( (char *)name, 0, IFStatus );
|
|
|
|
return STATUS_SUCCESS;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfaceStatusByIndex(DWORD index, PDWORD status)
|
|
|
|
{
|
2004-02-25 07:41:50 +00:00
|
|
|
*status = getAddrByIndexOrName( 0, index, IFStatus );
|
|
|
|
return STATUS_SUCCESS;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfaceEntryByName(const char *name, PMIB_IFROW entry)
|
|
|
|
{
|
2004-02-25 07:41:50 +00:00
|
|
|
HANDLE tcpFile;
|
|
|
|
IFInfo info;
|
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
|
|
|
|
|
|
|
DPRINT("Called.\n");
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
status = getInterfaceInfoByName( tcpFile, (char *)name, &info );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
memcpy( &entry->wszName[MAX_INTERFACE_NAME_LEN],
|
|
|
|
&info.if_info,
|
|
|
|
sizeof(info.if_info) );
|
|
|
|
}
|
|
|
|
|
2005-09-25 04:55:16 +00:00
|
|
|
DPRINT("entry->bDescr = %s\n", entry->bDescr);
|
2005-03-24 10:46:52 +00:00
|
|
|
|
2004-02-25 20:29:15 +00:00
|
|
|
closeTcpFile( tcpFile );
|
2004-02-25 07:41:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DWORD getInterfaceEntryByIndex(DWORD index, PMIB_IFROW entry)
|
|
|
|
{
|
|
|
|
HANDLE tcpFile;
|
2004-02-25 07:41:50 +00:00
|
|
|
IFInfo info;
|
2004-02-15 07:17:00 +00:00
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
|
|
|
|
|
|
|
DPRINT("Called.\n");
|
|
|
|
|
2004-02-25 07:41:50 +00:00
|
|
|
if( NT_SUCCESS(status) ) {
|
2004-02-25 20:29:15 +00:00
|
|
|
status = getInterfaceInfoByIndex( tcpFile, index, &info );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
memcpy( &entry->wszName[MAX_INTERFACE_NAME_LEN],
|
|
|
|
&info.if_info,
|
|
|
|
sizeof(info.if_info) );
|
|
|
|
}
|
|
|
|
|
|
|
|
closeTcpFile( tcpFile );
|
2004-02-15 07:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2005-03-24 10:46:52 +00:00
|
|
|
|
|
|
|
NTSTATUS addIPAddress( IPAddr Address, IPMask Mask, DWORD IfIndex,
|
|
|
|
PULONG NteContext, PULONG NteInstance )
|
|
|
|
{
|
|
|
|
HANDLE tcpFile;
|
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
|
|
|
IP_SET_DATA Data;
|
|
|
|
IO_STATUS_BLOCK Iosb;
|
|
|
|
|
|
|
|
DPRINT("Called.\n");
|
|
|
|
|
|
|
|
if( !NT_SUCCESS(status) ) return status;
|
|
|
|
|
|
|
|
Data.NteContext = IfIndex;
|
|
|
|
Data.NewAddress = Address;
|
|
|
|
Data.NewNetmask = Mask;
|
|
|
|
|
|
|
|
status = NtDeviceIoControlFile( tcpFile,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&Iosb,
|
|
|
|
IOCTL_SET_IP_ADDRESS,
|
|
|
|
&Data,
|
|
|
|
sizeof(Data),
|
|
|
|
&Data,
|
|
|
|
sizeof(Data) );
|
|
|
|
|
|
|
|
closeTcpFile( tcpFile );
|
|
|
|
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
|
|
*NteContext = Iosb.Information;
|
|
|
|
*NteInstance = Data.NewAddress;
|
|
|
|
}
|
|
|
|
|
2005-11-27 11:29:07 +00:00
|
|
|
if (!NT_SUCCESS(status)) {
|
|
|
|
DPRINT1("addIPAddress for if %d returning 0x%lx\n", IfIndex, status);
|
|
|
|
}
|
|
|
|
|
2005-11-27 12:28:45 +00:00
|
|
|
return status;
|
|
|
|
|
2005-03-24 10:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS deleteIpAddress( ULONG NteContext )
|
|
|
|
{
|
|
|
|
HANDLE tcpFile;
|
|
|
|
NTSTATUS status = openTcpFile( &tcpFile );
|
|
|
|
IO_STATUS_BLOCK Iosb;
|
|
|
|
|
|
|
|
DPRINT("Called.\n");
|
|
|
|
|
|
|
|
if( !NT_SUCCESS(status) ) return status;
|
|
|
|
|
|
|
|
status = NtDeviceIoControlFile( tcpFile,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&Iosb,
|
|
|
|
IOCTL_DELETE_IP_ADDRESS,
|
|
|
|
&NteContext,
|
|
|
|
sizeof(USHORT),
|
|
|
|
NULL,
|
|
|
|
0 );
|
|
|
|
|
|
|
|
closeTcpFile( tcpFile );
|
|
|
|
|
2005-11-27 11:29:07 +00:00
|
|
|
if (!NT_SUCCESS(status)) {
|
|
|
|
DPRINT1("deleteIpAddress(%lu) returning 0x%lx\n", NteContext, status);
|
|
|
|
}
|
|
|
|
|
2005-11-27 12:28:45 +00:00
|
|
|
return status;
|
2005-03-24 10:46:52 +00:00
|
|
|
}
|