Removed remaining kernel imports from ip lib.

Removed unneeded precomp.h from drivers/lib/ip.
Removed some memtrack and other spew.
Removed datagram send pipe part, and accompanying address file queue.
Simplified send pipe (major changes):
- Neighbor is solely responsible for firing normal ip datagrams to the peer.
- Transmit is the only place normal ip datagrams are passed to neighbor from.
- Simplified fragmentation code.
- Made callbacks explicit and always called in neighbor and transmit.
- Clarified ownership of transmitted NdisPacket.
- Ditto IPPackets here and in icmp.
- PC(Packet)->DLComplete is *only* used by lan.c and loopback.c
- Simplified loopback send mechanism
Added the beginnings of a test suite

svn path=/trunk/; revision=11582
This commit is contained in:
Art Yerkes
2004-11-07 20:37:21 +00:00
parent da9108e6ff
commit 8a640a70d2
67 changed files with 1853 additions and 1994 deletions
-35
View File
@@ -1,35 +0,0 @@
#include <limits.h>
#include <roscfg.h>
#include <basetsd.h>
#include <ddk/ntddk.h>
#include <rosrtl/string.h>
#include <rosrtl/recmutex.h>
#include <tcpip.h>
#include <loopback.h>
#include <ip.h>
#include <icmp.h>
#include <udp.h>
#include <tcp.h>
#include <rawip.h>
#include <address.h>
#include <receive.h>
#include <transmit.h>
#include <routines.h>
#include <neighbor.h>
#include <checksum.h>
#include <route.h>
#include <router.h>
#include <prefix.h>
#include <pool.h>
#include <arp.h>
#include <lan.h>
#include <irp.h>
#include <tilists.h>
#include <dispatch.h>
#include <fileobjs.h>
#include <datagram.h>
#include <info.h>
#include <ndishack.h>
#include <memtrack.h>
#include <interface.h>
#include <oskittcp.h>
+2 -2
View File
@@ -1,4 +1,4 @@
# $Id: makefile,v 1.5 2004/10/08 01:28:32 arty Exp $
# $Id: makefile,v 1.6 2004/11/07 20:37:20 arty Exp $
PATH_TO_TOP = ../../..
@@ -24,6 +24,7 @@ TARGET_OBJECTS = \
network/address.o \
network/arp.o \
network/checksum.o \
transport/datagram/datagram.o \
network/i386/checksum.o \
network/icmp.o \
network/interface.o \
@@ -37,7 +38,6 @@ TARGET_OBJECTS = \
network/router.o \
network/routines.o \
network/transmit.o \
transport/datagram/datagram.o \
transport/rawip/rawip.o \
transport/tcp/event.o \
transport/tcp/if.o \
+3 -4
View File
@@ -93,7 +93,7 @@ VOID IPAddressFree(
* Nothing
*/
{
ExFreePool(Object);
PoolFreeBuffer(Object);
}
@@ -192,7 +192,7 @@ NTSTATUS AddrBuildAddress(
ValidAddr = (PTDI_ADDRESS_IP)TdiAddress->Address;
IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
if (!IPAddress)
return STATUS_INSUFFICIENT_RESOURCES;
@@ -305,9 +305,8 @@ PIP_ADDRESS AddrBuildIPv4(
{
PIP_ADDRESS IPAddress;
IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
if (IPAddress != NULL) {
IPAddress->RefCount = 1;
IPAddress->Type = IP_ADDRESS_V4;
IPAddress->Address.IPv4Address = Address;
IPAddress->Free = IPAddressFree;
-3
View File
@@ -222,7 +222,6 @@ VOID ARPReceive(
AddrInitIPv4(Address, *((PULONG)SenderProtoAddress));
NCE = NBLocateNeighbor(Address);
if (NCE) {
DereferenceObject(Address);
/* We know the sender. Update the hardware address
and state in our neighbor address cache */
NBUpdateNeighbor(NCE, SenderHWAddress, NUD_REACHABLE);
@@ -233,8 +232,6 @@ VOID ARPReceive(
NCE = NBAddNeighbor(Interface, Address, SenderHWAddress,
Header->HWAddrLen, NUD_REACHABLE);
}
if (NCE)
DereferenceObject(NCE)
if (Header->Opcode != ARP_OPCODE_REQUEST)
return;
+44 -65
View File
@@ -25,21 +25,20 @@ VOID SendICMPComplete(
* This routine is called by IP when a ICMP send completes
*/
{
PIP_PACKET IPPacket = NULL;
IPPacket =(PIP_PACKET)Context;
TI_DbgPrint(DEBUG_ICMP, ("Freeing NDIS packet (%X).\n", Packet));
/* Free packet */
FreeNdisPacket(Packet);
TI_DbgPrint(DEBUG_ICMP, ("Freeing IP packet at %X.\n", IPPacket));
TI_DbgPrint(DEBUG_ICMP, ("Done\n"));
}
PIP_PACKET PrepareICMPPacket(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket,
PIP_ADDRESS Destination,
PCHAR Data,
UINT DataSize)
/*
* FUNCTION: Prepares an ICMP packet
@@ -51,42 +50,41 @@ PIP_PACKET PrepareICMPPacket(
* Pointer to IP packet, NULL if there is not enough free resources
*/
{
PIP_PACKET IPPacket;
PNDIS_PACKET NdisPacket;
NDIS_STATUS NdisStatus;
PIPv4_HEADER IPHeader;
PVOID DataBuffer;
ULONG Size;
TI_DbgPrint(DEBUG_ICMP, ("Called. DataSize (%d).\n", DataSize));
/* Prepare ICMP packet */
/* FIXME: Assumes IPv4*/
IPPacket = IPCreatePacket(IP_ADDRESS_V4);
if (!IPPacket)
return NULL;
/* No special flags */
IPPacket->Flags = 0;
Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) +
sizeof(ICMP_HEADER) + DataSize;
DataBuffer = exAllocatePool(NonPagedPool, Size);
if (!DataBuffer) {
exFreePool( IPPacket );
return NULL;
}
Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) + DataSize;
TI_DbgPrint(DEBUG_ICMP, ("Size (%d). Data at (0x%X).\n", Size, DataBuffer));
TI_DbgPrint(MAX_TRACE, ("NdisPacket at (0x%X).\n", NdisPacket));
/* Allocate NDIS packet */
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Size );
if( !NT_SUCCESS(NdisStatus) ) return NULL;
IPPacket->NdisPacket = NdisPacket;
GetDataPtr( IPPacket->NdisPacket, MaxLLHeaderSize,
(PCHAR *)&IPPacket->Header, &IPPacket->ContigSize );
IPPacket->Data = ((PCHAR)IPPacket->Header) + IPPacket->HeaderSize;
TI_DbgPrint(DEBUG_ICMP, ("Size (%d). Data at (0x%X).\n", Size, Data));
TI_DbgPrint(DEBUG_ICMP, ("NdisPacket at (0x%X).\n", NdisPacket));
IPPacket->Header = (PVOID)((ULONG_PTR)DataBuffer + MaxLLHeaderSize);
IPPacket->HeaderSize = sizeof(IPv4_HEADER);
IPPacket->Data = (PVOID)(((ULONG_PTR)IPPacket->Header) +
IPPacket->HeaderSize);
IPPacket->TotalSize = Size - MaxLLHeaderSize;
TI_DbgPrint(DEBUG_ICMP, ("Copying Address: %x -> %x\n",
&IPPacket->DstAddr, Destination));
RtlCopyMemory(&IPPacket->DstAddr, Destination, sizeof(IP_ADDRESS));
RtlCopyMemory(IPPacket->Data, Data, DataSize);
/* Build IPv4 header. FIXME: IPv4 only */
@@ -97,8 +95,7 @@ PIP_PACKET PrepareICMPPacket(
/* Normal Type-of-Service */
IPHeader->Tos = 0;
/* Length of data and header */
IPHeader->TotalLength = WH2N((USHORT)DataSize +
sizeof(IPv4_HEADER) + sizeof(ICMP_HEADER));
IPHeader->TotalLength = WH2N((USHORT)DataSize + sizeof(IPv4_HEADER));
/* Identification */
IPHeader->Id = (USHORT)Random();
/* One fragment at offset 0 */
@@ -114,14 +111,6 @@ PIP_PACKET PrepareICMPPacket(
/* Destination address */
IPHeader->DstAddr = Destination->Address.IPv4Address;
TI_DbgPrint(MID_TRACE,("Allocating packet\n"));
/* Allocate NDIS packet */
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, DataBuffer, Size );
IPPacket->NdisPacket = NdisPacket;
GetDataPtr( IPPacket->NdisPacket, MaxLLHeaderSize,
(PCHAR *)&IPPacket->Header, &IPPacket->ContigSize );
IPPacket->Data = ((PCHAR)IPPacket->Header) + IPPacket->HeaderSize;
TI_DbgPrint(MID_TRACE,("Leaving\n"));
@@ -177,15 +166,14 @@ VOID ICMPReceive(
/* Discard packet */
break;
}
/* Send datagram up the protocol stack */
/*RawIPReceive(NTE, IPPacket);*/
}
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
PIP_PACKET IPPacket,
PIP_TRANSMIT_COMPLETE Complete,
PVOID Context)
/*
* FUNCTION: Transmits an ICMP packet
* ARGUMENTS:
@@ -204,11 +192,7 @@ VOID ICMPTransmit(
/* Get a route to the destination address */
if (RouteGetRouteToDestination(&IPPacket->DstAddr, NULL, &RCN) == IP_SUCCESS) {
/* Send the packet */
if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS) {
FreeNdisPacket(IPPacket->NdisPacket);
}
/* We're done with the RCN */
DereferenceObject(RCN);
IPSendDatagram(IPPacket, RCN, Complete, Context);
} else {
TI_DbgPrint(MIN_TRACE, ("RCN at (0x%X).\n", RCN));
@@ -216,7 +200,7 @@ VOID ICMPTransmit(
TI_DbgPrint(DEBUG_ICMP, ("No route to destination address 0x%X.\n",
IPPacket->DstAddr.Address.IPv4Address));
/* Discard packet */
FreeNdisPacket(IPPacket->NdisPacket);
Complete( Context, IPPacket->NdisPacket, NDIS_STATUS_NOT_ACCEPTED );
}
}
@@ -240,31 +224,26 @@ VOID ICMPReply(
* notify him of the problem
*/
{
UINT DataSize;
PIP_PACKET NewPacket;
UINT DataSize, PayloadSize;
IP_PACKET NewPacket = *IPPacket;
TI_DbgPrint(DEBUG_ICMP, ("Called. Type (%d) Code (%d).\n", Type, Code));
DataSize = IPPacket->TotalSize - IPPacket->HeaderSize -
sizeof(ICMP_HEADER);;
if ((DataSize) > (576 - sizeof(IPv4_HEADER) - sizeof(ICMP_HEADER)))
DataSize = 576;
DataSize = IPPacket->TotalSize - IPPacket->HeaderSize;
PayloadSize = DataSize - sizeof(ICMP_HEADER);
if ((PayloadSize) > 576) {
PayloadSize = 576;
DataSize = PayloadSize + sizeof(ICMP_HEADER);
}
if( !PrepareICMPPacket(NTE, &NewPacket, &IPPacket->SrcAddr,
IPPacket->Data, DataSize) ) return;
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
if (!NewPacket)
return;
((PICMP_HEADER)NewPacket.Data)->Type = Type;
((PICMP_HEADER)NewPacket.Data)->Code = Code;
((PICMP_HEADER)NewPacket.Data)->Checksum = 0;
RtlCopyMemory(NewPacket->Data, IPPacket->Data,
DataSize + sizeof(ICMP_HEADER));
((PICMP_HEADER)NewPacket->Data)->Type = Type;
((PICMP_HEADER)NewPacket->Data)->Code = Code;
((PICMP_HEADER)NewPacket->Data)->Checksum = 0;
PC(NewPacket->NdisPacket)->Complete = SendICMPComplete;
PC(NewPacket->NdisPacket)->Context = NewPacket;
ICMPTransmit(NTE, NewPacket);
ICMPTransmit(NTE, &NewPacket, SendICMPComplete, NULL);
}
/* EOF */
+2 -2
View File
@@ -32,13 +32,13 @@ UINT CountInterfaces() {
KIRQL OldIrql;
IF_LIST_ITER(CurrentIF);
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
ForEachInterface(CurrentIF) {
Count++;
} EndFor(CurrentIF);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return Count;
}
+42 -110
View File
@@ -32,7 +32,7 @@ VOID FreePacket(
* Object = Pointer to an IP packet structure
*/
{
ExFreeToNPagedLookasideList(&IPPacketList, Object);
TcpipFreeToNPagedLookasideList(&IPPacketList, Object);
}
@@ -122,7 +122,6 @@ PADDRESS_ENTRY CreateADE(
INIT_TAG(ADE, TAG('A','D','E',' '));
ADE->Free = FreeADE;
ADE->RefCount = 1;
ADE->NTE = NTE;
ADE->Type = Type;
ADE->Address = Address;
@@ -153,20 +152,6 @@ VOID DestroyADE(
/* Unlink the address entry from the list */
RemoveEntryList(&ADE->ListEntry);
/* Dereference the address */
DereferenceObject(ADE->Address);
/* Dereference the NTE */
DereferenceObject(ADE->NTE);
#ifdef DBG
ADE->RefCount--;
if (ADE->RefCount != 0) {
TI_DbgPrint(MIN_TRACE, ("Address entry at (0x%X) has (%d) references (should be 0).\n", ADE, ADE->RefCount));
}
#endif
/* And free the ADE */
FreeADE(ADE);
}
@@ -200,8 +185,7 @@ VOID DestroyADEs(
}
PIP_PACKET IPCreatePacket(
ULONG Type)
PIP_PACKET IPCreatePacket(ULONG Type)
/*
* FUNCTION: Creates an IP packet object
* ARGUMENTS:
@@ -212,7 +196,7 @@ PIP_PACKET IPCreatePacket(
{
PIP_PACKET IPPacket;
IPPacket = ExAllocateFromNPagedLookasideList(&IPPacketList);
IPPacket = TcpipAllocateFromNPagedLookasideList(&IPPacketList);
if (!IPPacket)
return NULL;
@@ -222,7 +206,6 @@ PIP_PACKET IPCreatePacket(
INIT_TAG(IPPacket, TAG('I','P','K','T'));
IPPacket->Free = FreePacket;
IPPacket->RefCount = 1;
IPPacket->Type = Type;
IPPacket->HeaderSize = 20;
@@ -246,7 +229,6 @@ PIP_PACKET IPInitializePacket(
INIT_TAG(IPPacket, TAG('I','P','K','T'));
IPPacket->Free = DontFreePacket;
IPPacket->RefCount = 1;
IPPacket->Type = Type;
return IPPacket;
@@ -293,16 +275,7 @@ PNET_TABLE_ENTRY IPCreateNTE(
NTE->Interface = IF;
/* One reference is for beeing alive and one reference is for the ADE */
NTE->RefCount = 2;
NTE->Address = Address;
/* One reference is for NTE, one reference is given to the
address entry, and one reference is given to the prefix
list entry */
ReferenceObject(Address);
ReferenceObject(Address);
ReferenceObject(Address);
/* Create an address entry and add it to the list */
ADE = CreateADE(IF, NTE->Address, ADE_UNICAST, NTE);
@@ -320,14 +293,11 @@ PNET_TABLE_ENTRY IPCreateNTE(
return NULL;
}
/* Reference the interface for the prefix list entry */
ReferenceObject(IF);
/* Add NTE to the list on the interface */
InsertTailList(&IF->NTEListHead, &NTE->IFListEntry);
/* Add NTE to the global net table list */
ExInterlockedInsertTailList(&NetTableListHead, &NTE->NTListEntry, &NetTableListLock);
TcpipInterlockedInsertTailList(&NetTableListHead, &NTE->NTListEntry, &NetTableListLock);
return NTE;
}
@@ -353,9 +323,9 @@ VOID DestroyNTE(
TI_DbgPrint(DEBUG_IP, ("NTE (%s).\n", NTE->Address));
/* Invalidate the prefix list entry for this NTE */
KeAcquireSpinLock(&PrefixListLock, &OldIrql);
TcpipAcquireSpinLock(&PrefixListLock, &OldIrql);
DestroyPLE(NTE->PLE);
KeReleaseSpinLock(&PrefixListLock, OldIrql);
TcpipReleaseSpinLock(&PrefixListLock, OldIrql);
/* Remove NTE from the interface list */
RemoveEntryList(&NTE->IFListEntry);
@@ -367,16 +337,6 @@ VOID DestroyNTE(
*/
/* Dereference the objects that are referenced */
DereferenceObject(NTE->Address);
DereferenceObject(NTE->Interface);
#ifdef DBG
NTE->RefCount--;
if (NTE->RefCount != 0) {
TI_DbgPrint(MIN_TRACE, ("Net table entry at (0x%X) has (%d) references (should be 0).\n", NTE, NTE->RefCount));
}
#endif
/* And free the NTE */
exFreePool(NTE);
}
@@ -435,7 +395,9 @@ PNET_TABLE_ENTRY IPLocateNTEOnInterface(
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (%s) AddressType (0x%X).\n",
IF, A2S(Address), AddressType));
KeAcquireSpinLock(&IF->Lock, &OldIrql);
if( !IF ) return NULL;
TcpipAcquireSpinLock(&IF->Lock, &OldIrql);
/* Search the list and return the NTE if found */
CurrentEntry = IF->ADEListHead.Flink;
@@ -447,15 +409,14 @@ PNET_TABLE_ENTRY IPLocateNTEOnInterface(
while (CurrentEntry != &IF->ADEListHead) {
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_ENTRY, ListEntry);
if (AddrIsEqual(Address, Current->Address)) {
ReferenceObject(Current->NTE);
*AddressType = Current->Type;
KeReleaseSpinLock(&IF->Lock, OldIrql);
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return Current->NTE;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&IF->Lock, OldIrql);
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return NULL;
}
@@ -486,7 +447,7 @@ PNET_TABLE_ENTRY IPLocateNTE(
// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
KeAcquireSpinLock(&NetTableListLock, &OldIrql);
TcpipAcquireSpinLock(&NetTableListLock, &OldIrql);
/* Search the list and return the NTE if found */
CurrentEntry = NetTableListHead.Flink;
@@ -494,14 +455,13 @@ PNET_TABLE_ENTRY IPLocateNTE(
Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, NTListEntry);
NTE = IPLocateNTEOnInterface(Current->Interface, Address, AddressType);
if (NTE) {
ReferenceObject(NTE);
KeReleaseSpinLock(&NetTableListLock, OldIrql);
TcpipReleaseSpinLock(&NetTableListLock, OldIrql);
return NTE;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&NetTableListLock, OldIrql);
TcpipReleaseSpinLock(&NetTableListLock, OldIrql);
return NULL;
}
@@ -531,7 +491,7 @@ PADDRESS_ENTRY IPLocateADE(
// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
/* Search the interface list */
ForEachInterface(CurrentIF) {
@@ -539,14 +499,13 @@ PADDRESS_ENTRY IPLocateADE(
ForEachADE(CurrentIF->ADEListHead,CurrentADE) {
if ((AddrIsEqual(Address, CurrentADE->Address)) &&
(CurrentADE->Type == AddressType)) {
ReferenceObject(CurrentADE);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
} EndFor(CurrentADE);
} EndFor(CurrentIF);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return NULL;
}
@@ -572,7 +531,7 @@ PADDRESS_ENTRY IPGetDefaultADE(
TI_DbgPrint(DEBUG_IP, ("Called. AddressType (0x%X).\n", AddressType));
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
/* Search the interface list */
ForEachInterface(CurrentIF) {
@@ -581,8 +540,7 @@ PADDRESS_ENTRY IPGetDefaultADE(
TI_DbgPrint(DEBUG_IP,("Checking interface %x\n", CurrentIF));
ForEachADE(CurrentIF->ADEListHead,CurrentADE) {
if (CurrentADE->Type == AddressType) {
ReferenceObject(CurrentADE);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
} EndFor(CurrentADE);
@@ -594,14 +552,13 @@ PADDRESS_ENTRY IPGetDefaultADE(
if (LoopbackIsRegistered) {
ForEachADE(CurrentIF->ADEListHead,CurrentADE) {
if (CurrentADE->Type == AddressType) {
ReferenceObject(CurrentADE);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
} EndFor(CurrentADE);
}
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return NULL;
}
@@ -682,7 +639,6 @@ PIP_INTERFACE IPCreateInterface(
INIT_TAG(IF, TAG('F','A','C','E'));
IF->Free = FreeIF;
IF->RefCount = 1;
IF->Context = BindInfo->Context;
IF->HeaderSize = BindInfo->HeaderSize;
if (IF->HeaderSize > MaxLLHeaderSize)
@@ -700,7 +656,7 @@ PIP_INTERFACE IPCreateInterface(
InitializeListHead(&IF->ADEListHead);
InitializeListHead(&IF->NTEListHead);
KeInitializeSpinLock(&IF->Lock);
TcpipInitializeSpinLock(&IF->Lock);
#ifdef __NTDRIVER__
InsertTDIInterfaceEntity( IF );
@@ -727,20 +683,12 @@ VOID IPDestroyInterface(
RemoveTDIInterfaceEntity( IF );
#endif
KeAcquireSpinLock(&NetTableListLock, &OldIrql1);
KeAcquireSpinLock(&IF->Lock, &OldIrql2);
TcpipAcquireSpinLock(&NetTableListLock, &OldIrql1);
TcpipAcquireSpinLock(&IF->Lock, &OldIrql2);
DestroyADEs(IF);
DestroyNTEs(IF);
KeReleaseSpinLock(&IF->Lock, OldIrql2);
KeReleaseSpinLock(&NetTableListLock, OldIrql1);
#ifdef DBG
IF->RefCount--;
if (IF->RefCount != 0) {
TI_DbgPrint(MIN_TRACE, ("Interface at (0x%X) has (%d) references (should be 0).\n", IF, IF->RefCount));
}
#endif
TcpipReleaseSpinLock(&IF->Lock, OldIrql2);
TcpipReleaseSpinLock(&NetTableListLock, OldIrql1);
exFreePool(IF);
}
@@ -764,7 +712,7 @@ BOOLEAN IPRegisterInterface(
TI_DbgPrint(MID_TRACE, ("Called. IF (0x%X).\n", IF));
KeAcquireSpinLock(&IF->Lock, &OldIrql);
TcpipAcquireSpinLock(&IF->Lock, &OldIrql);
/* Add routes to all NTEs on this interface */
CurrentEntry = IF->NTEListHead.Flink;
@@ -772,51 +720,37 @@ BOOLEAN IPRegisterInterface(
Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
/* Add a permanent neighbor for this NTE */
ReferenceObject(Current->Address);
NCE = NBAddNeighbor(IF, Current->Address, IF->Address,
IF->AddressLength, NUD_PERMANENT);
if (!NCE) {
TI_DbgPrint(MIN_TRACE, ("Could not create NCE.\n"));
DereferenceObject(Current->Address);
KeReleaseSpinLock(&IF->Lock, OldIrql);
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return FALSE;
}
/* Reference objects for forward information base */
ReferenceObject(Current->Address);
ReferenceObject(Current->PLE->Prefix);
ReferenceObject(NCE);
/* 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"));
DereferenceObject(Current->Address);
DereferenceObject(Current->PLE->Prefix);
DereferenceObject(NCE);
}
RCN = RouteAddRouteToDestination(Current->Address, Current, IF, NCE);
if (!RCN) {
TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n"));
DereferenceObject(Current->Address);
KeReleaseSpinLock(&IF->Lock, OldIrql);
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
}
/* Don't need this any more since the route cache references the NCE */
DereferenceObject(NCE);
CurrentEntry = CurrentEntry->Flink;
}
/* Add interface to the global interface list */
ASSERT(&IF->ListEntry);
ExInterlockedInsertTailList(&InterfaceListHead,
&IF->ListEntry,
&InterfaceListLock);
TcpipInterlockedInsertTailList(&InterfaceListHead,
&IF->ListEntry,
&InterfaceListLock);
/* Allow TCP to hang some configuration on this interface */
IF->TCPContext = TCPPrepareInterface( IF );
KeReleaseSpinLock(&IF->Lock, OldIrql);
TcpipReleaseSpinLock(&IF->Lock, OldIrql);
return TRUE;
}
@@ -839,8 +773,8 @@ VOID IPUnregisterInterface(
TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X).\n", IF));
KeAcquireSpinLock(&NetTableListLock, &OldIrql1);
KeAcquireSpinLock(&IF->Lock, &OldIrql2);
TcpipAcquireSpinLock(&NetTableListLock, &OldIrql1);
TcpipAcquireSpinLock(&IF->Lock, &OldIrql2);
/* Remove routes to all NTEs on this interface */
CurrentEntry = IF->NTEListHead.Flink;
@@ -855,22 +789,20 @@ VOID IPUnregisterInterface(
/* Remove permanent NCE, but first we have to find it */
NCE = NBLocateNeighbor(Current->Address);
if (NCE) {
DereferenceObject(NCE);
if (NCE)
NBRemoveNeighbor(NCE);
}
CurrentEntry = CurrentEntry->Flink;
}
KeAcquireSpinLock(&InterfaceListLock, &OldIrql3);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql3);
/* Ouch...three spinlocks acquired! Fortunately
we don't unregister interfaces very often */
RemoveEntryList(&IF->ListEntry);
KeReleaseSpinLock(&InterfaceListLock, OldIrql3);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql3);
KeReleaseSpinLock(&IF->Lock, OldIrql2);
KeReleaseSpinLock(&NetTableListLock, OldIrql1);
TcpipReleaseSpinLock(&IF->Lock, OldIrql2);
TcpipReleaseSpinLock(&NetTableListLock, OldIrql1);
}
@@ -981,11 +913,11 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath)
/* Initialize NTE list and protecting lock */
InitializeListHead(&NetTableListHead);
KeInitializeSpinLock(&NetTableListLock);
TcpipInitializeSpinLock(&NetTableListLock);
/* Initialize reassembly list and protecting lock */
InitializeListHead(&ReassemblyListHead);
KeInitializeSpinLock(&ReassemblyListLock);
TcpipInitializeSpinLock(&ReassemblyListLock);
InitPLE();
+14 -102
View File
@@ -10,63 +10,7 @@
#include "precomp.h"
VOID STDCALL KeAcquireSpinLockAtDpcLevel (IN PKSPIN_LOCK SpinLock);
VOID STDCALL KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock);
WORK_QUEUE_ITEM LoopWorkItem;
PIP_INTERFACE Loopback = NULL;
/* Indicates wether the loopback interface is currently transmitting */
BOOLEAN LoopBusy = FALSE;
/* Loopback transmit queue */
PNDIS_PACKET LoopQueueHead = (PNDIS_PACKET)NULL;
PNDIS_PACKET LoopQueueTail = (PNDIS_PACKET)NULL;
/* Spin lock for protecting loopback transmit queue */
KSPIN_LOCK LoopQueueLock;
VOID STDCALL RealTransmit(
PVOID Context)
/*
* FUNCTION: Transmits one or more packet(s) in loopback queue to ourselves
* ARGUMENTS:
* Context = Pointer to context information (loopback interface)
*/
{
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
IP_PACKET IPPacket;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLockAtDpcLevel(&LoopQueueLock);
while (TRUE)
{
/* Get the next packet from the queue (if any) */
NdisPacket = LoopQueueHead;
if (!NdisPacket)
break;
TI_DbgPrint(MAX_TRACE, ("NdisPacket (0x%X)\n", NdisPacket));
LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
KeReleaseSpinLockFromDpcLevel(&LoopQueueLock);
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
&NdisBuffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
IPReceive(Context, &IPPacket);
AdjustPacket(NdisPacket, 0, PC(NdisPacket)->DLOffset);
PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
KeAcquireSpinLockAtDpcLevel(&LoopQueueLock);
}
LoopBusy = FALSE;
KeReleaseSpinLockFromDpcLevel(&LoopQueueLock);
}
VOID LoopTransmit(
PVOID Context,
@@ -84,46 +28,23 @@ VOID LoopTransmit(
* Type = LAN protocol type (unused)
*/
{
PNDIS_PACKET *pNdisPacket;
KIRQL OldIrql;
IP_PACKET IPPacket;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
/* NDIS send routines don't have an offset argument so we
must offset the data in upper layers and adjust the
packet here. We save the offset in the packet context
area so it can be undone before we release the packet */
AdjustPacket(NdisPacket, Offset, 0);
PC(NdisPacket)->DLOffset = Offset;
IPPacket.NdisPacket = NdisPacket;
IPPacket.HeaderSize = 0;
GetDataPtr( NdisPacket, 0, (PCHAR *)&IPPacket.Header, &IPPacket.TotalSize );
pNdisPacket = (PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
*pNdisPacket = NULL;
KeAcquireSpinLock(&LoopQueueLock, &OldIrql);
/* Add packet to transmit queue */
if (LoopQueueHead != NULL)
{
/* Transmit queue is not empty */
pNdisPacket = (PNDIS_PACKET*)LoopQueueTail->u.s3.MacReserved;
*pNdisPacket = NdisPacket;
}
else
{
/* Transmit queue is empty */
LoopQueueHead = NdisPacket;
}
LoopQueueTail = NdisPacket;
/* If RealTransmit is not running (or scheduled to run) then schedule it to run now */
if (!LoopBusy)
{
LoopBusy = TRUE; /* The loopback interface is now busy */
ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
}
KeReleaseSpinLock(&LoopQueueLock, OldIrql);
TI_DbgPrint(MAX_TRACE,
("Doing receive (complete: %x, context %x, packet %x)\n",
PC(NdisPacket)->DLComplete, Context, NdisPacket));
IPReceive(Context, &IPPacket);
TI_DbgPrint(MAX_TRACE,
("Finished receive (complete: %x, context %x, packet %x)\n",
PC(NdisPacket)->DLComplete, Context, NdisPacket));
PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
TI_DbgPrint(MAX_TRACE, ("Done\n"));
}
NDIS_STATUS LoopRegisterAdapter(
@@ -163,16 +84,7 @@ NDIS_STATUS LoopRegisterAdapter(
if ((Loopback != NULL) && (IPCreateNTE(Loopback, Address, 8)))
{
/* Reference the interface for the NTE. The reference for
the address is just passed on to the NTE */
ReferenceObject(Loopback);
IPRegisterInterface(Loopback);
ExInitializeWorkItem(&LoopWorkItem, RealTransmit, Loopback);
KeInitializeSpinLock(&LoopQueueLock);
LoopBusy = FALSE;
}
else
{
+39 -38
View File
@@ -15,7 +15,7 @@ VOID TrackTag( DWORD Tag ) {
}
VOID TrackingInit() {
KeInitializeSpinLock( &AllocatedObjectsLock );
TcpipInitializeSpinLock( &AllocatedObjectsLock );
InitializeListHead( &AllocatedObjectsList );
}
@@ -23,68 +23,69 @@ VOID ShowTrackedThing( PCHAR What, PALLOCATION_TRACKER Thing,
PCHAR File, UINT Line ) {
/* if( ShowTag( Thing->Tag ) ) */
if( File ) {
DbgPrint( "[%s] Thing %08x %c%c%c%c (%s:%d) (Called from %s:%d)\n",
What,
Thing->Thing,
((PCHAR)&Thing->Tag)[3],
((PCHAR)&Thing->Tag)[2],
((PCHAR)&Thing->Tag)[1],
((PCHAR)&Thing->Tag)[0],
Thing->FileName,
Thing->LineNo,
File, Line );
TI_DbgPrint(MAX_TRACE,
("[%s] Thing %08x %c%c%c%c (%s:%d) (Called from %s:%d)\n",
What,
Thing->Thing,
((PCHAR)&Thing->Tag)[3],
((PCHAR)&Thing->Tag)[2],
((PCHAR)&Thing->Tag)[1],
((PCHAR)&Thing->Tag)[0],
Thing->FileName,
Thing->LineNo,
File, Line));
} else {
DbgPrint( "[%s] Thing %08x %c%c%c%c (%s:%d)\n",
What,
Thing->Thing,
((PCHAR)&Thing->Tag)[3],
((PCHAR)&Thing->Tag)[2],
((PCHAR)&Thing->Tag)[1],
((PCHAR)&Thing->Tag)[0],
Thing->FileName,
Thing->LineNo );
TI_DbgPrint(MAX_TRACE,
( "[%s] Thing %08x %c%c%c%c (%s:%d)\n",
What,
Thing->Thing,
((PCHAR)&Thing->Tag)[3],
((PCHAR)&Thing->Tag)[2],
((PCHAR)&Thing->Tag)[1],
((PCHAR)&Thing->Tag)[0],
Thing->FileName,
Thing->LineNo ));
}
}
VOID TrackWithTag( DWORD Tag, PVOID Thing, PCHAR FileName, DWORD LineNo ) {
PALLOCATION_TRACKER TrackedThing =
ExAllocatePool( NonPagedPool, sizeof(*TrackedThing) );
PoolAllocateBuffer( sizeof(*TrackedThing) );
KIRQL OldIrql;
PLIST_ENTRY Entry;
PALLOCATION_TRACKER ThingInList;
KeAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
Entry = AllocatedObjectsList.Flink;
while( Entry != &AllocatedObjectsList ) {
ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry);
if( ThingInList->Thing == Thing ) {
RemoveEntryList(Entry);
KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
ShowTrackedThing( "Alloc", ThingInList, FileName, LineNo );
ExFreePool( ThingInList );
PoolFreeBuffer( ThingInList );
TrackDumpFL( FileName, LineNo );
DbgPrint("TRACK: SPECIFIED ALREADY ALLOCATED ITEM %x\n", Thing);
KeBugCheck( 0 );
TcpipBugCheck( 0 );
}
Entry = Entry->Flink;
}
KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
if( TrackedThing ) {
TrackedThing->Tag = Tag;
TrackedThing->Thing = Thing;
TrackedThing->FileName = FileName;
TrackedThing->LineNo = LineNo;
ExInterlockedInsertTailList( &AllocatedObjectsList,
&TrackedThing->Entry,
&AllocatedObjectsLock );
InsertTailList( &AllocatedObjectsList, &TrackedThing->Entry );
ShowTrackedThing( "Alloc", TrackedThing, FileName, LineNo );
}
TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
/*TrackDumpFL( FileName, LineNo );*/
}
@@ -101,7 +102,7 @@ VOID UntrackFL( PCHAR File, DWORD Line, PVOID Thing ) {
PLIST_ENTRY Entry;
PALLOCATION_TRACKER ThingInList;
KeAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
Entry = AllocatedObjectsList.Flink;
while( Entry != &AllocatedObjectsList ) {
ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry);
@@ -110,17 +111,17 @@ VOID UntrackFL( PCHAR File, DWORD Line, PVOID Thing ) {
ShowTrackedThing( "Free ", ThingInList, File, Line );
ExFreePool( ThingInList );
KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
PoolFreeBuffer( ThingInList );
TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
/* TrackDumpFL( File, Line ); */
return;
}
Entry = Entry->Flink;
}
KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
TrackDumpFL( File, Line );
DbgPrint("UNTRACK: SPECIFIED ALREADY FREE ITEM %x\n", Thing);
KeBugCheck( 0 );
TcpipBugCheck( 0 );
}
VOID TrackDumpFL( PCHAR File, DWORD Line ) {
@@ -128,16 +129,16 @@ VOID TrackDumpFL( PCHAR File, DWORD Line ) {
PLIST_ENTRY Entry;
PALLOCATION_TRACKER Thing;
DbgPrint("Dump: %s:%d\n", File, Line);
TI_DbgPrint(MAX_TRACE,("Dump: %s:%d\n", File, Line));
KeAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
Entry = AllocatedObjectsList.Flink;
while( Entry != &AllocatedObjectsList ) {
Thing = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry);
ShowTrackedThing( "Dump ", Thing, 0, 0 );
Entry = Entry->Flink;
}
KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
}
#endif/*MEMTRACK*/
+171 -185
View File
@@ -10,14 +10,68 @@
#include "precomp.h"
NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
VOID NBCompleteSend( PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS Status ) {
PNEIGHBOR_PACKET Packet = (PNEIGHBOR_PACKET)Context;
TI_DbgPrint(MID_TRACE, ("Called\n"));
Packet->Complete( Packet->Context, Packet->Packet, STATUS_SUCCESS );
TI_DbgPrint(MID_TRACE, ("Completed\n"));
PoolFreeBuffer( Packet );
TI_DbgPrint(MID_TRACE, ("Freed\n"));
}
VOID FreeNCE(
PVOID Object)
{
ExFreePool(Object);
VOID NBSendPackets( PNEIGHBOR_CACHE_ENTRY NCE ) {
PLIST_ENTRY PacketEntry;
PNEIGHBOR_PACKET Packet;
/* Send any waiting packets */
if( !IsListEmpty( &NCE->PacketQueue ) ) {
PacketEntry = RemoveHeadList( &NCE->PacketQueue );
Packet = CONTAINING_RECORD( PacketEntry, NEIGHBOR_PACKET, Next );
TI_DbgPrint
(MID_TRACE,
("PacketEntry: %x, NdisPacket %x\n",
PacketEntry, Packet->Packet));
PC(Packet->Packet)->DLComplete = NBCompleteSend;
PC(Packet->Packet)->Context = Packet;
NCE->Interface->Transmit
( NCE->Interface->Context,
Packet->Packet,
MaxLLHeaderSize,
NCE->LinkAddress,
LAN_PROTO_IPv4 );
}
}
VOID NBFlushPacketQueue( PNEIGHBOR_CACHE_ENTRY NCE,
BOOL CallComplete,
NTSTATUS ErrorCode ) {
PLIST_ENTRY PacketEntry;
PNEIGHBOR_PACKET Packet;
while( !IsListEmpty( &NCE->PacketQueue ) ) {
PacketEntry = RemoveHeadList( &NCE->PacketQueue );
Packet = CONTAINING_RECORD
( PacketEntry, NEIGHBOR_PACKET, Next );
TI_DbgPrint
(MID_TRACE,
("PacketEntry: %x, NdisPacket %x\n",
PacketEntry, Packet->Packet));
if( CallComplete )
Packet->Complete( Packet->Context,
Packet->Packet,
NDIS_STATUS_REQUEST_ABORTED );
PoolFreeBuffer( Packet );
}
}
VOID NCETimeout(
@@ -28,62 +82,48 @@ VOID NCETimeout(
* The neighbor cache lock must be held
*/
{
PNDIS_PACKET NdisPacket;
PNDIS_PACKET NextNdisPacket;
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
TI_DbgPrint(DEBUG_NCACHE, ("NCE->State is (0x%X).\n", NCE->State));
switch (NCE->State)
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X).\n", NCE));
TI_DbgPrint(DEBUG_NCACHE, ("NCE->State is (0x%X).\n", NCE->State));
switch (NCE->State)
{
case NUD_INCOMPLETE:
case NUD_INCOMPLETE:
/* Retransmission timer expired */
if (NCE->EventCount++ > MAX_MULTICAST_SOLICIT)
{
{
/* We have retransmitted too many times */
/* Calling IPSendComplete with cache lock held is not
a great thing to do. We don't get here very often
so maybe it's not that big a problem */
a great thing to do. We don't get here very often
so maybe it's not that big a problem */
/* Flush packet queue */
NdisPacket = NCE->WaitQueue;
while (NdisPacket != NULL)
{
NextNdisPacket = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
IPSendComplete((PVOID)NCE->Interface,
NdisPacket,
NDIS_STATUS_REQUEST_ABORTED);
NdisPacket = NextNdisPacket;
}
NCE->WaitQueue = NULL;
NBFlushPacketQueue( NCE, TRUE, NDIS_STATUS_REQUEST_ABORTED );
NCE->EventCount = 0;
/* Remove route cache entries with references to this NCE.
Remember that neighbor cache lock is acquired before the
route cache lock */
Remember that neighbor cache lock is acquired before the
route cache lock */
RouteInvalidateNCE(NCE);
}
}
else
{
{
/* Retransmit request */
NBSendSolicit(NCE);
}
}
break;
case NUD_DELAY:
case NUD_DELAY:
/* FIXME: Delayed state */
TI_DbgPrint(DEBUG_NCACHE, ("NCE delay state.\n"));
break;
case NUD_PROBE:
case NUD_PROBE:
/* FIXME: Probe state */
TI_DbgPrint(DEBUG_NCACHE, ("NCE probe state.\n"));
break;
default:
default:
/* Should not happen since the event timer is not used in the other states */
TI_DbgPrint(MIN_TRACE, ("Invalid NCE state (%d).\n", NCE->State));
break;
@@ -104,7 +144,7 @@ VOID NBTimeout(VOID)
PNEIGHBOR_CACHE_ENTRY NCE;
for (i = 0; i <= NB_HASHMASK; i++) {
KeAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
for (NCE = NeighborCache[i].Cache;
NCE != NULL; NCE = NCE->Next) {
@@ -118,7 +158,7 @@ VOID NBTimeout(VOID)
}
}
KeReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
}
}
@@ -127,14 +167,13 @@ VOID NBStartup(VOID)
* FUNCTION: Starts the neighbor cache
*/
{
UINT i;
TI_DbgPrint(DEBUG_NCACHE, ("Called.\n"));
for (i = 0; i <= NB_HASHMASK; i++)
{
NeighborCache[i].Cache = NULL;
KeInitializeSpinLock(&NeighborCache[i].Lock);
UINT i;
TI_DbgPrint(DEBUG_NCACHE, ("Called.\n"));
for (i = 0; i <= NB_HASHMASK; i++) {
NeighborCache[i].Cache = NULL;
TcpipInitializeSpinLock(&NeighborCache[i].Lock);
}
}
@@ -145,8 +184,6 @@ VOID NBShutdown(VOID)
{
PNEIGHBOR_CACHE_ENTRY NextNCE;
PNEIGHBOR_CACHE_ENTRY CurNCE;
PNDIS_PACKET NextNdisPacket;
PNDIS_PACKET NdisPacket;
KIRQL OldIrql;
UINT i;
@@ -155,41 +192,24 @@ VOID NBShutdown(VOID)
/* Remove possible entries from the cache */
for (i = 0; i <= NB_HASHMASK; i++)
{
KeAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
TcpipAcquireSpinLock(&NeighborCache[i].Lock, &OldIrql);
CurNCE = NeighborCache[i].Cache;
while (CurNCE)
{
while (CurNCE) {
NextNCE = CurNCE->Next;
/* Remove all references from route cache */
RouteInvalidateNCE(CurNCE);
/* Flush wait queue */
NdisPacket = CurNCE->WaitQueue;
while (NdisPacket)
{
NextNdisPacket = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
FreeNdisPacket(NdisPacket);
NdisPacket = NextNdisPacket;
}
NBFlushPacketQueue( CurNCE, FALSE, STATUS_SUCCESS );
#ifdef DBG
if (CurNCE->RefCount != 1)
{
TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 1).\n", CurNCE, CurNCE->RefCount));
}
#endif
/* Remove reference for being alive */
DereferenceObject(CurNCE);
CurNCE = NextNCE;
CurNCE = NextNCE;
}
NeighborCache[i].Cache = NULL;
KeReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
TcpipReleaseSpinLock(&NeighborCache[i].Lock, OldIrql);
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
@@ -204,41 +224,41 @@ 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)
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 */
/* 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));
}
if (!IsListEmpty(&NCE->Interface->NTEListHead))
{
/* 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
{
} else {
TI_DbgPrint(MIN_TRACE, ("Interface at 0x%X has zero NTE.\n",
NCE->Interface));
}
}
else
{
/* FIXME: Unicast solicitation since we have a cached address */
TI_DbgPrint(MIN_TRACE, ("Uninplemented unicast solicitation.\n"));
}
} else {
/* FIXME: Unicast solicitation since we have a cached address */
TI_DbgPrint(MIN_TRACE, ("Uninplemented unicast solicitation.\n"));
}
}
@@ -286,22 +306,15 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
INIT_TAG(NCE, TAG('N','C','E',' '));
/* Initialize NCE free routine */
NCE->Free = FreeNCE;
/* Reference once for beeing alive and once for the caller */
NCE->RefCount = 2;
NCE->Interface = Interface;
NCE->Address = *Address;
NCE->LinkAddressLength = LinkAddressLength;
NCE->LinkAddress = (PVOID)&NCE[1];
if (LinkAddress != NULL)
{
if( LinkAddress )
RtlCopyMemory(NCE->LinkAddress, LinkAddress, LinkAddressLength);
}
NCE->State = State;
NCE->EventTimer = 0; /* Not in use */
NCE->WaitQueue = NULL;
InitializeListHead( &NCE->PacketQueue );
HashValue = *(PULONG)&Address->Address;
HashValue ^= HashValue >> 16;
@@ -311,12 +324,12 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
NCE->Table = &NeighborCache[HashValue];
KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
NCE->Next = NeighborCache[HashValue].Cache;
NeighborCache[HashValue].Cache = NCE;
KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
return NCE;
}
@@ -335,30 +348,19 @@ VOID NBUpdateNeighbor(
* The link address and state is updated. Any waiting packets are sent
*/
{
PNDIS_PACKET Current;
PNDIS_PACKET Next;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X) LinkAddress (0x%X) State (0x%X).\n", NCE, LinkAddress, State));
KeAcquireSpinLock(&NCE->Table->Lock, &OldIrql);
RtlCopyMemory(NCE->LinkAddress, LinkAddress, NCE->LinkAddressLength);
NCE->State = State;
Current = NCE->WaitQueue;
NCE->WaitQueue = NULL;
KeReleaseSpinLock(&NCE->Table->Lock, OldIrql);
/* Send any waiting packets */
while (Current != NULL)
{
/* Our link to the next packet is broken by the
datalink layer code so we must save it here */
Next = (PNDIS_PACKET)PC(Current)->DLComplete;
IPSendFragment(Current, NCE);
Current = Next;
}
KIRQL OldIrql;
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X) LinkAddress (0x%X) State (0x%X).\n", NCE, LinkAddress, State));
TcpipAcquireSpinLock(&NCE->Table->Lock, &OldIrql);
RtlCopyMemory(NCE->LinkAddress, LinkAddress, NCE->LinkAddressLength);
NCE->State = State;
TcpipReleaseSpinLock(&NCE->Table->Lock, OldIrql);
if( NCE->State & NUD_CONNECTED )
NBSendPackets( NCE );
}
PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
@@ -386,7 +388,7 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
HashValue ^= HashValue >> 4;
HashValue &= NB_HASHMASK;
KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
NCE = NeighborCache[HashValue].Cache;
@@ -395,12 +397,7 @@ PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
NCE = NCE->Next;
}
if (NCE)
{
ReferenceObject(NCE);
}
KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
@@ -429,11 +426,10 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
NCE = NBLocateNeighbor(Address);
if (NCE == NULL)
{
ReferenceObject(Address);
NCE = NBAddNeighbor(Interface, Address, NULL,
Interface->AddressLength, NUD_INCOMPLETE);
NCE->EventTimer = 1;
NCE->EventCount = 0;
NCE = NBAddNeighbor(Interface, Address, NULL,
Interface->AddressLength, NUD_INCOMPLETE);
NCE->EventTimer = 1;
NCE->EventCount = 0;
}
return NCE;
@@ -441,7 +437,9 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
BOOLEAN NBQueuePacket(
PNEIGHBOR_CACHE_ENTRY NCE,
PNDIS_PACKET NdisPacket)
PNDIS_PACKET NdisPacket,
PNEIGHBOR_PACKET_COMPLETE PacketComplete,
PVOID PacketContext)
/*
* FUNCTION: Queues a packet on an NCE for later transmission
* ARGUMENTS:
@@ -453,21 +451,30 @@ BOOLEAN NBQueuePacket(
{
PKSPIN_LOCK Lock;
KIRQL OldIrql;
PNEIGHBOR_PACKET Packet;
TI_DbgPrint
(DEBUG_NCACHE,
("Called. NCE (0x%X) NdisPacket (0x%X).\n", NCE, NdisPacket));
TI_DbgPrint(DEBUG_NCACHE, ("Called. NCE (0x%X) NdisPacket (0x%X).\n", NCE, NdisPacket));
Packet = PoolAllocateBuffer( sizeof(NEIGHBOR_PACKET) );
if( !Packet ) return FALSE;
/* FIXME: Should we limit the number of queued packets? */
Lock = &NCE->Table->Lock;
KeAcquireSpinLock(Lock, &OldIrql);
TcpipAcquireSpinLock(Lock, &OldIrql);
/* Use data link level completion handler pointer to link
queued packets together */
PC(NdisPacket)->DLComplete = (PACKET_COMPLETION_ROUTINE)NCE->WaitQueue;
NCE->WaitQueue = NdisPacket;
Packet->Complete = PacketComplete;
Packet->Context = PacketContext;
Packet->Packet = NdisPacket;
InsertTailList( &NCE->PacketQueue, &Packet->Next );
KeReleaseSpinLock(Lock, OldIrql);
if( NCE->State & NUD_CONNECTED )
NBSendPackets( NCE );
TcpipReleaseSpinLock(Lock, OldIrql);
return TRUE;
}
@@ -485,8 +492,6 @@ VOID NBRemoveNeighbor(
{
PNEIGHBOR_CACHE_ENTRY *PrevNCE;
PNEIGHBOR_CACHE_ENTRY CurNCE;
PNDIS_PACKET NextNdisPacket;
PNDIS_PACKET NdisPacket;
ULONG HashValue;
KIRQL OldIrql;
@@ -498,7 +503,7 @@ VOID NBRemoveNeighbor(
HashValue ^= HashValue >> 4;
HashValue &= NB_HASHMASK;
KeAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
TcpipAcquireSpinLock(&NeighborCache[HashValue].Lock, &OldIrql);
/* Search the list and remove the NCE from the list if found */
for (PrevNCE = &NeighborCache[HashValue].Cache;
@@ -510,34 +515,15 @@ VOID NBRemoveNeighbor(
/* Found it, now unlink it from the list */
*PrevNCE = CurNCE->Next;
/* Purge wait queue */
NdisPacket = CurNCE->WaitQueue;
while (NdisPacket != NULL)
{
NextNdisPacket = (PNDIS_PACKET)PC(NdisPacket)->DLComplete;
FreeNdisPacket(NdisPacket);
NdisPacket = NextNdisPacket;
}
NBFlushPacketQueue( CurNCE, TRUE, NDIS_STATUS_REQUEST_ABORTED );
/* Remove all references from route cache */
RouteInvalidateNCE(CurNCE);
#ifdef DBG
CurNCE->RefCount--;
if (CurNCE->RefCount != 0)
{
TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 0).\n",
CurNCE, CurNCE->RefCount));
}
#endif
ExFreePool(CurNCE);
KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
return;
break;
}
}
KeReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
TcpipReleaseSpinLock(&NeighborCache[HashValue].Lock, OldIrql);
}
+5 -20
View File
@@ -20,7 +20,7 @@ KSPIN_LOCK PrefixListLock;
VOID InitPLE() {
/* Initialize the prefix list and protecting lock */
InitializeListHead(&PrefixListHead);
KeInitializeSpinLock(&PrefixListLock);
TcpipInitializeSpinLock(&PrefixListLock);
}
@@ -46,14 +46,13 @@ PPREFIX_LIST_ENTRY CreatePLE(PIP_INTERFACE IF, PIP_ADDRESS Prefix, UINT Length)
TI_DbgPrint(DEBUG_IP, ("Prefix (%s).\n", A2S(Prefix)));
/* Allocate space for an PLE and set it up */
PLE = ExAllocatePool(NonPagedPool, sizeof(PREFIX_LIST_ENTRY));
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->RefCount = 1;
PLE->Interface = IF;
PLE->Prefix = Prefix;
PLE->PrefixLength = Length;
@@ -82,22 +81,8 @@ VOID DestroyPLE(
/* Unlink the prefix list entry from the list */
RemoveEntryList(&PLE->ListEntry);
/* Dereference the address */
DereferenceObject(PLE->Prefix);
/* Dereference the interface */
DereferenceObject(PLE->Interface);
#ifdef DBG
PLE->RefCount--;
if (PLE->RefCount != 0) {
TI_DbgPrint(MIN_TRACE, ("Prefix list entry at (0x%X) has (%d) references (should be 0).\n", PLE, PLE->RefCount));
}
#endif
/* And free the PLE */
ExFreePool(PLE);
PoolFreeBuffer(PLE);
}
@@ -114,7 +99,7 @@ VOID DestroyPLEs(
TI_DbgPrint(DEBUG_IP, ("Called.\n"));
KeAcquireSpinLock(&PrefixListLock, &OldIrql);
TcpipAcquireSpinLock(&PrefixListLock, &OldIrql);
/* Search the list and remove every PLE we find */
CurrentEntry = PrefixListHead.Flink;
@@ -125,6 +110,6 @@ VOID DestroyPLEs(
DestroyPLE(Current);
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&PrefixListLock, OldIrql);
TcpipReleaseSpinLock(&PrefixListLock, OldIrql);
}
+34 -29
View File
@@ -18,6 +18,11 @@ NPAGED_LOOKASIDE_LIST IPDRList;
NPAGED_LOOKASIDE_LIST IPFragmentList;
NPAGED_LOOKASIDE_LIST IPHoleList;
VOID ReflectPacketComplete(
PVOID Context,
PNDIS_PACKET Packet,
NDIS_STATUS Status ) {
}
PIPDATAGRAM_HOLE CreateHoleDescriptor(
ULONG First,
@@ -36,7 +41,7 @@ PIPDATAGRAM_HOLE CreateHoleDescriptor(
TI_DbgPrint(DEBUG_IP, ("Called. First (%d) Last (%d).\n", First, Last));
Hole = ExAllocateFromNPagedLookasideList(&IPHoleList);
Hole = TcpipAllocateFromNPagedLookasideList(&IPHoleList);
if (!Hole) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
@@ -77,7 +82,7 @@ VOID FreeIPDR(
TI_DbgPrint(DEBUG_IP, ("Freeing hole descriptor at (0x%X).\n", CurrentH));
/* And free the hole descriptor */
ExFreeToNPagedLookasideList(&IPHoleList, CurrentH);
TcpipFreeToNPagedLookasideList(&IPHoleList, CurrentH);
CurrentEntry = NextEntry;
}
@@ -98,7 +103,7 @@ VOID FreeIPDR(
TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF));
/* And free the fragment descriptor */
ExFreeToNPagedLookasideList(&IPFragmentList, CurrentF);
TcpipFreeToNPagedLookasideList(&IPFragmentList, CurrentF);
CurrentEntry = NextEntry;
}
@@ -110,7 +115,7 @@ VOID FreeIPDR(
TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR));
ExFreeToNPagedLookasideList(&IPDRList, IPDR);
TcpipFreeToNPagedLookasideList(&IPDRList, IPDR);
}
@@ -126,9 +131,9 @@ VOID RemoveIPDR(
TI_DbgPrint(DEBUG_IP, ("Removing IPDR at (0x%X).\n", IPDR));
KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
TcpipAcquireSpinLock(&ReassemblyListLock, &OldIrql);
RemoveEntryList(&IPDR->ListEntry);
KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
TcpipReleaseSpinLock(&ReassemblyListLock, OldIrql);
}
@@ -151,7 +156,7 @@ PIPDATAGRAM_REASSEMBLY GetReassemblyInfo(
TI_DbgPrint(DEBUG_IP, ("Searching for IPDR for IP packet at (0x%X).\n", IPPacket));
KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
TcpipAcquireSpinLock(&ReassemblyListLock, &OldIrql);
/* FIXME: Assume IPv4 */
@@ -162,14 +167,14 @@ PIPDATAGRAM_REASSEMBLY GetReassemblyInfo(
(Header->Id == Current->Id) &&
(Header->Protocol == Current->Protocol) &&
(AddrIsEqual(&IPPacket->DstAddr, &Current->DstAddr))) {
KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
TcpipReleaseSpinLock(&ReassemblyListLock, OldIrql);
return Current;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
TcpipReleaseSpinLock(&ReassemblyListLock, OldIrql);
return NULL;
}
@@ -264,7 +269,7 @@ __inline VOID Cleanup(
{
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
KeReleaseSpinLock(Lock, OldIrql);
TcpipReleaseSpinLock(Lock, OldIrql);
RemoveIPDR(IPDR);
FreeIPDR(IPDR);
if (Buffer)
@@ -307,14 +312,14 @@ VOID ProcessFragment(
if (IPDR) {
TI_DbgPrint(DEBUG_IP, ("Continueing assembly.\n"));
/* We have a reassembly structure */
KeAcquireSpinLock(&IPDR->Lock, &OldIrql);
TcpipAcquireSpinLock(&IPDR->Lock, &OldIrql);
CurrentEntry = IPDR->HoleListHead.Flink;
Hole = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
} else {
TI_DbgPrint(DEBUG_IP, ("Starting new assembly.\n"));
/* We don't have a reassembly structure, create one */
IPDR = ExAllocateFromNPagedLookasideList(&IPDRList);
IPDR = TcpipAllocateFromNPagedLookasideList(&IPDRList);
if (!IPDR)
/* We don't have the resources to process this packet, discard it */
return;
@@ -325,7 +330,7 @@ VOID ProcessFragment(
Hole = CreateHoleDescriptor(0, 65536);
if (!Hole) {
/* We don't have the resources to process this packet, discard it */
ExFreeToNPagedLookasideList(&IPDRList, IPDR);
TcpipFreeToNPagedLookasideList(&IPDRList, IPDR);
return;
}
AddrInitIPv4(&IPDR->SrcAddr, IPv4Header->SrcAddr);
@@ -338,15 +343,15 @@ VOID ProcessFragment(
InsertTailList(&IPDR->HoleListHead, &Hole->ListEntry);
CurrentEntry = IPDR->HoleListHead.Flink;
KeInitializeSpinLock(&IPDR->Lock);
TcpipInitializeSpinLock(&IPDR->Lock);
KeAcquireSpinLock(&IPDR->Lock, &OldIrql);
TcpipAcquireSpinLock(&IPDR->Lock, &OldIrql);
/* Update the reassembly list */
ExInterlockedInsertTailList(
&ReassemblyListHead,
&IPDR->ListEntry,
&ReassemblyListLock);
TcpipInterlockedInsertTailList(
&ReassemblyListHead,
&IPDR->ListEntry,
&ReassemblyListLock);
}
FragFirst = (WN2H(IPv4Header->FlagsFragOfs) & IPv4_FRAGOFS_MASK) << 3;
@@ -394,7 +399,7 @@ VOID ProcessFragment(
/* Put the new hole descriptor in the list */
InsertTailList(&IPDR->HoleListHead, &Hole->ListEntry);
} else
ExFreeToNPagedLookasideList(&IPHoleList, Hole);
TcpipFreeToNPagedLookasideList(&IPHoleList, Hole);
/* If this is the first fragment, save the IP header */
if (FragFirst == 0) {
@@ -415,7 +420,7 @@ VOID ProcessFragment(
/* Create a buffer, copy the data into it and put it
in the fragment list */
Fragment = ExAllocateFromNPagedLookasideList(&IPFragmentList);
Fragment = TcpipAllocateFromNPagedLookasideList(&IPFragmentList);
if (!Fragment) {
/* We don't have the resources to process this packet, discard it */
Cleanup(&IPDR->Lock, OldIrql, IPDR, NULL);
@@ -462,7 +467,7 @@ VOID ProcessFragment(
Datagram = ReassembleDatagram(IPDR);
KeReleaseSpinLock(&IPDR->Lock, OldIrql);
TcpipReleaseSpinLock(&IPDR->Lock, OldIrql);
RemoveIPDR(IPDR);
FreeIPDR(IPDR);
@@ -481,7 +486,7 @@ VOID ProcessFragment(
TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram));
(*Datagram->Free)(Datagram);
} else
KeReleaseSpinLock(&IPDR->Lock, OldIrql);
TcpipReleaseSpinLock(&IPDR->Lock, OldIrql);
}
@@ -495,7 +500,7 @@ VOID IPFreeReassemblyList(
PLIST_ENTRY CurrentEntry;
PIPDATAGRAM_REASSEMBLY Current;
KeAcquireSpinLock(&ReassemblyListLock, &OldIrql);
TcpipAcquireSpinLock(&ReassemblyListLock, &OldIrql);
CurrentEntry = ReassemblyListHead.Flink;
while (CurrentEntry != &ReassemblyListHead) {
@@ -509,7 +514,7 @@ VOID IPFreeReassemblyList(
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&ReassemblyListLock, OldIrql);
TcpipReleaseSpinLock(&ReassemblyListLock, OldIrql);
}
@@ -581,9 +586,6 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
if (NTE) {
/* This packet is destined for us */
ProcessFragment(IF, IPPacket, NTE);
/* Done with this NTE */
DereferenceObject(NTE);
} else {
/* This packet is not destined for us. If we are a router,
try to find a route and forward the packet */
@@ -591,9 +593,12 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
/* FIXME: Check if acting as a router */
NCE = NULL;
if (NCE) {
PROUTE_CACHE_NODE RCN;
/* FIXME: Possibly fragment datagram */
/* Forward the packet */
IPSendFragment(IPPacket->NdisPacket, NCE);
if(!RouteGetRouteToDestination( &IPPacket->DstAddr, NULL, &RCN ))
IPSendDatagram(IPPacket, RCN, ReflectPacketComplete, IPPacket);
} else {
TI_DbgPrint(MIN_TRACE, ("No route to destination (0x%X).\n",
IPPacket->DstAddr.Address.IPv4Address));
+21 -69
View File
@@ -116,13 +116,6 @@ VOID RemoveAboveExternal(VOID)
RouteCache = Sibling;
Sibling->Parent = NULL;
}
DereferenceObject(Parent);
#if 0
TI_DbgPrint(MIN_TRACE, ("Displaying tree (after).\n"));
PrintTree(RouteCache);
#endif
}
@@ -294,10 +287,6 @@ VOID RemoveRouteToDestination(
#endif
}
/* Dereference NTE and NCE */
DereferenceObject(RCN->NTE);
DereferenceObject(RCN->NCE);
ExternalRCN->Parent = RemNode->Parent;
RemoveAboveExternal();
@@ -378,20 +367,6 @@ VOID RemoveSubtree(
/* Traverse right subtree */
RemoveSubtree(Node->Right);
/* Finally remove the node itself */
/* It's an internal node, so dereference NTE and NCE */
DereferenceObject(Node->NTE);
DereferenceObject(Node->NCE);
#ifdef DBG
if (Node->RefCount != 1)
TI_DbgPrint(MIN_TRACE, ("RCN at (0x%X) has (%d) references (should be 1).\n", Node, Node->RefCount));
#endif
/* Remove reference for being alive */
DereferenceObject(Node);
}
}
@@ -453,7 +428,7 @@ NTSTATUS RouteShutdown(
TI_DbgPrint(DEBUG_RCACHE, ("Called.\n"));
KeAcquireSpinLock(&RouteCacheLock, &OldIrql);
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
#if 0
TI_DbgPrint(MIN_TRACE, ("Displaying tree.\n"));
PrintTree(RouteCache);
@@ -463,7 +438,7 @@ NTSTATUS RouteShutdown(
FreeRCN(ExternalRCN);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
ExDeleteNPagedLookasideList(&IPRCNList);
@@ -500,7 +475,7 @@ UINT RouteGetRouteToDestination(
TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NTE (%s).\n",
A2S(Destination), NTE ? A2S(NTE->Address) : ""));
KeAcquireSpinLock(&RouteCacheLock, &OldIrql);
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
#if 0
TI_DbgPrint(MIN_TRACE, ("Displaying tree (before).\n"));
@@ -519,17 +494,15 @@ UINT RouteGetRouteToDestination(
NTE = RouterFindBestNTE(Interface, Destination);
if (!NTE) {
/* We cannot get to the specified destination. Return error */
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
return IP_NO_ROUTE_TO_DESTINATION;
}
} else
ReferenceObject(NTE);
}
/* The destination address is on-link. Check our neighbor cache */
NCE = NBFindOrCreateNeighbor(Interface, Destination);
if (!NCE) {
DereferenceObject(NTE);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
return IP_NO_RESOURCES;
}
} else {
@@ -537,7 +510,7 @@ UINT RouteGetRouteToDestination(
NCE = RouterGetRoute(Destination, NTE);
if (!NCE) {
/* We cannot get to the specified destination. Return error */
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
return IP_NO_ROUTE_TO_DESTINATION;
}
}
@@ -549,13 +522,10 @@ UINT RouteGetRouteToDestination(
} else
RCN2 = ExpandExternalRCN();
if (!RCN2) {
DereferenceObject(NTE);
DereferenceObject(NCE);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
return IP_NO_RESOURCES;
}
RCN2->RefCount = 1;
RCN2->State = RCN_STATE_COMPUTED;
RCN2->NTE = NTE;
RtlCopyMemory(&RCN2->Destination, Destination, sizeof(IP_ADDRESS));
@@ -568,17 +538,10 @@ UINT RouteGetRouteToDestination(
reference them here */
}
/* Reference the RCN for the user */
ReferenceObject(RCN2);
#if 0
TI_DbgPrint(MIN_TRACE, ("Displaying tree (after).\n"));
PrintTree(RouteCache);
#endif
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
*RCN = RCN2;
TI_DbgPrint(MID_TRACE,("RCN->PathMTU: %d\n", RCN2->PathMTU));
return IP_SUCCESS;
}
@@ -612,7 +575,7 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination(
A2S(NTE->Address),
A2S(&NCE->Address)));
KeAcquireSpinLock(&RouteCacheLock, &OldIrql);
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
/* Locate an external RCN we can expand */
RCN = RouteCache;
@@ -635,7 +598,7 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination(
} else
RCN = ExpandExternalRCN();
if (!RCN) {
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
return NULL;
}
@@ -644,24 +607,13 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination(
INIT_TAG(RCN, TAG('R','C','N',' '));
/* Reference once for beeing alive */
RCN->RefCount = 1;
RCN->State = RCN_STATE_PERMANENT;
RCN->NTE = NTE;
RtlCopyMemory(&RCN->Destination, Destination, sizeof(IP_ADDRESS));
RCN->PathMTU = IF->MTU;
RCN->NCE = NCE;
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
/* The route cache node references the NTE and the NCE */
ReferenceObject(NTE);
if (NCE)
ReferenceObject(NCE);
#if 0
TI_DbgPrint(MIN_TRACE, ("Displaying tree.\n"));
PrintTree(RouteCache);
#endif
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
return RCN;
}
@@ -679,11 +631,11 @@ VOID RouteRemoveRouteToDestination(
TI_DbgPrint(DEBUG_RCACHE, ("Called. RCN (0x%X).\n", RCN));
KeAcquireSpinLock(&RouteCacheLock, &OldIrql);
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
RemoveRouteToDestination(RCN);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
}
@@ -699,9 +651,9 @@ VOID RouteInvalidateNTE(
TI_DbgPrint(DEBUG_RCACHE, ("Called. NTE (0x%X).\n", NTE));
KeAcquireSpinLock(&RouteCacheLock, &OldIrql);
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
InvalidateNTEOnSubtree(NTE, RouteCache);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
}
@@ -717,9 +669,9 @@ VOID RouteInvalidateNCE(
TI_DbgPrint(DEBUG_RCACHE, ("Called. NCE (0x%X).\n", NCE));
KeAcquireSpinLock(&RouteCacheLock, &OldIrql);
TcpipAcquireSpinLock(&RouteCacheLock, &OldIrql);
InvalidateNCEOnSubtree(NCE, RouteCache);
KeReleaseSpinLock(&RouteCacheLock, OldIrql);
TcpipReleaseSpinLock(&RouteCacheLock, OldIrql);
}
NTSTATUS
@@ -728,9 +680,9 @@ RouteFriendlyAddRoute( PIPROUTE_ENTRY ire ) {
/* Find IF */
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
//RouteAddRouteToDestination(&Dest,Nte,If,Nce);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
return STATUS_SUCCESS;
}
+12 -44
View File
@@ -27,7 +27,7 @@ VOID FreeFIB(
* Object = Pointer to an forward information base structure
*/
{
ExFreePool(Object);
PoolFreeBuffer(Object);
}
@@ -46,19 +46,6 @@ VOID DestroyFIBE(
/* Unlink the FIB entry from the list */
RemoveEntryList(&FIBE->ListEntry);
/* Dereference the referenced objects */
DereferenceObject(FIBE->NetworkAddress);
DereferenceObject(FIBE->Netmask);
DereferenceObject(FIBE->Router);
#ifdef DBG
FIBE->RefCount--;
if (FIBE->RefCount != 0) {
TI_DbgPrint(MIN_TRACE, ("FIB entry at (0x%X) has (%d) references (Should be 0).\n", FIBE, FIBE->RefCount));
}
#endif
/* And free the FIB entry */
FreeFIB(FIBE);
}
@@ -235,7 +222,7 @@ PNET_TABLE_ENTRY RouterFindBestNTE(
TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s).\n", A2S(Destination)));
KeAcquireSpinLock(&Interface->Lock, &OldIrql);
TcpipAcquireSpinLock(&Interface->Lock, &OldIrql);
CurrentEntry = Interface->NTEListHead.Flink;
while (CurrentEntry != &Interface->NTEListHead) {
@@ -245,22 +232,17 @@ PNET_TABLE_ENTRY RouterFindBestNTE(
Length = CommonPrefixLength(Destination, Current->Address);
if (BestNTE) {
if (Length > BestLength) {
/* This seems to be a better NTE */
DereferenceObject(BestNTE);
ReferenceObject(Current);
BestNTE = Current;
BestLength = Length;
}
} else {
/* First suitable NTE found, save it */
ReferenceObject(Current);
BestNTE = Current;
BestLength = Length;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&Interface->Lock, OldIrql);
TcpipReleaseSpinLock(&Interface->Lock, OldIrql);
return BestNTE;
}
@@ -331,7 +313,7 @@ PFIB_ENTRY RouterAddRoute(
A2S(Netmask),
A2S(&Router->Address)));
FIBE = ExAllocatePool(NonPagedPool, sizeof(FIB_ENTRY));
FIBE = PoolAllocateBuffer(sizeof(FIB_ENTRY));
if (!FIBE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NULL;
@@ -346,7 +328,7 @@ PFIB_ENTRY RouterAddRoute(
FIBE->Metric = Metric;
/* Add FIB to the forward information base */
ExInterlockedInsertTailList(&FIBListHead, &FIBE->ListEntry, &FIBLock);
TcpipInterlockedInsertTailList(&FIBListHead, &FIBE->ListEntry, &FIBLock);
return FIBE;
}
@@ -381,7 +363,7 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
if( NTE )
TI_DbgPrint(DEBUG_ROUTER, ("NTE (%s).\n", A2S(NTE->Address)));
KeAcquireSpinLock(&FIBLock, &OldIrql);
TcpipAcquireSpinLock(&FIBLock, &OldIrql);
CurrentEntry = FIBListHead.Flink;
while (CurrentEntry != &FIBListHead) {
@@ -402,15 +384,12 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
((State == BestState) &&
(Length > BestLength))) {
/* This seems to be a better router */
DereferenceObject(BestNCE);
ReferenceObject(NCE);
BestNCE = NCE;
BestLength = Length;
BestState = State;
}
} else {
/* First suitable router found, save it */
ReferenceObject(NCE);
BestNCE = NCE;
BestLength = Length;
BestState = State;
@@ -419,7 +398,7 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&FIBLock, OldIrql);
TcpipReleaseSpinLock(&FIBLock, OldIrql);
return BestNCE;
}
@@ -439,9 +418,9 @@ VOID RouterRemoveRoute(
TI_DbgPrint(DEBUG_ROUTER, ("FIBE (%s).\n", A2S(FIBE->NetworkAddress)));
KeAcquireSpinLock(&FIBLock, &OldIrql);
TcpipAcquireSpinLock(&FIBLock, &OldIrql);
DestroyFIBE(FIBE);
KeReleaseSpinLock(&FIBLock, OldIrql);
TcpipReleaseSpinLock(&FIBLock, OldIrql);
}
@@ -480,15 +459,12 @@ PFIB_ENTRY RouterCreateRouteIPv4(
pNetmask = AddrBuildIPv4(Netmask);
if (!pNetmask) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
DereferenceObject(pNetworkAddress);
return NULL;
}
pRouterAddress = AddrBuildIPv4(RouterAddress);
if (!pRouterAddress) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
DereferenceObject(pNetworkAddress);
DereferenceObject(pNetmask);
return NULL;
}
@@ -500,21 +476,13 @@ PFIB_ENTRY RouterCreateRouteIPv4(
NUD_PROBE);
if (!NCE) {
/* Not enough free resources */
DereferenceObject(pNetworkAddress);
DereferenceObject(pNetmask);
DereferenceObject(pRouterAddress);
return NULL;
}
ReferenceObject(pNetworkAddress);
ReferenceObject(pNetmask);
FIBE = RouterAddRoute(pNetworkAddress, pNetmask, NCE, 1);
if (!FIBE) {
/* Not enough free resources */
NBRemoveNeighbor(NCE);
DereferenceObject(pNetworkAddress);
DereferenceObject(pNetmask);
DereferenceObject(pRouterAddress);
(pNetworkAddress->Free)(pNetworkAddress);
(pNetmask->Free)(pNetmask);
@@ -537,7 +505,7 @@ NTSTATUS RouterStartup(
/* Initialize the Forward Information Base */
InitializeListHead(&FIBListHead);
KeInitializeSpinLock(&FIBLock);
TcpipInitializeSpinLock(&FIBLock);
#if 0
/* TEST: Create a test route */
@@ -563,9 +531,9 @@ NTSTATUS RouterShutdown(
TI_DbgPrint(DEBUG_ROUTER, ("Called.\n"));
/* Clear Forward Information Base */
KeAcquireSpinLock(&FIBLock, &OldIrql);
TcpipAcquireSpinLock(&FIBLock, &OldIrql);
DestroyFIBEs();
KeReleaseSpinLock(&FIBLock, OldIrql);
TcpipReleaseSpinLock(&FIBLock, OldIrql);
return STATUS_SUCCESS;
}
+3 -12
View File
@@ -166,18 +166,9 @@ VOID DisplayIPPacket(
//OskitDumpBuffer( p, Length );
}
if (IPPacket->NdisPacket) {
NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
Length -= MaxLLHeaderSize;
CharBuffer = exAllocatePool(NonPagedPool, Length);
Length = CopyPacketToBuffer(CharBuffer, IPPacket->NdisPacket, MaxLLHeaderSize, Length);
DisplayIPHeader(CharBuffer, Length);
exFreePool(CharBuffer);
} else {
CharBuffer = IPPacket->Header;
Length = IPPacket->ContigSize;
DisplayIPHeader(CharBuffer, Length);
}
CharBuffer = IPPacket->Header;
Length = IPPacket->ContigSize;
DisplayIPHeader(CharBuffer, Length);
#endif
}
+110 -182
View File
@@ -10,6 +10,66 @@
#include "precomp.h"
BOOLEAN PrepareNextFragment(PIPFRAGMENT_CONTEXT IFC);
NTSTATUS IPSendFragment(PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE,
PIPFRAGMENT_CONTEXT IFC);
VOID IPSendComplete
(PVOID Context, PNDIS_PACKET NdisPacket, NDIS_STATUS NdisStatus)
/*
* FUNCTION: IP datagram fragment send completion handler
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to NDIS packet that was sent
* NdisStatus = NDIS status of operation
* NOTES:
* This routine is called when an IP datagram fragment has been sent
*/
{
PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)Context;
TI_DbgPrint
(MAX_TRACE,
("Called. Context (0x%X) NdisPacket (0x%X) NdisStatus (0x%X)\n",
Context, NdisPacket, NdisStatus));
/* FIXME: Stop sending fragments and cleanup datagram buffers if
there was an error */
if (PrepareNextFragment(IFC)) {
/* A fragment was prepared for transmission, so send it */
IPSendFragment(IFC->NdisPacket, IFC->NCE, IFC);
} else {
TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n"));
/* There are no more fragments to transmit, so call completion handler */
FreeNdisPacket(IFC->NdisPacket);
IFC->Complete(IFC->Context, IFC->Datagram, NdisStatus);
exFreePool(IFC);
}
}
NTSTATUS IPSendFragment(
PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE,
PIPFRAGMENT_CONTEXT IFC)
/*
* FUNCTION: Sends an IP datagram fragment to a neighbor
* ARGUMENTS:
* NdisPacket = Pointer to an NDIS packet containing fragment
* NCE = Pointer to NCE for first hop to destination
* RETURNS:
* Status of operation
* NOTES:
* Lowest level IP send routine
*/
{
TI_DbgPrint(MAX_TRACE, ("Called. NdisPacket (0x%X) NCE (0x%X).\n", NdisPacket, NCE));
TI_DbgPrint(MAX_TRACE, ("NCE->State = %d.\n", NCE->State));
return NBQueuePacket(NCE, NdisPacket, IPSendComplete, IFC);
}
BOOLEAN PrepareNextFragment(
PIPFRAGMENT_CONTEXT IFC)
@@ -45,7 +105,10 @@ BOOLEAN PrepareNextFragment(
MoreFragments = FALSE;
}
RtlCopyMemory(IFC->Data, IFC->DatagramData, DataSize);
TI_DbgPrint(MID_TRACE,("Copying data from %x to %x (%d)\n",
IFC->DatagramData, IFC->Data, DataSize));
RtlCopyMemory(IFC->Data, IFC->DatagramData, DataSize); // SAFE
FragOfs = (USHORT)IFC->Position; // Swap?
if (MoreFragments)
@@ -75,11 +138,12 @@ BOOLEAN PrepareNextFragment(
}
}
NTSTATUS SendFragments(
PIP_PACKET IPPacket,
PNEIGHBOR_CACHE_ENTRY NCE,
UINT PathMTU)
UINT PathMTU,
PIP_TRANSMIT_COMPLETE Complete,
PVOID Context)
/*
* FUNCTION: Fragments and sends the first fragment of an IP datagram
* ARGUMENTS:
@@ -95,182 +159,61 @@ NTSTATUS SendFragments(
PIPFRAGMENT_CONTEXT IFC;
NDIS_STATUS NdisStatus;
PVOID Data;
UINT BufferSize = MaxLLHeaderSize + PathMTU, InSize;
PCHAR InData;
TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X) PathMTU (%d).\n",
IPPacket, NCE, PathMTU));
/* Make a smaller buffer if we will only send one fragment */
GetDataPtr( IPPacket->NdisPacket, 0, &InData, &InSize );
if( InSize < BufferSize ) BufferSize = InSize;
TI_DbgPrint(MAX_TRACE, ("Fragment buffer is %d bytes\n", BufferSize));
IFC = exAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT));
if (IFC == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
/* We allocate a buffer for a PathMTU sized packet and reuse
it for all fragments */
Data = exAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
if (Data == NULL) {
exFreePool(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate NDIS packet */
NdisStatus = AllocatePacketWithBuffer
( &IFC->NdisPacket, Data, MaxLLHeaderSize + PathMTU );
( &IFC->NdisPacket, NULL, BufferSize );
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(IFC->NdisPacket, IFC->NdisBuffer);
if( !NT_SUCCESS(NdisStatus) ) {
exFreePool( IFC );
return NdisStatus;
}
IFC->Header = (PVOID)((ULONG_PTR)Data + MaxLLHeaderSize);
GetDataPtr( IFC->NdisPacket, 0, (PCHAR *)&Data, &InSize );
IFC->Header = ((PCHAR)Data) + MaxLLHeaderSize;
IFC->Datagram = IPPacket->NdisPacket;
IFC->DatagramData = IPPacket->Header;
IFC->DatagramData = ((PCHAR)IPPacket->Header) + IPPacket->HeaderSize;
IFC->HeaderSize = IPPacket->HeaderSize;
IFC->PathMTU = PathMTU;
IFC->NCE = NCE;
IFC->Position = 0;
IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize;
IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize);
IFC->Complete = Complete;
IFC->Context = Context;
PC(IFC->NdisPacket)->DLComplete = IPSendComplete;
/* Set upper layer completion function to NULL to indicate that
this packet is an IP datagram fragment and thus we should
check for more fragments to send. If this is NULL the
Context field is a pointer to an IPFRAGMENT_CONTEXT structure */
PC(IFC->NdisPacket)->Complete = NULL;
PC(IFC->NdisPacket)->Context = IFC;
TI_DbgPrint(MID_TRACE,("Copying header from %x to %x (%d)\n",
IPPacket->Header, IFC->Header,
IPPacket->HeaderSize));
/* Copy IP datagram header to fragment buffer */
RtlCopyMemory(IFC->Header, IPPacket->Header, IPPacket->HeaderSize);
RtlCopyMemory( IFC->Header, IPPacket->Header, IPPacket->HeaderSize );
/* Prepare next fragment for transmission and send it */
PrepareNextFragment(IFC);
IPSendFragment(IFC->NdisPacket, NCE);
IPSendFragment(IFC->NdisPacket, NCE, IFC);
return STATUS_SUCCESS;
}
VOID IPSendComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: IP datagram fragment send completion handler
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to NDIS packet that was sent
* NdisStatus = NDIS status of operation
* NOTES:
* This routine is called when an IP datagram fragment has been sent
*/
{
TI_DbgPrint(MAX_TRACE, ("Called. Context (0x%X) NdisPacket (0x%X) NdisStatus (0x%X)\n",
Context, NdisPacket, NdisStatus));
/* FIXME: Stop sending fragments and cleanup datagram buffers if
there was an error */
if (PC(NdisPacket) && PC(NdisPacket)->Complete)
/* This datagram was only one fragment long so call completion handler now */
(*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus);
else {
/* This was one of many fragments of an IP datagram. Prepare
next fragment and send it or if there are no more fragments,
call upper layer completion routine */
PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)PC(NdisPacket)->Context;
if (PrepareNextFragment(IFC)) {
/* A fragment was prepared for transmission, so send it */
IPSendFragment(IFC->NdisPacket, IFC->NCE);
} else {
TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n"));
/* There are no more fragments to transmit, so call completion handler */
NdisPacket = IFC->Datagram;
FreeNdisPacket(IFC->NdisPacket);
exFreePool(IFC);
(*PC(NdisPacket)->Complete)
(PC(NdisPacket)->Context,
NdisPacket,
NdisStatus);
}
}
}
NTSTATUS IPSendFragment(
PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Sends an IP datagram fragment to a neighbor
* ARGUMENTS:
* NdisPacket = Pointer to an NDIS packet containing fragment
* NCE = Pointer to NCE for first hop to destination
* RETURNS:
* Status of operation
* NOTES:
* Lowest level IP send routine
*/
{
TI_DbgPrint(MAX_TRACE, ("Called. NdisPacket (0x%X) NCE (0x%X).\n", NdisPacket, NCE));
TI_DbgPrint(MAX_TRACE, ("NCE->State = %d.\n", NCE->State));
PC(NdisPacket)->DLComplete = IPSendComplete;
switch (NCE->State) {
case NUD_PERMANENT:
/* Neighbor is always valid */
break;
case NUD_REACHABLE:
/* Neighbor is reachable */
/* FIXME: Set reachable timer */
break;
case NUD_STALE:
/* Enter delay state and send packet */
/* FIXME: Enter delay state */
break;
case NUD_DELAY:
case NUD_PROBE:
/* In these states we send the packet and hope the neighbor
hasn't changed hardware address */
break;
case NUD_INCOMPLETE:
TI_DbgPrint(MAX_TRACE, ("Queueing packet.\n"));
/* We don't know the hardware address of the first hop to
the destination. Queue the packet on the NCE and return */
NBQueuePacket(NCE, NdisPacket);
return STATUS_SUCCESS;
default:
/* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown NCE state.\n"));
return STATUS_SUCCESS;
}
(*NCE->Interface->Transmit)(NCE->Interface->Context,
NdisPacket,
MaxLLHeaderSize,
NCE->LinkAddress,
LAN_PROTO_IPv4);
return STATUS_SUCCESS;
}
NTSTATUS IPSendDatagram(
PIP_PACKET IPPacket,
PROUTE_CACHE_NODE RCN)
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PROUTE_CACHE_NODE RCN,
PIP_TRANSMIT_COMPLETE Complete, PVOID Context)
/*
* FUNCTION: Sends an IP datagram to a remote address
* ARGUMENTS:
@@ -285,7 +228,6 @@ NTSTATUS IPSendDatagram(
*/
{
PNEIGHBOR_CACHE_ENTRY NCE;
UINT PathMTU;
TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) RCN (0x%X)\n", IPPacket, RCN));
@@ -294,40 +236,26 @@ NTSTATUS IPSendDatagram(
NCE = RCN->NCE;
#ifdef DBG
if (!NCE) {
TI_DbgPrint(MIN_TRACE, ("No NCE to use.\n"));
FreeNdisPacket(IPPacket->NdisPacket);
return STATUS_SUCCESS;
}
#endif
/* Fetch path MTU now, because it may change */
PathMTU = RCN->PathMTU;
TI_DbgPrint(MID_TRACE,("PathMTU: %d\n", PathMTU));
if (IPPacket->TotalSize > PathMTU) {
TI_DbgPrint(MID_TRACE,("Doing SendFragments\n"));
return SendFragments(IPPacket, NCE, PathMTU);
TI_DbgPrint(MID_TRACE,("PathMTU: %d\n", RCN->PathMTU));
if ((IPPacket->Flags & IP_PACKET_FLAG_RAW) == 0) {
/* Calculate checksum of IP header */
TI_DbgPrint(MID_TRACE,("-> not IP_PACKET_FLAG_RAW\n"));
((PIPv4_HEADER)IPPacket->Header)->Checksum = 0;
((PIPv4_HEADER)IPPacket->Header)->Checksum = (USHORT)
IPv4Checksum(IPPacket->Header, IPPacket->HeaderSize, 0);
TI_DbgPrint(MID_TRACE,("IP Check: %x\n", ((PIPv4_HEADER)IPPacket->Header)->Checksum));
TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n",
WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength)));
} else {
if ((IPPacket->Flags & IP_PACKET_FLAG_RAW) == 0) {
/* Calculate checksum of IP header */
TI_DbgPrint(MID_TRACE,("-> not IP_PACKET_FLAG_RAW\n"));
((PIPv4_HEADER)IPPacket->Header)->Checksum = 0;
((PIPv4_HEADER)IPPacket->Header)->Checksum = (USHORT)
IPv4Checksum(IPPacket->Header, IPPacket->HeaderSize, 0);
TI_DbgPrint(MID_TRACE,("IP Check: %x\n", ((PIPv4_HEADER)IPPacket->Header)->Checksum));
TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n",
WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength)));
} else {
TI_DbgPrint(MAX_TRACE, ("Sending raw packet (flags are 0x%X).\n",
IPPacket->Flags));
}
return IPSendFragment(IPPacket->NdisPacket, NCE);
TI_DbgPrint(MAX_TRACE, ("Sending raw packet (flags are 0x%X).\n",
IPPacket->Flags));
}
return SendFragments(IPPacket, NCE, RCN->PathMTU, Complete, Context);
}
/* EOF */
@@ -10,233 +10,6 @@
#include "precomp.h"
/* Pending request queue */
LIST_ENTRY DGPendingListHead;
KSPIN_LOCK DGPendingListLock;
/* Work queue item for pending requests */
WORK_QUEUE_ITEM DGWorkItem;
VOID STDCALL DatagramWorker(
PVOID Context)
/*
* FUNCTION: Handles pending send requests
* ARGUMENTS:
* Context = Pointer to context information (unused)
* NOTES:
* This routine is called after the driver has run out of resources.
* It processes send requests or shedules them to be processed
*/
{
PLIST_ENTRY CurrentADFEntry;
PLIST_ENTRY CurrentSREntry;
PADDRESS_FILE CurrentADF;
PDATAGRAM_SEND_REQUEST CurrentSR;
KIRQL OldIrql1;
KIRQL OldIrql2;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&DGPendingListLock, &OldIrql1);
CurrentADFEntry = DGPendingListHead.Flink;
while (CurrentADFEntry != &DGPendingListHead)
{
RemoveEntryList(CurrentADFEntry);
CurrentADF = CONTAINING_RECORD(CurrentADFEntry,
ADDRESS_FILE,
ListEntry);
KeAcquireSpinLock(&CurrentADF->Lock, &OldIrql2);
if (AF_IS_BUSY(CurrentADF))
{
/* The send worker function is already running so we just
set the pending send flag on the address file object */
AF_SET_PENDING(CurrentADF, AFF_SEND);
KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
}
else
{
if (!IsListEmpty(&CurrentADF->TransmitQueue))
{
/* The transmit queue is not empty. Dequeue a send
request and process it */
CurrentSREntry = RemoveHeadList(&CurrentADF->TransmitQueue);
CurrentSR = CONTAINING_RECORD(CurrentADFEntry,
DATAGRAM_SEND_REQUEST,
ListEntry);
KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
DGSend(CurrentADF, CurrentSR);
}
else
{
KeReleaseSpinLock(&CurrentADF->Lock, OldIrql2);
}
}
CurrentADFEntry = CurrentADFEntry->Flink;
}
KeReleaseSpinLock(&DGPendingListLock, OldIrql1);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID SendDatagramComplete(
PVOID Context,
PNDIS_PACKET Packet,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: Datagram transmit completion handler
* ARGUMENTS:
* Context = Pointer to context infomation (DATAGRAM_SEND_REQUEST)
* Packet = Pointer to NDIS packet
* NdisStatus = Status of transmit operation
* NOTES:
* This routine is called by IP when a datagram send completes.
* We shedule the out-of-resource worker function if there
* are pending address files in the queue
*/
{
KIRQL OldIrql;
ULONG BytesSent;
PVOID CompleteContext;
PDATAGRAM_SEND_REQUEST SendRequest;
DATAGRAM_COMPLETION_ROUTINE Complete;
BOOLEAN QueueWorkItem;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
Complete = SendRequest->Complete;
CompleteContext = SendRequest->Context;
BytesSent = SendRequest->BufferSize;
/* If there are pending send requests, shedule worker function */
KeAcquireSpinLock(&DGPendingListLock, &OldIrql);
QueueWorkItem = (!IsListEmpty(&DGPendingListHead));
KeReleaseSpinLock(&DGPendingListLock, OldIrql);
if (QueueWorkItem)
ExQueueWorkItem(&DGWorkItem, CriticalWorkQueue);
TI_DbgPrint(MAX_TRACE, ("Calling 0x%X.\n", Complete));
/* Call completion routine for send request */
(*Complete)(Context, NdisStatus, BytesSent);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID DGSend(
PVOID Context,
PDATAGRAM_SEND_REQUEST SendRequest)
/*
* FUNCTION: Sends a datagram to IP layer
* ARGUMENTS:
* Context = Pointer to context information (ADDRESS_FILE)
* SendRequest = Pointer to send request
*/
{
KIRQL OldIrql;
NTSTATUS Status;
USHORT LocalPort;
PIP_PACKET IPPacket;
PROUTE_CACHE_NODE RCN;
PLIST_ENTRY CurrentEntry;
PADDRESS_FILE AddrFile = Context;
PADDRESS_ENTRY ADE;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* Get the information we need from the address file
now so we minimize the time we hold the spin lock */
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
ASSERT(AddrFile->ADE);
LocalPort = AddrFile->Port;
ADE = AddrFile->ADE;
ReferenceObject(ADE);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* Loop until there are no more send requests in the
transmit queue or until we run out of resources */
for (;;)
{
TI_DbgPrint(MIN_TRACE, ("Looping on DGSend !!!! WHEE!\n"));
if (!NT_SUCCESS(Status))
{
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* An error occurred, enqueue the send request again and return */
InsertHeadList(&AddrFile->TransmitQueue, &SendRequest->ListEntry);
DereferenceObject(ADE);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MIN_TRACE, ("Leaving (insufficient resources).\n"));
return;
}
/* Get a route to the destination address */
if (RouteGetRouteToDestination(&SendRequest->RemoteAddress, ADE->NTE, &RCN) == IP_SUCCESS)
{
/* Set completion routine and send the packet */
IPPacket = &SendRequest->Packet;
PC(IPPacket->NdisPacket)->Complete = SendDatagramComplete;
PC(IPPacket->NdisPacket)->Context = SendRequest;
if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS)
{
TI_DbgPrint(MIN_TRACE, ("!! Datagram sent !! (completing)\n"));
SendDatagramComplete(SendRequest,
IPPacket->NdisPacket,
NDIS_STATUS_REQUEST_ABORTED);
}
/* We're done with the RCN */
DereferenceObject(RCN);
}
else
{
/* No route to destination */
/* FIXME: Which error code should we use here? */
TI_DbgPrint(MIN_TRACE,
("No route to destination address (0x%X).\n",
SendRequest->RemoteAddress.Address.IPv4Address));
SendDatagramComplete(SendRequest,
IPPacket->NdisPacket,
NDIS_STATUS_REQUEST_ABORTED);
}
/* Check transmit queue for more to send */
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (!IsListEmpty(&AddrFile->TransmitQueue))
{
/* Transmit queue is not empty, process one more request */
CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MIN_TRACE, ("List is not empty\n"));
}
else
{
/* Transmit queue is empty */
AF_CLR_PENDING(AddrFile, AFF_SEND);
DereferenceObject(ADE);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (empty queue).\n"));
return;
}
}
}
VOID DGDeliverData(
PADDRESS_FILE AddrFile,
PIP_ADDRESS Address,
@@ -268,7 +41,7 @@ VOID DGDeliverData(
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AddrFile->Protocol == IPPROTO_UDP)
{
@@ -305,13 +78,12 @@ VOID DGDeliverData(
/* Remove the request from the queue */
RemoveEntryList(&Current->ListEntry);
AddrFile->RefCount--;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
if (Found)
{
@@ -335,7 +107,7 @@ VOID DGDeliverData(
ReceiveHandler = AddrFile->ReceiveDatagramHandler;
HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
if (Address->Type == IP_ADDRESS_V4)
{
@@ -368,336 +140,3 @@ VOID DGDeliverData(
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID DGCancelSendRequest(
PADDRESS_FILE AddrFile,
PVOID Context)
/*
* FUNCTION: Cancels a datagram send request
* ARGUMENTS:
* AddrFile = Pointer to address file of the request
* Context = Pointer to context information for completion handler
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PDATAGRAM_SEND_REQUEST Current = NULL;
BOOLEAN Found = FALSE;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Search the request list for the specified request and remove it */
CurrentEntry = AddrFile->TransmitQueue.Flink;
while ((CurrentEntry != &AddrFile->TransmitQueue) && (!Found))
{
Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
if (Context == Current->Context)
{
/* We've found the request, now remove it from the queue */
RemoveEntryList(CurrentEntry);
AddrFile->RefCount--;
Found = TRUE;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
if (Found)
{
/* Complete the request and free its resources */
(*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
exFreePool(Current);
}
else
{
TI_DbgPrint(MID_TRACE, ("Cannot find send request.\n"));
}
}
VOID DGCancelReceiveRequest(
PADDRESS_FILE AddrFile,
PVOID Context)
/*
* FUNCTION: Cancels a datagram receive request
* ARGUMENTS:
* AddrFile = Pointer to address file of the request
* Context = Pointer to context information for completion handler
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PDATAGRAM_RECEIVE_REQUEST Current = NULL;
BOOLEAN Found = FALSE;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Search the request list for the specified request and remove it */
CurrentEntry = AddrFile->ReceiveQueue.Flink;
while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found))
{
Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
if (Context == Current->Context)
{
/* We've found the request, now remove it from the queue */
RemoveEntryList(CurrentEntry);
AddrFile->RefCount--;
Found = TRUE;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
if (Found)
{
/* Complete the request and free its resources */
(*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
exFreePool(Current);
}
else
{
TI_DbgPrint(MID_TRACE, ("Cannot find receive request.\n"));
}
}
NTSTATUS DGTransmit(
PADDRESS_FILE AddressFile,
PDATAGRAM_SEND_REQUEST SendRequest)
/*
* FUNCTION: Transmits or queues a send request
* ARGUMENTS:
* AddressFile = Pointer to address file
* SendRequest = Pointer to send request
* RETURNS:
* Status of operation
*/
{
KIRQL OldIrql;
KeAcquireSpinLock(&AddressFile->Lock, &OldIrql);
if (AF_IS_BUSY(AddressFile))
{
/* Queue send request on the transmit queue */
InsertTailList(&AddressFile->TransmitQueue, &SendRequest->ListEntry);
/* Reference address file and set pending send request flag */
ReferenceObject(AddressFile);
AF_SET_PENDING(AddressFile, AFF_SEND);
KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (queued).\n"));
}
else
{
KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
/* Send the datagram */
DGSend(AddressFile, SendRequest);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
}
return STATUS_PENDING;
}
NTSTATUS DGSendDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR BufferData,
ULONG DataSize,
PULONG DataUsed )
/*
* FUNCTION: Sends a datagram to a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Packet = Pointer to NDIS buffer with data
* RETURNS:
* Status of operation
*/
{
KIRQL OldIrql;
NTSTATUS Status;
PDATAGRAM_SEND_REQUEST SendRequest;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
*DataUsed = DataSize;
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AF_IS_VALID(AddrFile)) {
/* Initialize a send request */
SendRequest = exAllocatePool( NonPagedPool,
sizeof( DATAGRAM_SEND_REQUEST ) );
if( SendRequest ) {
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return STATUS_INSUFFICIENT_RESOURCES;
}
SendRequest->Complete = NULL;
SendRequest->Context = NULL;
SendRequest->Packet.Header = BufferData + MaxLLHeaderSize;
SendRequest->Packet.ContigSize = DataSize;
SendRequest->Packet.TotalSize = DataSize;
if (NT_SUCCESS(Status)) {
Status = AddrGetAddress(ConnInfo->RemoteAddress,
&SendRequest->RemoteAddress,
&SendRequest->RemotePort);
if (NT_SUCCESS(Status))
{
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return DGTransmit(AddrFile, SendRequest);
}
else
{
exFreePool(SendRequest);
}
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
Status = STATUS_ADDRESS_CLOSED;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
return Status;
}
NTSTATUS DGReceiveDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived)
/*
* FUNCTION: Attempts to receive a datagram from a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer chain to store received data
* ReceiveLength = Maximum size to use of buffer (0 if all can be used)
* ReceiveFlags = Receive flags (None, Normal, Peek)
* ReturnInfo = Pointer to structure for return information
* BytesReceive = Pointer to structure for number of bytes received
* RETURNS:
* Status of operation
* NOTES:
* This is the high level interface for receiving datagrams
*/
{
KIRQL OldIrql;
NTSTATUS Status;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AF_IS_VALID(AddrFile))
{
ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
if (ReceiveRequest)
{
/* Initialize a receive request */
/* Extract the remote address filter from the request (if any) */
if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress))
{
Status = AddrGetAddress(ConnInfo->RemoteAddress,
&ReceiveRequest->RemoteAddress,
&ReceiveRequest->RemotePort);
if (!NT_SUCCESS(Status))
{
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
exFreePool(ReceiveRequest);
return Status;
}
}
else
{
ReceiveRequest->RemotePort = 0;
}
ReceiveRequest->ReturnInfo = ReturnInfo;
ReceiveRequest->Buffer = Buffer;
/* If ReceiveLength is 0, the whole buffer is available to us */
ReceiveRequest->BufferSize = ReceiveLength;
ReceiveRequest->Complete = NULL;
ReceiveRequest->Context = NULL;
/* Queue receive request */
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
/* Reference address file and set pending receive request flag */
AddrFile->RefCount++;
AF_SET_PENDING(AddrFile, AFF_RECEIVE);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
return STATUS_PENDING;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
Status = STATUS_INVALID_ADDRESS;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
return Status;
}
NTSTATUS DGStartup(
VOID)
/*
* FUNCTION: Initializes the datagram subsystem
* RETURNS:
* Status of operation
*/
{
InitializeListHead(&DGPendingListHead);
KeInitializeSpinLock(&DGPendingListLock);
ExInitializeWorkItem(&DGWorkItem, DatagramWorker, NULL);
return STATUS_SUCCESS;
}
NTSTATUS DGShutdown(
VOID)
/*
* FUNCTION: Shuts down the datagram subsystem
* RETURNS:
* Status of operation
*/
{
return STATUS_SUCCESS;
}
+22 -6
View File
@@ -74,6 +74,10 @@ NTSTATUS BuildRawIPPacket(
return STATUS_SUCCESS;
}
VOID RawIPSendComplete
( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status ) {
FreeNdisPacket( Packet );
}
NTSTATUS RawIPSendDatagram(
PADDRESS_FILE AddrFile,
@@ -94,6 +98,8 @@ NTSTATUS RawIPSendDatagram(
{
NDIS_STATUS Status;
IP_PACKET Packet;
PROUTE_CACHE_NODE RCN;
IP_ADDRESS RemoteAddress;
Status = AllocatePacketWithBuffer( &Packet.NdisPacket,
BufferData,
@@ -108,13 +114,23 @@ NTSTATUS RawIPSendDatagram(
BufferLen,
AddrFile->ADE->Address,
AddrFile->Port );
if( Status == NDIS_STATUS_SUCCESS )
Status = DGSendDatagram(AddrFile, ConnInfo, BufferData, BufferLen,
DataUsed);
else
FreeNdisPacket( Packet.NdisPacket );
/* NdisFreeBuffer( Buffer ); */
if( Status == NDIS_STATUS_SUCCESS ) {
RemoteAddress.Type = IP_ADDRESS_V4;
RtlCopyMemory( &RemoteAddress.Address.IPv4Address,
BufferData + FIELD_OFFSET(IPv4_HEADER, DstAddr),
sizeof(IPv4_RAW_ADDRESS) );
Status = RouteGetRouteToDestination( &RemoteAddress, NULL, &RCN );
if( !NT_SUCCESS(Status) ) {
FreeNdisPacket( Packet.NdisPacket );
return Status;
}
IPSendDatagram( &Packet, RCN, RawIPSendComplete, NULL );
} else
FreeNdisPacket( Packet.NdisPacket );
return Status;
}
+31 -27
View File
@@ -42,7 +42,7 @@ int TCPSocketState(void *ClientData,
("Completing Connect Request %x\n", Bucket->Request));
Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
/* Frees the bucket allocated in TCPConnect */
ExFreePool( Bucket );
PoolFreeBuffer( Bucket );
}
} else if( (NewState & SEL_READ) || (NewState & SEL_FIN) ) {
TI_DbgPrint(MID_TRACE,("Readable (or closed): irp list %s\n",
@@ -78,13 +78,21 @@ int TCPSocketState(void *ClientData,
if( NewState & SEL_FIN && !RecvLen ) {
Status = STATUS_END_OF_FILE;
Received = 0;
} else
} else {
TI_DbgPrint(MID_TRACE, ("Connection: %x\n", Connection));
TI_DbgPrint
(MID_TRACE,
("Connection->SocketContext: %x\n",
Connection->SocketContext));
TI_DbgPrint(MID_TRACE, ("RecvBuffer: %x\n", RecvBuffer));
Status = TCPTranslateError
( OskitTCPRecv( Connection->SocketContext,
RecvBuffer,
RecvLen,
&Received,
0 ) );
}
TI_DbgPrint(MID_TRACE,("TCP Bytes: %d\n", Received));
@@ -118,7 +126,9 @@ int TCPSocketState(void *ClientData,
void TCPPacketSendComplete( PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus ) {
TI_DbgPrint(MID_TRACE,("called\n"));
TI_DbgPrint(MID_TRACE,("called %x\n", NdisPacket));
FreeNdisPacket(NdisPacket);
TI_DbgPrint(MID_TRACE,("done\n"));
}
#define STRINGIFY(x) #x
@@ -151,35 +161,29 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
LocalAddress.Address.IPv4Address,
RemoteAddress.Address.IPv4Address);
ASSERT( (LocalAddress.Address.IPv4Address & 0xc0000000) != 0xc0000000 );
Status = RouteGetRouteToDestination( &RemoteAddress,
NULL,
&RCN );
Status = RouteGetRouteToDestination( &RemoteAddress, NULL, &RCN );
if( !NT_SUCCESS(Status) || !RCN ) return OSK_EADDRNOTAVAIL;
NdisStatus =
AllocatePacketWithBuffer( &Packet.NdisPacket, data, len );
NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL,
MaxLLHeaderSize + len );
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MAX_TRACE, ("Error from NDIS: %08x\n", NdisStatus));
return STATUS_NO_MEMORY;
}
AdjustPacket( Packet.NdisPacket, 0, MaxLLHeaderSize );
GetDataPtr( Packet.NdisPacket, 0, (PCHAR *)&Packet.Header, &Packet.ContigSize );
TI_DbgPrint(MAX_TRACE,("PC(Packet.NdisPacket) is %s (%x)\n", STRINGIFY(PC(Packet.NdisPacket)), PC(Packet.NdisPacket)));
PC(Packet.NdisPacket)->Complete = TCPPacketSendComplete;
OskitDumpBuffer((PCHAR)(PC(Packet.NdisPacket)),sizeof(*(PC(Packet.NdisPacket))));
GetDataPtr( Packet.NdisPacket, MaxLLHeaderSize,
(PCHAR *)&Packet.Header, &Packet.ContigSize );
RtlCopyMemory( Packet.Header, data, len );
Packet.HeaderSize = sizeof(IPv4_HEADER);
Packet.TotalSize = len;
Packet.SrcAddr = LocalAddress;
Packet.DstAddr = RemoteAddress;
IPSendFragment( Packet.NdisPacket, RCN->NCE );
IPSendDatagram( &Packet, RCN, TCPPacketSendComplete, NULL );
if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL;
else return 0;
@@ -187,7 +191,7 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
void *TCPMalloc( void *ClientData,
OSK_UINT Bytes, OSK_PCHAR File, OSK_UINT Line ) {
void *v = ExAllocatePool( NonPagedPool, Bytes );
void *v = PoolAllocateBuffer( Bytes );
if( v ) TrackWithTag( FOURCC('f','b','s','d'), v, File, Line );
return v;
}
@@ -195,7 +199,7 @@ void *TCPMalloc( void *ClientData,
void TCPFree( void *ClientData,
void *data, OSK_PCHAR File, OSK_UINT Line ) {
UntrackFL( File, Line, data );
ExFreePool( data );
PoolFreeBuffer( data );
}
int TCPSleep( void *ClientData, void *token, int priority, char *msg,
@@ -206,14 +210,14 @@ int TCPSleep( void *ClientData, void *token, int priority, char *msg,
("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n",
token, priority, msg, tmio));
SleepingThread = ExAllocatePool( NonPagedPool, sizeof( *SleepingThread ) );
SleepingThread = PoolAllocateBuffer( sizeof( *SleepingThread ) );
if( SleepingThread ) {
KeInitializeEvent( &SleepingThread->Event, NotificationEvent, FALSE );
SleepingThread->SleepToken = token;
ExAcquireFastMutex( &SleepingThreadsLock );
TcpipAcquireFastMutex( &SleepingThreadsLock );
InsertTailList( &SleepingThreadsList, &SleepingThread->Entry );
ExReleaseFastMutex( &SleepingThreadsLock );
TcpipReleaseFastMutex( &SleepingThreadsLock );
TI_DbgPrint(MID_TRACE,("Waiting on %x\n", token));
KeWaitForSingleObject( &SleepingThread->Event,
@@ -222,11 +226,11 @@ int TCPSleep( void *ClientData, void *token, int priority, char *msg,
TRUE,
NULL );
ExAcquireFastMutex( &SleepingThreadsLock );
TcpipAcquireFastMutex( &SleepingThreadsLock );
RemoveEntryList( &SleepingThread->Entry );
ExReleaseFastMutex( &SleepingThreadsLock );
TcpipReleaseFastMutex( &SleepingThreadsLock );
ExFreePool( SleepingThread );
PoolFreeBuffer( SleepingThread );
}
TI_DbgPrint(MID_TRACE,("Waiting finished: %x\n", token));
return 0;
@@ -236,7 +240,7 @@ void TCPWakeup( void *ClientData, void *token ) {
PLIST_ENTRY Entry;
PSLEEPING_THREAD SleepingThread;
ExAcquireFastMutex( &SleepingThreadsLock );
TcpipAcquireFastMutex( &SleepingThreadsLock );
Entry = SleepingThreadsList.Flink;
while( Entry != &SleepingThreadsList ) {
SleepingThread = CONTAINING_RECORD(Entry, SLEEPING_THREAD, Entry);
@@ -247,5 +251,5 @@ void TCPWakeup( void *ClientData, void *token ) {
}
Entry = Entry->Flink;
}
ExReleaseFastMutex( &SleepingThreadsLock );
TcpipReleaseFastMutex( &SleepingThreadsLock );
}
+5 -1
View File
@@ -17,7 +17,6 @@
#include "precomp.h"
#if 0
#include <sys/param.h>
#include <sys/kernel.h>
@@ -102,6 +101,11 @@ POSK_IFADDR TCPFindInterface( void *ClientData,
return NULL;
}
TI_DbgPrint(MID_TRACE,("NCE: %x\n", NCE));
TI_DbgPrint(MID_TRACE,("NCE->Interface: %x\n", NCE->Interface));
TI_DbgPrint(MID_TRACE,("NCE->Interface->TCPContext: %x\n",
NCE->Interface->TCPContext));
addr_in = (struct sockaddr_in *)
((POSK_IFADDR)NCE->Interface->TCPContext)->ifa_addr;
TI_DbgPrint(MID_TRACE,("returning addr %x\n", addr_in->sin_addr.s_addr));
+24 -27
View File
@@ -28,14 +28,11 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
/* Initialize spin lock that protects the connection endpoint file object */
KeInitializeSpinLock(&Connection->Lock);
TcpipInitializeSpinLock(&Connection->Lock);
InitializeListHead(&Connection->ConnectRequest);
InitializeListHead(&Connection->ListenRequest);
InitializeListHead(&Connection->ReceiveRequest);
/* Reference the object */
Connection->RefCount = 1;
/* Save client context pointer */
Connection->ClientContext = ClientContext;
@@ -58,13 +55,13 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
"Proto %d\n",
Connection, Family, Type, Proto));
RecursiveMutexEnter( &TCPLock, TRUE );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
Status = TCPTranslateError( OskitTCPSocket( Connection,
&Connection->SocketContext,
Family,
Type,
Proto ) );
RecursiveMutexLeave( &TCPLock );
TcpipRecursiveMutexLeave( &TCPLock );
return Status;
}
@@ -83,13 +80,13 @@ VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
IPPacket->TotalSize,
IPPacket->HeaderSize));
RecursiveMutexEnter( &TCPLock, TRUE );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
OskitTCPReceiveDatagram( IPPacket->Header,
IPPacket->TotalSize,
IPPacket->HeaderSize );
RecursiveMutexLeave( &TCPLock );
TcpipRecursiveMutexLeave( &TCPLock );
}
/* event.c */
@@ -135,7 +132,7 @@ NTSTATUS TCPStartup(VOID)
* Status of operation
*/
{
RecursiveMutexInit( &TCPLock );
TcpipRecursiveMutexInit( &TCPLock );
ExInitializeFastMutex( &SleepingThreadsLock );
InitializeListHead( &SleepingThreadsList );
@@ -250,7 +247,7 @@ NTSTATUS TCPConnect
Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
if( !Bucket ) return STATUS_NO_MEMORY;
RecursiveMutexEnter( &TCPLock, TRUE );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
/* Freed in TCPSocketState */
Bucket->Request.RequestNotifyObject = (PVOID)Complete;
@@ -290,7 +287,7 @@ NTSTATUS TCPConnect
&AddressToConnect,
sizeof(AddressToConnect));
RecursiveMutexLeave( &TCPLock );
TcpipRecursiveMutexLeave( &TCPLock );
if( Status == OSK_EINPROGRESS || Status == STATUS_SUCCESS )
return STATUS_PENDING;
@@ -304,11 +301,11 @@ NTSTATUS TCPClose
TI_DbgPrint(MID_TRACE,("TCPClose started\n"));
RecursiveMutexEnter( &TCPLock, TRUE );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
RecursiveMutexLeave( &TCPLock );
TcpipRecursiveMutexLeave( &TCPLock );
TI_DbgPrint(MID_TRACE,("TCPClose finished %x\n", Status));
@@ -322,14 +319,14 @@ NTSTATUS TCPListen
PVOID Context) {
NTSTATUS Status;
RecursiveMutexEnter( &TCPLock, TRUE );
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext,
Backlog ) );
RecursiveMutexLeave( &TCPLock );
return Status;
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext,
Backlog ) );
TcpipRecursiveMutexLeave( &TCPLock );
return Status;
}
NTSTATUS TCPAccept
@@ -353,7 +350,7 @@ NTSTATUS TCPReceiveData
TI_DbgPrint(MID_TRACE,("Called for %d bytes\n", ReceiveLength));
RecursiveMutexEnter( &TCPLock, TRUE );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
@@ -390,7 +387,7 @@ NTSTATUS TCPReceiveData
*BytesReceived = Received;
}
RecursiveMutexLeave( &TCPLock );
TcpipRecursiveMutexLeave( &TCPLock );
TI_DbgPrint(MID_TRACE,("Status %x\n", Status));
@@ -405,7 +402,7 @@ NTSTATUS TCPSendData
ULONG Flags) {
NTSTATUS Status;
RecursiveMutexEnter( &TCPLock, TRUE );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
TI_DbgPrint(MID_TRACE,("Connection = %x\n", Connection));
TI_DbgPrint(MID_TRACE,("Connection->SocketContext = %x\n",
@@ -416,7 +413,7 @@ NTSTATUS TCPSendData
Status = OskitTCPSend( Connection->SocketContext,
BufferData, PacketSize, (PUINT)DataUsed, 0 );
RecursiveMutexLeave( &TCPLock );
TcpipRecursiveMutexLeave( &TCPLock );
return Status;
}
@@ -424,9 +421,9 @@ NTSTATUS TCPSendData
VOID TCPTimeout(VOID) {
static int Times = 0;
if( (Times++ % 5) == 0 ) {
RecursiveMutexEnter( &TCPLock, TRUE );
TcpipRecursiveMutexEnter( &TCPLock, TRUE );
TimerOskitTCP();
RecursiveMutexLeave( &TCPLock );
TcpipRecursiveMutexLeave( &TCPLock );
}
}
+92 -25
View File
@@ -169,6 +169,10 @@ NTSTATUS BuildUDPPacket(
return STATUS_SUCCESS;
}
VOID UDPSendPacketComplete
( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status ) {
FreeNdisPacket( Packet );
}
NTSTATUS UDPSendDatagram(
PADDRESS_FILE AddrFile,
@@ -191,6 +195,8 @@ NTSTATUS UDPSendDatagram(
PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
IP_ADDRESS RemoteAddress;
USHORT RemotePort;
NTSTATUS Status;
PROUTE_CACHE_NODE RCN;
TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
AddrFile, ConnInfo, BufferData, DataSize));
@@ -208,19 +214,25 @@ NTSTATUS UDPSendDatagram(
return STATUS_UNSUCCESSFUL;
}
BuildUDPPacket( &Packet,
&RemoteAddress,
RemotePort,
AddrFile->ADE->Address,
AddrFile->Port,
BufferData,
DataSize );
Status = BuildUDPPacket( &Packet,
&RemoteAddress,
RemotePort,
AddrFile->ADE->Address,
AddrFile->Port,
BufferData,
DataSize );
return DGSendDatagram(AddrFile,
ConnInfo,
Packet.Header,
Packet.TotalSize,
DataUsed);
if( !NT_SUCCESS(Status) )
return Status;
Status = RouteGetRouteToDestination( &RemoteAddress, NULL, &RCN );
if( !NT_SUCCESS(Status) )
return Status;
IPSendDatagram( &Packet, RCN, UDPSendPacketComplete, NULL );
return STATUS_SUCCESS;
}
@@ -248,23 +260,78 @@ NTSTATUS UDPReceiveDatagram(
* This is the high level interface for receiving UDP datagrams
*/
{
return DGReceiveDatagram(AddrFile,
ConnInfo,
BufferData,
ReceiveLength,
ReceiveFlags,
ReturnInfo,
BytesReceived);
KIRQL OldIrql;
NTSTATUS Status;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AF_IS_VALID(AddrFile))
{
ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
if (ReceiveRequest)
{
/* Initialize a receive request */
/* Extract the remote address filter from the request (if any) */
if (((ConnInfo->RemoteAddressLength != 0)) && (ConnInfo->RemoteAddress))
{
Status = AddrGetAddress(ConnInfo->RemoteAddress,
&ReceiveRequest->RemoteAddress,
&ReceiveRequest->RemotePort);
if (!NT_SUCCESS(Status))
{
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
exFreePool(ReceiveRequest);
return Status;
}
}
else
{
ReceiveRequest->RemotePort = 0;
}
ReceiveRequest->ReturnInfo = ReturnInfo;
ReceiveRequest->Buffer = BufferData;
/* If ReceiveLength is 0, the whole buffer is available to us */
ReceiveRequest->BufferSize = ReceiveLength;
ReceiveRequest->Complete = NULL;
ReceiveRequest->Context = NULL;
/* Queue receive request */
InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
AF_SET_PENDING(AddrFile, AFF_RECEIVE);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
return STATUS_PENDING;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
else
{
Status = STATUS_INVALID_ADDRESS;
}
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
return Status;
}
VOID UDPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
VOID UDPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
/*
* FUNCTION: Receives and queues a UDP datagram
* ARGUMENTS:
* NTE = Pointer to net table entry which the packet was received on
* FUNCTION: Receives and queues a UDP datagram
* 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 UDP datagrams. It strips
@@ -45,6 +45,11 @@
#ifndef KERNEL
extern int errno; /* global error number */
#endif
#undef _POSIX_SOURCE
#endif
#ifdef _POSIX_SOURCE
#error yuck
#endif
#define OSK_EPERM 1 /* Operation not permitted */
@@ -62,7 +67,7 @@ extern int errno; /* global error number */
#define OSK_ENOMEM 12 /* Cannot allocate memory */
#define OSK_EACCES 13 /* Permission denied */
#define OSK_EFAULT 14 /* Bad address */
#ifndef _POSIX_SOURCOSK_E
#ifndef _POSIX_SOURCE
#define OSK_ENOTBLK 15 /* Block device required */
#endif
#define OSK_EBUSY 16 /* Device busy */
@@ -1,6 +1,10 @@
#ifndef _OSKITFREEBSD_H
#define _OSKITFREEBSD_H
#ifdef linux
#include <netinet/in.h>
#endif
extern void oskittcp_die(const char *file, int line);
#ifdef _MSC_VER
@@ -1,6 +1,10 @@
#ifndef OSKITTCP_H
#define OSKITTCP_H
#ifdef linux
#include <netinet/in.h>
#endif
#ifndef _MSC_VER
#include <roscfg.h>
#endif/*_MSC_VER*/
@@ -67,9 +67,6 @@ in_cksum(m, len)
} l_util;
for (;m && len; m = m->m_next) {
OS_DbgPrint(OSK_MID_TRACE,("Processing m %x (%d)\n", m, len));
OskitDumpBuffer( m->m_data, m->m_len );
if (m->m_len == 0)
continue;
w = mtod(m, u_short *);
@@ -79,9 +79,11 @@ mbinit()
#else
#define NCL_INIT 1
#endif
printf("Here1\n");
s = splimp();
if (m_clalloc(NCL_INIT, M_DONTWAIT) == 0)
goto bad;
printf("Here2\n");
splx(s);
return;
bad:
@@ -113,8 +115,14 @@ m_clalloc(ncl, nowait)
return (0);
npg = ncl * CLSIZE;
printf("kmem_malloc(%d)\n", npg);
p = (caddr_t)kmem_malloc(mb_map, ctob(npg),
nowait ? M_NOWAIT : M_WAITOK);
printf("kmem_malloc done\n");
/*
* Either the map is now full, or this is nowait and there
* are no pages left.
@@ -125,11 +133,13 @@ m_clalloc(ncl, nowait)
ncl = ncl * CLBYTES / MCLBYTES;
for (i = 0; i < ncl; i++) {
((union mcluster *)p)->mcl_next = mclfree;
printf( "Freeing %x onto the free list\n", p);
mclfree = (union mcluster *)p;
p += MCLBYTES;
mbstat.m_clfree++;
}
mbstat.m_clusters += ncl;
printf( "done with m_clalloc\n");
return (1);
}
#endif /* !OSKIT */
+67 -41
View File
@@ -180,13 +180,8 @@ VOID STDCALL ProtocolSendComplete(
* Status = Status of the operation
*/
{
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
AdjustPacket(Packet, Adapter->HeaderSize, PC(Packet)->DLOffset);
TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n"));
(*PC(Packet)->DLComplete)(Adapter->Context, Packet, Status);
(*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
}
@@ -225,7 +220,10 @@ VOID STDCALL LanReceiveWorker( PVOID Context ) {
/* Determine which upper layer protocol that should receive
this packet and pass it to the correct receive handler */
OskitDumpBuffer( IPPacket.Header, BytesTransferred );
TI_DbgPrint(MID_TRACE,
("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
IPPacket.ContigSize, IPPacket.TotalSize,
BytesTransferred));
PacketType = ((PETH_HEADER)IPPacket.Header)->EType;
IPPacket.Header = ((PCHAR)IPPacket.Header) + sizeof(ETH_HEADER);
@@ -279,7 +277,7 @@ VOID STDCALL ProtocolTransferDataComplete(
WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
if( !WQItem ) return;
KeAcquireSpinLockAtDpcLevel( &LanWorkLock );
TcpipAcquireSpinLockAtDpcLevel( &LanWorkLock );
WorkStart = IsListEmpty( &LanWorkList );
WQItem->Packet = Packet;
WQItem->Adapter = Adapter;
@@ -287,7 +285,7 @@ VOID STDCALL ProtocolTransferDataComplete(
InsertTailList( &LanWorkList, &WQItem->ListEntry );
if( WorkStart )
ExQueueWorkItem( &LanWorkItem, CriticalWorkQueue );
KeReleaseSpinLockFromDpcLevel( &LanWorkLock );
TcpipReleaseSpinLockFromDpcLevel( &LanWorkLock );
}
NDIS_STATUS STDCALL ProtocolReceive(
@@ -314,6 +312,7 @@ NDIS_STATUS STDCALL ProtocolReceive(
{
USHORT EType;
UINT PacketType, BytesTransferred;
UINT temp;
IP_PACKET IPPacket;
PCHAR BufferData;
NDIS_STATUS NdisStatus;
@@ -354,32 +353,37 @@ NDIS_STATUS STDCALL ProtocolReceive(
/* Get a transfer data packet */
KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
TI_DbgPrint(DEBUG_DATALINK, ("Adapter: %x (MTU %d)\n",
Adapter, Adapter->MTU));
//TcpipAcquireSpinLockAtDpcLevel(&Adapter->Lock);
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Adapter->MTU );
if( NdisStatus != NDIS_STATUS_SUCCESS ) {
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
//TcpipReleaseSpinLockFromDpcLevel(&Adapter->Lock);
return NDIS_STATUS_NOT_ACCEPTED;
}
TI_DbgPrint(DEBUG_DATALINK, ("pretransfer LookaheadBufferSize %d packsize %d\n",LookaheadBufferSize,PacketSize));
{
UINT temp;
temp = PacketSize;
GetDataPtr( NdisPacket, 0, &BufferData, &temp );
}
IPPacket.NdisPacket = NdisPacket;
IPPacket.Position = 0;
if ((LookaheadBufferSize + HeaderBufferSize) < PacketSize)
{
TI_DbgPrint(DEBUG_DATALINK, ("pretransfer LookaheadBufferSize %d packsize %d\n",LookaheadBufferSize,PacketSize));
TI_DbgPrint(DEBUG_DATALINK, ("pretransfer LookaheadBufferSize %d packsize %d bufferdata %x\n",LookaheadBufferSize,PacketSize, BufferData));
/* Get the data */
*BufferData = 0;
TI_DbgPrint(DEBUG_DATALINK, ("Poked the buffer\n"));
NdisTransferData(&NdisStatus,
Adapter->NdisHandle,
MacReceiveContext,
0,
PacketSize + HeaderBufferSize,
PacketSize,
NdisPacket,
&BytesTransferred);
} else {
@@ -395,7 +399,7 @@ NDIS_STATUS STDCALL ProtocolReceive(
TI_DbgPrint(DEBUG_DATALINK, ("Calling complete\n"));
/* Release the packet descriptor */
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
//TcpipReleaseSpinLockFromDpcLevel(&Adapter->Lock);
if (NdisStatus != NDIS_STATUS_PENDING)
ProtocolTransferDataComplete(BindingContext,
@@ -492,19 +496,28 @@ VOID LANTransmit(
{
NDIS_STATUS NdisStatus;
PETH_HEADER EHeader;
PVOID Data;
PCHAR Data;
UINT Size;
KIRQL OldIrql;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
TI_DbgPrint(DEBUG_DATALINK,
("Called( NdisPacket %x, Offset %d, Adapter %x )\n",
NdisPacket, Offset, Adapter));
TI_DbgPrint(DEBUG_DATALINK,
("Adapter Address [%02x %02x %02x %02x %02x %02x]\n",
Adapter->HWAddress[0] & 0xff,
Adapter->HWAddress[1] & 0xff,
Adapter->HWAddress[2] & 0xff,
Adapter->HWAddress[3] & 0xff,
Adapter->HWAddress[4] & 0xff,
Adapter->HWAddress[5] & 0xff));
/* XXX arty -- Handled adjustment in a saner way than before ...
* not needed immediately */
GetDataPtr( NdisPacket, 0, &Data, &Size );
/* NDIS send routines don't have an offset argument so we
must offset the data in upper layers and adjust the
packet here. We save the offset in the packet context
area so it can be undone before we release the packet */
Data = AdjustPacket(NdisPacket, Offset, Adapter->HeaderSize);
PC(NdisPacket)->DLOffset = Offset;
if (Adapter->State == LAN_STATE_STARTED) {
switch (Adapter->Media) {
case NdisMedium802_3:
@@ -548,9 +561,26 @@ VOID LANTransmit(
break;
}
KeAcquireSpinLock( &Adapter->Lock, &OldIrql );
TI_DbgPrint( MID_TRACE, ("LinkAddress: %x\n", LinkAddress));
if( LinkAddress ) {
TI_DbgPrint
( MID_TRACE,
("Link Address [%02x %02x %02x %02x %02x %02x]\n",
((PCHAR)LinkAddress)[0] & 0xff,
((PCHAR)LinkAddress)[1] & 0xff,
((PCHAR)LinkAddress)[2] & 0xff,
((PCHAR)LinkAddress)[3] & 0xff,
((PCHAR)LinkAddress)[4] & 0xff,
((PCHAR)LinkAddress)[5] & 0xff));
}
OskitDumpBuffer( Data, Size );
TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
TI_DbgPrint(MID_TRACE, ("NdisSend\n"));
NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket);
KeReleaseSpinLock( &Adapter->Lock, OldIrql );
TI_DbgPrint(MID_TRACE, ("NdisSend Done\n"));
TcpipReleaseSpinLock( &Adapter->Lock, OldIrql );
if (NdisStatus != NDIS_STATUS_PENDING)
ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NdisStatus);
@@ -728,10 +758,6 @@ VOID BindAdapter(
Netmask->Free(Netmask);
/* Reference the interface for the NTE. The reference
for the address is just passed on to the NTE */
ReferenceObject(IF);
/* Register interface with IP layer */
IPRegisterInterface(IF);
@@ -957,15 +983,15 @@ NDIS_STATUS LANUnregisterAdapter(
/* Unbind adapter from IP layer */
UnbindAdapter(Adapter);
KeAcquireSpinLock(&Adapter->Lock, &OldIrql);
TcpipAcquireSpinLock(&Adapter->Lock, &OldIrql);
NdisHandle = Adapter->NdisHandle;
if (NdisHandle) {
Adapter->NdisHandle = NULL;
KeReleaseSpinLock(&Adapter->Lock, OldIrql);
TcpipReleaseSpinLock(&Adapter->Lock, OldIrql);
NdisCloseAdapter(&NdisStatus, NdisHandle);
if (NdisStatus == NDIS_STATUS_PENDING) {
KeWaitForSingleObject(&Adapter->Event,
TcpipWaitForSingleObject(&Adapter->Event,
UserRequest,
KernelMode,
FALSE,
@@ -973,7 +999,7 @@ NDIS_STATUS LANUnregisterAdapter(
NdisStatus = Adapter->NdisStatus;
}
} else
KeReleaseSpinLock(&Adapter->Lock, OldIrql);
TcpipReleaseSpinLock(&Adapter->Lock, OldIrql);
FreeAdapter(Adapter);
@@ -1051,7 +1077,7 @@ VOID LANUnregisterProtocol(
PLAN_ADAPTER Current;
KIRQL OldIrql;
KeAcquireSpinLock(&AdapterListLock, &OldIrql);
TcpipAcquireSpinLock(&AdapterListLock, &OldIrql);
/* Search the list and remove every adapter we find */
CurrentEntry = AdapterListHead.Flink;
@@ -1063,7 +1089,7 @@ VOID LANUnregisterProtocol(
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&AdapterListLock, OldIrql);
TcpipReleaseSpinLock(&AdapterListLock, OldIrql);
NdisDeregisterProtocol(&NdisStatus, NdisProtocolHandle);
ProtocolRegistered = FALSE;
@@ -1080,14 +1106,14 @@ VOID LANShutdown() {
PLAN_WQ_ITEM WorkItem;
PLIST_ENTRY ListEntry;
KeAcquireSpinLock( &LanWorkLock, &OldIrql );
TcpipAcquireSpinLock( &LanWorkLock, &OldIrql );
while( !IsListEmpty( &LanWorkList ) ) {
ListEntry = RemoveHeadList( &LanWorkList );
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
FreeNdisPacket( WorkItem->Packet );
ExFreePool( WorkItem );
}
KeReleaseSpinLock( &LanWorkLock, OldIrql );
TcpipReleaseSpinLock( &LanWorkLock, OldIrql );
}
/* EOF */
+8 -104
View File
@@ -10,67 +10,6 @@
#include "precomp.h"
WORK_QUEUE_ITEM LoopWorkItem;
PIP_INTERFACE Loopback = NULL;
/* Indicates wether the loopback interface is currently transmitting */
BOOLEAN LoopBusy = FALSE;
/* Loopback transmit queue */
PNDIS_PACKET LoopQueueHead = (PNDIS_PACKET)NULL;
PNDIS_PACKET LoopQueueTail = (PNDIS_PACKET)NULL;
/* Spin lock for protecting loopback transmit queue */
KSPIN_LOCK LoopQueueLock;
VOID STDCALL RealTransmit(
PVOID Context)
/*
* FUNCTION: Transmits one or more packet(s) in loopback queue to ourselves
* ARGUMENTS:
* Context = Pointer to context information (loopback interface)
*/
{
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
IP_PACKET IPPacket;
KIRQL OldIrql;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&LoopQueueLock);
while (TRUE)
{
/* Get the next packet from the queue (if any) */
NdisPacket = LoopQueueHead;
if (!NdisPacket)
break;
TI_DbgPrint(MAX_TRACE, ("NdisPacket (0x%X)\n", NdisPacket));
LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
KeReleaseSpinLockFromDpcLevel(&LoopQueueLock);
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
&NdisBuffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
IPReceive(Context, &IPPacket);
AdjustPacket(NdisPacket, 0, PC(NdisPacket)->DLOffset);
PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
/* Lower IRQL for a moment to prevent starvation */
KeLowerIrql(OldIrql);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&LoopQueueLock);
}
LoopBusy = FALSE;
KeReleaseSpinLockFromDpcLevel(&LoopQueueLock);
KeLowerIrql(OldIrql);
}
VOID LoopTransmit(
PVOID Context,
PNDIS_PACKET NdisPacket,
@@ -87,46 +26,16 @@ VOID LoopTransmit(
* Type = LAN protocol type (unused)
*/
{
PNDIS_PACKET *pNdisPacket;
KIRQL OldIrql;
IP_PACKET IPPacket;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
/* NDIS send routines don't have an offset argument so we
must offset the data in upper layers and adjust the
packet here. We save the offset in the packet context
area so it can be undone before we release the packet */
AdjustPacket(NdisPacket, Offset, 0);
PC(NdisPacket)->DLOffset = Offset;
pNdisPacket = (PNDIS_PACKET*)NdisPacket->u.s3.MacReserved;
*pNdisPacket = NULL;
KeAcquireSpinLock(&LoopQueueLock, &OldIrql);
/* Add packet to transmit queue */
if (LoopQueueHead != NULL)
{
/* Transmit queue is not empty */
pNdisPacket = (PNDIS_PACKET*)LoopQueueTail->u.s3.MacReserved;
*pNdisPacket = NdisPacket;
}
else
{
/* Transmit queue is empty */
LoopQueueHead = NdisPacket;
}
LoopQueueTail = NdisPacket;
/* If RealTransmit is not running (or scheduled to run) then schedule it to run now */
if (!LoopBusy)
{
LoopBusy = TRUE; /* The loopback interface is now busy */
ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
}
KeReleaseSpinLock(&LoopQueueLock, OldIrql);
IPPacket.NdisPacket = NdisPacket;
IPReceive(Context, &IPPacket);
TI_DbgPrint(MAX_TRACE, ("Finished receive\n"));
PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
TI_DbgPrint(MAX_TRACE, ("Done\n"));
}
NDIS_STATUS LoopRegisterAdapter(
@@ -171,11 +80,6 @@ NDIS_STATUS LoopRegisterAdapter(
ReferenceObject(Loopback);
IPRegisterInterface(Loopback);
ExInitializeWorkItem(&LoopWorkItem, RealTransmit, Loopback);
KeInitializeSpinLock(&LoopQueueLock);
LoopBusy = FALSE;
}
else
{
@@ -16,7 +16,6 @@
#define AddrInitIPv4(IPAddress, RawAddress) \
{ \
INIT_TAG((IPAddress), TAG('I','P','V','4')); \
(IPAddress)->RefCount = 1; \
(IPAddress)->Type = IP_ADDRESS_V4; \
(IPAddress)->Address.IPv4Address = (RawAddress); \
(IPAddress)->Free = IPAddressFree; \
+6
View File
@@ -0,0 +1,6 @@
#ifndef _TCPIP_BUG_H
#define _TCPIP_BUG_H
VOID TcpipBugCheck( ULONG BugCode );
#endif/*_TCPIP_BUG_H*/
+3 -1
View File
@@ -55,7 +55,9 @@ VOID ICMPReceive(
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
PIP_PACKET IPPacket,
PIP_TRANSMIT_COMPLETE Complete,
PVOID Context);
VOID ICMPReply(
PNET_TABLE_ENTRY NTE,
-5
View File
@@ -22,7 +22,6 @@ typedef IPv6_RAW_ADDRESS *PIPv6_RAW_ADDRESS;
/* IP style address */
typedef struct IP_ADDRESS {
DEFINE_TAG
ULONG RefCount; /* Number of references to this address */
UCHAR Type; /* Type of IP address */
union {
IPv4_RAW_ADDRESS IPv4Address; /* IPv4 address (in network byte order) */
@@ -64,7 +63,6 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)(
/* Structure for an IP packet */
typedef struct _IP_PACKET {
DEFINE_TAG
ULONG RefCount; /* Reference count for this object */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */
UCHAR Flags; /* Flags for packet (see IP_PACKET_FLAG_xx below)*/
@@ -98,7 +96,6 @@ typedef struct _PACKET_CONTEXT {
typedef struct _ADDRESS_ENTRY {
DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
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 */
@@ -119,7 +116,6 @@ typedef struct _NET_TABLE_ENTRY {
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 */
ULONG RefCount; /* Reference count */
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;
@@ -151,7 +147,6 @@ typedef struct _IP_INTERFACE {
LIST_ENTRY NTEListHead; /* List of NTEs on this interface */
LIST_ENTRY ADEListHead; /* List of ADEs on this interface */
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources used by the object */
KSPIN_LOCK Lock; /* Spin lock for this object */
PVOID Context; /* Pointer to link layer context information */
+20
View File
@@ -0,0 +1,20 @@
#ifndef _LOCK_H
#define _LOCK_H
extern KIRQL TcpipGetCurrentIrql();
extern VOID TcpipInitializeSpinLock( PKSPIN_LOCK SpinLock );
extern VOID TcpipAcquireSpinLock( PKSPIN_LOCK SpinLock, PKIRQL Irql );
extern VOID TcpipReleaseSpinLock( PKSPIN_LOCK SpinLock, KIRQL Irql );
extern VOID TcpipAcquireSpinLockAtDpcLevel( PKSPIN_LOCK SpinLock );
extern VOID TcpipReleaseSpinLockFromDpcLevel( PKSPIN_LOCK SpinLock );
extern VOID TcpipInterlockedInsertTailList( PLIST_ENTRY ListHead,
PLIST_ENTRY Item,
PKSPIN_LOCK Lock );
extern VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex );
extern VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex );
extern VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex );
extern UINT TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex,
BOOL ToWrite );
extern VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex );
#endif/*_LOCK_H*/
+6 -4
View File
@@ -1,6 +1,8 @@
#ifndef MEMTRACK_H
#define MEMTRACK_H
#include <pool.h>
#ifndef FOURCC
#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
#endif
@@ -39,13 +41,13 @@ VOID TrackDumpFL( PCHAR File, DWORD Line );
VOID TrackTag( DWORD Tag );
static inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) {
PVOID Out = ExAllocatePool( type, size );
PVOID Out = PoolAllocateBuffer( size );
if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line );
return Out;
}
static inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) {
UntrackFL(File, Line, Data);
ExFreePool(Data);
PoolFreeBuffer(Data);
}
#define MEMTRACK_MAX_TAGS_TO_TRACK 64
@@ -57,8 +59,8 @@ static inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) {
#define Untrack(x)
#define TrackTag(x)
#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z)
#define exAllocatePool(x,y) ExAllocatePool(x,y)
#define exFreePool(x) ExFreePool(x)
#define exAllocatePool(x,y) PoolAllocateBuffer(y)
#define exFreePool(x) PoolFreeBuffer(x)
#define TrackWithTag(w,x,y,z)
#define UntrackFL(x,y,z)
#endif
+14 -5
View File
@@ -10,6 +10,16 @@
#define NB_HASHMASK 0xF /* Hash mask for neighbor cache */
typedef VOID (*PNEIGHBOR_PACKET_COMPLETE)
( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status );
typedef struct _NEIGHBOR_PACKET {
LIST_ENTRY Next;
PNDIS_PACKET Packet;
PNEIGHBOR_PACKET_COMPLETE Complete;
PVOID Context;
} NEIGHBOR_PACKET, *PNEIGHBOR_PACKET;
typedef struct NEIGHBOR_CACHE_TABLE {
struct NEIGHBOR_CACHE_ENTRY *Cache; /* Pointer to cache */
KSPIN_LOCK Lock; /* Protecting lock */
@@ -20,17 +30,14 @@ typedef struct NEIGHBOR_CACHE_ENTRY {
DEFINE_TAG
struct NEIGHBOR_CACHE_ENTRY *Next; /* Pointer to next entry */
struct NEIGHBOR_CACHE_TABLE *Table; /* Pointer to table */
ULONG RefCount; /* Number of references */
OBJECT_FREE_ROUTINE Free; /* Routine to free resources for the object */
UCHAR State; /* State of NCE */
UINT EventTimer; /* Ticks since last event */
UINT EventCount; /* Number of events */
PIP_INTERFACE Interface; /* Pointer to interface */
UINT LinkAddressLength; /* Length of link address */
PVOID LinkAddress; /* Pointer to link address */
PNDIS_PACKET WaitQueue; /* Pointer to NDIS packets
waiting to be sent */
IP_ADDRESS Address; /* IP address of neighbor */
LIST_ENTRY PacketQueue; /* Packet queue */
} NEIGHBOR_CACHE_ENTRY, *PNEIGHBOR_CACHE_ENTRY;
/* NCE states */
@@ -93,7 +100,9 @@ PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
BOOLEAN NBQueuePacket(
PNEIGHBOR_CACHE_ENTRY NCE,
PNDIS_PACKET NdisPacket);
PNDIS_PACKET NdisPacket,
PNEIGHBOR_PACKET_COMPLETE PacketComplete,
PVOID PacketContext);
VOID NBRemoveNeighbor(
PNEIGHBOR_CACHE_ENTRY NCE);
+3
View File
@@ -14,6 +14,9 @@ PVOID PoolAllocateBuffer(
VOID PoolFreeBuffer(
PVOID Buffer);
PVOID TcpipAllocateFromNPagedLookasideList( PNPAGED_LOOKASIDE_LIST List );
VOID TcpipFreeToNPagedLookasideList( PNPAGED_LOOKASIDE_LIST List,
PVOID Thing );
NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Len,
BOOLEAN Copy );
+11 -8
View File
@@ -6,28 +6,31 @@
#include <tcpip.h>
#include <loopback.h>
#include <ip.h>
#include <icmp.h>
#include <udp.h>
#include <tcp.h>
#include <rawip.h>
#include <lan.h>
#include <checksum.h>
#include <address.h>
#include <receive.h>
#include <transmit.h>
#include <routines.h>
#include <neighbor.h>
#include <checksum.h>
#include <route.h>
#include <receive.h>
#include <transmit.h>
#include <router.h>
#include <prefix.h>
#include <pool.h>
#include <rawip.h>
#include <icmp.h>
#include <udp.h>
#include <tcp.h>
#include <arp.h>
#include <lan.h>
#include <irp.h>
#include <tilists.h>
#include <dispatch.h>
#include <fileobjs.h>
#include <datagram.h>
#include <info.h>
#include <lock.h>
#include <wait.h>
#include <bug.h>
#include <memtrack.h>
#include <oskittcp.h>
#include <interface.h>
@@ -11,7 +11,6 @@
typedef struct _PREFIX_LIST_ENTRY {
DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
PIP_INTERFACE Interface; /* Pointer to interface */
PIP_ADDRESS Prefix; /* Pointer to prefix */
UINT PrefixLength; /* Length of prefix */
@@ -29,7 +29,6 @@ typedef struct IPDATAGRAM_HOLE {
typedef struct IPDATAGRAM_REASSEMBLY {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Protecting spin lock */
ULONG RefCount; /* Reference count for this object */
UINT DataSize; /* Size of datagram data area */
IP_ADDRESS SrcAddr; /* Source address */
IP_ADDRESS DstAddr; /* Destination address */
@@ -25,7 +25,6 @@ typedef struct ROUTE_CACHE_NODE {
struct ROUTE_CACHE_NODE *Right; /* Pointer to right child */
/* Memebers above this line must not be moved */
DEFINE_TAG
ULONG RefCount; /* Reference count */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
UCHAR State; /* RCN state (RCN_STATE_*) */
IP_ADDRESS Destination; /* Destination address */
@@ -13,7 +13,6 @@
/* Forward Information Base Entry */
typedef struct _FIB_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */
PIP_ADDRESS NetworkAddress; /* Address of network */
PIP_ADDRESS Netmask; /* Netmask of network */
@@ -158,6 +158,9 @@ extern ULONG EntityCount;
extern ULONG EntityMax;
extern UDP_STATISTICS UDPStats;
extern NTSTATUS TiGetProtocolNumber( PUNICODE_STRING FileName,
PULONG Protocol );
#endif /* __TCPIP_H */
/* EOF */
@@ -168,7 +168,6 @@ typedef struct _ADDRESS_FILE {
DEFINE_TAG
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
ULONG RefCount; /* Number of references to this object */
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 */
@@ -308,7 +307,6 @@ typedef struct _TDI_BUCKET {
typedef struct _CONNECTION_ENDPOINT {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
PVOID ClientContext; /* Pointer to client context information */
PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */
PVOID SocketContext; /* Context for lower layer */
@@ -335,7 +333,6 @@ typedef struct _CONNECTION_ENDPOINT {
typedef struct _CONTROL_CHANNEL {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
} CONTROL_CHANNEL, *PCONTROL_CHANNEL;
/* Transport (TCP/UDP) endpoint context structure. The FileObject->FsContext
@@ -346,7 +343,6 @@ typedef struct _TRANSPORT_CONTEXT {
CONNECTION_CONTEXT ConnectionContext;
HANDLE ControlChannel;
} Handle;
ULONG RefCount;
BOOL CancelIrps;
KEVENT CleanupEvent;
} TRANSPORT_CONTEXT, *PTRANSPORT_CONTEXT;
+7 -16
View File
@@ -7,10 +7,9 @@
#ifndef __TRANSMIT_H
#define __TRANSMIT_H
#include <neighbor.h>
#include <route.h>
#include <ip.h>
typedef VOID (*PIP_TRANSMIT_COMPLETE)( PVOID Context,
PNDIS_PACKET Packet,
NDIS_STATUS Status );
/* IP fragment context information */
typedef struct IPFRAGMENT_CONTEXT {
@@ -26,21 +25,13 @@ typedef struct IPFRAGMENT_CONTEXT {
UINT BytesLeft; /* Number of bytes left to send */
UINT PathMTU; /* Path Maximum Transmission Unit */
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE to use */
PIP_TRANSMIT_COMPLETE Complete; /* Completion Routine */
PVOID Context; /* Completion Context */
} IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT;
VOID IPSendComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus);
NTSTATUS IPSendFragment(
PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE);
NTSTATUS IPSendDatagram(
PIP_PACKET IPPacket,
PROUTE_CACHE_NODE RCN);
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PROUTE_CACHE_NODE RCN,
PIP_TRANSMIT_COMPLETE Complete, PVOID Context);
#endif /* __TRANSMIT_H */
+10
View File
@@ -0,0 +1,10 @@
#ifndef _TCPIP_WAIT_H
#define _TCPIP_WAIT_H
NTSTATUS TcpipWaitForSingleObject( PVOID Object,
KWAIT_REASON Reason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout );
#endif/*_TCPIP_WAIT_H*/
+14 -4
View File
@@ -1,4 +1,4 @@
# $Id: makefile,v 1.29 2004/10/23 21:05:11 chorns Exp $
# $Id: makefile,v 1.30 2004/11/07 20:37:18 arty Exp $
PATH_TO_TOP = ../../..
@@ -13,8 +13,8 @@ TARGET_PCH = include/precomp.h
# -DMEMTRACK
TARGET_CFLAGS = \
-D__USE_W32API \
-DNDIS40 \
-DMEMTRACK \
-DNDIS40 \
-Wall -Werror \
-I./include \
-I$(PATH_TO_TOP)/drivers/lib/oskittcp/include \
@@ -36,9 +36,18 @@ TCPIP_OBJECTS = tcpip/buffer.o \
tcpip/fileobjs.o \
tcpip/irp.o \
tcpip/main.o \
tcpip/pool.o
tcpip/pool.o \
tcpip/proto.o \
tcpip/lock.o \
tcpip/wait.o \
tcpip/bug.o
INFO_OBJECTS = tcpip/info.o tcpip/ninfo.o tcpip/tinfo.o tcpip/iinfo.o
DATALINK_OBJECTS = datalink/lan.o datalink/loopback.o
DATALINK_OBJECTS = datalink/lan.o
MOCKOBJS = tcpip/mockbuffer.o \
tcpip/mockwait.o \
tcpip/mocklock.o \
tcpip/mockpool.o \
tcpip/mockbug.o
TARGET_OBJECTS = \
$(TCPIP_OBJECTS) \
@@ -49,6 +58,7 @@ preall: preclean
$(MAKE) -C ../../lib/ip
$(MAKE) -C ../../lib/oskittcp
$(MAKE) all
$(MAKE) $(MOCKOBJS)
preclean:
$(RM) $(PATH_TO_TOP)/dk/w32/lib/ip.a \
+6 -37
View File
@@ -286,41 +286,6 @@ UINT CopyPacketToBufferChain(
}
PVOID AdjustPacket(
PNDIS_PACKET Packet,
UINT Available,
UINT Needed)
/*
* FUNCTION: Adjusts the amount of unused space at the beginning of the packet
* ARGUMENTS:
* Packet = Pointer to packet
* Available = Number of bytes available at start of first buffer
* Needed = Number of bytes needed for the header
* RETURNS:
* Pointer to start of packet
*/
{
PNDIS_BUFFER NdisBuffer;
INT Adjust;
TI_DbgPrint(DEBUG_PBUFFER, ("Available = %d, Needed = %d.\n", Available, Needed));
Adjust = Available - Needed;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
/* If Adjust is zero there is no need to adjust this packet as
there is no additional space at start the of first buffer */
if (Adjust != 0) {
NdisBuffer->MappedSystemVa = (PVOID) ((ULONG_PTR)(NdisBuffer->MappedSystemVa) + Adjust);
NdisBuffer->ByteOffset += Adjust;
NdisBuffer->ByteCount -= Adjust;
}
return NdisBuffer->MappedSystemVa;
}
UINT ResizePacket(
PNDIS_PACKET Packet,
UINT Size)
@@ -389,11 +354,11 @@ NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
if( !NewData ) return NDIS_STATUS_NOT_ACCEPTED; // XXX
TrackWithTag(EXALLOC_TAG, NewData, File, Line);
if( Data )
RtlCopyMemory(NewData, Data, Len);
if( Data ) RtlCopyMemory(NewData, Data, Len);
NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
if( Status != NDIS_STATUS_SUCCESS ) {
UntrackFL( File, Line, NewData );
ExFreePool( NewData );
return Status;
}
@@ -401,7 +366,9 @@ NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
if( Status != NDIS_STATUS_SUCCESS ) {
UntrackFL( File, Line, NewData );
ExFreePool( NewData );
UntrackFL( File, Line, Packet );
FreeNdisPacket( Packet );
}
TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line);
@@ -435,8 +402,10 @@ VOID FreeNdisPacketX
NdisGetNextBuffer(Buffer, &NextBuffer);
NdisQueryBuffer(Buffer, &Data, &Length);
TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer));
UntrackFL(File,Line,Buffer);
NdisFreeBuffer(Buffer);
TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data));
UntrackFL(File,Line,Data);
ExFreePool(Data);
}
+11
View File
@@ -0,0 +1,11 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/bug.c
* PURPOSE: Bugcheck
* PROGRAMMERS: Art Yerkes
* REVISIONS:
*/
#include "precomp.h"
VOID TcpipBugCheck( ULONG BugCode ) { KeBugCheck( BugCode ); }
+17 -57
View File
@@ -34,7 +34,6 @@ NTSTATUS DispPrepareIrpForCancel(
if (!Irp->Cancel) {
IoMarkIrpPending(Irp);
IoSetCancelRoutine(Irp, CancelRoutine);
Context->RefCount++;
IoReleaseCancelSpinLock(OldIrql);
TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP at 0x%X can now be cancelled).\n", Irp));
@@ -74,16 +73,9 @@ VOID DispCancelComplete(
IoAcquireCancelSpinLock(&OldIrql);
/* Remove the reference taken by the cancel routine */
TranContext->RefCount--;
if (TranContext->RefCount == 0) {
TI_DbgPrint(DEBUG_IRP, ("Setting TranContext->CleanupEvent to signaled.\n"));
/* Set the cleanup event */
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
}
TI_DbgPrint(DEBUG_REFCOUNT, ("TranContext->RefCount (%d).\n", TranContext->RefCount));
TI_DbgPrint(DEBUG_IRP, ("Setting TranContext->CleanupEvent to signaled.\n"));
/* Set the cleanup event */
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
IoReleaseCancelSpinLock(OldIrql);
@@ -121,10 +113,6 @@ VOID DispCancelRequest(
TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
#endif
/* Increase reference count to prevent accidential closure
of the object while inside the cancel routine */
TranContext->RefCount++;
IoReleaseCancelSpinLock(Irp->CancelIrql);
/* Try canceling the request */
@@ -140,7 +128,7 @@ VOID DispCancelRequest(
break;
}
DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);
/*DGCancelSendRequest(TranContext->Handle.AddressHandle, Irp);*/
break;
case TDI_RECEIVE_DATAGRAM:
@@ -149,7 +137,7 @@ VOID DispCancelRequest(
break;
}
DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);
/*DGCancelReceiveRequest(TranContext->Handle.AddressHandle, Irp);*/
break;
default:
@@ -163,7 +151,6 @@ VOID DispCancelRequest(
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID DispDataRequestComplete(
PVOID Context,
NTSTATUS Status,
@@ -191,13 +178,8 @@ VOID DispDataRequestComplete(
IoAcquireCancelSpinLock(&OldIrql);
IoSetCancelRoutine(Irp, NULL);
TranContext->RefCount--;
TI_DbgPrint(DEBUG_REFCOUNT, ("TranContext->RefCount (%d).\n", TranContext->RefCount));
if (TranContext->RefCount == 0) {
TI_DbgPrint(DEBUG_IRP, ("Setting TranContext->CleanupEvent to signaled.\n"));
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
}
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
if (Irp->Cancel || TranContext->CancelIrps) {
/* The IRP has been cancelled */
@@ -317,8 +299,7 @@ NTSTATUS DispTdiAssociateAddress(
TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
return STATUS_INVALID_PARAMETER;
}
/* The connection endpoint references the address file object */
ReferenceObject(AddrFile);
Connection->AddressFile = AddrFile;
/* Add connection endpoint to the address file */
@@ -327,7 +308,7 @@ NTSTATUS DispTdiAssociateAddress(
/* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
ObDereferenceObject(FileObject);
return Status;
return Status;
}
@@ -367,22 +348,12 @@ NTSTATUS DispTdiConnect(
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
#if 0
Status = TCPBind( Connection,
&Connection->SocketContext,
Parameters->RequestConnectionInformation );
TI_DbgPrint(MID_TRACE, ("TCP Bind returned %08x\n", Status));
if( NT_SUCCESS(Status) )
#endif
Status = TCPConnect(
TranContext->Handle.ConnectionContext,
Parameters->RequestConnectionInformation,
Parameters->ReturnConnectionInformation,
DispDataRequestComplete,
Irp );
Status = TCPConnect(
TranContext->Handle.ConnectionContext,
Parameters->RequestConnectionInformation,
Parameters->ReturnConnectionInformation,
DispDataRequestComplete,
Irp );
TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
@@ -403,7 +374,6 @@ NTSTATUS DispTdiDisassociateAddress(
PCONNECTION_ENDPOINT Connection;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@@ -428,11 +398,6 @@ NTSTATUS DispTdiDisassociateAddress(
return STATUS_INVALID_PARAMETER;
}
/* Remove the reference put on the address file object */
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
DereferenceObject(Connection->AddressFile);
KeReleaseSpinLock(&Connection->Lock, OldIrql);
return STATUS_SUCCESS;
}
@@ -497,9 +462,6 @@ NTSTATUS DispTdiDisconnect(
return STATUS_BUFFER_OVERFLOW;
}
/* FIXME: Is this count really the one we should return? */
AddressInfo->ActivityCount = AddrFile->RefCount;
Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
Address->TAAddressCount = 1;
Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
@@ -627,9 +589,6 @@ NTSTATUS DispTdiQueryInformation(
return STATUS_BUFFER_OVERFLOW;
}
/* FIXME: Is this count really the one we should return? */
AddressInfo->ActivityCount = AddrFile->RefCount;
Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
Address->TAAddressCount = 1;
Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
@@ -700,6 +659,7 @@ NTSTATUS DispTdiReceive(
Irp);
if (Status != STATUS_PENDING)
{
ASSERT(0);
DispDataRequestComplete(Irp, Status, BytesReceived);
}
}
@@ -961,7 +921,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
Status = STATUS_SUCCESS;
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Set the event handler. if an event handler is associated with
a specific event, it's flag (RegisteredXxxHandler) is TRUE.
@@ -1082,7 +1042,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
Status = STATUS_INVALID_PARAMETER;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
return Status;
}
+28 -68
View File
@@ -64,7 +64,7 @@ PADDRESS_FILE AddrSearchNext(
CurrentEntry = SearchContext->Next;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
while (CurrentEntry != &AddressFileListHead) {
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);
@@ -91,7 +91,7 @@ PADDRESS_FILE AddrSearchNext(
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
if (Found) {
SearchContext->Next = CurrentEntry->Flink;
@@ -140,11 +140,11 @@ VOID DeleteAddress(PADDRESS_FILE AddrFile)
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Remove address file from the global list */
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
RemoveEntryList(&AddrFile->ListEntry);
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* FIXME: Kill TCP connections on this address file object */
@@ -158,10 +158,10 @@ VOID DeleteAddress(PADDRESS_FILE AddrFile)
NextEntry = CurrentEntry->Flink;
ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
/* Abort the request and free its resources */
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
ExFreePool(ReceiveRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
CurrentEntry = NextEntry;
}
@@ -174,30 +174,15 @@ VOID DeleteAddress(PADDRESS_FILE AddrFile)
SendRequest = CONTAINING_RECORD(CurrentEntry,
DATAGRAM_SEND_REQUEST, ListEntry);
/* Abort the request and free its resources */
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
(*SendRequest->Complete)(SendRequest->Context, STATUS_ADDRESS_CLOSED, 0);
ExFreePool(SendRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* Dereference address entry */
DereferenceObject(AddrFile->ADE);
/* Dereference address cache */
if (AddrFile->AddrCache)
DereferenceObject(AddrFile->AddrCache);
#ifdef DBG
/* Remove reference provided at creation time */
AddrFile->RefCount--;
if (AddrFile->RefCount != 0)
TI_DbgPrint(DEBUG_REFCOUNT, ("AddrFile->RefCount is (%d) (should be 0).\n", AddrFile->RefCount));
#endif
(*AddrFile->Free)(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
@@ -217,36 +202,17 @@ VOID DeleteConnectionEndpoint(
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Remove connection endpoint from the global list */
KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
RemoveEntryList(&Connection->ListEntry);
KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
/* Dereference and remove the address file if it exists */
if (Connection->AddressFile) {
DereferenceObject(Connection->AddressFile);
}
KeReleaseSpinLock(&Connection->Lock, OldIrql);
#ifdef DBG
/* Remove reference provided at creation time */
Connection->RefCount--;
if (Connection->RefCount != 0)
TI_DbgPrint(DEBUG_REFCOUNT, ("Connection->RefCount is (%d) (should be 0).\n",
Connection->RefCount));
#endif
TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
ExFreePool(Connection);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID STDCALL RequestWorker(
PVOID Context)
#if 0
VOID STDCALL RequestWorker(PVOID Context)
/*
* FUNCTION: Worker routine for processing address file object requests
* ARGUMENTS:
@@ -259,7 +225,7 @@ VOID STDCALL RequestWorker(
TI_DbgPrint(MID_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Check it the address file should be deleted */
if (AF_IS_PENDING(AddrFile, AFF_DELETE)) {
@@ -269,7 +235,7 @@ VOID STDCALL RequestWorker(
RtnComplete = AddrFile->Complete;
RtnContext = AddrFile->Context;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
@@ -292,7 +258,7 @@ VOID STDCALL RequestWorker(
ReferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* The send routine processes the send requests in
the transmit queue on the address file. When the
@@ -302,9 +268,9 @@ VOID STDCALL RequestWorker(
resources available to complete all send requests */
DGSend(AddrFile, SendRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
DereferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (send request).\n"));
@@ -317,11 +283,11 @@ VOID STDCALL RequestWorker(
AF_CLR_BUSY(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
#endif
/*
* FUNCTION: Open an address file object
@@ -411,14 +377,11 @@ NTSTATUS FileOpenAddress(
InitializeListHead(&AddrFile->TransmitQueue);
/* Initialize work queue item. We use this for pending requests */
ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);
/*ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);*/
/* Initialize spin lock that protects the address file object */
KeInitializeSpinLock(&AddrFile->Lock);
/* Reference the object */
AddrFile->RefCount = 1;
/* Set valid flag so the address can be used */
AF_SET_VALID(AddrFile);
@@ -455,14 +418,14 @@ NTSTATUS FileCloseAddress(
AddrFile = Request->Handle.AddressHandle;
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if ((!AF_IS_BUSY(AddrFile)) && (AddrFile->RefCount == 1)) {
if (!AF_IS_BUSY(AddrFile)) {
/* Set address file object exclusive to us */
AF_SET_BUSY(AddrFile);
AF_CLR_VALID(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
} else {
@@ -477,10 +440,10 @@ NTSTATUS FileCloseAddress(
if (!AF_IS_BUSY(AddrFile)) {
/* Worker function is not running, so shedule it to run */
AF_SET_BUSY(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
ExQueueWorkItem(&AddrFile->WorkItem, CriticalWorkQueue);
} else
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
@@ -488,7 +451,7 @@ NTSTATUS FileCloseAddress(
} else
Status = STATUS_ADDRESS_CLOSED;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
@@ -602,9 +565,6 @@ NTSTATUS FileOpenControlChannel(
/* Initialize spin lock that protects the address file object */
KeInitializeSpinLock(&ControlChannel->Lock);
/* Reference the object */
ControlChannel->RefCount = 1;
/* Return address file object */
Request->Handle.ControlChannel = ControlChannel;
+9 -9
View File
@@ -32,7 +32,7 @@ VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) {
("Inserting interface %08x (%d entities already)\n",
Interface, EntityCount));
KeAcquireSpinLock( &EntityListLock, &OldIrql );
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
/* Count IP Entities */
for( i = 0; i < EntityCount; i++ )
@@ -50,14 +50,14 @@ VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) {
EntityCount++;
KeReleaseSpinLock( &EntityListLock, OldIrql );
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
}
VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
KIRQL OldIrql;
UINT i;
KeAcquireSpinLock( &EntityListLock, &OldIrql );
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
/* Remove entities that have this interface as context
* In the future, this might include AT_ENTITY types, too
@@ -71,7 +71,7 @@ VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
}
}
KeReleaseSpinLock( &EntityListLock, OldIrql );
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
}
TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
@@ -83,14 +83,14 @@ TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
TI_DbgPrint(MAX_TRACE,("About to copy %d TDIEntityIDs to user\n",
EntityCount));
KeAcquireSpinLock(&EntityListLock, &OldIrql);
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
Size = EntityCount * sizeof(TDIEntityID);
*BufferSize = Size;
if (BufSize < Size)
{
KeReleaseSpinLock( &EntityListLock, OldIrql );
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
/* The buffer is too small to contain requested data */
return TDI_BUFFER_TOO_SMALL;
}
@@ -103,7 +103,7 @@ TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
sizeof(TDIEntityID));
}
KeReleaseSpinLock(&EntityListLock, OldIrql);
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
return TDI_SUCCESS;
}
@@ -152,7 +152,7 @@ TDI_STATUS InfoTdiQueryInformationEx(
else
Status = InfoTdiQueryListEntities(Buffer, BufferSize);
} else {
KeAcquireSpinLock( &EntityListLock, &OldIrql );
TcpipAcquireSpinLock( &EntityListLock, &OldIrql );
for( i = 0; i < EntityCount; i++ ) {
if( EntityList[i].tei_entity == ID->toi_entity.tei_entity &&
@@ -164,7 +164,7 @@ TDI_STATUS InfoTdiQueryInformationEx(
}
}
KeReleaseSpinLock( &EntityListLock, OldIrql );
TcpipReleaseSpinLock( &EntityListLock, OldIrql );
if( FoundEntity ) {
TI_DbgPrint(MAX_TRACE,
+57
View File
@@ -0,0 +1,57 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/lock.c
* PURPOSE: Locking and unlocking
* PROGRAMMERS: Art Yerkes
* REVISIONS:
*/
#include "precomp.h"
KIRQL TcpipGetCurrentIrql() { return KeGetCurrentIrql(); }
VOID TcpipInitializeSpinLock( PKSPIN_LOCK SpinLock ) {
KeInitializeSpinLock( SpinLock );
}
VOID TcpipAcquireSpinLock( PKSPIN_LOCK SpinLock, PKIRQL Irql ) {
KeAcquireSpinLock( SpinLock, Irql );
}
VOID TcpipAcquireSpinLockAtDpcLevel( PKSPIN_LOCK SpinLock ) {
KeAcquireSpinLockAtDpcLevel( SpinLock );
}
VOID TcpipReleaseSpinLock( PKSPIN_LOCK SpinLock, KIRQL Irql ) {
KeReleaseSpinLock( SpinLock, Irql );
}
VOID TcpipReleaseSpinLockFromDpcLevel( PKSPIN_LOCK SpinLock ) {
KeReleaseSpinLockFromDpcLevel( SpinLock );
}
VOID TcpipInterlockedInsertTailList( PLIST_ENTRY ListHead,
PLIST_ENTRY Item,
PKSPIN_LOCK Lock ) {
ExInterlockedInsertTailList( ListHead, Item, Lock );
}
VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ) {
ExAcquireFastMutex( Mutex );
}
VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) {
ExReleaseFastMutex( Mutex );
}
VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
RecursiveMutexInit( RecMutex );
}
UINT TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOL ToWrite ) {
return RecursiveMutexEnter( RecMutex, ToWrite );
}
VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
RecursiveMutexLeave( RecMutex );
}
+11 -61
View File
@@ -101,46 +101,6 @@ VOID TiWriteErrorLog(
#endif
}
NTSTATUS TiGetProtocolNumber(
PUNICODE_STRING FileName,
PULONG Protocol)
/*
* FUNCTION: Returns the protocol number from a file name
* ARGUMENTS:
* FileName = Pointer to string with file name
* Protocol = Pointer to buffer to put protocol number in
* RETURNS:
* Status of operation
*/
{
UNICODE_STRING us;
NTSTATUS Status;
ULONG Value;
PWSTR Name;
TI_DbgPrint(MAX_TRACE, ("Called. FileName (%wZ).\n", FileName));
Name = FileName->Buffer;
if (*Name++ != (WCHAR)L'\\')
return STATUS_UNSUCCESSFUL;
if (*Name == (WCHAR)NULL)
return STATUS_UNSUCCESSFUL;
RtlInitUnicodeString(&us, Name);
Status = RtlUnicodeStringToInteger(&us, 10, &Value);
if (!NT_SUCCESS(Status) || ((Value > 255)))
return STATUS_UNSUCCESSFUL;
*Protocol = Value;
return STATUS_SUCCESS;
}
/*
* FUNCTION: Creates a file object
* ARGUMENTS:
@@ -149,6 +109,7 @@ NTSTATUS TiGetProtocolNumber(
* RETURNS:
* Status of the operation
*/
NTSTATUS TiCreateFileObject(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
@@ -183,7 +144,6 @@ CP
return STATUS_INSUFFICIENT_RESOURCES;
}
CP
Context->RefCount = 1;
Context->CancelIrps = FALSE;
KeInitializeEvent(&Context->CleanupEvent, NotificationEvent, FALSE);
CP
@@ -217,7 +177,7 @@ CP
TI_DbgPrint(MIN_TRACE, ("AddressType: %\n",
Address->Address[0].AddressType));
}
ExFreePool(Context);
PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
CP
@@ -234,12 +194,12 @@ CP
Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol);
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n"));
ExFreePool(Context);
PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
} else {
TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject));
ExFreePool(Context);
PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
CP
@@ -261,7 +221,7 @@ CP
if (EaInfo->EaValueLength < sizeof(PVOID)) {
TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n"));
ExFreePool(Context);
PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
@@ -269,7 +229,7 @@ CP
if (DeviceObject != TCPDeviceObject) {
TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
ExFreePool(Context);
PoolFreeBuffer(Context);
return STATUS_INVALID_PARAMETER;
}
@@ -292,7 +252,7 @@ CP
}
if (!NT_SUCCESS(Status))
ExFreePool(Context);
PoolFreeBuffer(Context);
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
@@ -323,14 +283,6 @@ VOID TiCleanupFileObjectComplete(
IoAcquireCancelSpinLock(&OldIrql);
/* Remove the initial reference provided at object creation time */
TranContext->RefCount--;
#ifdef DBG
if (TranContext->RefCount != 0)
TI_DbgPrint(DEBUG_REFCOUNT, ("TranContext->RefCount is %i, should be 0.\n", TranContext->RefCount));
#endif
KeSetEvent(&TranContext->CleanupEvent, 0, FALSE);
IoReleaseCancelSpinLock(OldIrql);
@@ -449,7 +401,7 @@ TiDispatchOpenClose(
case IRP_MJ_CLOSE:
Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
if (Context)
ExFreePool(Context);
PoolFreeBuffer(Context);
Status = STATUS_SUCCESS;
break;
@@ -648,11 +600,11 @@ VOID STDCALL TiUnload(
#ifdef DBG
KIRQL OldIrql;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
if (!IsListEmpty(&AddressFileListHead)) {
TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
}
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
#endif
/* Cancel timer */
KeCancelTimer(&IPTimer);
@@ -667,7 +619,6 @@ VOID STDCALL TiUnload(
TCPShutdown();
UDPShutdown();
RawIPShutdown();
DGShutdown();
/* Shutdown network level protocol subsystem */
IPShutdown();
@@ -698,7 +649,7 @@ VOID STDCALL TiUnload(
IoDeleteDevice(IPDeviceObject);
if (EntityList)
ExFreePool(EntityList);
PoolFreeBuffer(EntityList);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
@@ -847,7 +798,6 @@ DriverEntry(
IPStartup(RegistryPath);
/* Initialize transport level protocol subsystems */
DGStartup();
RawIPStartup();
UDPStartup();
TCPStartup();
@@ -0,0 +1,492 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/buffer.c
* PURPOSE: Miscellaneous operations on NDIS_BUFFERs and packets.
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include "precomp.h"
VOID XNdisGetFirstBufferFromPacket(PNDIS_PACKET Packet,
PNDIS_BUFFER *FirstBuffer,
PVOID *FirstBufferVA,
PUINT FirstBufferLength,
PUINT TotalBufferLength)
{
PNDIS_BUFFER _Buffer;
_Buffer = (Packet)->Private.Head;
*(FirstBuffer) = _Buffer;
*(FirstBufferVA) = MmGetMdlVirtualAddress(_Buffer);
if (_Buffer != NULL) {
*(FirstBufferLength) = MmGetMdlByteCount(_Buffer);
_Buffer = _Buffer->Next;
} else
*(FirstBufferLength) = 0;
*(TotalBufferLength) = *(FirstBufferLength);
while (_Buffer != NULL) {
*(TotalBufferLength) += MmGetMdlByteCount(_Buffer);
_Buffer = _Buffer->Next;
}
}
/*
* @implemented
*/
VOID XNdisQueryBuffer
(PNDIS_BUFFER Buffer,
PVOID *VirtualAddress,
PUINT Length)
/*
* FUNCTION:
* Queries an NDIS buffer for information
* ARGUMENTS:
* Buffer = Pointer to NDIS buffer to query
* VirtualAddress = Address of buffer to place virtual address
* Length = Address of buffer to place length of buffer
*/
{
if (VirtualAddress != NULL)
*(PVOID*)VirtualAddress = Buffer->MappedSystemVa;
*Length = ((PMDL)Buffer)->ByteCount;
}
__inline INT SkipToOffset(
PNDIS_BUFFER Buffer,
UINT Offset,
PCHAR *Data,
PUINT Size)
/*
* FUNCTION: Skip Offset bytes into a buffer chain
* ARGUMENTS:
* Buffer = Pointer to NDIS buffer
* Offset = Number of bytes to skip
* Data = Address of a pointer that on return will contain the
* address of the offset in the buffer
* Size = Address of a pointer that on return will contain the
* size of the destination buffer
* RETURNS:
* Offset into buffer, -1 if buffer chain was smaller than Offset bytes
* NOTES:
* Buffer may be NULL
*/
{
for (;;) {
if (!Buffer)
return -1;
XNdisQueryBuffer(Buffer, (PVOID)Data, Size);
if (Offset < *Size) {
*Data = (PCHAR)((ULONG_PTR) *Data + Offset);
*Size -= Offset;
break;
}
Offset -= *Size;
NdisGetNextBuffer(Buffer, &Buffer);
}
return Offset;
}
UINT CopyBufferToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PCHAR SrcData,
UINT Length)
/*
* FUNCTION: Copies data from a buffer to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcData = Pointer to source buffer
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the destination
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, DstSize;
PCHAR DstData;
TI_DbgPrint(DEBUG_PBUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
/* Skip DstOffset bytes in the destination buffer chain */
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(DstSize, Length);
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
SrcData = (PCHAR)((ULONG_PTR)SrcData + BytesToCopy);
Length -= BytesToCopy;
if (Length == 0)
break;
DstSize -= BytesToCopy;
if (DstSize == 0) {
/* No more bytes in desination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
XNdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
}
}
return BytesCopied;
}
UINT CopyBufferChainToBuffer(
PCHAR DstData,
PNDIS_BUFFER SrcBuffer,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS buffer chain to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcBuffer = Pointer to source NDIS buffer
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, SrcSize;
PCHAR SrcData;
TI_DbgPrint(DEBUG_PBUFFER, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
/* Skip SrcOffset bytes in the source buffer chain */
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(SrcSize, Length);
TI_DbgPrint(DEBUG_PBUFFER, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
DstData = (PCHAR)((ULONG_PTR)DstData + BytesToCopy);
Length -= BytesToCopy;
if (Length == 0)
break;
SrcSize -= BytesToCopy;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
XNdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
}
}
return BytesCopied;
}
UINT CopyPacketToBuffer(
PCHAR DstData,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
PNDIS_BUFFER FirstBuffer;
PVOID Address;
UINT FirstLength;
UINT TotalLength;
TI_DbgPrint(DEBUG_PBUFFER, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData, SrcPacket, SrcOffset, Length));
XNdisGetFirstBufferFromPacket(SrcPacket,
&FirstBuffer,
&Address,
&FirstLength,
&TotalLength);
return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
}
UINT CopyPacketToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source and
* destination buffer sizes
*/
{
PNDIS_BUFFER SrcBuffer;
PCHAR DstData, SrcData;
UINT DstSize, SrcSize;
UINT Count, Total;
TI_DbgPrint(DEBUG_PBUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length));
/* Skip DstOffset bytes in the destination buffer chain */
XNdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Skip SrcOffset bytes in the source packet */
XNdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID *)&SrcData, &SrcSize, &Total);
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Copy the data */
for (Total = 0;;) {
/* Find out how many bytes we can copy at one time */
if (Length < SrcSize)
Count = Length;
else
Count = SrcSize;
if (DstSize < Count)
Count = DstSize;
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
Total += Count;
Length -= Count;
if (Length == 0)
break;
DstSize -= Count;
if (DstSize == 0) {
/* No more bytes in destination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
XNdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
}
SrcSize -= Count;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
XNdisQueryBuffer(SrcBuffer, (PVOID)&SrcData, &SrcSize);
}
}
return Total;
}
PVOID AdjustPacket(
PNDIS_PACKET Packet,
UINT Available,
UINT Needed)
/*
* FUNCTION: Adjusts the amount of unused space at the beginning of the packet
* ARGUMENTS:
* Packet = Pointer to packet
* Available = Number of bytes available at start of first buffer
* Needed = Number of bytes needed for the header
* RETURNS:
* Pointer to start of packet
*/
{
PNDIS_BUFFER NdisBuffer;
INT Adjust;
TI_DbgPrint(DEBUG_PBUFFER, ("Available = %d, Needed = %d.\n", Available, Needed));
Adjust = Available - Needed;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
/* If Adjust is zero there is no need to adjust this packet as
there is no additional space at start the of first buffer */
if (Adjust != 0) {
NdisBuffer->MappedSystemVa = (PVOID) ((ULONG_PTR)(NdisBuffer->MappedSystemVa) + Adjust);
NdisBuffer->ByteOffset += Adjust;
NdisBuffer->ByteCount -= Adjust;
}
return NdisBuffer->MappedSystemVa;
}
UINT ResizePacket(
PNDIS_PACKET Packet,
UINT Size)
/*
* FUNCTION: Resizes an NDIS packet
* ARGUMENTS:
* Packet = Pointer to packet
* Size = Number of bytes in first buffer
* RETURNS:
* Previous size of first buffer
*/
{
PNDIS_BUFFER NdisBuffer;
UINT OldSize;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
OldSize = NdisBuffer->ByteCount;
if (Size != OldSize)
NdisBuffer->ByteCount = Size;
return OldSize;
}
NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length,
BOOLEAN Copy ) {
PNDIS_BUFFER Buffer;
NDIS_STATUS Status;
PCHAR NewBuf;
if( Copy ) {
NewBuf = PoolAllocateBuffer( Length );
if( !NewBuf ) return STATUS_NO_MEMORY;
RtlCopyMemory( NewBuf, Data, Length );
} else NewBuf = Data;
NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, Data, Length );
if( Status != NDIS_STATUS_SUCCESS ) return Status;
NdisChainBufferAtFront( Packet, Buffer );
return STATUS_SUCCESS;
}
void GetDataPtr( PNDIS_PACKET Packet,
UINT Offset,
PCHAR *DataOut,
PUINT Size ) {
PNDIS_BUFFER Buffer;
NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
if( !Buffer ) return;
SkipToOffset( Buffer, Offset, DataOut, Size );
}
NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
PCHAR Data, UINT Len,
PCHAR File, UINT Line ) {
PNDIS_PACKET Packet;
PNDIS_BUFFER Buffer;
NDIS_STATUS Status;
PCHAR NewData;
NewData = ExAllocatePool( NonPagedPool, Len );
if( !NewData ) return NDIS_STATUS_NOT_ACCEPTED; // XXX
TrackWithTag(EXALLOC_TAG, NewData, File, Line);
if( Data )
RtlCopyMemory(NewData, Data, Len);
NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
if( Status != NDIS_STATUS_SUCCESS ) {
ExFreePool( NewData );
return Status;
}
TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line);
NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
if( Status != NDIS_STATUS_SUCCESS ) {
ExFreePool( NewData );
FreeNdisPacket( Packet );
}
TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line);
NdisChainBufferAtFront( Packet, Buffer );
*NdisPacket = Packet;
return NDIS_STATUS_SUCCESS;
}
VOID FreeNdisPacketX
( PNDIS_PACKET Packet,
PCHAR File,
UINT Line )
/*
* FUNCTION: Frees an NDIS packet
* ARGUMENTS:
* Packet = Pointer to NDIS packet to be freed
*/
{
PNDIS_BUFFER Buffer, NextBuffer;
TI_DbgPrint(DEBUG_PBUFFER, ("Packet (0x%X)\n", Packet));
/* Free all the buffers in the packet first */
NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
for (; Buffer != NULL; Buffer = NextBuffer) {
PVOID Data;
UINT Length;
NdisGetNextBuffer(Buffer, &NextBuffer);
XNdisQueryBuffer(Buffer, &Data, &Length);
UntrackFL(File,Line,Buffer);
NdisFreeBuffer(Buffer);
UntrackFL(File,Line,Data);
ExFreePool(Data);
}
/* Finally free the NDIS packet discriptor */
UntrackFL(File,Line,Packet);
NdisFreePacket(Packet);
}
+14
View File
@@ -0,0 +1,14 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/bug.c
* PURPOSE: Bugcheck
* PROGRAMMERS: Art Yerkes
* REVISIONS:
*/
#include "precomp.h"
VOID TcpipBugCheck( ULONG BugCode ) {
DbgPrint("BugCheck called: %x\n", BugCode);
ASSERT(0);
}
@@ -0,0 +1,56 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/lock.c
* PURPOSE: Locking and unlocking
* PROGRAMMERS: Art Yerkes
* REVISIONS:
*/
#include "precomp.h"
KIRQL KernelIrql = PASSIVE_LEVEL;
KIRQL TcpipGetCurrentIrql() { return KernelIrql; }
VOID TcpipInitializeSpinLock( PKSPIN_LOCK SpinLock ) {
}
VOID TcpipAcquireSpinLock( PKSPIN_LOCK SpinLock, PKIRQL Irql ) {
*Irql = KernelIrql;
KernelIrql = DISPATCH_LEVEL;
}
VOID TcpipAcquireSpinLockAtDpcLevel( PKSPIN_LOCK SpinLock ) {
ASSERT(KernelIrql == DPC_LEVEL);
}
VOID TcpipReleaseSpinLock( PKSPIN_LOCK SpinLock, KIRQL Irql ) {
ASSERT( Irql <= KernelIrql );
KernelIrql = Irql;
}
VOID TcpipReleaseSpinLockFromDpcLevel( PKSPIN_LOCK SpinLock ) {
ASSERT(KernelIrql == DPC_LEVEL);
}
VOID TcpipInterlockedInsertTailList( PLIST_ENTRY ListHead,
PLIST_ENTRY Item,
PKSPIN_LOCK Lock ) {
InsertTailList( ListHead, Item );
}
VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ) {
}
VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) {
}
VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
}
UINT TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOL ToWrite ) {
return 0;
}
VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
}
@@ -0,0 +1,58 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/pool.c
* PURPOSE: Routines for controling pools
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include "precomp.h"
PVOID PoolAllocateBuffer(
ULONG Size)
/*
* FUNCTION: Returns a buffer from the free buffer pool
* RETURNS:
* Pointer to buffer, NULL if there was not enough
* free resources
*/
{
PVOID Buffer;
/* FIXME: Get buffer from a free buffer pool with enough room */
Buffer = malloc(Size);
TI_DbgPrint(DEBUG_MEMORY, ("Allocated (%i) bytes at (0x%X).\n", Size, Buffer));
return Buffer;
}
VOID PoolFreeBuffer(
PVOID Buffer)
/*
* FUNCTION: Returns a buffer to the free buffer pool
* ARGUMENTS:
* Buffer = Buffer to return to free buffer pool
*/
{
/* FIXME: Put buffer in free buffer pool */
TI_DbgPrint(DEBUG_MEMORY, ("Freeing buffer at (0x%X).\n", Buffer));
free(Buffer);
}
PVOID TcpipAllocateFromNPagedLookasideList( PNPAGED_LOOKASIDE_LIST List ) {
return PoolAllocateBuffer( List->Size );
}
VOID TcpipFreeToNPagedLookasideList( PNPAGED_LOOKASIDE_LIST List,
PVOID Thing ) {
PoolFreeBuffer( Thing );
}
/* EOF */
@@ -0,0 +1,17 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/lock.c
* PURPOSE: Waiting and signalling
* PROGRAMMERS: Art Yerkes
* REVISIONS:
*/
#include "precomp.h"
NTSTATUS TcpipWaitForSingleObject( PVOID Object,
KWAIT_REASON Reason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout ) {
return STATUS_SUCCESS;
}
+6 -6
View File
@@ -24,7 +24,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer,
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
ForEachInterface(CurrentIF) {
IpCurrent->Index = Count;
@@ -46,7 +46,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer,
Count++;
} EndFor(CurrentIF);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
Status = InfoCopyOut( (PCHAR)IpAddress, sizeof(*IpAddress) * Count,
Buffer, BufferSize );
@@ -108,14 +108,14 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
RtCurrent->Metric1 = RCacheCur->Metric;
RtCurrent->Type = 2 /* PF_INET */;
KeAcquireSpinLock(&EntityListLock, &OldIrql);
TcpipAcquireSpinLock(&EntityListLock, &OldIrql);
for( RtCurrent->Index = EntityCount - 1;
RtCurrent->Index >= 0 &&
RCacheCur->Router->Interface !=
EntityList[RtCurrent->Index].context;
RtCurrent->Index-- );
RtCurrent->Index = EntityList[RtCurrent->Index].tei_instance;
KeReleaseSpinLock(&EntityListLock, OldIrql);
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
} else {
TI_DbgPrint(MAX_TRACE, ("%d: BAD: NA %08x NM %08x GW %08x MT %d\n",
RtCurrent - RouteEntries,
@@ -155,14 +155,14 @@ TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer,
/* Count number of addresses */
AddrCount = 0;
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
TcpipAcquireSpinLock(&InterfaceListLock, &OldIrql);
ForEachInterface(CurrentIF) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
AddrCount += CountInterfaceAddresses( CurrentIF );
} EndFor(CurrentIF);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
TcpipReleaseSpinLock(&InterfaceListLock, OldIrql);
SnmpInfo.NumIf = IfCount;
SnmpInfo.NumAddr = AddrCount;
+11 -2
View File
@@ -24,7 +24,7 @@ PVOID PoolAllocateBuffer(
/* FIXME: Get buffer from a free buffer pool with enough room */
Buffer = exAllocatePool(NonPagedPool, Size);
Buffer = ExAllocatePool(NonPagedPool, Size);
TI_DbgPrint(DEBUG_MEMORY, ("Allocated (%i) bytes at (0x%X).\n", Size, Buffer));
@@ -44,7 +44,16 @@ VOID PoolFreeBuffer(
TI_DbgPrint(DEBUG_MEMORY, ("Freeing buffer at (0x%X).\n", Buffer));
exFreePool(Buffer);
ExFreePool(Buffer);
}
PVOID TcpipAllocateFromNPagedLookasideList( PNPAGED_LOOKASIDE_LIST List ) {
return ExAllocateFromNPagedLookasideList( List );
}
VOID TcpipFreeToNPagedLookasideList( PNPAGED_LOOKASIDE_LIST List,
PVOID Thing ) {
ExFreeToNPagedLookasideList( List, Thing );
}
/* EOF */
+40
View File
@@ -0,0 +1,40 @@
#include "precomp.h"
NTSTATUS TiGetProtocolNumber(
PUNICODE_STRING FileName,
PULONG Protocol)
/*
* FUNCTION: Returns the protocol number from a file name
* ARGUMENTS:
* FileName = Pointer to string with file name
* Protocol = Pointer to buffer to put protocol number in
* RETURNS:
* Status of operation
*/
{
UNICODE_STRING us;
NTSTATUS Status;
ULONG Value;
PWSTR Name;
TI_DbgPrint(MAX_TRACE, ("Called. FileName (%wZ).\n", FileName));
Name = FileName->Buffer;
if (*Name++ != (WCHAR)L'\\')
return STATUS_UNSUCCESSFUL;
if (*Name == (WCHAR)NULL)
return STATUS_UNSUCCESSFUL;
RtlInitUnicodeString(&us, Name);
Status = RtlUnicodeStringToInteger(&us, 10, &Value);
if (!NT_SUCCESS(Status) || ((Value > 255)))
return STATUS_UNSUCCESSFUL;
*Protocol = Value;
return STATUS_SUCCESS;
}
+18
View File
@@ -0,0 +1,18 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/lock.c
* PURPOSE: Waiting and signalling
* PROGRAMMERS: Art Yerkes
* REVISIONS:
*/
#include "precomp.h"
NTSTATUS TcpipWaitForSingleObject( PVOID Object,
KWAIT_REASON Reason,
KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
PLARGE_INTEGER Timeout ) {
return KeWaitForSingleObject
( Object, Reason, WaitMode, Alertable, Timeout );
}
+29 -1
View File
@@ -8,7 +8,35 @@ TARGET_PCH =
TARGET_LIBPATH = .
TARGET_CFLAGS = -I$(REGTESTS_PATH_INC)
TARGET_LIBS = \
../tcpip/main.o \
../tcpip/dispatch.o \
../tcpip/irp.o \
../tcpip/fileobjs.o \
../tcpip/proto.o \
../tcpip/mockbuffer.o \
../tcpip/mocklock.o \
../tcpip/mockwait.o \
../tcpip/mockpool.o \
../tcpip/mockbug.o \
../tcpip/info.o \
../tcpip/ninfo.o \
../tcpip/iinfo.o \
../tcpip/tinfo.o \
../datalink/lan.o \
$(PATH_TO_TOP)/dk/w32/lib/ip.a \
$(PATH_TO_TOP)/dk/w32/lib/oskittcp.a
TARGET_CFLAGS = \
-I$(REGTESTS_PATH_INC) \
-D__USE_W32API \
-DNDIS40 \
-DMEMTRACK \
-Wall -Werror \
-I../include \
-I$(PATH_TO_TOP)/drivers/lib/oskittcp/include \
-I$(PATH_TO_TOP)/w32api/include \
-I$(PATH_TO_TOP)/include
-include Makefile.tests
+52
View File
@@ -0,0 +1,52 @@
# Import stubs Auto-generated by ./stubgen.sh
ntoskrnl.a _imp_@InterlockedDecrement@4
ntoskrnl.a _imp_@InterlockedExchange@8
ntoskrnl.a _imp_@InterlockedIncrement@4
ntoskrnl.a _imp_@InterlockedPopEntrySList@4
ntoskrnl.a _imp_@InterlockedPushEntrySList@8
ntoskrnl.a _imp_@IofCompleteRequest@8
ntoskrnl.a _imp_@ObfDereferenceObject@4
ntoskrnl.a _imp__ExAllocatePool@8
ntoskrnl.a _imp__ExDeleteNPagedLookasideList@4
ntoskrnl.a _imp__ExFreePool@4
ntoskrnl.a _imp__ExInitializeNPagedLookasideList@28
ntoskrnl.a _imp__ExInterlockedInsertTailList@12
ntoskrnl.a _imp__ExInterlockedRemoveHeadList@8
ntoskrnl.a _imp__ExQueueWorkItem@8
ntoskrnl.a _imp__IoAcquireCancelSpinLock@4
ntoskrnl.a _imp__IoAllocateMdl@20
ntoskrnl.a _imp__IoCreateDevice@28
ntoskrnl.a _imp__IoDeleteDevice@4
ntoskrnl.a _imp__IoFileObjectType
ntoskrnl.a _imp__IoFreeMdl@4
ntoskrnl.a _imp__IoReleaseCancelSpinLock@4
ntoskrnl.a _imp__KeBugCheck@4
ntoskrnl.a _imp__KeCancelTimer@4
ntoskrnl.a _imp__KeInitializeDpc@12
ntoskrnl.a _imp__KeInitializeEvent@12
ntoskrnl.a _imp__KeInitializeSpinLock@4
ntoskrnl.a _imp__KeInitializeTimer@4
ntoskrnl.a _imp__KeResetEvent@4
ntoskrnl.a _imp__KeSetEvent@12
ntoskrnl.a _imp__KeSetTimerEx@20
ntoskrnl.a _imp__KeWaitForSingleObject@20
ntoskrnl.a _imp__MmMapLockedPages@8
ntoskrnl.a _imp__MmProbeAndLockPages@12
ntoskrnl.a _imp__MmUnlockPages@4
ndis.a _imp__NDIS_BUFFER_TO_SPAN_PAGES@4
ndis.a _imp__NdisAllocateBuffer@20
ndis.a _imp__NdisAllocateBufferPool@12
ndis.a _imp__NdisAllocatePacket@12
ndis.a _imp__NdisAllocatePacketPool@16
ndis.a _imp__NdisCloseAdapter@8
ndis.a _imp__NdisDeregisterProtocol@8
ndis.a _imp__NdisFreeBuffer@4
ndis.a _imp__NdisFreeBufferPool@4
ndis.a _imp__NdisFreePacket@4
ndis.a _imp__NdisFreePacketPool@4
ndis.a _imp__NdisOpenAdapter@44
ndis.a _imp__NdisRegisterProtocol@16
ndis.a _imp__NdisRequest@12
ndis.a _imp__NdisSend@12
ndis.a _imp__NdisTransferData@28
ntoskrnl.a _imp__ObReferenceObjectByHandle@24
@@ -0,0 +1,33 @@
#include <roscfg.h>
#include "../../include/precomp.h"
#include "regtests.h"
#define MTU 1500
struct packet {
int size;
char data[MTU];
};
static void RunTest() {
const struct packet Packets[] = {
{ 0 }
};
int i;
IP_INTERFACE IF;
IP_PACKET IPPacket;
NTSTATUS Status = STATUS_SUCCESS;
/* Init interface */
/* Init packet */
for( i = 0; NT_SUCCESS(Status) && i < Packets[i].size; i++ ) {
IPPacket.Header = (PUCHAR)Packets[i].data;
IPPacket.TotalSize = Packets[i].size;
IPReceive( &IF, &IPPacket );
}
_AssertEqualValue(Status,STATUS_SUCCESS);
}
_Dispatcher(IpreceiveTest, "IPReceive");
@@ -0,0 +1,13 @@
#include <roscfg.h>
#include "../../include/precomp.h"
#include "regtests.h"
static void RunTest() {
UNICODE_STRING Str;
int Proto;
RtlInitUnicodeString( &Str, L"1" );
TiGetProtocolNumber( &Str, (PULONG)&Proto );
_AssertEqualValue(1, Proto);
}
_Dispatcher(TigetprotocolnumberTest, "TiGetProtocolNumber");