mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 06:52:56 +00:00
- Rewrite IOCTL_TCP_QUERY_INFORMATION_EX/IOCTL_TCP_SET_INFORMATION_EX handling
- Remove duplicate defines for the same IOCTL - Remove unneeded code - Fix a completely wrong implementation of ENTITY_TYPE_ID - Perform parameter checking - Remove several hacks in iphlpapi that worked around bugs in the previous implementation - We now support retrieving interface-specific routing tables and ARP tables svn path=/trunk/; revision=43338
This commit is contained in:
parent
8a1b2b51be
commit
a3ab545150
10 changed files with 380 additions and 491 deletions
|
@ -323,36 +323,8 @@ BOOL isLoopback( HANDLE tcpFile, TDIEntityID *loop_maybe ) {
|
||||||
loop_maybe,
|
loop_maybe,
|
||||||
&entryInfo );
|
&entryInfo );
|
||||||
|
|
||||||
return NT_SUCCESS(status) && (!entryInfo.ent.if_type ||
|
return NT_SUCCESS(status) &&
|
||||||
entryInfo.ent.if_type == IFENT_SOFTWARE_LOOPBACK);
|
(entryInfo.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;
|
|
||||||
|
|
||||||
TRACE("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 );
|
|
||||||
|
|
||||||
TRACE("TdiGetEntityType() => %08x %08x\n", *type, status);
|
|
||||||
|
|
||||||
return (status ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ) {
|
BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ) {
|
||||||
|
@ -374,9 +346,9 @@ BOOL hasArp( HANDLE tcpFile, TDIEntityID *arp_maybe ) {
|
||||||
sizeof(type),
|
sizeof(type),
|
||||||
&returnSize,
|
&returnSize,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if( !NT_SUCCESS(status) ) return FALSE;
|
if( !NT_SUCCESS(status) ) return FALSE;
|
||||||
return type == AT_ENTITY;
|
|
||||||
|
return (type & AT_ARP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
|
static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
|
||||||
|
@ -386,7 +358,6 @@ static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
|
||||||
TDIEntityID *entIDSet = 0;
|
TDIEntityID *entIDSet = 0;
|
||||||
NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entIDSet, &numEntities );
|
NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entIDSet, &numEntities );
|
||||||
IFInfo *infoSetInt = 0;
|
IFInfo *infoSetInt = 0;
|
||||||
BOOL interfaceInfoComplete;
|
|
||||||
int curInterf = 0, i;
|
int curInterf = 0, i;
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS(status)) {
|
||||||
|
@ -412,8 +383,7 @@ static NTSTATUS getInterfaceInfoSet( HANDLE tcpFile,
|
||||||
TDIEntityID ip_ent;
|
TDIEntityID ip_ent;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
interfaceInfoComplete = FALSE;
|
status = getNthIpEntity( tcpFile, curInterf, &ip_ent );
|
||||||
status = getNthIpEntity( tcpFile, 0, &ip_ent );
|
|
||||||
if( NT_SUCCESS(status) )
|
if( NT_SUCCESS(status) )
|
||||||
status = tdiGetIpAddrsForIpEntity
|
status = tdiGetIpAddrsForIpEntity
|
||||||
( tcpFile, &ip_ent, &addrs, &numAddrs );
|
( tcpFile, &ip_ent, &addrs, &numAddrs );
|
||||||
|
|
|
@ -60,8 +60,6 @@
|
||||||
#define TCP_REQUEST_QUERY_INFORMATION_INIT { { { 0 } } }
|
#define TCP_REQUEST_QUERY_INFORMATION_INIT { { { 0 } } }
|
||||||
#define TCP_REQUEST_SET_INFORMATION_INIT { { 0 } }
|
#define TCP_REQUEST_SET_INFORMATION_INIT { { 0 } }
|
||||||
|
|
||||||
#define IP_MIB_ROUTETABLE_ENTRY_ID 0x101
|
|
||||||
|
|
||||||
// As in the mib from RFC 1213
|
// As in the mib from RFC 1213
|
||||||
|
|
||||||
typedef struct _IPRouteEntry {
|
typedef struct _IPRouteEntry {
|
||||||
|
|
|
@ -62,30 +62,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BOOL isIpEntity( HANDLE tcpFile, TDIEntityID *ent ) {
|
BOOL isIpEntity( HANDLE tcpFile, TDIEntityID *ent ) {
|
||||||
DWORD entityType, returnedLen;
|
return (ent->tei_entity == CL_NL_ENTITY ||
|
||||||
NTSTATUS status;
|
ent->tei_entity == CO_NL_ENTITY);
|
||||||
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 );
|
|
||||||
|
|
||||||
TRACE("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 ) {
|
NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent ) {
|
||||||
|
@ -182,9 +160,9 @@ NTSTATUS tdiGetRoutesForIpEntity
|
||||||
status = tdiGetSetOfThings( tcpFile,
|
status = tdiGetSetOfThings( tcpFile,
|
||||||
INFO_CLASS_PROTOCOL,
|
INFO_CLASS_PROTOCOL,
|
||||||
INFO_TYPE_PROVIDER,
|
INFO_TYPE_PROVIDER,
|
||||||
IP_MIB_ROUTETABLE_ENTRY_ID,
|
IP_MIB_ARPTABLE_ENTRY_ID,
|
||||||
ent->tei_entity,
|
CL_NL_ENTITY,
|
||||||
0,
|
ent->tei_instance,
|
||||||
0,
|
0,
|
||||||
sizeof(IPRouteEntry),
|
sizeof(IPRouteEntry),
|
||||||
(PVOID *)routes,
|
(PVOID *)routes,
|
||||||
|
@ -204,8 +182,8 @@ NTSTATUS tdiGetIpAddrsForIpEntity
|
||||||
INFO_CLASS_PROTOCOL,
|
INFO_CLASS_PROTOCOL,
|
||||||
INFO_TYPE_PROVIDER,
|
INFO_TYPE_PROVIDER,
|
||||||
IP_MIB_ADDRTABLE_ENTRY_ID,
|
IP_MIB_ADDRTABLE_ENTRY_ID,
|
||||||
ent->tei_entity,
|
CL_NL_ENTITY,
|
||||||
0,
|
ent->tei_instance,
|
||||||
0,
|
0,
|
||||||
sizeof(IPAddrEntry),
|
sizeof(IPAddrEntry),
|
||||||
(PVOID *)addrs,
|
(PVOID *)addrs,
|
||||||
|
|
|
@ -69,8 +69,9 @@ DWORD createIpForwardEntry( PMIB_IPFORWARDROW pRoute ) {
|
||||||
if( NT_SUCCESS(status) ) {
|
if( NT_SUCCESS(status) ) {
|
||||||
req.Req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
req.Req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||||
req.Req.ID.toi_type = INFO_TYPE_PROVIDER;
|
req.Req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||||
req.Req.ID.toi_id = IP_MIB_ROUTETABLE_ENTRY_ID;
|
req.Req.ID.toi_id = IP_MIB_ARPTABLE_ENTRY_ID;
|
||||||
req.Req.ID.toi_entity = id;
|
req.Req.ID.toi_entity.tei_instance = id.tei_instance;
|
||||||
|
req.Req.ID.toi_entity.tei_instance = CL_NL_ENTITY;
|
||||||
req.Req.BufferSize = sizeof(*rte);
|
req.Req.BufferSize = sizeof(*rte);
|
||||||
rte =
|
rte =
|
||||||
(IPRouteEntry *)&req.Req.Buffer[0];
|
(IPRouteEntry *)&req.Req.Buffer[0];
|
||||||
|
@ -133,8 +134,9 @@ DWORD deleteIpForwardEntry( PMIB_IPFORWARDROW pRoute ) {
|
||||||
if( NT_SUCCESS(status) ) {
|
if( NT_SUCCESS(status) ) {
|
||||||
req.Req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
req.Req.ID.toi_class = INFO_CLASS_PROTOCOL;
|
||||||
req.Req.ID.toi_type = INFO_TYPE_PROVIDER;
|
req.Req.ID.toi_type = INFO_TYPE_PROVIDER;
|
||||||
req.Req.ID.toi_id = IP_MIB_ROUTETABLE_ENTRY_ID;
|
req.Req.ID.toi_id = IP_MIB_ARPTABLE_ENTRY_ID;
|
||||||
req.Req.ID.toi_entity = id;
|
req.Req.ID.toi_entity.tei_instance = id.tei_instance;
|
||||||
|
req.Req.ID.toi_entity.tei_entity = CL_NL_ENTITY;
|
||||||
req.Req.BufferSize = sizeof(*rte);
|
req.Req.BufferSize = sizeof(*rte);
|
||||||
rte =
|
rte =
|
||||||
(IPRouteEntry *)&req.Req.Buffer[0];
|
(IPRouteEntry *)&req.Req.Buffer[0];
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#ifndef __INFO_H
|
#ifndef __INFO_H
|
||||||
#define __INFO_H
|
#define __INFO_H
|
||||||
|
|
||||||
|
#include <tcpioctl.h>
|
||||||
|
|
||||||
#define MAX_PHYSADDR_LEN 8
|
#define MAX_PHYSADDR_LEN 8
|
||||||
#define MAX_IFDESCR_LEN 256
|
#define MAX_IFDESCR_LEN 256
|
||||||
|
|
||||||
|
@ -100,23 +102,6 @@ typedef struct IFENTRY {
|
||||||
ULONG DescrLen;
|
ULONG DescrLen;
|
||||||
} IFENTRY, *PIFENTRY;
|
} IFENTRY, *PIFENTRY;
|
||||||
|
|
||||||
#define IP_MIB_STATS_ID 1
|
|
||||||
#define IF_MIB_STATS_ID 1
|
|
||||||
|
|
||||||
#ifndef IP_MIB_ROUTETABLE_ENTRY_ID
|
|
||||||
#define IP_MIB_ROUTETABLE_ENTRY_ID 0x101
|
|
||||||
#endif
|
|
||||||
#ifndef IP_MIB_ADDRTABLE_ENTRY_ID
|
|
||||||
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
|
|
||||||
#endif
|
|
||||||
#ifndef IP_MIB_ARPTABLE_ENTRY_ID
|
|
||||||
#define IP_MIB_ARPTABLE_ENTRY_ID 0x101
|
|
||||||
#endif
|
|
||||||
#ifndef MAX_PHYSADDR_SIZE
|
|
||||||
#define MAX_PHYSADDR_SIZE 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Only UDP is supported */
|
/* Only UDP is supported */
|
||||||
#define TDI_SERVICE_FLAGS (TDI_SERVICE_CONNECTIONLESS_MODE | \
|
#define TDI_SERVICE_FLAGS (TDI_SERVICE_CONNECTIONLESS_MODE | \
|
||||||
TDI_SERVICE_BROADCAST_SUPPORTED)
|
TDI_SERVICE_BROADCAST_SUPPORTED)
|
||||||
|
@ -157,54 +142,28 @@ TDI_STATUS InfoTdiSetInformationEx(
|
||||||
PVOID Buffer,
|
PVOID Buffer,
|
||||||
UINT BufferSize);
|
UINT BufferSize);
|
||||||
|
|
||||||
/* Network layer info functions */
|
TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID,
|
||||||
TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PNDIS_BUFFER Buffer,
|
|
||||||
PUINT BufferSize );
|
|
||||||
|
|
||||||
TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PCHAR Buffer,
|
|
||||||
UINT BufferSize );
|
|
||||||
|
|
||||||
TDI_STATUS InfoTransportLayerTdiQueryEx( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PNDIS_BUFFER Buffer,
|
|
||||||
PUINT BufferSize );
|
|
||||||
|
|
||||||
TDI_STATUS InfoTransportLayerTdiSetEx( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PCHAR Buffer,
|
|
||||||
UINT BufferSize );
|
|
||||||
|
|
||||||
TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PNDIS_BUFFER Buffer,
|
PNDIS_BUFFER Buffer,
|
||||||
PUINT BufferSize );
|
PUINT BufferSize);
|
||||||
|
|
||||||
TDI_STATUS InfoInterfaceTdiSetEx( UINT InfoClass,
|
TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID,
|
||||||
UINT InfoType,
|
PIP_INTERFACE Interface,
|
||||||
UINT InfoId,
|
PNDIS_BUFFER Buffer,
|
||||||
PVOID Context,
|
PUINT BufferSize);
|
||||||
TDIEntityID *id,
|
|
||||||
PCHAR Buffer,
|
TDI_STATUS InfoTdiQueryGetIPSnmpInfo( TDIEntityID ID,
|
||||||
UINT BufferSize );
|
PNDIS_BUFFER Buffer,
|
||||||
|
PUINT BufferSize );
|
||||||
|
|
||||||
|
TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer,
|
||||||
|
PUINT BufferSize );
|
||||||
|
|
||||||
|
TDI_STATUS InfoTdiSetRoute(PIPROUTE_ENTRY Route);
|
||||||
|
|
||||||
|
TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID,
|
||||||
|
PIP_INTERFACE Interface,
|
||||||
|
PNDIS_BUFFER Buffer,
|
||||||
|
PUINT BufferSize);
|
||||||
|
|
||||||
/* Insert and remove interface entities */
|
/* Insert and remove interface entities */
|
||||||
VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface );
|
VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface );
|
||||||
|
|
|
@ -149,29 +149,12 @@ struct sockaddr
|
||||||
char sa_data[14];
|
char sa_data[14];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TDI_STATUS (*InfoRequest_f)( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PNDIS_BUFFER Buffer,
|
|
||||||
PUINT BufferSize );
|
|
||||||
|
|
||||||
typedef TDI_STATUS (*InfoSet_f)( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PCHAR Buffer,
|
|
||||||
UINT BufferSize );
|
|
||||||
|
|
||||||
/* Sufficient information to manage the entity list */
|
/* Sufficient information to manage the entity list */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT tei_entity;
|
UINT tei_entity;
|
||||||
UINT tei_instance;
|
UINT tei_instance;
|
||||||
PVOID context;
|
PVOID context;
|
||||||
InfoRequest_f info_req;
|
UINT flags;
|
||||||
InfoSet_f info_set;
|
|
||||||
} TDIEntityInfo;
|
} TDIEntityInfo;
|
||||||
|
|
||||||
#ifndef htons
|
#ifndef htons
|
||||||
|
|
|
@ -10,21 +10,26 @@
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
|
||||||
TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID,
|
TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID,
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
PNDIS_BUFFER Buffer,
|
PNDIS_BUFFER Buffer,
|
||||||
PUINT BufferSize) {
|
PUINT BufferSize) {
|
||||||
TDI_STATUS Status = TDI_INVALID_REQUEST;
|
TDI_STATUS Status = TDI_INVALID_REQUEST;
|
||||||
PIFENTRY OutData;
|
PIFENTRY OutData;
|
||||||
PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
|
PLAN_ADAPTER IF;
|
||||||
PCHAR IFDescr;
|
PCHAR IFDescr;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
UINT DescrLenMax = MAX_IFDESCR_LEN - 1;
|
UINT DescrLenMax = MAX_IFDESCR_LEN - 1;
|
||||||
NDIS_STATUS NdisStatus;
|
NDIS_STATUS NdisStatus;
|
||||||
|
|
||||||
|
if (!Interface)
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
IF = (PLAN_ADAPTER)Interface->Context;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO,
|
TI_DbgPrint(DEBUG_INFO,
|
||||||
("Getting IFEntry MIB (IF %08x LA %08x) (%04x:%d)\n",
|
("Getting IFEntry MIB (IF %08x LA %08x) (%04x:%d)\n",
|
||||||
Interface, IF, ID->tei_entity, ID->tei_instance));
|
Interface, IF, ID.tei_entity, ID.tei_instance));
|
||||||
|
|
||||||
OutData =
|
OutData =
|
||||||
(PIFENTRY)exAllocatePool( NonPagedPool,
|
(PIFENTRY)exAllocatePool( NonPagedPool,
|
||||||
|
@ -91,7 +96,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID,
|
||||||
Size = IFDescr - (PCHAR)OutData + 1;
|
Size = IFDescr - (PCHAR)OutData + 1;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO, ("Finished IFEntry MIB (%04x:%d) size %d\n",
|
TI_DbgPrint(DEBUG_INFO, ("Finished IFEntry MIB (%04x:%d) size %d\n",
|
||||||
ID->tei_entity, ID->tei_instance, Size));
|
ID.tei_entity, ID.tei_instance, Size));
|
||||||
|
|
||||||
Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize );
|
Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize );
|
||||||
exFreePool( OutData );
|
exFreePool( OutData );
|
||||||
|
@ -101,7 +106,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID *ID,
|
TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID,
|
||||||
PIP_INTERFACE Interface,
|
PIP_INTERFACE Interface,
|
||||||
PNDIS_BUFFER Buffer,
|
PNDIS_BUFFER Buffer,
|
||||||
PUINT BufferSize) {
|
PUINT BufferSize) {
|
||||||
|
@ -122,58 +127,106 @@ TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID *ID,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoTdiQueryGetArpCapability(TDIEntityID *ID,
|
VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) {
|
||||||
PIP_INTERFACE Interface,
|
KIRQL OldIrql;
|
||||||
PNDIS_BUFFER Buffer,
|
UINT IFCount = 0, CLNLCount = 0, CLTLCount = 0, COTLCount = 0, ATCount = 0, ERCount = 0, i;
|
||||||
PUINT BufferSize) {
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG Capability = 0x280;
|
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("Copying out %d bytes (AT_ENTITY capability)\n",
|
TI_DbgPrint(DEBUG_INFO,
|
||||||
sizeof(Capability)));
|
("Inserting interface %08x (%d entities already)\n",
|
||||||
Status = InfoCopyOut
|
Interface, EntityCount));
|
||||||
( (PVOID)&Capability, sizeof(Capability), Buffer, BufferSize );
|
|
||||||
|
|
||||||
return Status;
|
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
|
||||||
|
|
||||||
|
/* Count IP Entities */
|
||||||
|
for( i = 0; i < EntityCount; i++ )
|
||||||
|
switch( EntityList[i].tei_entity )
|
||||||
|
{
|
||||||
|
case IF_ENTITY:
|
||||||
|
IFCount++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CL_NL_ENTITY:
|
||||||
|
CLNLCount++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CL_TL_ENTITY:
|
||||||
|
CLTLCount++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CO_TL_ENTITY:
|
||||||
|
COTLCount++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AT_ENTITY:
|
||||||
|
ATCount++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ER_ENTITY:
|
||||||
|
ERCount++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityList[EntityCount].tei_entity = IF_ENTITY;
|
||||||
|
EntityList[EntityCount].tei_instance = IFCount;
|
||||||
|
EntityList[EntityCount].context = Interface;
|
||||||
|
EntityList[EntityCount].flags = IF_MIB;
|
||||||
|
EntityCount++;
|
||||||
|
EntityList[EntityCount].tei_entity = CL_NL_ENTITY;
|
||||||
|
EntityList[EntityCount].tei_instance = CLNLCount;
|
||||||
|
EntityList[EntityCount].context = Interface;
|
||||||
|
EntityList[EntityCount].flags = CL_NL_IP;
|
||||||
|
EntityCount++;
|
||||||
|
EntityList[EntityCount].tei_entity = CL_TL_ENTITY;
|
||||||
|
EntityList[EntityCount].tei_instance = CLTLCount;
|
||||||
|
EntityList[EntityCount].context = Interface;
|
||||||
|
EntityList[EntityCount].flags = CL_TL_UDP;
|
||||||
|
EntityCount++;
|
||||||
|
EntityList[EntityCount].tei_entity = CO_TL_ENTITY;
|
||||||
|
EntityList[EntityCount].tei_instance = COTLCount;
|
||||||
|
EntityList[EntityCount].context = Interface;
|
||||||
|
EntityList[EntityCount].flags = CO_TL_TCP;
|
||||||
|
EntityCount++;
|
||||||
|
EntityList[EntityCount].tei_entity = ER_ENTITY;
|
||||||
|
EntityList[EntityCount].tei_instance = ERCount;
|
||||||
|
EntityList[EntityCount].context = Interface;
|
||||||
|
EntityList[EntityCount].flags = ER_ICMP;
|
||||||
|
EntityCount++;
|
||||||
|
EntityList[EntityCount].tei_entity = AT_ENTITY;
|
||||||
|
EntityList[EntityCount].tei_instance = ATCount;
|
||||||
|
EntityList[EntityCount].context = Interface;
|
||||||
|
EntityList[EntityCount].flags = AT_ARP;
|
||||||
|
EntityCount++;
|
||||||
|
|
||||||
|
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass,
|
VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
|
||||||
UINT InfoType,
|
KIRQL OldIrql;
|
||||||
UINT InfoId,
|
UINT i;
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
TI_DbgPrint(DEBUG_INFO,("Removing TDI entry 0x%x\n", Interface));
|
||||||
PNDIS_BUFFER Buffer,
|
|
||||||
PUINT BufferSize ) {
|
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
|
||||||
if( InfoClass == INFO_CLASS_GENERIC &&
|
|
||||||
InfoType == INFO_TYPE_PROVIDER &&
|
/* Remove entities that have this interface as context
|
||||||
InfoId == ENTITY_TYPE_ID &&
|
* In the future, this might include AT_ENTITY types, too
|
||||||
id->tei_entity == AT_ENTITY ) {
|
*/
|
||||||
return InfoTdiQueryGetArpCapability( id, Context, Buffer, BufferSize );
|
for( i = 0; i < EntityCount; i++ ) {
|
||||||
} else if( InfoClass == INFO_CLASS_PROTOCOL &&
|
TI_DbgPrint(DEBUG_INFO,("--> examining TDI entry 0x%x\n", EntityList[i].context));
|
||||||
InfoType == INFO_TYPE_PROVIDER &&
|
if( EntityList[i].context == Interface ) {
|
||||||
InfoId == IF_MIB_STATS_ID ) {
|
if( i != EntityCount-1 ) {
|
||||||
return InfoTdiQueryGetInterfaceMIB( id, Context, Buffer, BufferSize );
|
memcpy( &EntityList[i],
|
||||||
} else if( InfoClass == INFO_CLASS_GENERIC &&
|
&EntityList[--EntityCount],
|
||||||
InfoType == INFO_TYPE_PROVIDER &&
|
sizeof(EntityList[i]) );
|
||||||
InfoId == ENTITY_TYPE_ID ) {
|
} else {
|
||||||
ULONG Temp = IF_MIB;
|
EntityCount--;
|
||||||
return InfoCopyOut( (PCHAR)&Temp, sizeof(Temp), Buffer, BufferSize );
|
}
|
||||||
} else if( InfoClass == INFO_CLASS_PROTOCOL &&
|
}
|
||||||
InfoType == INFO_TYPE_PROVIDER &&
|
}
|
||||||
InfoId == IP_MIB_ARPTABLE_ENTRY_ID ) {
|
|
||||||
return InfoTdiQueryGetArptableMIB( id, Context, Buffer, BufferSize );
|
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
|
||||||
} else
|
|
||||||
return TDI_INVALID_REQUEST;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoInterfaceTdiSetEx( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PCHAR Buffer,
|
|
||||||
UINT BufferSize ) {
|
|
||||||
TI_DbgPrint(DEBUG_INFO, ("Got Request: Class %x Type %x Id %x, EntityID %x:%x\n",
|
|
||||||
InfoClass, InfoId, id->tei_entity, id->tei_instance));
|
|
||||||
return TDI_INVALID_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
|
@ -12,6 +12,35 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <route.h>
|
#include <route.h>
|
||||||
|
|
||||||
|
PVOID GetContext(TDIEntityID ID)
|
||||||
|
{
|
||||||
|
UINT i;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PVOID Context;
|
||||||
|
|
||||||
|
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
|
||||||
|
|
||||||
|
for (i = 0; i < EntityCount; i++)
|
||||||
|
{
|
||||||
|
if (EntityList[i].tei_entity == ID.tei_entity &&
|
||||||
|
EntityList[i].tei_instance == ID.tei_instance)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == EntityCount)
|
||||||
|
{
|
||||||
|
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
|
||||||
|
DbgPrint("WARNING: Unable to get context for %d %d\n", ID.tei_entity, ID.tei_instance);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context = EntityList[i].context;
|
||||||
|
|
||||||
|
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
|
||||||
|
|
||||||
|
return Context;
|
||||||
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut,
|
TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut,
|
||||||
PNDIS_BUFFER ClientBuf, PUINT ClientBufSize ) {
|
PNDIS_BUFFER ClientBuf, PUINT ClientBufSize ) {
|
||||||
UINT RememberedCBSize = *ClientBufSize;
|
UINT RememberedCBSize = *ClientBufSize;
|
||||||
|
@ -27,60 +56,38 @@ TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) {
|
TDI_STATUS InfoTdiQueryEntityType(TDIEntityID ID,
|
||||||
|
PNDIS_BUFFER Buffer,
|
||||||
|
PUINT BufferSize)
|
||||||
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
UINT Count = 0, i;
|
UINT i, Flags = 0;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO,
|
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
|
||||||
("Inserting interface %08x (%d entities already)\n",
|
|
||||||
Interface, EntityCount));
|
|
||||||
|
|
||||||
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
|
for (i = 0; i < EntityCount; i++)
|
||||||
|
{
|
||||||
/* Count IP Entities */
|
if (EntityList[i].tei_entity == ID.tei_entity &&
|
||||||
for( i = 0; i < EntityCount; i++ )
|
EntityList[i].tei_instance == ID.tei_instance)
|
||||||
if( EntityList[i].tei_entity == IF_ENTITY ) {
|
break;
|
||||||
Count++;
|
|
||||||
TI_DbgPrint(DEBUG_INFO, ("Entity %d is an IF. Found %d\n",
|
|
||||||
i, Count));
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityList[EntityCount].tei_entity = IF_ENTITY;
|
|
||||||
EntityList[EntityCount].tei_instance = Count;
|
|
||||||
EntityList[EntityCount].context = Interface;
|
|
||||||
EntityList[EntityCount].info_req = InfoInterfaceTdiQueryEx;
|
|
||||||
EntityList[EntityCount].info_set = InfoInterfaceTdiSetEx;
|
|
||||||
|
|
||||||
EntityCount++;
|
|
||||||
|
|
||||||
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
|
|
||||||
KIRQL OldIrql;
|
|
||||||
UINT i;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO,("Removing TDI entry 0x%x\n", Interface));
|
|
||||||
|
|
||||||
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
|
|
||||||
|
|
||||||
/* Remove entities that have this interface as context
|
|
||||||
* In the future, this might include AT_ENTITY types, too
|
|
||||||
*/
|
|
||||||
for( i = 0; i < EntityCount; i++ ) {
|
|
||||||
TI_DbgPrint(DEBUG_INFO,("--> examining TDI entry 0x%x\n", EntityList[i].context));
|
|
||||||
if( EntityList[i].context == Interface ) {
|
|
||||||
if( i != EntityCount-1 ) {
|
|
||||||
memcpy( &EntityList[i],
|
|
||||||
&EntityList[--EntityCount],
|
|
||||||
sizeof(EntityList[i]) );
|
|
||||||
} else {
|
|
||||||
EntityCount--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
|
if (i == EntityCount)
|
||||||
|
{
|
||||||
|
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flags = EntityList[i].flags;
|
||||||
|
|
||||||
|
InfoCopyOut((PCHAR)&Flags,
|
||||||
|
sizeof(ULONG),
|
||||||
|
Buffer,
|
||||||
|
BufferSize);
|
||||||
|
|
||||||
|
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
|
||||||
|
|
||||||
|
return TDI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
|
TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
|
||||||
|
@ -139,12 +146,7 @@ TDI_STATUS InfoTdiQueryInformationEx(
|
||||||
* Status of operation
|
* Status of operation
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
PVOID EntityListContext;
|
||||||
UINT i;
|
|
||||||
PVOID context = NULL;
|
|
||||||
NTSTATUS Status = TDI_INVALID_PARAMETER;
|
|
||||||
BOOLEAN FoundEntity = FALSE;
|
|
||||||
InfoRequest_f InfoRequest = NULL;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO,
|
TI_DbgPrint(DEBUG_INFO,
|
||||||
("InfoEx Req: %x %x %x!%04x:%d\n",
|
("InfoEx Req: %x %x %x!%04x:%d\n",
|
||||||
|
@ -154,79 +156,83 @@ TDI_STATUS InfoTdiQueryInformationEx(
|
||||||
ID->toi_entity.tei_entity,
|
ID->toi_entity.tei_entity,
|
||||||
ID->toi_entity.tei_instance));
|
ID->toi_entity.tei_instance));
|
||||||
|
|
||||||
/* Check wether it is a query for a list of entities */
|
switch (ID->toi_class)
|
||||||
if (ID->toi_entity.tei_entity == GENERIC_ENTITY)
|
|
||||||
{
|
{
|
||||||
if ((ID->toi_class != INFO_CLASS_GENERIC) ||
|
case INFO_CLASS_GENERIC:
|
||||||
(ID->toi_type != INFO_TYPE_PROVIDER) ||
|
switch (ID->toi_id)
|
||||||
(ID->toi_id != ENTITY_LIST_ID)) {
|
{
|
||||||
TI_DbgPrint(DEBUG_INFO,("Invalid parameter\n"));
|
case ENTITY_LIST_ID:
|
||||||
Status = TDI_INVALID_PARAMETER;
|
if (ID->toi_type != INFO_TYPE_PROVIDER)
|
||||||
} else
|
return TDI_INVALID_PARAMETER;
|
||||||
Status = InfoTdiQueryListEntities(Buffer, BufferSize);
|
|
||||||
} else if (ID->toi_entity.tei_entity == AT_ENTITY) {
|
|
||||||
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
|
|
||||||
|
|
||||||
for( i = 0; i < EntityCount; i++ ) {
|
return InfoTdiQueryListEntities(Buffer, BufferSize);
|
||||||
if( EntityList[i].tei_entity == IF_ENTITY &&
|
|
||||||
EntityList[i].tei_instance == ID->toi_entity.tei_instance ) {
|
|
||||||
InfoRequest = EntityList[i].info_req;
|
|
||||||
context = EntityList[i].context;
|
|
||||||
FoundEntity = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
|
case ENTITY_TYPE_ID:
|
||||||
|
if (ID->toi_type != INFO_TYPE_PROVIDER)
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
|
||||||
if( FoundEntity ) {
|
return InfoTdiQueryEntityType(ID->toi_entity, Buffer, BufferSize);
|
||||||
TI_DbgPrint(DEBUG_INFO,
|
|
||||||
("Calling AT Entity %d (%04x:%d) InfoEx (%x,%x,%x)\n",
|
|
||||||
i, ID->toi_entity.tei_entity,
|
|
||||||
ID->toi_entity.tei_instance,
|
|
||||||
ID->toi_class, ID->toi_type, ID->toi_id));
|
|
||||||
Status = InfoRequest( ID->toi_class,
|
|
||||||
ID->toi_type,
|
|
||||||
ID->toi_id,
|
|
||||||
context,
|
|
||||||
&ID->toi_entity,
|
|
||||||
Buffer,
|
|
||||||
BufferSize );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
|
|
||||||
|
|
||||||
for( i = 0; i < EntityCount; i++ ) {
|
default:
|
||||||
if( EntityList[i].tei_entity == ID->toi_entity.tei_entity &&
|
return TDI_INVALID_REQUEST;
|
||||||
EntityList[i].tei_instance == ID->toi_entity.tei_instance ) {
|
}
|
||||||
InfoRequest = EntityList[i].info_req;
|
|
||||||
context = EntityList[i].context;
|
|
||||||
FoundEntity = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
|
case INFO_CLASS_PROTOCOL:
|
||||||
|
switch (ID->toi_id)
|
||||||
|
{
|
||||||
|
case IF_MIB_STATS_ID:
|
||||||
|
if (ID->toi_entity.tei_entity == IF_ENTITY)
|
||||||
|
if ((EntityListContext = GetContext(ID->toi_entity)))
|
||||||
|
return InfoTdiQueryGetInterfaceMIB(ID->toi_entity, EntityListContext, Buffer, BufferSize);
|
||||||
|
else
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
else if (ID->toi_entity.tei_entity == CL_NL_ENTITY ||
|
||||||
|
ID->toi_entity.tei_entity == CO_NL_ENTITY)
|
||||||
|
return InfoTdiQueryGetIPSnmpInfo(ID->toi_entity, Buffer, BufferSize);
|
||||||
|
else
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
|
||||||
if( FoundEntity ) {
|
case IP_MIB_ADDRTABLE_ENTRY_ID:
|
||||||
TI_DbgPrint(DEBUG_INFO,
|
if (ID->toi_entity.tei_entity != CL_NL_ENTITY &&
|
||||||
("Calling Entity %d (%04x:%d) InfoEx (%x,%x,%x)\n",
|
ID->toi_entity.tei_entity != CO_NL_ENTITY)
|
||||||
i, ID->toi_entity.tei_entity,
|
return TDI_INVALID_PARAMETER;
|
||||||
ID->toi_entity.tei_instance,
|
|
||||||
ID->toi_class, ID->toi_type, ID->toi_id));
|
if (ID->toi_type != INFO_TYPE_PROVIDER)
|
||||||
Status = InfoRequest( ID->toi_class,
|
return TDI_INVALID_PARAMETER;
|
||||||
ID->toi_type,
|
|
||||||
ID->toi_id,
|
return InfoTdiQueryGetAddrTable(ID->toi_entity, Buffer, BufferSize);
|
||||||
context,
|
|
||||||
&ID->toi_entity,
|
case IP_MIB_ARPTABLE_ENTRY_ID:
|
||||||
Buffer,
|
if (ID->toi_type != INFO_TYPE_PROVIDER)
|
||||||
BufferSize );
|
return TDI_INVALID_PARAMETER;
|
||||||
}
|
|
||||||
|
if (ID->toi_entity.tei_entity == AT_ENTITY)
|
||||||
|
if ((EntityListContext = GetContext(ID->toi_entity)))
|
||||||
|
return InfoTdiQueryGetArptableMIB(ID->toi_entity, EntityListContext,
|
||||||
|
Buffer, BufferSize);
|
||||||
|
else
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
else if (ID->toi_entity.tei_entity == CO_NL_ENTITY ||
|
||||||
|
ID->toi_entity.tei_entity == CL_NL_ENTITY)
|
||||||
|
return InfoTdiQueryGetRouteTable(Buffer, BufferSize);
|
||||||
|
else
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
case IP_INTFC_INFO_ID:
|
||||||
|
if (ID->toi_type != INFO_TYPE_PROVIDER)
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return InfoTdiQueryGetIFInfo(Context, Buffer, BufferSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TDI_INVALID_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TDI_INVALID_REQUEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO,("Status: %08x\n", Status));
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoTdiSetInformationEx
|
TDI_STATUS InfoTdiSetInformationEx
|
||||||
|
@ -245,24 +251,26 @@ TDI_STATUS InfoTdiSetInformationEx
|
||||||
* Status of operation
|
* Status of operation
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
switch( ID->toi_class ) {
|
switch (ID->toi_class)
|
||||||
case INFO_CLASS_PROTOCOL:
|
{
|
||||||
switch( ID->toi_type ) {
|
case INFO_CLASS_PROTOCOL:
|
||||||
case INFO_TYPE_PROVIDER:
|
switch (ID->toi_id)
|
||||||
switch( ID->toi_id ) {
|
{
|
||||||
case IP_MIB_ROUTETABLE_ENTRY_ID:
|
case IP_MIB_ARPTABLE_ENTRY_ID:
|
||||||
return InfoNetworkLayerTdiSetEx
|
if (ID->toi_id != INFO_TYPE_PROVIDER)
|
||||||
( ID->toi_class,
|
return TDI_INVALID_PARAMETER;
|
||||||
ID->toi_type,
|
|
||||||
ID->toi_id,
|
|
||||||
NULL,
|
|
||||||
&ID->toi_entity,
|
|
||||||
Buffer,
|
|
||||||
BufferSize );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TDI_INVALID_PARAMETER;
|
if (ID->toi_entity.tei_entity != CL_NL_ENTITY &&
|
||||||
|
ID->toi_entity.tei_entity != CO_NL_ENTITY)
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return InfoTdiSetRoute((PIPROUTE_ENTRY)Buffer);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TDI_INVALID_REQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return TDI_INVALID_REQUEST;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -699,17 +699,7 @@ DriverEntry(
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityList[0].tei_entity = CL_NL_ENTITY;
|
EntityCount = 0;
|
||||||
EntityList[0].tei_instance = 0;
|
|
||||||
EntityList[0].context = 0;
|
|
||||||
EntityList[0].info_req = InfoNetworkLayerTdiQueryEx;
|
|
||||||
EntityList[0].info_set = InfoNetworkLayerTdiSetEx;
|
|
||||||
EntityList[1].tei_entity = CL_TL_ENTITY;
|
|
||||||
EntityList[1].tei_instance = 0;
|
|
||||||
EntityList[1].context = 0;
|
|
||||||
EntityList[1].info_req = InfoTransportLayerTdiQueryEx;
|
|
||||||
EntityList[1].info_set = InfoTransportLayerTdiSetEx;
|
|
||||||
EntityCount = 2;
|
|
||||||
EntityMax = MAX_TDI_ENTITIES;
|
EntityMax = MAX_TDI_ENTITIES;
|
||||||
|
|
||||||
/* Allocate NDIS packet descriptors */
|
/* Allocate NDIS packet descriptors */
|
||||||
|
|
|
@ -13,57 +13,7 @@
|
||||||
#define IP_ROUTE_TYPE_ADD 3
|
#define IP_ROUTE_TYPE_ADD 3
|
||||||
#define IP_ROUTE_TYPE_DEL 2
|
#define IP_ROUTE_TYPE_DEL 2
|
||||||
|
|
||||||
TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer,
|
|
||||||
PUINT BufferSize ) {
|
|
||||||
|
|
||||||
TDI_STATUS Status = TDI_INVALID_REQUEST;
|
|
||||||
KIRQL OldIrql;
|
|
||||||
UINT Count = 0;
|
|
||||||
UINT IfCount = CountInterfaces();
|
|
||||||
PIPADDR_ENTRY IpAddress =
|
|
||||||
exAllocatePool( NonPagedPool, sizeof( IPADDR_ENTRY ) * IfCount );
|
|
||||||
PIPADDR_ENTRY IpCurrent = IpAddress;
|
|
||||||
IF_LIST_ITER(CurrentIF);
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
|
|
||||||
|
|
||||||
if (!IpAddress)
|
|
||||||
return TDI_NO_RESOURCES;
|
|
||||||
|
|
||||||
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
|
|
||||||
|
|
||||||
ForEachInterface(CurrentIF) {
|
|
||||||
IpCurrent->Index = CurrentIF->Index;
|
|
||||||
IpCurrent->Addr = 0;
|
|
||||||
IpCurrent->BcastAddr = 0;
|
|
||||||
IpCurrent->Mask = 0;
|
|
||||||
|
|
||||||
/* Locate the diffrent addresses and put them the right place */
|
|
||||||
GetInterfaceIPv4Address( CurrentIF,
|
|
||||||
ADE_UNICAST,
|
|
||||||
&IpCurrent->Addr );
|
|
||||||
GetInterfaceIPv4Address( CurrentIF,
|
|
||||||
ADE_BROADCAST,
|
|
||||||
&IpCurrent->BcastAddr );
|
|
||||||
GetInterfaceIPv4Address( CurrentIF,
|
|
||||||
ADE_ADDRMASK,
|
|
||||||
&IpCurrent->Mask );
|
|
||||||
IpCurrent++;
|
|
||||||
Count++;
|
|
||||||
} EndFor(CurrentIF);
|
|
||||||
ASSERT( Count == IfCount );
|
|
||||||
|
|
||||||
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
|
|
||||||
|
|
||||||
Status = InfoCopyOut( (PCHAR)IpAddress, sizeof(*IpAddress) * IfCount,
|
|
||||||
Buffer, BufferSize );
|
|
||||||
|
|
||||||
exFreePool( IpAddress );
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get IPRouteEntry s for each of the routes in the system */
|
/* Get IPRouteEntry s for each of the routes in the system */
|
||||||
TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
|
TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
|
||||||
|
@ -138,7 +88,65 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer,
|
TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID,
|
||||||
|
PNDIS_BUFFER Buffer,
|
||||||
|
PUINT BufferSize)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PIPADDR_ENTRY IPEntry;
|
||||||
|
PIP_INTERFACE CurrentIF;
|
||||||
|
UINT i;
|
||||||
|
|
||||||
|
TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
|
||||||
|
|
||||||
|
|
||||||
|
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
|
||||||
|
|
||||||
|
for (i = 0; i < EntityCount; i++)
|
||||||
|
{
|
||||||
|
if (EntityList[i].tei_entity == ID.tei_entity &&
|
||||||
|
EntityList[i].tei_instance == ID.tei_instance)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == EntityCount)
|
||||||
|
{
|
||||||
|
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
|
||||||
|
return TDI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPEntry = exAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY));
|
||||||
|
if (!IPEntry)
|
||||||
|
{
|
||||||
|
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
|
||||||
|
return TDI_NO_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentIF = EntityList[i].context;
|
||||||
|
|
||||||
|
IPEntry->Index = CurrentIF->Index;
|
||||||
|
GetInterfaceIPv4Address(CurrentIF,
|
||||||
|
ADE_UNICAST,
|
||||||
|
&IPEntry->Addr);
|
||||||
|
GetInterfaceIPv4Address(CurrentIF,
|
||||||
|
ADE_ADDRMASK,
|
||||||
|
&IPEntry->Mask);
|
||||||
|
GetInterfaceIPv4Address(CurrentIF,
|
||||||
|
ADE_BROADCAST,
|
||||||
|
&IPEntry->BcastAddr);
|
||||||
|
|
||||||
|
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
|
||||||
|
|
||||||
|
InfoCopyOut((PCHAR)IPEntry, sizeof(IPADDR_ENTRY),
|
||||||
|
Buffer, BufferSize);
|
||||||
|
|
||||||
|
exFreePool(IPEntry);
|
||||||
|
|
||||||
|
return TDI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDI_STATUS InfoTdiQueryGetIPSnmpInfo( TDIEntityID ID,
|
||||||
|
PNDIS_BUFFER Buffer,
|
||||||
PUINT BufferSize ) {
|
PUINT BufferSize ) {
|
||||||
IPSNMP_INFO SnmpInfo;
|
IPSNMP_INFO SnmpInfo;
|
||||||
UINT IfCount = CountInterfaces();
|
UINT IfCount = CountInterfaces();
|
||||||
|
@ -161,95 +169,35 @@ TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass,
|
TDI_STATUS InfoTdiSetRoute(PIPROUTE_ENTRY Route)
|
||||||
UINT InfoType,
|
{
|
||||||
UINT InfoId,
|
IP_ADDRESS Address, Netmask, Router;
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PNDIS_BUFFER Buffer,
|
|
||||||
PUINT BufferSize ) {
|
|
||||||
TDI_STATUS Status = TDI_INVALID_REQUEST;
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO, ("Called.\n"));
|
|
||||||
|
|
||||||
switch( InfoClass ) {
|
|
||||||
case INFO_CLASS_GENERIC:
|
|
||||||
if( InfoType == INFO_TYPE_PROVIDER && InfoId == ENTITY_TYPE_ID ) {
|
|
||||||
ULONG Return = CL_NL_IP;
|
|
||||||
Status = InfoCopyOut( (PCHAR)&Return, sizeof(Return),
|
|
||||||
Buffer, BufferSize );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INFO_CLASS_PROTOCOL:
|
|
||||||
switch( InfoType ) {
|
|
||||||
case INFO_TYPE_PROVIDER:
|
|
||||||
switch( InfoId ) {
|
|
||||||
case IP_MIB_ADDRTABLE_ENTRY_ID:
|
|
||||||
Status = InfoTdiQueryGetAddrTable( Buffer, BufferSize );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IP_MIB_ROUTETABLE_ENTRY_ID:
|
|
||||||
Status = InfoTdiQueryGetRouteTable( Buffer, BufferSize );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IP_MIB_STATS_ID:
|
|
||||||
Status = InfoTdiQueryGetIPSnmpInfo( Buffer, BufferSize );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
|
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass,
|
|
||||||
UINT InfoType,
|
|
||||||
UINT InfoId,
|
|
||||||
PVOID Context,
|
|
||||||
TDIEntityID *id,
|
|
||||||
PCHAR Buffer,
|
|
||||||
UINT BufferSize ) {
|
|
||||||
NTSTATUS Status = TDI_INVALID_REQUEST;
|
|
||||||
IP_ADDRESS Address;
|
|
||||||
IP_ADDRESS Netmask;
|
|
||||||
IP_ADDRESS Router;
|
|
||||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO,("Called\n"));
|
AddrInitIPv4( &Address, Route->Dest );
|
||||||
|
AddrInitIPv4( &Netmask, Route->Mask );
|
||||||
|
AddrInitIPv4( &Router, Route->Gw );
|
||||||
|
|
||||||
//OskitDumpBuffer( (OSK_PCHAR)Buffer, BufferSize );
|
if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */
|
||||||
|
TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address)));
|
||||||
|
/* Find the existing route this belongs to */
|
||||||
|
NCE = RouterGetRoute( &Router );
|
||||||
|
if (!NCE) return TDI_INVALID_PARAMETER;
|
||||||
|
|
||||||
if( InfoClass == INFO_CLASS_PROTOCOL &&
|
/* Really add the route */
|
||||||
InfoType == INFO_TYPE_PROVIDER &&
|
if (!RouterCreateRoute( &Address, &Netmask, &Router,
|
||||||
InfoId == IP_MIB_ROUTETABLE_ENTRY_ID &&
|
NCE->Interface, Route->Metric1))
|
||||||
id->tei_entity == CL_NL_ENTITY ) { /* Add or delete a route */
|
return TDI_NO_RESOURCES;
|
||||||
PIPROUTE_ENTRY Route = (PIPROUTE_ENTRY)Buffer;
|
|
||||||
AddrInitIPv4( &Address, Route->Dest );
|
|
||||||
AddrInitIPv4( &Netmask, Route->Mask );
|
|
||||||
AddrInitIPv4( &Router, Route->Gw );
|
|
||||||
|
|
||||||
if( Route->Type == IP_ROUTE_TYPE_ADD ) { /* Add the route */
|
return TDI_SUCCESS;
|
||||||
TI_DbgPrint(DEBUG_INFO,("Adding route (%s)\n", A2S(&Address)));
|
} else if( Route->Type == IP_ROUTE_TYPE_DEL ) {
|
||||||
/* Find the existing route this belongs to */
|
TI_DbgPrint(DEBUG_INFO,("Removing route (%s)\n", A2S(&Address)));
|
||||||
NCE = RouterGetRoute( &Router );
|
if (NT_SUCCESS(RouterRemoveRoute( &Address, &Router )))
|
||||||
/* Really add the route */
|
return TDI_SUCCESS;
|
||||||
if( NCE &&
|
else
|
||||||
RouterCreateRoute( &Address, &Netmask, &Router,
|
return TDI_INVALID_PARAMETER;
|
||||||
NCE->Interface, Route->Metric1 ) )
|
}
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
else
|
|
||||||
Status = STATUS_UNSUCCESSFUL;
|
|
||||||
} else if( Route->Type == IP_ROUTE_TYPE_DEL ) {
|
|
||||||
TI_DbgPrint(DEBUG_INFO,("Removing route (%s)\n", A2S(&Address)));
|
|
||||||
Status = RouterRemoveRoute( &Address, &Router );
|
|
||||||
} else Status = TDI_INVALID_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_INFO,("Returning %x\n", Status));
|
return TDI_INVALID_REQUEST;
|
||||||
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue