mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-30 04:13:33 +00:00
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:
@@ -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>
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _TCPIP_BUG_H
|
||||
#define _TCPIP_BUG_H
|
||||
|
||||
VOID TcpipBugCheck( ULONG BugCode );
|
||||
|
||||
#endif/*_TCPIP_BUG_H*/
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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*/
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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,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 */
|
||||
|
||||
|
||||
@@ -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*/
|
||||
@@ -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 \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 ); }
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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");
|
||||
Reference in New Issue
Block a user