- Removed prefix.c and the prefix list. Adapter and route netmasks are now

checked directly.
- Removed ADE lists on adapters and associated functions.  Adapters now have
  a set of address fields with well-known meanings.
- Removed functions that allocate IP_ADDRESS.  No IP_ADDRESS is ever allocated
  alone any longer.  This saves management overhead and heap traffic.
- Removed NET_TABLE_ENTRY and NTE list and associated functions.  Lookups are
  now done against the original information sources, the adapter list, the
  neighbor cache and the route table.
- Propogated NTE removal throughout, changing NTE to IP_INTERFACE in every
  case.
- When we have alias support, we'll create multiple interfaces referencing
  the same adapter.  This is consistent with the way BSDs do it and I feel
  it provides sufficient abstraction.
- Allow a zero-length buffer request in info to return the number of bytes
  needed for the request to succeed.

svn path=/trunk/; revision=11812
This commit is contained in:
Art Yerkes 2004-11-25 23:56:59 +00:00
parent fd54d2585c
commit bcfb287416
37 changed files with 525 additions and 1340 deletions

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.7 2004/11/14 21:28:21 arty Exp $
# $Id: makefile,v 1.8 2004/11/25 23:56:58 arty Exp $
PATH_TO_TOP = ../../..
@ -12,6 +12,7 @@ TARGET_PCH = $(PATH_TO_TOP)/drivers/lib/ip/include/precomp.h
TARGET_CFLAGS = \
-D__USE_W32API \
-DMEMTRACK \
-D_SEH_NO_NATIVE_NLG \
-Wall -Werror \
-Iinclude \
-I../../net/tcpip/include \
@ -33,7 +34,6 @@ TARGET_OBJECTS = \
network/memtrack.o \
network/neighbor.o \
network/ports.o \
network/prefix.o \
network/receive.o \
network/route.o \
network/router.o \

View file

@ -202,7 +202,6 @@ NTSTATUS AddrBuildAddress(
return STATUS_SUCCESS;
}
/*
* FUNCTION: Returns wether two addresses are equal
* ARGUMENTS:
@ -291,72 +290,6 @@ BOOLEAN AddrIsEqualIPv4(
}
/*
* FUNCTION: Build an IPv4 style address
* ARGUMENTS:
* Address = Raw IPv4 address (network byte order)
* RETURNS:
* Pointer to IP address structure, NULL if there was not enough free
* non-paged memory
*/
PIP_ADDRESS AddrBuildIPv4(
IPv4_RAW_ADDRESS Address)
{
PIP_ADDRESS IPAddress;
IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
if (IPAddress != NULL) {
IPAddress->Type = IP_ADDRESS_V4;
IPAddress->Address.IPv4Address = Address;
}
return IPAddress;
}
/*
* FUNCTION: Clone an IP address
* ARGUMENTS:
* IPAddress = Pointer to IP address
* RETURNS:
* Pointer to new IP address structure, NULL if there was not enough free
* non-paged memory
*/
PIP_ADDRESS AddrCloneAddress(
PIP_ADDRESS Address)
{
if (Address->Type == IP_ADDRESS_V4)
{
return AddrBuildIPv4(Address->Address.IPv4Address);
}
else
{
TI_DbgPrint(MIN_TRACE, ("Cannot clone IPv6 address.\n"));
return NULL;
}
}
/*
* FUNCTION: Locates and returns an address entry using IPv4 adress as argument
* ARGUMENTS:
* Address = Raw IPv4 address
* RETURNS:
* Pointer to address entry if found, NULL if not found
* NOTES:
* Only unicast addresses are considered.
* If found, the address is referenced
*/
PADDRESS_ENTRY AddrLocateADEv4(
IPv4_RAW_ADDRESS Address)
{
IP_ADDRESS Addr;
AddrInitIPv4(&Addr, Address);
return IPLocateADE(&Addr, ADE_UNICAST);
}
unsigned long PASCAL inet_addr(const char *AddrString)
/*
* Convert an ansi string dotted-quad address to a ulong

View file

@ -108,27 +108,21 @@ VOID ARPTransmitComplete(
}
BOOLEAN ARPTransmit(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE)
BOOLEAN ARPTransmit(PIP_ADDRESS Address, PIP_INTERFACE Interface)
/*
* FUNCTION: Creates an ARP request and transmits it on a network
* ARGUMENTS:
* Address = Pointer to IP address to resolve
* NTE = Pointer to net table entru to use for transmitting request
* RETURNS:
* TRUE if the request was successfully sent, FALSE if not
*/
{
PIP_INTERFACE Interface;
PNDIS_PACKET NdisPacket;
UCHAR ProtoAddrLen;
USHORT ProtoType;
TI_DbgPrint(DEBUG_ARP, ("Called.\n"));
Interface = NTE->Interface;
switch (Address->Type) {
case IP_ADDRESS_V4:
ProtoType = (USHORT)ETYPE_IPv4; /* IPv4 */
@ -151,7 +145,7 @@ BOOLEAN ARPTransmit(
(UCHAR)Interface->AddressLength, /* Hardware address length */
(UCHAR)ProtoAddrLen, /* Protocol address length */
Interface->Address, /* Sender's (local) hardware address */
&NTE->Address->Address, /* Sender's (local) protocol address */
&Interface->Unicast.Address.IPv4Address,/* Sender's (local) protocol address */
NULL, /* Don't care */
&Address->Address, /* Target's (remote) protocol address */
ARP_OPCODE_REQUEST); /* ARP request */
@ -180,11 +174,10 @@ VOID ARPReceive(
*/
{
PARP_HEADER Header;
PIP_ADDRESS Address;
IP_ADDRESS Address;
PVOID SenderHWAddress;
PVOID SenderProtoAddress;
PVOID TargetProtoAddress;
PADDRESS_ENTRY ADE;
PNEIGHBOR_CACHE_ENTRY NCE;
PNDIS_PACKET NdisPacket;
PIP_INTERFACE Interface = (PIP_INTERFACE)Context;
@ -213,17 +206,16 @@ VOID ARPReceive(
TargetProtoAddress = (PVOID)((ULONG_PTR)SenderProtoAddress +
Header->ProtoAddrLen + Header->HWAddrLen);
Address = AddrBuildIPv4(*((PULONG)TargetProtoAddress));
ADE = IPLocateADE(Address, ADE_UNICAST);
if (!ADE) {
if( !AddrLocateADEv4( *((PIPv4_RAW_ADDRESS)TargetProtoAddress),
&Address) ) {
TI_DbgPrint(DEBUG_ARP, ("Target address (0x%X) is not mine.\n", *((PULONG)TargetProtoAddress)));
return;
}
/* Check if we know the sender */
AddrInitIPv4(Address, *((PULONG)SenderProtoAddress));
NCE = NBLocateNeighbor(Address);
AddrInitIPv4(&Address, *((PULONG)SenderProtoAddress));
NCE = NBLocateNeighbor(&Address);
if (NCE) {
/* We know the sender. Update the hardware address
and state in our neighbor address cache */
@ -232,13 +224,13 @@ VOID ARPReceive(
/* The packet had our protocol address as target. The sender
may want to communicate with us soon, so add his address
to our address cache */
NCE = NBAddNeighbor(Interface, Address, SenderHWAddress,
NCE = NBAddNeighbor(Interface, &Address, SenderHWAddress,
Header->HWAddrLen, NUD_REACHABLE);
}
if (Header->Opcode != ARP_OPCODE_REQUEST)
return;
/* This is a request for our address. Swap the addresses and
send an ARP reply back to the sender */
NdisPacket = PrepareARPPacket(
@ -247,7 +239,7 @@ VOID ARPReceive(
(UCHAR)Interface->AddressLength, /* Hardware address length */
(UCHAR)Header->ProtoAddrLen, /* Protocol address length */
Interface->Address, /* Sender's (local) hardware address */
&ADE->Address.Address, /* Sender's (local) protocol address */
&Interface->Unicast.Address.IPv4Address,/* Sender's (local) protocol address */
SenderHWAddress, /* Target's (remote) hardware address */
SenderProtoAddress, /* Target's (remote) protocol address */
ARP_OPCODE_REPLY); /* ARP reply */

View file

@ -35,7 +35,7 @@ VOID SendICMPComplete(
PIP_PACKET PrepareICMPPacket(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket,
PIP_ADDRESS Destination,
PCHAR Data,
@ -107,7 +107,7 @@ PIP_PACKET PrepareICMPPacket(
/* Checksum is 0 (for later calculation of this) */
IPHeader->Checksum = 0;
/* Source address */
IPHeader->SrcAddr = NTE->Address->Address.IPv4Address;
IPHeader->SrcAddr = Interface->Unicast.Address.IPv4Address;
/* Destination address */
IPHeader->DstAddr = Destination->Address.IPv4Address;
@ -119,7 +119,7 @@ PIP_PACKET PrepareICMPPacket(
VOID ICMPReceive(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket)
/*
* FUNCTION: Receives an ICMP packet
@ -153,7 +153,7 @@ VOID ICMPReceive(
switch (ICMPHeader->Type) {
case ICMP_TYPE_ECHO_REQUEST:
ICMPReply( NTE, IPPacket, ICMP_TYPE_ECHO_REPLY, 0 );
ICMPReply( Interface, IPPacket, ICMP_TYPE_ECHO_REPLY, 0 );
return;
case ICMP_TYPE_ECHO_REPLY:
@ -170,7 +170,6 @@ VOID ICMPReceive(
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket,
PIP_TRANSMIT_COMPLETE Complete,
PVOID Context)
@ -190,7 +189,7 @@ VOID ICMPTransmit(
IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0);
/* Get a route to the destination address */
if (RouteGetRouteToDestination(&IPPacket->DstAddr, NULL, &RCN) == IP_SUCCESS) {
if (RouteGetRouteToDestination(&IPPacket->DstAddr, &RCN) == IP_SUCCESS) {
/* Send the packet */
IPSendDatagram(IPPacket, RCN, Complete, Context);
} else {
@ -206,7 +205,7 @@ VOID ICMPTransmit(
VOID ICMPReply(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket,
UCHAR Type,
UCHAR Code)
@ -236,14 +235,14 @@ VOID ICMPReply(
DataSize = PayloadSize + sizeof(ICMP_HEADER);
}
if( !PrepareICMPPacket(NTE, &NewPacket, &IPPacket->SrcAddr,
if( !PrepareICMPPacket(Interface, &NewPacket, &IPPacket->SrcAddr,
IPPacket->Data, DataSize) ) return;
((PICMP_HEADER)NewPacket.Data)->Type = Type;
((PICMP_HEADER)NewPacket.Data)->Code = Code;
((PICMP_HEADER)NewPacket.Data)->Checksum = 0;
ICMPTransmit(NTE, &NewPacket, SendICMPComplete, NULL);
ICMPTransmit(&NewPacket, SendICMPComplete, NULL);
}
/* EOF */

View file

@ -15,16 +15,30 @@
NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface,
ULONG TargetType,
PULONG Address ) {
ADE_LIST_ITER(CurrentADE);
switch( TargetType ) {
case ADE_UNICAST:
*Address = Interface->Unicast.Address.IPv4Address;
break;
ForEachADE(Interface->ADEListHead,CurrentADE) {
if (CurrentADE->Type == TargetType) {
*Address = CurrentADE->Address.Address.IPv4Address;
return STATUS_SUCCESS;
}
} EndFor(CurrentADE);
return STATUS_UNSUCCESSFUL;
case ADE_ADDRMASK:
*Address = Interface->Netmask.Address.IPv4Address;
break;
case ADE_BROADCAST:
*Address =
Interface->Unicast.Address.IPv4Address |
~Interface->Netmask.Address.IPv4Address;
break;
case ADE_POINTOPOINT:
*Address = Interface->PointToPoint.Address.IPv4Address;
break;
default:
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
UINT CountInterfaces() {
@ -43,18 +57,6 @@ UINT CountInterfaces() {
return Count;
}
UINT CountInterfaceAddresses( PIP_INTERFACE Interface ) {
UINT AddrCount = 0;
ADE_LIST_ITER(CurrentADE);
ForEachADE(Interface->ADEListHead,CurrentADE) {
if( CurrentADE->Type == ADE_UNICAST )
AddrCount++;
} EndFor(CurrentADE);
return AddrCount;
}
NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed ) {
NDIS_STATUS NdisStatus;
PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
@ -80,23 +82,147 @@ NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed ) {
NTSTATUS GetInterfaceName( PIP_INTERFACE Interface,
PCHAR NameBuffer,
UINT Len ) {
NDIS_STATUS NdisStatus;
PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
ULONG ResultSize = 0;
NTSTATUS Status =
RtlUnicodeToMultiByteN( NameBuffer,
Len,
&ResultSize,
Interface->Name.Buffer,
Interface->Name.Length );
#ifdef __NTDRIVER__
/* Get maximum link speed */
NdisStatus = NDISCall(IF,
NdisRequestQueryInformation,
OID_GEN_FRIENDLY_NAME,
NameBuffer,
Len);
#else
(void)IF;
NdisStatus = NDIS_STATUS_SUCCESS;
strncpy( NameBuffer, "eth", Len );
#endif
return
NdisStatus != NDIS_STATUS_SUCCESS ?
STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
if( NT_SUCCESS(Status) )
NameBuffer[ResultSize] = 0;
else
NameBuffer[0] = 0;
return Status;
}
/*
* FUNCTION: Locates and returns an address entry using IPv4 adress as argument
* ARGUMENTS:
* Address = Raw IPv4 address
* RETURNS:
* Pointer to address entry if found, NULL if not found
* NOTES:
* Only unicast addresses are considered.
* If found, the address is referenced
*/
BOOLEAN AddrLocateADEv4(
IPv4_RAW_ADDRESS MatchAddress, PIP_ADDRESS Address)
{
KIRQL OldIrql;
BOOLEAN Matched = FALSE;
IF_LIST_ITER(CurrentIF);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
ForEachInterface(CurrentIF) {
if( AddrIsEqualIPv4( &CurrentIF->Unicast, MatchAddress ) ) {
Address->Address.IPv4Address = MatchAddress;
Matched = TRUE; break;
}
} EndFor(CurrentIF);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return Matched;
}
BOOLEAN IPGetDefaultAddress( PIP_ADDRESS Address ) {
KIRQL OldIrql;
BOOLEAN Matched = FALSE;
IF_LIST_ITER(CurrentIF);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
/* Find the first 'real' interface */
ForEachInterface(CurrentIF) {
if( CurrentIF->Context ) {
*Address = CurrentIF->Unicast;
Matched = TRUE; break;
}
} EndFor(CurrentIF);
/* Not matched, use the first one */
if( !Matched ) {
ForEachInterface(CurrentIF) {
*Address = CurrentIF->Unicast;
Matched = TRUE; break;
} EndFor(CurrentIF);
}
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return Matched;
}
BOOLEAN HasPrefix(
PIP_ADDRESS Address,
PIP_ADDRESS Prefix,
UINT Length)
/*
* FUNCTION: Determines wether an address has an given prefix
* ARGUMENTS:
* Address = Pointer to address to use
* Prefix = Pointer to prefix to check for
* Length = Length of prefix
* RETURNS:
* TRUE if the address has the prefix, FALSE if not
* NOTES:
* The two addresses must be of the same type
*/
{
PUCHAR pAddress = (PUCHAR)&Address->Address;
PUCHAR pPrefix = (PUCHAR)&Prefix->Address;
TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) Prefix (0x%X) Length (%d).\n", Address, Prefix, Length));
#if 0
TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) Prefix (%s).\n",
A2S(Address), A2S(Prefix)));
#endif
/* Check that initial integral bytes match */
while (Length > 8) {
if (*pAddress++ != *pPrefix++)
return FALSE;
Length -= 8;
}
/* Check any remaining bits */
if ((Length > 0) && ((*pAddress >> (8 - Length)) != (*pPrefix >> (8 - Length))))
return FALSE;
return TRUE;
}
PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address)
/*
* FUNCTION: Checks all on-link prefixes to find out if an address is on-link
* ARGUMENTS:
* Address = Pointer to address to check
* RETURNS:
* Pointer to interface if address is on-link, NULL if not
*/
{
KIRQL OldIrql;
IF_LIST_ITER(CurrentIF);
TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X)\n", Address));
TI_DbgPrint(DEBUG_ROUTER, ("Address (%s)\n", A2S(Address)));
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
ForEachInterface(CurrentIF) {
if (HasPrefix(Address, &CurrentIF->Unicast,
AddrCountPrefixBits(&CurrentIF->Netmask))) {
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentIF;
}
} EndFor(CurrentIF);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return NULL;
}

View file

@ -46,31 +46,6 @@ VOID DontFreePacket(
{
}
VOID FreeADE(
PVOID Object)
/*
* FUNCTION: Frees an address entry object
* ARGUMENTS:
* Object = Pointer to an address entry structure
*/
{
exFreePool(Object);
}
VOID FreeNTE(
PVOID Object)
/*
* FUNCTION: Frees a net table entry object
* ARGUMENTS:
* Object = Pointer to an net table entry structure
*/
{
exFreePool(Object);
}
VOID FreeIF(
PVOID Object)
/*
@ -83,108 +58,6 @@ VOID FreeIF(
}
PADDRESS_ENTRY CreateADE(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
UCHAR Type,
PNET_TABLE_ENTRY NTE)
/*
* FUNCTION: Creates an address entry and binds it to an interface
* ARGUMENTS:
* IF = Pointer to interface
* Address = Pointer to referenced interface address
* Type = Type of address (ADE_*)
* NTE = Pointer to net table entry
* RETURNS:
* Pointer to ADE, NULL if there was not enough free resources
* NOTES:
* The interface lock must be held when called. The address entry
* retains a reference to the provided address and NTE. The caller
* is responsible for referencing the these before calling.
* As long as you have referenced an ADE you can safely use the
* address and NTE as the ADE references both
*/
{
PADDRESS_ENTRY ADE;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) Type (0x%X) NTE (0x%X).\n",
IF, Address, Type, NTE));
TI_DbgPrint(DEBUG_IP, ("Address (%s) NTE (%s).\n",
A2S(Address), A2S(NTE->Address)));
/* Allocate space for an ADE and set it up */
ADE = exAllocatePool(NonPagedPool, sizeof(ADDRESS_ENTRY));
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
INIT_TAG(ADE, TAG('A','D','E',' '));
ADE->Free = FreeADE;
ADE->NTE = NTE;
ADE->Type = Type;
RtlCopyMemory(&ADE->Address,Address,sizeof(ADE->Address));
/* Add ADE to the list on the interface */
InsertTailList(&IF->ADEListHead, &ADE->ListEntry);
return ADE;
}
VOID DestroyADE(
PIP_INTERFACE IF,
PADDRESS_ENTRY ADE)
/*
* FUNCTION: Destroys an address entry
* ARGUMENTS:
* IF = Pointer to interface
* ADE = Pointer to address entry
* NOTES:
* The interface lock must be held when called
*/
{
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) ADE (0x%X).\n", IF, ADE));
TI_DbgPrint(DEBUG_IP, ("ADE (%s).\n", ADE->Address));
/* Unlink the address entry from the list */
RemoveEntryList(&ADE->ListEntry);
/* And free the ADE */
FreeADE(ADE);
}
VOID DestroyADEs(
PIP_INTERFACE IF)
/*
* FUNCTION: Destroys all address entries on an interface
* ARGUMENTS:
* IF = Pointer to interface
* NOTES:
* The interface lock must be held when called
*/
{
PLIST_ENTRY CurrentEntry;
PLIST_ENTRY NextEntry;
PADDRESS_ENTRY Current;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X).\n", IF));
/* Search the list and remove every ADE we find */
CurrentEntry = IF->ADEListHead.Flink;
while (CurrentEntry != &IF->ADEListHead) {
NextEntry = CurrentEntry->Flink;
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
/* Destroy the ADE */
DestroyADE(IF, Current);
CurrentEntry = NextEntry;
}
}
PIP_PACKET IPCreatePacket(ULONG Type)
/*
* FUNCTION: Creates an IP packet object
@ -235,334 +108,6 @@ PIP_PACKET IPInitializePacket(
}
PNET_TABLE_ENTRY IPCreateNTE(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
UINT PrefixLength)
/*
* FUNCTION: Creates a net table entry and binds it to an interface
* ARGUMENTS:
* IF = Pointer to interface
* Address = Pointer to interface address
* PrefixLength = Length of prefix
* RETURNS:
* Pointer to NTE, NULL if there was not enough free resources
* NOTES:
* The interface lock must be held when called.
* The net table entry retains a reference to the interface and
* the provided address. The caller is responsible for providing
* these references
*/
{
PNET_TABLE_ENTRY NTE;
PADDRESS_ENTRY ADE;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) PrefixLength (%d).\n", IF, Address, PrefixLength));
TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
/* Allocate room for an NTE */
NTE = exAllocatePool(NonPagedPool, sizeof(NET_TABLE_ENTRY));
if (!NTE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
INIT_TAG(NTE, TAG('N','T','E',' '));
INIT_TAG(Address, TAG('A','D','R','S'));
NTE->Free = FreeNTE;
NTE->Interface = IF;
NTE->Address = Address;
/* Create an address entry and add it to the list */
ADE = CreateADE(IF, NTE->Address, ADE_UNICAST, NTE);
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
exFreePool(NTE);
return NULL;
}
/* Create a prefix list entry for unicast address */
NTE->PLE = CreatePLE(IF, NTE->Address, PrefixLength);
if (!NTE->PLE) {
DestroyADE(IF, ADE);
exFreePool(NTE);
return NULL;
}
/* Add NTE to the list on the interface */
InsertTailList(&IF->NTEListHead, &NTE->IFListEntry);
/* Add NTE to the global net table list */
TcpipInterlockedInsertTailList(&NetTableListHead, &NTE->NTListEntry, &NetTableListLock);
return NTE;
}
VOID DestroyNTE(
PIP_INTERFACE IF,
PNET_TABLE_ENTRY NTE)
/*
* FUNCTION: Destroys a net table entry
* ARGUMENTS:
* IF = Pointer to interface
* NTE = Pointer to net table entry
* NOTES:
* The net table list lock must be held when called
* The interface lock must be held when called
*/
{
KIRQL OldIrql;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) NTE (0x%X).\n", IF, NTE));
TI_DbgPrint(DEBUG_IP, ("NTE (%s).\n", NTE->Address));
/* Invalidate the prefix list entry for this NTE */
TcpipAcquireSpinLock(&PrefixListLock, &OldIrql);
DestroyPLE(NTE->PLE);
TcpipReleaseSpinLock(&PrefixListLock, OldIrql);
/* Remove NTE from the interface list */
RemoveEntryList(&NTE->IFListEntry);
/* Remove NTE from the net table list */
/* TODO: DEBUG: removed by RobD to prevent failure when testing under bochs 6 sept 2002.
RemoveEntryList(&NTE->NTListEntry);
*/
/* And free the NTE */
exFreePool(NTE);
}
VOID DestroyNTEs(
PIP_INTERFACE IF)
/*
* FUNCTION: Destroys all net table entries on an interface
* ARGUMENTS:
* IF = Pointer to interface
* NOTES:
* The net table list lock must be held when called
* The interface lock may be held when called
*/
{
PLIST_ENTRY CurrentEntry;
PLIST_ENTRY NextEntry;
PNET_TABLE_ENTRY Current;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X).\n", IF));
/* Search the list and remove every NTE we find */
CurrentEntry = IF->NTEListHead.Flink;
while (CurrentEntry != &IF->NTEListHead) {
NextEntry = CurrentEntry->Flink;
Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
/* Destroy the NTE */
DestroyNTE(IF, Current);
CurrentEntry = NextEntry;
}
}
PNET_TABLE_ENTRY IPLocateNTEOnInterface(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
PUINT AddressType)
/*
* FUNCTION: Locates an NTE on an interface
* ARGUMENTS:
* IF = Pointer to interface
* Address = Pointer to IP address
* AddressType = Address of type of IP address
* NOTES:
* If found, the NTE is referenced for the caller. The caller is
* responsible for dereferencing after use
* RETURNS:
* Pointer to net table entry, NULL if none was found
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PADDRESS_ENTRY Current;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (%s) AddressType (0x%X).\n",
IF, A2S(Address), AddressType));
if( !IF ) return NULL;
TcpipAcquireSpinLock(&IF->Lock, &OldIrql);
/* Search the list and return the NTE if found */
CurrentEntry = IF->ADEListHead.Flink;
if (CurrentEntry == &IF->ADEListHead) {
TI_DbgPrint(DEBUG_IP, ("NTE list is empty!!!\n"));
}
while (CurrentEntry != &IF->ADEListHead) {
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
if (AddrIsEqual(Address, &Current->Address)) {
*AddressType = Current->Type;
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return Current->NTE;
}
CurrentEntry = CurrentEntry->Flink;
}
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return NULL;
}
PNET_TABLE_ENTRY IPLocateNTE(
PIP_ADDRESS Address,
PUINT AddressType)
/*
* FUNCTION: Locates an NTE for the network Address is on
* ARGUMENTS:
* Address = Pointer to an address to find associated NTE of
* AddressType = Address of address type
* NOTES:
* If found the NTE is referenced for the caller. The caller is
* responsible for dereferencing after use
* RETURNS:
* Pointer to NTE if the address was found, NULL if not.
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PNET_TABLE_ENTRY Current;
PNET_TABLE_ENTRY NTE;
// TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n",
// Address, AddressType));
// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
TcpipAcquireSpinLock(&NetTableListLock, &OldIrql);
/* Search the list and return the NTE if found */
CurrentEntry = NetTableListHead.Flink;
while (CurrentEntry != &NetTableListHead) {
Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, NTListEntry);
NTE = IPLocateNTEOnInterface(Current->Interface, Address, AddressType);
if (NTE) {
TcpipReleaseSpinLock(&NetTableListLock, OldIrql);
return NTE;
}
CurrentEntry = CurrentEntry->Flink;
}
TcpipReleaseSpinLock(&NetTableListLock, OldIrql);
return NULL;
}
PADDRESS_ENTRY IPLocateADE(
PIP_ADDRESS Address,
UINT AddressType)
/*
* FUNCTION: Locates an ADE for the address
* ARGUMENTS:
* Address = Pointer to an address to find associated ADE of
* AddressType = Type of address
* RETURNS:
* Pointer to ADE if the address was found, NULL if not.
* NOTES:
* If found the ADE is referenced for the caller. The caller is
* responsible for dereferencing after use
*/
{
KIRQL OldIrql;
IF_LIST_ITER(CurrentIF);
ADE_LIST_ITER(CurrentADE);
// TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n",
// Address, AddressType));
// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
/* Search the interface list */
ForEachInterface(CurrentIF) {
/* Search the address entry list and return the ADE if found */
ForEachADE(CurrentIF->ADEListHead,CurrentADE) {
if ((AddrIsEqual(Address, &CurrentADE->Address)) &&
(CurrentADE->Type == AddressType)) {
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
} EndFor(CurrentADE);
} EndFor(CurrentIF);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return NULL;
}
PADDRESS_ENTRY IPGetDefaultADE(
UINT AddressType)
/*
* FUNCTION: Returns a default address entry
* ARGUMENTS:
* AddressType = Type of address
* RETURNS:
* Pointer to ADE if found, NULL if not.
* NOTES:
* Loopback interface is only considered if it is the only interface.
* If found, the address entry is referenced
*/
{
KIRQL OldIrql;
ADE_LIST_ITER(CurrentADE);
IF_LIST_ITER(CurrentIF);
BOOLEAN LoopbackIsRegistered = FALSE;
TI_DbgPrint(DEBUG_IP, ("Called. AddressType (0x%X).\n", AddressType));
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
/* Search the interface list */
ForEachInterface(CurrentIF) {
if (CurrentIF != Loopback) {
/* Search the address entry list and return the first appropriate ADE found */
TI_DbgPrint(DEBUG_IP,("Checking interface %x\n", CurrentIF));
ForEachADE(CurrentIF->ADEListHead,CurrentADE) {
if (CurrentADE->Type == AddressType) {
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
} EndFor(CurrentADE);
} else
LoopbackIsRegistered = TRUE;
} EndFor(CurrentIF);
/* No address was found. Use loopback interface if available */
if (LoopbackIsRegistered) {
ForEachADE(CurrentIF->ADEListHead,CurrentADE) {
if (CurrentADE->Type == AddressType) {
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
} EndFor(CurrentADE);
}
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return NULL;
}
void STDCALL IPTimeout( PVOID Context ) {
/* Check if datagram fragments have taken too long to assemble */
IPDatagramReassemblyTimeout();
@ -576,7 +121,7 @@ void STDCALL IPTimeout( PVOID Context ) {
VOID IPDispatchProtocol(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket)
/*
* FUNCTION: IP protocol dispatcher
@ -603,7 +148,7 @@ VOID IPDispatchProtocol(
}
/* Call the appropriate protocol handler */
(*ProtocolTable[Protocol])(NTE, IPPacket);
(*ProtocolTable[Protocol])(Interface, IPPacket);
}
@ -653,9 +198,6 @@ PIP_INTERFACE IPCreateInterface(
IF->AddressLength = BindInfo->AddressLength;
IF->Transmit = BindInfo->Transmit;
InitializeListHead(&IF->ADEListHead);
InitializeListHead(&IF->NTEListHead);
TcpipInitializeSpinLock(&IF->Lock);
#ifdef __NTDRIVER__
@ -674,22 +216,12 @@ VOID IPDestroyInterface(
* IF = Pointer to interface to destroy
*/
{
KIRQL OldIrql1;
KIRQL OldIrql2;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X).\n", IF));
#ifdef __NTDRIVER__
RemoveTDIInterfaceEntity( IF );
#endif
TcpipAcquireSpinLock(&NetTableListLock, &OldIrql1);
TcpipAcquireSpinLock(&IF->Lock, &OldIrql2);
DestroyADEs(IF);
DestroyNTEs(IF);
TcpipReleaseSpinLock(&IF->Lock, OldIrql2);
TcpipReleaseSpinLock(&NetTableListLock, OldIrql1);
exFreePool(IF);
}
@ -705,8 +237,6 @@ BOOLEAN IPRegisterInterface(
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PNET_TABLE_ENTRY Current;
PROUTE_CACHE_NODE RCN;
PNEIGHBOR_CACHE_ENTRY NCE;
@ -714,31 +244,25 @@ BOOLEAN IPRegisterInterface(
TcpipAcquireSpinLock(&IF->Lock, &OldIrql);
/* Add routes to all NTEs on this interface */
CurrentEntry = IF->NTEListHead.Flink;
while (CurrentEntry != &IF->NTEListHead) {
Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
/* Add a permanent neighbor for this NTE */
NCE = NBAddNeighbor(IF, Current->Address, IF->Address,
IF->AddressLength, NUD_PERMANENT);
if (!NCE) {
TI_DbgPrint(MIN_TRACE, ("Could not create NCE.\n"));
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return FALSE;
}
/* NCE is already referenced */
if (!RouterAddRoute(Current->Address, &Current->PLE->Prefix, NCE, 1)) {
TI_DbgPrint(MIN_TRACE, ("Could not add route due to insufficient resources.\n"));
}
RCN = RouteAddRouteToDestination(Current->Address, Current, IF, NCE);
if (!RCN) {
TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n"));
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
}
CurrentEntry = CurrentEntry->Flink;
/* Add a permanent neighbor for this NTE */
NCE = NBAddNeighbor(IF, &IF->Unicast,
IF->Address, IF->AddressLength,
NUD_PERMANENT);
if (!NCE) {
TI_DbgPrint(MIN_TRACE, ("Could not create NCE.\n"));
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return FALSE;
}
/* NCE is already referenced */
if (!RouterAddRoute(&IF->Unicast, &IF->Netmask, NCE, 1)) {
TI_DbgPrint(MIN_TRACE, ("Could not add route due to insufficient resources.\n"));
}
RCN = RouteAddRouteToDestination(&IF->Unicast, IF, NCE);
if (!RCN) {
TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n"));
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
}
/* Add interface to the global interface list */
@ -764,45 +288,21 @@ VOID IPUnregisterInterface(
* IF = Pointer to interface to unregister
*/
{
KIRQL OldIrql1;
KIRQL OldIrql2;
KIRQL OldIrql3;
PLIST_ENTRY CurrentEntry;
PNET_TABLE_ENTRY Current;
PNEIGHBOR_CACHE_ENTRY NCE;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X).\n", IF));
TcpipAcquireSpinLock(&NetTableListLock, &OldIrql1);
TcpipAcquireSpinLock(&IF->Lock, &OldIrql2);
/* Remove routes to all NTEs on this interface */
CurrentEntry = IF->NTEListHead.Flink;
while (CurrentEntry != &IF->NTEListHead) {
Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
/* Remove NTE from global net table list */
RemoveEntryList(&Current->NTListEntry);
/* Remove all references from route cache to NTE */
RouteInvalidateNTE(Current);
/* Remove permanent NCE, but first we have to find it */
NCE = NBLocateNeighbor(Current->Address);
if (NCE)
NBRemoveNeighbor(NCE);
CurrentEntry = CurrentEntry->Flink;
}
/* Remove permanent NCE, but first we have to find it */
NCE = NBLocateNeighbor(&IF->Unicast);
if (NCE)
NBRemoveNeighbor(NCE);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql3);
/* Ouch...three spinlocks acquired! Fortunately
we don't unregister interfaces very often */
RemoveEntryList(&IF->ListEntry);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql3);
TcpipReleaseSpinLock(&IF->Lock, OldIrql2);
TcpipReleaseSpinLock(&NetTableListLock, OldIrql1);
}
@ -828,7 +328,7 @@ VOID IPRegisterProtocol(
VOID DefaultProtocolHandler(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket)
/*
* FUNCTION: Default handler for Internet protocols
@ -837,7 +337,8 @@ VOID DefaultProtocolHandler(
* IPPacket = Pointer to an IP packet that was received
*/
{
TI_DbgPrint(MID_TRACE, ("Packet of unknown Internet protocol discarded.\n"));
TI_DbgPrint(MID_TRACE, ("[IF %x] Packet of unknown Internet protocol "
"discarded.\n", Interface));
}
@ -919,8 +420,6 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath)
InitializeListHead(&ReassemblyListHead);
TcpipInitializeSpinLock(&ReassemblyListLock);
InitPLE();
IPInitialized = TRUE;
return STATUS_SUCCESS;
@ -951,9 +450,6 @@ NTSTATUS IPShutdown(
IPFreeReassemblyList();
/* Clear prefix list */
DestroyPLEs();
/* Destroy lookaside lists */
ExDeleteNPagedLookasideList(&IPHoleList);
ExDeleteNPagedLookasideList(&IPDRList);

View file

@ -63,47 +63,28 @@ NDIS_STATUS LoopRegisterAdapter(
* Status of operation
*/
{
PIP_ADDRESS Address;
NDIS_STATUS Status;
LLIP_BIND_INFO BindInfo;
Status = NDIS_STATUS_SUCCESS;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Address = AddrBuildIPv4(LOOPBACK_ADDRESS_IPv4);
if (Address != NULL)
{
LLIP_BIND_INFO BindInfo;
/* Bind the adapter to network (IP) layer */
BindInfo.Context = NULL;
BindInfo.HeaderSize = 0;
BindInfo.MinFrameSize = 0;
BindInfo.MTU = 16384;
BindInfo.Address = NULL;
BindInfo.AddressLength = 0;
BindInfo.Transmit = LoopTransmit;
Loopback = IPCreateInterface(&BindInfo);
if ((Loopback != NULL) && (IPCreateNTE(Loopback, Address, 8)))
{
IPRegisterInterface(Loopback);
}
else
{
Status = NDIS_STATUS_RESOURCES;
}
}
else
{
Status = NDIS_STATUS_RESOURCES;
}
if (!NT_SUCCESS(Status))
{
LoopUnregisterAdapter(NULL);
}
/* Bind the adapter to network (IP) layer */
BindInfo.Context = NULL;
BindInfo.HeaderSize = 0;
BindInfo.MinFrameSize = 0;
BindInfo.MTU = 16384;
BindInfo.Address = NULL;
BindInfo.AddressLength = 0;
BindInfo.Transmit = LoopTransmit;
Loopback = IPCreateInterface(&BindInfo);
AddrInitIPv4(&Loopback->Unicast, LOOPBACK_ADDRESS_IPv4);
AddrInitIPv4(&Loopback->Netmask, LOOPBACK_ADDRMASK_IPv4);
IPRegisterInterface(Loopback);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));

View file

@ -231,38 +231,16 @@ VOID NBSendSolicit(PNEIGHBOR_CACHE_ENTRY NCE)
* May be called with lock held on NCE's table
*/
{
PLIST_ENTRY CurrentEntry;
PNET_TABLE_ENTRY NTE;
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
if (NCE->State == NUD_INCOMPLETE)
{
/* This is the first solicitation of this neighbor. Broadcast
a request for the neighbor */
/* FIXME: Choose first NTE. We might want to give an NTE as argument */
if (!NCE->Interface || !NCE->Interface->NTEListHead.Flink) {
TI_DbgPrint(MID_TRACE,
("NCE->Interface: %x, "
"NCE->Interface->NTEListHead.Flink %x\n",
NCE->Interface,
NCE->Interface ? NCE->Interface->NTEListHead.Flink : 0));
}
TI_DbgPrint(MID_TRACE,("MARK\n"));
TI_DbgPrint(MID_TRACE,("NCE: %x\n", NCE));
TI_DbgPrint(MID_TRACE,("NCE->Interface: %x\n", NCE->Interface));
if (!IsListEmpty(&NCE->Interface->NTEListHead)) {
CurrentEntry = NCE->Interface->NTEListHead.Flink;
NTE = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY,
IFListEntry);
ARPTransmit(&NCE->Address, NTE);
} else {
TI_DbgPrint(MIN_TRACE, ("Interface at 0x%X has zero NTE.\n",
NCE->Interface));
}
ARPTransmit(&NCE->Address, NCE->Interface);
} else {
/* FIXME: Unicast solicitation since we have a cached address */
TI_DbgPrint(MIN_TRACE, ("Uninplemented unicast solicitation.\n"));
@ -301,8 +279,6 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
"LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n",
Interface, Address, LinkAddress, LinkAddressLength, State));
ASSERT(Address->Type == IP_ADDRESS_V4);
NCE = ExAllocatePool
(NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength);
if (NCE == NULL)
@ -323,6 +299,8 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
NCE->EventTimer = 0; /* Not in use */
InitializeListHead( &NCE->PacketQueue );
TI_DbgPrint(MID_TRACE,("NCE: %x\n", NCE));
HashValue = *(PULONG)&Address->Address;
HashValue ^= HashValue >> 16;
HashValue ^= HashValue >> 8;

View file

@ -1,115 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: network/ip.c
* PURPOSE: Internet Protocol module
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Art Yerkes (arty@users.sourceforge.net)
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include "precomp.h"
LIST_ENTRY PrefixListHead;
KSPIN_LOCK PrefixListLock;
/* --------- The Prefix List ---------- */
VOID InitPLE() {
/* Initialize the prefix list and protecting lock */
InitializeListHead(&PrefixListHead);
TcpipInitializeSpinLock(&PrefixListLock);
}
PPREFIX_LIST_ENTRY CreatePLE(PIP_INTERFACE IF, PIP_ADDRESS Prefix, UINT Length)
/*
* FUNCTION: Creates a prefix list entry and binds it to an interface
* ARGUMENTS:
* IF = Pointer to interface
* Prefix = Pointer to prefix
* Length = Length of prefix
* RETURNS:
* Pointer to PLE, NULL if there was not enough free resources
* NOTES:
* The prefix list entry retains a reference to the interface and
* the provided address. The caller is responsible for providing
* these references
*/
{
PPREFIX_LIST_ENTRY PLE;
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Prefix (0x%X) Length (%d).\n", IF, Prefix, Length));
TI_DbgPrint(DEBUG_IP, ("Prefix (%s).\n", A2S(Prefix)));
/* Allocate space for an PLE and set it up */
PLE = PoolAllocateBuffer(sizeof(PREFIX_LIST_ENTRY));
if (!PLE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
INIT_TAG(PLE, TAG('P','L','E',' '));
PLE->Interface = IF;
RtlCopyMemory(&PLE->Prefix, Prefix, sizeof(PLE->Prefix));
PLE->PrefixLength = Length;
/* Add PLE to the global prefix list */
ExInterlockedInsertTailList(&PrefixListHead, &PLE->ListEntry, &PrefixListLock);
return PLE;
}
VOID DestroyPLE(
PPREFIX_LIST_ENTRY PLE)
/*
* FUNCTION: Destroys an prefix list entry
* ARGUMENTS:
* PLE = Pointer to prefix list entry
* NOTES:
* The prefix list lock must be held when called
*/
{
TI_DbgPrint(DEBUG_IP, ("Called. PLE (0x%X).\n", PLE));
TI_DbgPrint(DEBUG_IP, ("PLE (%s).\n", PLE->Prefix));
/* Unlink the prefix list entry from the list */
RemoveEntryList(&PLE->ListEntry);
/* And free the PLE */
PoolFreeBuffer(PLE);
}
VOID DestroyPLEs(
VOID)
/*
* FUNCTION: Destroys all prefix list entries
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PLIST_ENTRY NextEntry;
PPREFIX_LIST_ENTRY Current;
TI_DbgPrint(DEBUG_IP, ("Called.\n"));
TcpipAcquireSpinLock(&PrefixListLock, &OldIrql);
/* Search the list and remove every PLE we find */
CurrentEntry = PrefixListHead.Flink;
while (CurrentEntry != &PrefixListHead) {
NextEntry = CurrentEntry->Flink;
Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
/* Destroy the PLE */
DestroyPLE(Current);
CurrentEntry = NextEntry;
}
TcpipReleaseSpinLock(&PrefixListLock, OldIrql);
}

View file

@ -273,14 +273,12 @@ __inline VOID Cleanup(
VOID ProcessFragment(
PIP_INTERFACE IF,
PIP_PACKET IPPacket,
PNET_TABLE_ENTRY NTE)
PIP_PACKET IPPacket)
/*
* FUNCTION: Processes an IP datagram or fragment
* ARGUMENTS:
* IF = Pointer to IP interface packet was receive on
* IPPacket = Pointer to IP packet
* NTE = Pointer to NTE packet was received on
* NOTES:
* This routine reassembles fragments and, if a whole datagram can
* be assembled, passes the datagram on to the IP protocol dispatcher
@ -465,7 +463,7 @@ VOID ProcessFragment(
DISPLAY_IP_PACKET(Datagram);
/* Give the packet to the protocol dispatcher */
IPDispatchProtocol(NTE, Datagram);
IPDispatchProtocol(IF, Datagram);
/* We're done with this datagram */
exFreePool(Datagram->Header);
@ -523,10 +521,6 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
* IPPacket = Pointer to IP packet
*/
{
PNEIGHBOR_CACHE_ENTRY NCE;
PNET_TABLE_ENTRY NTE;
UINT AddressType;
TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2;
@ -567,11 +561,9 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
/* FIXME: Possibly forward packets with multicast addresses */
/* FIXME: Should we allow packets to be received on the wrong interface? */
NTE = IPLocateNTEOnInterface(IF, &IPPacket->DstAddr, &AddressType);
if (NTE) {
/* This packet is destined for us */
ProcessFragment(IF, IPPacket, NTE);
/* XXX Find out if this packet is destined for us */
ProcessFragment(IF, IPPacket);
#if 0
} else {
/* This packet is not destined for us. If we are a router,
try to find a route and forward the packet */
@ -592,6 +584,7 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
/* FIXME: Send ICMP error code */
}
}
#endif
}

View file

@ -293,34 +293,6 @@ VOID RemoveRouteToDestination(
}
VOID InvalidateNTEOnSubtree(
PNET_TABLE_ENTRY NTE,
PROUTE_CACHE_NODE Node)
/*
* FUNCTION: Removes all RCNs with references to an NTE on a subtree
* ARGUMENNTS:
* NTE = Pointer to NTE to invalidate
* Node = Pointer to RCN to start removing nodes at
* NOTES:
* This function must be called with the route cache lock held.
*/
{
TI_DbgPrint(DEBUG_RCACHE, ("Called. NTE (0x%X) Node (0x%X).\n", NTE, Node));
if (IsInternalRCN(Node)) {
/* Traverse left subtree */
InvalidateNTEOnSubtree(NTE, Node->Left);
/* Traverse right subtree */
InvalidateNTEOnSubtree(NTE, Node->Right);
/* Finally check the node itself */
if (Node->NTE == NTE)
RemoveRouteToDestination(Node);
}
}
VOID InvalidateNCEOnSubtree(
PNEIGHBOR_CACHE_ENTRY NCE,
PROUTE_CACHE_NODE Node)
@ -446,16 +418,12 @@ NTSTATUS RouteShutdown(
}
UINT RouteGetRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PROUTE_CACHE_NODE *RCN)
UINT RouteGetRouteToDestination
(PIP_ADDRESS Destination, PROUTE_CACHE_NODE *RCN)
/*
* FUNCTION: Locates an RCN describing a route to a destination address
* ARGUMENTS:
* Destination = Pointer to destination address to find route to
* NTE = Pointer to NTE describing net to send on
* (NULL means routing module choose NTE to send on)
* RCN = Address of pointer to an RCN
* RETURNS:
* Status of operation
@ -469,11 +437,9 @@ UINT RouteGetRouteToDestination(
PNEIGHBOR_CACHE_ENTRY NCE;
PIP_INTERFACE Interface;
TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) NTE (0x%X).\n",
Destination, NTE));
TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X)\n", Destination));
TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NTE (%s).\n",
A2S(Destination), NTE ? A2S(NTE->Address) : ""));
TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s)\n", A2S(Destination)));
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
@ -488,17 +454,8 @@ UINT RouteGetRouteToDestination(
/* No route was found in the cache */
/* Check if the destination is on-link */
Interface = RouterFindOnLinkInterface(Destination, NTE);
Interface = FindOnLinkInterface(Destination);
if (Interface) {
if (!NTE) {
NTE = RouterFindBestNTE(Interface, Destination);
if (!NTE) {
/* We cannot get to the specified destination. Return error */
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
return IP_NO_ROUTE_TO_DESTINATION;
}
}
/* The destination address is on-link. Check our neighbor cache */
NCE = NBFindOrCreateNeighbor(Interface, Destination);
if (!NCE) {
@ -507,7 +464,7 @@ UINT RouteGetRouteToDestination(
}
} else {
/* Destination is not on any subnets we're on. Find a router to use */
NCE = RouterGetRoute(Destination, NTE);
NCE = RouterGetRoute(Destination);
if (!NCE) {
/* We cannot get to the specified destination. Return error */
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
@ -527,7 +484,6 @@ UINT RouteGetRouteToDestination(
}
RCN2->State = RCN_STATE_COMPUTED;
RCN2->NTE = NTE;
RtlCopyMemory(&RCN2->Destination, Destination, sizeof(IP_ADDRESS));
RCN2->PathMTU = NCE->Interface->MTU;
RCN2->NCE = NCE;
@ -549,14 +505,12 @@ UINT RouteGetRouteToDestination(
PROUTE_CACHE_NODE RouteAddRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE IF,
PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Adds a (permanent) route to a destination
* ARGUMENTS:
* Destination = Pointer to destination address
* NTE = Pointer to net table entry
* IF = Pointer to interface to use
* NCE = Pointer to first hop to destination
* RETURNS:
@ -567,12 +521,11 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination(
KIRQL OldIrql;
PROUTE_CACHE_NODE RCN;
TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) NTE (0x%X) IF (0x%X) NCE (0x%X).\n",
Destination, NTE, IF, NCE));
TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) IF (0x%X) NCE (0x%X).\n",
Destination, IF, NCE));
TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NTE (%s) NCE (%s).\n",
TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NCE (%s).\n",
A2S(Destination),
A2S(NTE->Address),
A2S(&NCE->Address)));
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
@ -608,7 +561,6 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination(
/* Reference once for beeing alive */
RCN->State = RCN_STATE_PERMANENT;
RCN->NTE = NTE;
RtlCopyMemory(&RCN->Destination, Destination, sizeof(IP_ADDRESS));
RCN->PathMTU = IF->MTU;
RCN->NCE = NCE;
@ -638,25 +590,6 @@ VOID RouteRemoveRouteToDestination(
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
}
VOID RouteInvalidateNTE(
PNET_TABLE_ENTRY NTE)
/*
* FUNCTION: Removes all RCNs with references to an NTE
* ARGUMENTS:
* NTE = Pointer to net table entry to invalidate
*/
{
KIRQL OldIrql;
TI_DbgPrint(DEBUG_RCACHE, ("Called. NTE (0x%X).\n", NTE));
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
InvalidateNTEOnSubtree(NTE, RouteCache);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
}
VOID RouteInvalidateNCE(
PNEIGHBOR_CACHE_ENTRY NCE)
/*

View file

@ -153,136 +153,12 @@ UINT CommonPrefixLength(
for (j = 0; (Addr1[i] & Bitmask) == (Addr2[i] & Bitmask); j++)
Bitmask >>= 1;
TI_DbgPrint(DEBUG_ROUTER, ("Returning %d\n", 8 * i + j));
return 8 * i + j;
}
BOOLEAN HasPrefix(
PIP_ADDRESS Address,
PIP_ADDRESS Prefix,
UINT Length)
/*
* FUNCTION: Determines wether an address has an given prefix
* ARGUMENTS:
* Address = Pointer to address to use
* Prefix = Pointer to prefix to check for
* Length = Length of prefix
* RETURNS:
* TRUE if the address has the prefix, FALSE if not
* NOTES:
* The two addresses must be of the same type
*/
{
PUCHAR pAddress = (PUCHAR)&Address->Address;
PUCHAR pPrefix = (PUCHAR)&Prefix->Address;
TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) Prefix (0x%X) Length (%d).\n", Address, Prefix, Length));
#if 0
TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) Prefix (%s).\n",
A2S(Address), A2S(Prefix)));
#endif
/* Check that initial integral bytes match */
while (Length > 8) {
if (*pAddress++ != *pPrefix++)
return FALSE;
Length -= 8;
}
/* Check any remaining bits */
if ((Length > 0) && ((*pAddress >> (8 - Length)) != (*pPrefix >> (8 - Length))))
return FALSE;
return TRUE;
}
PNET_TABLE_ENTRY RouterFindBestNTE(
PIP_INTERFACE Interface,
PIP_ADDRESS Destination)
/*
* FUNCTION: Checks all on-link prefixes to find out if an address is on-link
* ARGUMENTS:
* Interface = Pointer to interface to use
* Destination = Pointer to destination address
* NOTES:
* If found the NTE if referenced
* RETURNS:
* Pointer to NTE if found, NULL if not
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PNET_TABLE_ENTRY Current;
UINT Length, BestLength = 0;
PNET_TABLE_ENTRY BestNTE = NULL;
TI_DbgPrint(DEBUG_ROUTER, ("Called. Interface (0x%X) Destination (0x%X).\n", Interface, Destination));
TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s).\n", A2S(Destination)));
TcpipAcquireSpinLock(&Interface->Lock, &OldIrql);
CurrentEntry = Interface->NTEListHead.Flink;
while (CurrentEntry != &Interface->NTEListHead) {
Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
TI_DbgPrint(DEBUG_ROUTER, ("Looking at NTE %s\n", A2S(Current->Address)));
Length = CommonPrefixLength(Destination, Current->Address);
if (BestNTE) {
if (Length > BestLength) {
BestNTE = Current;
BestLength = Length;
}
} else {
BestNTE = Current;
BestLength = Length;
}
CurrentEntry = CurrentEntry->Flink;
}
TcpipReleaseSpinLock(&Interface->Lock, OldIrql);
return BestNTE;
}
PIP_INTERFACE RouterFindOnLinkInterface(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE)
/*
* FUNCTION: Checks all on-link prefixes to find out if an address is on-link
* ARGUMENTS:
* Address = Pointer to address to check
* NTE = Pointer to NTE to check (NULL = check all interfaces)
* RETURNS:
* Pointer to interface if address is on-link, NULL if not
*/
{
PLIST_ENTRY CurrentEntry;
PPREFIX_LIST_ENTRY Current;
TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) NTE (0x%X).\n", Address, NTE));
TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) NTE (%s).\n",
A2S(Address), NTE ? A2S(NTE->Address) : ""));
CurrentEntry = PrefixListHead.Flink;
while (CurrentEntry != &PrefixListHead) {
Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
if (HasPrefix(Address, &Current->Prefix, Current->PrefixLength) &&
((!NTE) || (NTE->Interface == Current->Interface)))
return Current->Interface;
CurrentEntry = CurrentEntry->Flink;
}
return NULL;
}
PFIB_ENTRY RouterAddRoute(
PIP_ADDRESS NetworkAddress,
PIP_ADDRESS Netmask,
@ -335,15 +211,11 @@ PFIB_ENTRY RouterAddRoute(
}
PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE)
PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination)
/*
* FUNCTION: Finds a router to use to get to Destination
* ARGUMENTS:
* Destination = Pointer to destination address (NULL means don't care)
* NTE = Pointer to NTE describing net to send on
* (NULL means don't care)
* RETURNS:
* Pointer to NCE for router, NULL if none was found
* NOTES:
@ -358,11 +230,9 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
UINT Length, BestLength = 0;
PNEIGHBOR_CACHE_ENTRY NCE, BestNCE = NULL;
TI_DbgPrint(DEBUG_ROUTER, ("Called. Destination (0x%X) NTE (0x%X).\n", Destination, NTE));
TI_DbgPrint(DEBUG_ROUTER, ("Called. Destination (0x%X)\n", Destination));
TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s)\n", A2S(Destination)));
if( NTE )
TI_DbgPrint(DEBUG_ROUTER, ("NTE (%s).\n", A2S(NTE->Address)));
TcpipAcquireSpinLock(&FIBLock, &OldIrql);
@ -374,28 +244,27 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
NCE = Current->Router;
State = NCE->State;
if ((!NTE) || (NTE->Interface == NCE->Interface)) {
if (Destination)
Length = CommonPrefixLength(Destination, &NCE->Address);
else
Length = 0;
if (Destination)
Length = CommonPrefixLength(Destination, &NCE->Address);
else
Length = 0;
if (BestNCE) {
if ((State > BestState) ||
((State == BestState) &&
(Length > BestLength))) {
/* This seems to be a better router */
BestNCE = NCE;
BestLength = Length;
BestState = State;
}
} else {
/* First suitable router found, save it */
BestNCE = NCE;
BestLength = Length;
BestState = State;
}
if (BestNCE) {
if ((State > BestState) ||
((State == BestState) &&
(Length > BestLength))) {
/* This seems to be a better router */
BestNCE = NCE;
BestLength = Length;
BestState = State;
}
} else {
/* First suitable router found, save it */
BestNCE = NCE;
BestLength = Length;
BestState = State;
}
}
CurrentEntry = NextEntry;
}
@ -425,11 +294,11 @@ VOID RouterRemoveRoute(
}
PFIB_ENTRY RouterCreateRouteIPv4(
IPv4_RAW_ADDRESS NetworkAddress,
IPv4_RAW_ADDRESS Netmask,
IPv4_RAW_ADDRESS RouterAddress,
PNET_TABLE_ENTRY NTE,
PFIB_ENTRY RouterCreateRoute(
IP_ADDRESS NetworkAddress,
IP_ADDRESS Netmask,
IP_ADDRESS RouterAddress,
PIP_INTERFACE Interface,
UINT Metric)
/*
* FUNCTION: Creates a route with IPv4 addresses as parameters
@ -445,42 +314,21 @@ PFIB_ENTRY RouterCreateRouteIPv4(
* for providing this reference
*/
{
PIP_ADDRESS pNetworkAddress;
PIP_ADDRESS pNetmask;
PIP_ADDRESS pRouterAddress;
PNEIGHBOR_CACHE_ENTRY NCE;
PFIB_ENTRY FIBE;
pNetworkAddress = AddrBuildIPv4(NetworkAddress);
if (!pNetworkAddress) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
pNetmask = AddrBuildIPv4(Netmask);
if (!pNetmask) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
pRouterAddress = AddrBuildIPv4(RouterAddress);
if (!pRouterAddress) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
}
/* The NCE references RouterAddress. The NCE is referenced for us */
NCE = NBAddNeighbor(NTE->Interface,
pRouterAddress,
NCE = NBAddNeighbor(Interface,
&RouterAddress,
NULL,
NTE->Interface->AddressLength,
Interface->AddressLength,
NUD_PROBE);
if (!NCE) {
/* Not enough free resources */
return NULL;
}
FIBE = RouterAddRoute(pNetworkAddress, pNetmask, NCE, 1);
FIBE = RouterAddRoute(&NetworkAddress, &Netmask, NCE, 1);
if (!FIBE) {
/* Not enough free resources */
NBRemoveNeighbor(NCE);

View file

@ -112,7 +112,7 @@ NTSTATUS RawIPSendDatagram(
if( Status == NDIS_STATUS_SUCCESS )
Status = BuildRawIPPacket( &Packet,
BufferLen,
&AddrFile->ADE->Address,
&AddrFile->Address,
AddrFile->Port );
if( Status == NDIS_STATUS_SUCCESS ) {
@ -121,7 +121,7 @@ NTSTATUS RawIPSendDatagram(
BufferData + FIELD_OFFSET(IPv4_HEADER, DstAddr),
sizeof(IPv4_RAW_ADDRESS) );
Status = RouteGetRouteToDestination( &RemoteAddress, NULL, &RCN );
Status = RouteGetRouteToDestination( &RemoteAddress, &RCN );
if( !NT_SUCCESS(Status) ) {
FreeNdisPacket( Packet.NdisPacket );
@ -137,7 +137,7 @@ NTSTATUS RawIPSendDatagram(
VOID RawIPReceive(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket)
/*
* FUNCTION: Receives and queues a raw IP datagram

View file

@ -180,7 +180,7 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
LocalAddress.Address.IPv4Address,
RemoteAddress.Address.IPv4Address);
Status = RouteGetRouteToDestination( &RemoteAddress, NULL, &RCN );
Status = RouteGetRouteToDestination( &RemoteAddress, &RCN );
if( !NT_SUCCESS(Status) || !RCN ) return OSK_EADDRNOTAVAIL;

View file

@ -86,7 +86,7 @@ POSK_IFADDR TCPFindInterface( void *ClientData,
TI_DbgPrint(MID_TRACE,("Address is %x\n", addr_in->sin_addr.s_addr));
NCE = RouterGetRoute(&Destination, NULL);
NCE = RouterGetRoute(&Destination);
if( !NCE || !NCE->Interface ) {
TI_DbgPrint(MID_TRACE,("no neighbor cache or no interface (%x %x)\n",

View file

@ -73,11 +73,10 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
return Status;
}
VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
/*
* FUNCTION: Receives and queues TCP data
* ARGUMENTS:
* NTE = Pointer to net table entry which the packet was received on
* IPPacket = Pointer to an IP packet that was received
* NOTES:
* This is the low level interface for receiving TCP data
@ -357,6 +356,19 @@ NTSTATUS TCPAccept
return Status;
}
VOID TCPCancelReceiveRequest( PVOID Context ) {
PLIST_ENTRY ListEntry;
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)Context;
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
for( ListEntry = Connection->ReceiveRequest.Flink;
ListEntry != &Connection->ReceiveRequest;
ListEntry = ListEntry->Flink ) {
}
TcpipRecursiveMutexLeave( &TCPLock );
}
NTSTATUS TCPReceiveData
( PCONNECTION_ENDPOINT Connection,
PNDIS_BUFFER Buffer,
@ -404,6 +416,7 @@ NTSTATUS TCPReceiveData
Bucket->Request.RequestNotifyObject = Complete;
Bucket->Request.RequestContext = Context;
*BytesReceived = 0;
InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
Status = STATUS_PENDING;
TI_DbgPrint(MID_TRACE,("Queued read irp\n"));

View file

@ -218,7 +218,7 @@ NTSTATUS UDPSendDatagram(
Status = BuildUDPPacket( &Packet,
&RemoteAddress,
RemotePort,
&AddrFile->ADE->Address,
&AddrFile->Address,
AddrFile->Port,
BufferData,
DataSize );
@ -226,7 +226,7 @@ NTSTATUS UDPSendDatagram(
if( !NT_SUCCESS(Status) )
return Status;
Status = RouteGetRouteToDestination( &RemoteAddress, NULL, &RCN );
Status = RouteGetRouteToDestination( &RemoteAddress, &RCN );
if( !NT_SUCCESS(Status) )
return Status;
@ -341,7 +341,7 @@ NTSTATUS UDPReceiveDatagram(
}
VOID UDPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
VOID UDPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
/*
* FUNCTION: Receives and queues a UDP datagram
* ARGUMENTS:

View file

@ -200,7 +200,7 @@ VOID STDCALL LanReceiveWorker( PVOID Context ) {
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
while( (ListEntry =
ExInterlockedRemoveHeadList( &LanWorkList, &LanWorkLock )) ) {
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
@ -251,7 +251,7 @@ VOID STDCALL LanReceiveWorker( PVOID Context ) {
break;
}
FreeNdisPacket( Packet );
FreeNdisPacket( Packet );
}
}
@ -600,7 +600,7 @@ OpenRegistryKey( PNDIS_STRING RegistryPath, PHANDLE RegHandle ) {
static NTSTATUS ReadIPAddressFromRegistry( HANDLE RegHandle,
PWCHAR RegistryValue,
PIP_ADDRESS *Address ) {
PIP_ADDRESS Address ) {
UNICODE_STRING ValueName;
UNICODE_STRING UnicodeAddress;
NTSTATUS Status;
@ -646,13 +646,77 @@ static NTSTATUS ReadIPAddressFromRegistry( HANDLE RegHandle,
}
AnsiAddress.Buffer[AnsiAddress.Length] = 0;
*Address = AddrBuildIPv4(inet_addr(AnsiAddress.Buffer));
if (!Address) {
exFreePool(AnsiAddress.Buffer);
return STATUS_UNSUCCESSFUL;
AddrInitIPv4(Address, inet_addr(AnsiAddress.Buffer));
return STATUS_SUCCESS;
}
static NTSTATUS ReadStringFromRegistry( HANDLE RegHandle,
PWCHAR RegistryValue,
PUNICODE_STRING String ) {
UNICODE_STRING ValueName;
UNICODE_STRING UnicodeString;
NTSTATUS Status;
ULONG ResultLength;
UCHAR buf[1024];
PKEY_VALUE_PARTIAL_INFORMATION Information = (PKEY_VALUE_PARTIAL_INFORMATION)buf;
RtlInitUnicodeString(&ValueName, RegistryValue);
Status =
ZwQueryValueKey(RegHandle,
&ValueName,
KeyValuePartialInformation,
Information,
sizeof(buf),
&ResultLength);
if (!NT_SUCCESS(Status))
return Status;
/* IP address is stored as a REG_MULTI_SZ - we only pay attention to the first one though */
TI_DbgPrint(MIN_TRACE, ("Information DataLength: 0x%x\n", Information->DataLength));
UnicodeString.Buffer = (PWCHAR)&Information->Data;
UnicodeString.Length = Information->DataLength;
UnicodeString.MaximumLength = Information->DataLength;
String->Buffer =
(PWCHAR)exAllocatePool( NonPagedPool,
UnicodeString.MaximumLength + sizeof(WCHAR) );
if( !String->Buffer ) return STATUS_NO_MEMORY;
String->MaximumLength = UnicodeString.MaximumLength;
RtlCopyUnicodeString( String, &UnicodeString );
return STATUS_SUCCESS;
}
static VOID GetSimpleAdapterNameFromRegistryPath
( PUNICODE_STRING TargetString,
PUNICODE_STRING RegistryPath ) {
PWCHAR i, LastSlash = NULL;
UINT NewStringLength = 0;
for( i = RegistryPath->Buffer;
i < RegistryPath->Buffer +
(RegistryPath->Length / sizeof(WCHAR));
i++ ) if( *i == '\\' ) LastSlash = i;
if( LastSlash ) LastSlash++; else LastSlash = RegistryPath->Buffer;
NewStringLength = RegistryPath->MaximumLength -
((LastSlash - RegistryPath->Buffer) * sizeof(WCHAR));
TargetString->Buffer =
(PWCHAR)exAllocatePool( NonPagedPool, NewStringLength );
if( !TargetString->Buffer ) {
TargetString->Length = TargetString->MaximumLength = 0;
return;
}
return *Address ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
TargetString->Length = TargetString->MaximumLength = NewStringLength;
RtlCopyMemory( TargetString->Buffer, LastSlash, NewStringLength );
}
VOID BindAdapter(
@ -668,8 +732,6 @@ VOID BindAdapter(
*/
{
PIP_INTERFACE IF;
PIP_ADDRESS Address = 0;
PIP_ADDRESS Netmask = 0;
NDIS_STATUS NdisStatus;
LLIP_BIND_INFO BindInfo;
ULONG Lookahead = LOOKAHEAD_SIZE;
@ -719,12 +781,25 @@ VOID BindAdapter(
if(NT_SUCCESS(Status))
Status = ReadIPAddressFromRegistry( RegHandle, L"IPAddress",
&Address );
&IF->Unicast );
if(NT_SUCCESS(Status))
Status = ReadIPAddressFromRegistry( RegHandle, L"SubnetMask",
&Netmask );
if(!NT_SUCCESS(Status) || !Address || !Netmask)
&IF->Netmask );
if(NT_SUCCESS(Status)) {
Status = ReadStringFromRegistry( RegHandle, L"DeviceDesc",
&IF->Name );
RtlZeroMemory( &IF->Name, sizeof( IF->Name ) );
/* I think that not getting a devicedesc is not a fatal error */
if( !NT_SUCCESS(Status) ) {
if( IF->Name.Buffer ) exFreePool( IF->Name.Buffer );
GetSimpleAdapterNameFromRegistryPath( &IF->Name, RegistryPath );
}
Status = STATUS_SUCCESS;
}
if(!NT_SUCCESS(Status))
{
TI_DbgPrint(MIN_TRACE, ("Unable to open protocol-specific registry key: 0x%x\n", Status));
@ -738,19 +813,12 @@ VOID BindAdapter(
TI_DbgPrint
(MID_TRACE,
("--> Our IP address on this interface: '%s'\n",
A2S(Address)));
A2S(&IF->Unicast)));
TI_DbgPrint
(MID_TRACE,
("--> Our net mask on this interface: '%s'\n",
A2S(Netmask)));
/* Create a net table entry for this interface */
if (!IPCreateNTE(IF, Address, AddrCountPrefixBits(Netmask))) {
TI_DbgPrint(MIN_TRACE, ("IPCreateNTE() failed.\n"));
IPDestroyInterface(IF);
return;
}
A2S(&IF->Netmask)));
/* Register interface with IP layer */
IPRegisterInterface(IF);
@ -794,7 +862,7 @@ VOID UnbindAdapter(
NDIS_STATUS LANRegisterAdapter(
PNDIS_STRING AdapterName,
PNDIS_STRING RegistryPath)
PNDIS_STRING RegistryPath)
/*
* FUNCTION: Registers protocol with an NDIS adapter
* ARGUMENTS:

View file

@ -55,14 +55,10 @@ BOOLEAN AddrIsEqualIPv4(
PIP_ADDRESS Address1,
IPv4_RAW_ADDRESS Address2);
PIP_ADDRESS AddrBuildIPv4(
IPv4_RAW_ADDRESS Address);
BOOLEAN AddrLocateADEv4(
IPv4_RAW_ADDRESS MatchAddress, PIP_ADDRESS Address);
PIP_ADDRESS AddrCloneAddress(
PIP_ADDRESS Address);
PADDRESS_ENTRY AddrLocateADEv4(
IPv4_RAW_ADDRESS Address);
BOOLEAN IPGetDefaultAddress( PIP_ADDRESS Address );
PADDRESS_FILE AddrSearchFirst(
PIP_ADDRESS Address,

View file

@ -24,9 +24,7 @@ typedef struct ARP_HEADER {
#define ARP_OPCODE_REPLY WH2N(0x0002) /* ARP reply */
BOOLEAN ARPTransmit(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE);
BOOLEAN ARPTransmit(PIP_ADDRESS Address, PIP_INTERFACE Interface);
VOID ARPReceive(
PVOID Context,

View file

@ -50,20 +50,19 @@ typedef struct ICMP_HEADER {
VOID ICMPReceive(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket);
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket,
PIP_TRANSMIT_COMPLETE Complete,
PVOID Context);
VOID ICMPReply(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket,
UCHAR Type,
UCHAR Code);
UCHAR Type,
UCHAR Code);
#endif /* __ICMP_H */

View file

@ -6,11 +6,11 @@
NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface,
ULONG Type,
PULONG Address );
UINT CountInterfaces();
UINT CountInterfaceAddresses( PIP_INTERFACE Interface );
NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed );
NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, PCHAR NameBuffer,
UINT NameMaxLen );
PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address);
#endif//_TCPIP_INTERFACE_H

View file

@ -106,35 +106,15 @@ typedef struct _PACKET_CONTEXT {
/* The ProtocolReserved field is structured as a PACKET_CONTEXT */
#define PC(Packet) ((PPACKET_CONTEXT)(&Packet->ProtocolReserved))
/* Address information a.k.a ADE */
typedef struct _ADDRESS_ENTRY {
DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
struct _NET_TABLE_ENTRY *NTE; /* NTE associated with this address */
UCHAR Type; /* Address type */
IP_ADDRESS Address; /* Pointer to address identifying this entry */
} ADDRESS_ENTRY, *PADDRESS_ENTRY;
/* Values for address type -- also the interface flags */
/* These values are mean to overlap meaningfully with the BSD ones */
#define ADE_UNICAST 0x01
#define ADE_MULTICAST 0x02
#define ADE_BROADCAST 0x02
#define ADE_ADDRMASK 0x04
#define ADE_POINTOPOINT 0x10
#define ADE_MULTICAST 0x8000
/* There is one NTE for each source (unicast) address assigned to an interface */
typedef struct _NET_TABLE_ENTRY {
DEFINE_TAG
LIST_ENTRY IFListEntry; /* Entry on interface list */
LIST_ENTRY NTListEntry; /* Entry on net table list */
struct _IP_INTERFACE *Interface; /* Pointer to interface on this net */
struct _PREFIX_LIST_ENTRY *PLE; /* Pointer to prefix list entry for this net */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
PIP_ADDRESS Address; /* Pointer to unicast address for this net */
} NET_TABLE_ENTRY, *PNET_TABLE_ENTRY;
/* Link layer transmit prototype */
typedef VOID (*LL_TRANSMIT_ROUTINE)(
PVOID Context,
@ -158,8 +138,6 @@ typedef struct _LLIP_BIND_INFO {
/* Information about an IP interface */
typedef struct _IP_INTERFACE {
DEFINE_TAG
LIST_ENTRY NTEListHead; /* List of NTEs on this interface */
LIST_ENTRY ADEListHead; /* List of ADEs on this interface */
LIST_ENTRY ListEntry; /* Entry on list */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources used by the object */
KSPIN_LOCK Lock; /* Spin lock for this object */
@ -167,10 +145,14 @@ typedef struct _IP_INTERFACE {
UINT HeaderSize; /* Size of link level header */
UINT MinFrameSize; /* Minimum frame size in bytes */
UINT MTU; /* Maximum transmission unit */
IP_ADDRESS Unicast; /* Unicast address */
IP_ADDRESS PointToPoint; /* Point to point address */
IP_ADDRESS Netmask; /* Netmask */
IP_ADDRESS Broadcast; /* Broadcast */
UNICODE_STRING Name; /* Adapter name */
PUCHAR Address; /* Pointer to interface address */
UINT AddressLength; /* Length of address in bytes */
LL_TRANSMIT_ROUTINE Transmit; /* Pointer to transmit function */
PVOID TCPContext; /* TCP Content for this interface */
} IP_INTERFACE, *PIP_INTERFACE;
@ -178,7 +160,7 @@ typedef struct _IP_INTERFACE {
#define IP_PROTOCOL_TABLE_SIZE 0x100
typedef VOID (*IP_PROTOCOL_HANDLER)(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket);
/* Loopback adapter address information (network byte order) */
@ -214,11 +196,6 @@ PIP_PACKET IPInitializePacket(
PIP_PACKET IPPacket,
ULONG Type);
PNET_TABLE_ENTRY IPCreateNTE(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
UINT PrefixLength);
PIP_INTERFACE IPCreateInterface(
PLLIP_BIND_INFO BindInfo);
@ -231,26 +208,10 @@ BOOLEAN IPRegisterInterface(
VOID IPUnregisterInterface(
PIP_INTERFACE IF);
PNET_TABLE_ENTRY IPLocateNTEOnInterface(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
PUINT AddressType);
PNET_TABLE_ENTRY IPLocateNTE(
PIP_ADDRESS Address,
PUINT AddressType);
PADDRESS_ENTRY IPLocateADE(
PIP_ADDRESS Address,
UINT AddressType);
PADDRESS_ENTRY IPGetDefaultADE(
UINT AddressType);
VOID STDCALL IPTimeout( PVOID Context );
VOID IPDispatchProtocol(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket);
VOID IPRegisterProtocol(

View file

@ -17,7 +17,6 @@
#include <receive.h>
#include <transmit.h>
#include <router.h>
#include <prefix.h>
#include <pool.h>
#include <rawip.h>
#include <icmp.h>
@ -36,3 +35,6 @@
#include <oskittcp.h>
#include <interface.h>
#include <ports.h>
#include <pseh.h>
#define NTOS_MODE_USER
#include <ntos.h>

View file

@ -1,27 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/info.h
* PURPOSE: TdiQueryInformation definitions
*/
#ifndef __PREFIX_H
#define __PREFIX_H
/* Prefix List Entry */
typedef struct _PREFIX_LIST_ENTRY {
DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
PIP_INTERFACE Interface; /* Pointer to interface */
IP_ADDRESS Prefix; /* Pointer to prefix */
UINT PrefixLength; /* Length of prefix */
} PREFIX_LIST_ENTRY, *PPREFIX_LIST_ENTRY;
extern LIST_ENTRY PrefixListHead;
extern KSPIN_LOCK PrefixListLock;
VOID InitPLE();
PPREFIX_LIST_ENTRY CreatePLE(PIP_INTERFACE IF, PIP_ADDRESS Prefix, UINT Len);
VOID DestroyPLE(PPREFIX_LIST_ENTRY PLE);
VOID DestroyPLEs();
#endif/*__PREFIX_H*/

View file

@ -15,7 +15,7 @@ NTSTATUS RawIPSendDatagram(
PULONG DataUsed);
VOID RawIPReceive(
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE Interface,
PIP_PACKET IPPacket);
NTSTATUS RawIPStartup(

View file

@ -28,7 +28,6 @@ typedef struct ROUTE_CACHE_NODE {
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
UCHAR State; /* RCN state (RCN_STATE_*) */
IP_ADDRESS Destination; /* Destination address */
PNET_TABLE_ENTRY NTE; /* Preferred NTE */
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE for first hop (NULL if none) */
UINT PathMTU; /* Path MTU to destination */
} ROUTE_CACHE_NODE, *PROUTE_CACHE_NODE;
@ -56,26 +55,18 @@ NTSTATUS RouteShutdown(
UINT RouteGetRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PROUTE_CACHE_NODE *RCN);
PROUTE_CACHE_NODE RouteAddRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE IF,
PNEIGHBOR_CACHE_ENTRY NCE);
VOID RouteRemoveRouteToDestination(
PROUTE_CACHE_NODE RCN);
VOID RouteRemoveRouteToDestination( PROUTE_CACHE_NODE RCN );
VOID RouteInvalidateNTE(
PNET_TABLE_ENTRY NTE);
VOID RouteInvalidateNCE( PNEIGHBOR_CACHE_ENTRY NCE );
VOID RouteInvalidateNCE(
PNEIGHBOR_CACHE_ENTRY NCE);
NTSTATUS
RouteFriendlyAddRoute( PIPROUTE_ENTRY ire );
NTSTATUS RouteFriendlyAddRoute( PIPROUTE_ENTRY ire );
UINT CountRouteNodes( PROUTE_CACHE_NODE Node );

View file

@ -20,33 +20,22 @@ typedef struct _FIB_ENTRY {
UINT Metric; /* Cost of this route */
} FIB_ENTRY, *PFIB_ENTRY;
PNET_TABLE_ENTRY RouterFindBestNTE(
PIP_INTERFACE Interface,
PIP_ADDRESS Destination);
PIP_INTERFACE RouterFindOnLinkInterface(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE);
PFIB_ENTRY RouterAddRoute(
PIP_ADDRESS NetworkAddress,
PIP_ADDRESS Netmask,
PNEIGHBOR_CACHE_ENTRY Router,
UINT Metric);
PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE);
PNEIGHBOR_CACHE_ENTRY RouterGetRoute(PIP_ADDRESS Destination);
VOID RouterRemoveRoute(
PFIB_ENTRY FIBE);
PFIB_ENTRY RouterCreateRouteIPv4(
IPv4_RAW_ADDRESS NetworkAddress,
IPv4_RAW_ADDRESS Netmask,
IPv4_RAW_ADDRESS RouterAddress,
PNET_TABLE_ENTRY NTE,
PFIB_ENTRY RouterCreateRoute(
IP_ADDRESS NetworkAddress,
IP_ADDRESS Netmask,
IP_ADDRESS RouterAddress,
PIP_INTERFACE Interface,
UINT Metric);
NTSTATUS RouterStartup(

View file

@ -84,6 +84,8 @@ typedef struct _SLEEPING_THREAD {
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext );
VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection );
VOID TCPCancelReceiveRequest( PVOID Context );
NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
UINT Family, UINT Type, UINT Proto );

View file

@ -7,10 +7,6 @@
PLIST_ENTRY TIPASTE(n,Entry); \
PIP_INTERFACE n;
#define ADE_LIST_ITER(n) \
PLIST_ENTRY TIPASTE(n,Entry); \
PADDRESS_ENTRY n;
#define ForEachInterface(n) \
TIPASTE(n,Entry) = InterfaceListHead.Flink; \
while (TIPASTE(n,Entry) != &InterfaceListHead) { \
@ -28,13 +24,4 @@
TIPASTE(n,Entry) = TIPASTE(n,Entry)->Flink; \
}
#define ForEachADE(ADEList,n) \
TIPASTE(n,Entry) = ADEList.Flink; \
ASSERT(TIPASTE(n,Entry)); \
while (TIPASTE(n,Entry) != &ADEList) { \
ASSERT(TIPASTE(n,Entry)); \
n = CONTAINING_RECORD(TIPASTE(n,Entry), \
ADDRESS_ENTRY, ListEntry); \
ASSERT(n);
#endif/*_TILISTS_H*/

View file

@ -174,7 +174,7 @@ typedef struct _ADDRESS_FILE {
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */
USHORT Flags; /* Flags for address file (see below) */
PADDRESS_ENTRY ADE; /* Associated address entry */
IP_ADDRESS Address; /* Address of this address file */
USHORT Protocol; /* Protocol number */
USHORT Port; /* Network port (network byte order) */
WORK_QUEUE_ITEM WorkItem; /* Work queue item handle */

View file

@ -61,8 +61,8 @@ NTSTATUS UDPReceiveDatagram(
PVOID Context);
VOID UDPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
PIP_INTERFACE Interface,
PIP_PACKET IPPacket);
NTSTATUS UDPStartup(
VOID);

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.31 2004/11/13 00:06:32 arty Exp $
# $Id: makefile,v 1.32 2004/11/25 23:56:59 arty Exp $
PATH_TO_TOP = ../../..
@ -13,6 +13,7 @@ TARGET_PCH = include/precomp.h
# -DMEMTRACK
TARGET_CFLAGS = \
-D__USE_W32API \
-D_SEH_NO_NATIVE_NLG \
-DMEMTRACK \
-DNDIS40 \
-Wall -Werror \
@ -25,6 +26,7 @@ TARGET_DDKLIBS = \
$(PATH_TO_TOP)/dk/w32/lib/ip.a \
$(PATH_TO_TOP)/dk/w32/lib/oskittcp.a \
$(PATH_TO_TOP)/dk/w32/lib/rosrtl.a \
$(PATH_TO_TOP)/dk/w32/lib/pseh.a \
ndis.a
TARGET_CLEAN = tcpip/*.o datalink/*.o \

View file

@ -469,7 +469,7 @@ NTSTATUS DispTdiDisconnect(
Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
Address->Address[0].Address[0].sin_port = AddrFile->Port;
Address->Address[0].Address[0].in_addr = AddrFile->ADE->Address.Address.IPv4Address;
Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address;
RtlZeroMemory(
&Address->Address[0].Address[0].sin_zero,
sizeof(Address->Address[0].Address[0].sin_zero));
@ -595,7 +595,7 @@ NTSTATUS DispTdiQueryInformation(
Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
Address->Address[0].Address[0].sin_port = AddrFile->Port;
Address->Address[0].Address[0].in_addr = AddrFile->ADE->Address.Address.IPv4Address;
Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address;
RtlZeroMemory(
&Address->Address[0].Address[0].sin_zero,
sizeof(Address->Address[0].Address[0].sin_zero));
@ -643,10 +643,11 @@ NTSTATUS DispTdiReceive(
}
/* Initialize a receive request */
Status = DispPrepareIrpForCancel(
IrpSp->FileObject->FsContext,
Irp,
(PDRIVER_CANCEL)DispCancelRequest);
Status = DispPrepareIrpForCancel
(TranContext->Handle.ConnectionContext,
Irp,
(PDRIVER_CANCEL)TCPCancelReceiveRequest);
TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
if (NT_SUCCESS(Status))
{
@ -708,10 +709,12 @@ NTSTATUS DispTdiReceiveDatagram(
Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
Request.RequestNotifyObject = DispDataRequestComplete;
Request.RequestContext = Irp;
Status = DispPrepareIrpForCancel(
IrpSp->FileObject->FsContext,
Irp,
(PDRIVER_CANCEL)DispCancelRequest);
if (NT_SUCCESS(Status))
{
PCHAR DataBuffer;
@ -786,6 +789,7 @@ NTSTATUS DispTdiSend(
IrpSp->FileObject->FsContext,
Irp,
(PDRIVER_CANCEL)DispCancelRequest);
TI_DbgPrint(MID_TRACE,("TCPIP<<< Got an MDL: %x\n", Irp->MdlAddress));
if (NT_SUCCESS(Status))
{
@ -849,6 +853,7 @@ NTSTATUS DispTdiSendDatagram(
IrpSp->FileObject->FsContext,
Irp,
(PDRIVER_CANCEL)DispCancelRequest);
if (NT_SUCCESS(Status)) {
PCHAR DataBuffer;
UINT BufferSize;
@ -1092,8 +1097,10 @@ VOID DispTdiQueryInformationExComplete(
MmUnlockPages(QueryContext->InputMdl);
IoFreeMdl(QueryContext->InputMdl);
MmUnlockPages(QueryContext->OutputMdl);
IoFreeMdl(QueryContext->OutputMdl);
if( QueryContext->OutputMdl ) {
MmUnlockPages(QueryContext->OutputMdl);
IoFreeMdl(QueryContext->OutputMdl);
}
QueryContext->Irp->IoStatus.Information = ByteCount;
QueryContext->Irp->IoStatus.Status = Status;
@ -1163,9 +1170,7 @@ NTSTATUS DispTdiQueryInformationEx(
QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
if (QueryContext) {
#ifdef _MSC_VER
try {
#endif
_SEH_TRY {
InputMdl = IoAllocateMdl(InputBuffer,
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
FALSE, TRUE, NULL);
@ -1187,14 +1192,12 @@ NTSTATUS DispTdiQueryInformationEx(
RtlCopyMemory(&QueryContext->QueryInfo,
InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
#ifdef _MSC_VER
} except(EXCEPTION_EXECUTE_HANDLER) {
Status = GetExceptionCode();
}
#endif
} _SEH_HANDLE {
Status = _SEH_GetExceptionCode();
} _SEH_END;
if (NT_SUCCESS(Status)) {
Size = MmGetMdlByteCount(OutputMdl);
@ -1231,8 +1234,57 @@ NTSTATUS DispTdiQueryInformationEx(
ExFreePool(QueryContext);
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
} else
Status = STATUS_INVALID_PARAMETER;
} else if( InputBufferLength ==
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) {
/* Handle the case where the user is probing the buffer for length */
TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
InputBufferLength, OutputBufferLength));
InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
Size = 0;
QueryContext = ExAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
_SEH_TRY {
InputMdl = IoAllocateMdl(InputBuffer,
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
FALSE, TRUE, NULL);
MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
IoModifyAccess);
InputMdlLocked = TRUE;
Status = STATUS_SUCCESS;
} _SEH_HANDLE {
TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n"));
Status = _SEH_GetExceptionCode();
} _SEH_END;
if( !NT_SUCCESS(Status) || !InputMdl ) {
if( InputMdl ) IoFreeMdl( InputMdl );
ExFreePool(QueryContext);
return Status;
}
RtlCopyMemory(&QueryContext->QueryInfo,
InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
QueryContext->Irp = Irp;
QueryContext->InputMdl = InputMdl;
QueryContext->OutputMdl = NULL;
Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
Request.RequestContext = QueryContext;
Status = InfoTdiQueryInformationEx(&Request,
&QueryContext->QueryInfo.ID,
NULL,
&Size,
&QueryContext->QueryInfo.Context);
DispTdiQueryInformationExComplete(QueryContext, Status, Size);
TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
} else Status = STATUS_INVALID_PARAMETER;
TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status));

View file

@ -69,7 +69,7 @@ PADDRESS_FILE AddrSearchNext(
while (CurrentEntry != &AddressFileListHead) {
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);
IPAddress = &Current->ADE->Address;
IPAddress = &Current->Address;
TI_DbgPrint(DEBUG_ADDRFILE, ("Comparing: ((%d, %d, %s), (%d, %d, %s)).\n",
WN2H(Current->Port),
@ -226,8 +226,9 @@ NTSTATUS FileOpenAddress(
USHORT Protocol,
PVOID Options)
{
PADDRESS_FILE AddrFile;
IPv4_RAW_ADDRESS IPv4Address;
BOOLEAN Matched;
PADDRESS_FILE AddrFile;
TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol));
@ -250,18 +251,18 @@ NTSTATUS FileOpenAddress(
/* FIXME: IPv4 only */
IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0)
AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
Matched = IPGetDefaultAddress(&AddrFile->Address);
else
AddrFile->ADE = AddrLocateADEv4(IPv4Address);
Matched = AddrLocateADEv4(IPv4Address, &AddrFile->Address);
if (!AddrFile->ADE) {
if (!Matched) {
ExFreePool(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
}
TI_DbgPrint(MID_TRACE, ("Opening address %s for communication (P=%d U=%d).\n",
A2S(&AddrFile->ADE->Address), Protocol, IPPROTO_UDP));
A2S(&AddrFile->Address), Protocol, IPPROTO_UDP));
/* Protocol specific handling */
switch (Protocol) {

View file

@ -147,9 +147,10 @@ TDI_STATUS InfoTdiQueryInformationEx(
{
if ((ID->toi_class != INFO_CLASS_GENERIC) ||
(ID->toi_type != INFO_TYPE_PROVIDER) ||
(ID->toi_id != ENTITY_LIST_ID))
(ID->toi_id != ENTITY_LIST_ID)) {
TI_DbgPrint(MAX_TRACE,("Invalid parameter\n"));
Status = TDI_INVALID_PARAMETER;
else
} else
Status = InfoTdiQueryListEntities(Buffer, BufferSize);
} else {
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );

View file

@ -37,7 +37,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer,
ADE_UNICAST,
&IpAddress->Addr );
GetInterfaceIPv4Address( CurrentIF,
ADE_MULTICAST,
ADE_BROADCAST,
&IpAddress->BcastAddr );
GetInterfaceIPv4Address( CurrentIF,
ADE_ADDRMASK,
@ -86,7 +86,7 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
while( RtCurrent < RouteEntries + RtCount ) {
/* Copy Desitnation */
if( RCacheCur->Router ) {
TI_DbgPrint(MAX_TRACE, ("%d: NA %08x NM %08x GW %08x MT %d\n",
TI_DbgPrint(MAX_TRACE, ("%d: NA %08x NM %08x GW %08x MT %x\n",
RtCurrent - RouteEntries,
&RCacheCur->NetworkAddress.Address,
&RCacheCur->Netmask.Address,
@ -108,11 +108,12 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
RtCurrent->Type = 2 /* PF_INET */;
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
for( RtCurrent->Index = EntityCount - 1;
RtCurrent->Index >= 0 &&
for( RtCurrent->Index = EntityCount;
RtCurrent->Index > 0 &&
RCacheCur->Router->Interface !=
EntityList[RtCurrent->Index].context;
EntityList[RtCurrent->Index - 1].context;
RtCurrent->Index-- );
RtCurrent->Index = EntityList[RtCurrent->Index].tei_instance;
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
} else {
@ -140,31 +141,17 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer,
PUINT BufferSize ) {
KIRQL OldIrql;
IF_LIST_ITER(CurrentIF);
IPSNMP_INFO SnmpInfo;
UINT IfCount = CountInterfaces();
UINT AddrCount = 0;
UINT RouteCount = CountRouteNodes( NULL );
TDI_STATUS Status = TDI_INVALID_REQUEST;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
/* Count number of addresses */
AddrCount = 0;
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
ForEachInterface(CurrentIF) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
AddrCount += CountInterfaceAddresses( CurrentIF );
} EndFor(CurrentIF);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
SnmpInfo.NumIf = IfCount;
SnmpInfo.NumAddr = AddrCount;
SnmpInfo.NumAddr = 1;
SnmpInfo.NumRoutes = RouteCount;
Status = InfoCopyOut( (PCHAR)&SnmpInfo, sizeof(SnmpInfo),
@ -227,6 +214,5 @@ TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass,
TDIEntityID *id,
PCHAR Buffer,
UINT BufferSize ) {
TDI_STATUS Status = TDI_INVALID_REQUEST;
return Status;
return STATUS_UNSUCCESSFUL;
}