diff --git a/reactos/drivers/net/tcpip/datalink/arp.c b/reactos/drivers/net/tcpip/datalink/arp.c index 3c7059eed30..01a21b55836 100644 --- a/reactos/drivers/net/tcpip/datalink/arp.c +++ b/reactos/drivers/net/tcpip/datalink/arp.c @@ -49,7 +49,7 @@ PNDIS_PACKET PrepareARPPacket( PVOID DataBuffer; ULONG Size; - TI_DbgPrint(MID_TRACE, ("Called.\n")); + TI_DbgPrint(DEBUG_ARP, ("Called.\n")); /* Prepare ARP packet */ Size = MaxLLHeaderSize + sizeof(ARP_HEADER) + @@ -125,7 +125,7 @@ VOID ARPTransmitComplete( * This routine is called when an ARP request has been sent */ { - TI_DbgPrint(MID_TRACE, ("Called.\n")); + TI_DbgPrint(DEBUG_ARP, ("Called.\n")); FreeNdisPacket(NdisPacket); } @@ -148,7 +148,7 @@ BOOLEAN ARPTransmit( UCHAR ProtoAddrLen; USHORT ProtoType; - TI_DbgPrint(MID_TRACE, ("Called.\n")); + TI_DbgPrint(DEBUG_ARP, ("Called.\n")); Interface = NTE->Interface; @@ -206,7 +206,7 @@ VOID ARPReceive( PNDIS_PACKET NdisPacket; PIP_INTERFACE Interface = (PIP_INTERFACE)Context; - TI_DbgPrint(MID_TRACE, ("Called.\n")); + TI_DbgPrint(DEBUG_ARP, ("Called.\n")); Header = (PARP_HEADER)Packet->Header; diff --git a/reactos/drivers/net/tcpip/datalink/lan.c b/reactos/drivers/net/tcpip/datalink/lan.c index d83ef259d1f..1af32e93fcd 100644 --- a/reactos/drivers/net/tcpip/datalink/lan.c +++ b/reactos/drivers/net/tcpip/datalink/lan.c @@ -632,8 +632,8 @@ VOID BindAdapter( } /* FIXME: Get address from registry. - For now just use a private address, eg. 10.0.0.10 */ - Address = AddrBuildIPv4(0x0A00000A); + For now just use a private address, eg. 10.0.0.100 */ + Address = AddrBuildIPv4(0x6400000A); if (!Address) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); FreeTDPackets(Adapter); diff --git a/reactos/drivers/net/tcpip/include/address.h b/reactos/drivers/net/tcpip/include/address.h index c8835913c13..2121f27d9cc 100644 --- a/reactos/drivers/net/tcpip/include/address.h +++ b/reactos/drivers/net/tcpip/include/address.h @@ -21,6 +21,12 @@ (IPAddress)->Address.IPv4Address = (RawAddress); \ } +#ifdef DBG + +PCHAR A2S( + PIP_ADDRESS Address); + +#endif /* DBG */ BOOLEAN AddrIsUnspecified( PIP_ADDRESS Address); diff --git a/reactos/drivers/net/tcpip/include/debug.h b/reactos/drivers/net/tcpip/include/debug.h index d79641c21a2..61317ecd66d 100644 --- a/reactos/drivers/net/tcpip/include/debug.h +++ b/reactos/drivers/net/tcpip/include/debug.h @@ -15,18 +15,19 @@ #define MID_TRACE 0x00000002 #define MAX_TRACE 0x00000003 -#define DEBUG_MEMORY 0x00000100 -#define DEBUG_BUFFER 0x00000200 -#define DEBUG_IRP 0x00000400 -#define DEBUG_REFCOUNT 0x00000800 -#define DEBUG_ADDRFILE 0x00001000 -#define DEBUG_DATALINK 0x00002000 -#define DEBUG_ARP 0x00004000 -#define DEBUG_IP 0x00008000 -#define DEBUG_ICMP 0x00010000 -#define DEBUG_ROUTER 0x00020000 -#define DEBUG_RCACHE 0x00040000 -#define DEBUG_NCACHE 0x00080000 +#define DEBUG_CHECK 0x00000100 +#define DEBUG_MEMORY 0x00000200 +#define DEBUG_BUFFER 0x00000400 +#define DEBUG_IRP 0x00000800 +#define DEBUG_REFCOUNT 0x00001000 +#define DEBUG_ADDRFILE 0x00002000 +#define DEBUG_DATALINK 0x00004000 +#define DEBUG_ARP 0x00008000 +#define DEBUG_IP 0x00010000 +#define DEBUG_ICMP 0x00020000 +#define DEBUG_ROUTER 0x00040000 +#define DEBUG_RCACHE 0x00080000 +#define DEBUG_NCACHE 0x00100000 #define DEBUG_ULTRA 0xFFFFFFFF #ifdef DBG @@ -95,7 +96,9 @@ extern DWORD DebugTraceLevel; #define CHECKPOINT \ - do { TI_DbgPrint(MIN_TRACE, ("(%s:%d)\n", __FILE__, __LINE__)); } while(0); + do { TI_DbgPrint(DEBUG_CHECK, ("(%s:%d)\n", __FILE__, __LINE__)); } while(0); + +#define CP CHECKPOINT #endif /* __DEBUG_H */ diff --git a/reactos/drivers/net/tcpip/include/ip.h b/reactos/drivers/net/tcpip/include/ip.h index 3ee693a74f4..86b613bcde2 100644 --- a/reactos/drivers/net/tcpip/include/ip.h +++ b/reactos/drivers/net/tcpip/include/ip.h @@ -20,8 +20,8 @@ typedef struct IP_ADDRESS { ULONG RefCount; /* Number of references to this address */ UCHAR Type; /* Type of IP address */ union { - IPv4_RAW_ADDRESS IPv4Address; /* IPv4 address */ - PIPv6_RAW_ADDRESS IPv6Address; /* IPv6 address */ + IPv4_RAW_ADDRESS IPv4Address; /* IPv4 address (in network byte order) */ + PIPv6_RAW_ADDRESS IPv6Address; /* IPv6 address (in network byte order) */ } Address; } IP_ADDRESS, *PIP_ADDRESS; @@ -58,6 +58,7 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)( typedef struct IP_PACKET { ULONG RefCount; /* Reference count for this object */ UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */ + UCHAR Flags; /* Flags for packet (see IP_PACKET_FLAG_xx below)*/ PVOID Header; /* Pointer to IP header for this packet */ UINT HeaderSize; /* Size of IP header */ PVOID Data; /* Current pointer into packet data */ @@ -69,6 +70,9 @@ typedef struct IP_PACKET { IP_ADDRESS DstAddr; /* Destination address */ } IP_PACKET, *PIP_PACKET; +#define IP_PACKET_FLAG_RAW 0x01 /* Raw IP packet */ + + /* Packet context */ typedef struct PACKET_CONTEXT { PACKET_COMPLETION_ROUTINE Complete; /* Transport level completion handler */ @@ -161,11 +165,12 @@ typedef VOID (*IP_PROTOCOL_HANDLER)( PIP_PACKET IPPacket); /* Loopback adapter address information (network byte order) */ -#define LOOPBACK_ADDRESS_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0x7F000001)) +#define LOOPBACK_ADDRESS_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0x7F000001)) #define LOOPBACK_BCASTADDR_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0x7F0000FF)) #define LOOPBACK_ADDRMASK_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0xFFFFFF00)) /* Protocol definitions */ +#define IPPROTO_RAW 0 /* Raw IP */ #define IPPROTO_ICMP 1 /* Internet Control Message Protocol */ #define IPPROTO_IGMP 2 /* Internet Group Management Protocol */ #define IPPROTO_TCP 6 /* Transmission Control Protocol */ diff --git a/reactos/drivers/net/tcpip/makefile b/reactos/drivers/net/tcpip/makefile index e57ea3a2d6f..2696c2ab426 100644 --- a/reactos/drivers/net/tcpip/makefile +++ b/reactos/drivers/net/tcpip/makefile @@ -4,7 +4,7 @@ PATH_TO_TOP = ../../.. TARGETNAME=tcpip -CFLAGS = -I./include -O2 +CFLAGS = -I./include -O2 -DDBG RESOURCE_OBJECT = $(TARGETNAME).coff TCPIP_OBJECTS = tcpip/main.o tcpip/address.o tcpip/checksum.o \ diff --git a/reactos/drivers/net/tcpip/network/ip.c b/reactos/drivers/net/tcpip/network/ip.c index 62a321447d3..19736d354b7 100644 --- a/reactos/drivers/net/tcpip/network/ip.c +++ b/reactos/drivers/net/tcpip/network/ip.c @@ -60,6 +60,9 @@ PADDRESS_ENTRY CreateADE( TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) Type (0x%X) NTE (0x%X).\n", IF, Address, Type, NTE)); + TI_DbgPrint(DEBUG_IP, ("Address (%s) NTE (%s).\n", + A2S(Address), A2S(NTE->Address))); + /* Allocate space for an ADE and set it up */ ADE = PoolAllocateBuffer(sizeof(ADDRESS_ENTRY)); if (!ADE) { @@ -93,6 +96,8 @@ VOID DestroyADE( { TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) ADE (0x%X).\n", IF, ADE)); + TI_DbgPrint(DEBUG_IP, ("ADE (%s).\n", ADE->Address)); + /* Unlink the address entry from the list */ RemoveEntryList(&ADE->ListEntry); @@ -166,6 +171,8 @@ PPREFIX_LIST_ENTRY CreatePLE( TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Prefix (0x%X) Length (%d).\n", IF, Prefix, Length)); + TI_DbgPrint(DEBUG_IP, ("Prefix (%s).\n", A2S(Prefix))); + /* Allocate space for an PLE and set it up */ PLE = PoolAllocateBuffer(sizeof(PREFIX_LIST_ENTRY)); if (!PLE) { @@ -197,6 +204,8 @@ VOID DestroyPLE( { TI_DbgPrint(DEBUG_IP, ("Called. PLE (0x%X).\n", PLE)); + TI_DbgPrint(DEBUG_IP, ("PLE (%s).\n", PLE->Prefix)); + /* Unlink the prefix list entry from the list */ RemoveEntryList(&PLE->ListEntry); @@ -271,6 +280,8 @@ PNET_TABLE_ENTRY IPCreateNTE( TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) PrefixLength (%d).\n", IF, Address, PrefixLength)); + TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address))); + /* Allocate room for an NTE */ NTE = PoolAllocateBuffer(sizeof(NET_TABLE_ENTRY)); if (!NTE) { @@ -337,6 +348,8 @@ VOID DestroyNTE( TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) NTE (0x%X).\n", IF, NTE)); + TI_DbgPrint(DEBUG_IP, ("NTE (%s).\n", NTE->Address)); + /* Invalidate the prefix list entry for this NTE */ KeAcquireSpinLock(&PrefixListLock, &OldIrql); DestroyPLE(NTE->PLE); @@ -411,8 +424,10 @@ PNET_TABLE_ENTRY IPLocateNTEOnInterface( PLIST_ENTRY CurrentEntry; PADDRESS_ENTRY Current; - TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) AddressType (0x%X).\n", - IF, Address, AddressType)); +// TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X) Address (0x%X) AddressType (0x%X).\n", +// IF, Address, AddressType)); + +// TI_DbgPrint(DEBUG_IP, ("Address (%s) AddressType (0x%X).\n", A2S(Address))); KeAcquireSpinLock(&IF->Lock, &OldIrql); @@ -455,9 +470,11 @@ PNET_TABLE_ENTRY IPLocateNTE( PNET_TABLE_ENTRY Current; PNET_TABLE_ENTRY NTE; - TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n", - Address, AddressType)); - +// TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n", +// Address, AddressType)); + +// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address))); + KeAcquireSpinLock(&NetTableListLock, &OldIrql); /* Search the list and return the NTE if found */ @@ -500,8 +517,10 @@ PADDRESS_ENTRY IPLocateADE( PIP_INTERFACE CurrentIF; PADDRESS_ENTRY CurrentADE; - TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n", - Address, AddressType)); +// TI_DbgPrint(DEBUG_IP, ("Called. Address (0x%X) AddressType (0x%X).\n", +// Address, AddressType)); + +// TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address))); KeAcquireSpinLock(&InterfaceListLock, &OldIrql); @@ -549,9 +568,8 @@ PADDRESS_ENTRY IPGetDefaultADE( PLIST_ENTRY CurrentADEEntry; PIP_INTERFACE CurrentIF; PADDRESS_ENTRY CurrentADE; -#if 1 BOOLEAN LoopbackIsRegistered = FALSE; -#endif + TI_DbgPrint(DEBUG_IP, ("Called. AddressType (0x%X).\n", AddressType)); KeAcquireSpinLock(&InterfaceListLock, &OldIrql); @@ -560,9 +578,8 @@ PADDRESS_ENTRY IPGetDefaultADE( CurrentIFEntry = InterfaceListHead.Flink; while (CurrentIFEntry != &InterfaceListHead) { CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry); -#if 1 + if (CurrentIF != Loopback) { -#endif /* Search the address entry list and return the first appropriate ADE found */ CurrentADEEntry = CurrentIF->ADEListHead.Flink; while (CurrentADEEntry != &CurrentIF->ADEListHead) { @@ -573,13 +590,11 @@ PADDRESS_ENTRY IPGetDefaultADE( return CurrentADE; } CurrentADEEntry = CurrentADEEntry->Flink; -#if 1 } else LoopbackIsRegistered = TRUE; -#endif CurrentIFEntry = CurrentIFEntry->Flink; } -#if 1 + /* No address was found. Use loopback interface if available */ if (LoopbackIsRegistered) { CurrentADEEntry = Loopback->ADEListHead.Flink; @@ -593,7 +608,7 @@ PADDRESS_ENTRY IPGetDefaultADE( CurrentADEEntry = CurrentADEEntry->Flink; } } -#endif + KeReleaseSpinLock(&InterfaceListLock, OldIrql); return NULL; @@ -775,6 +790,20 @@ BOOLEAN IPRegisterInterface( KeReleaseSpinLock(&IF->Lock, OldIrql); return FALSE; } +#if 1 + /* Reference objects for forward information base */ + ReferenceObject(Current->Address); + ReferenceObject(Current->PLE->Prefix); + ReferenceObject(Current); + /* NCE is already referenced */ + if (!RouterAddRoute(Current->Address, Current->PLE->Prefix, Current, NCE, 1)) { + TI_DbgPrint(MIN_TRACE, ("Could not add route due to insufficient resources.\n")); + DereferenceObject(Current->Address); + DereferenceObject(Current->PLE->Prefix); + DereferenceObject(Current); + DereferenceObject(NCE); + } +#else RCN = RouteAddRouteToDestination(Current->Address, Current, IF, NCE); if (!RCN) { TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n")); @@ -784,7 +813,7 @@ BOOLEAN IPRegisterInterface( } /* Don't need this any more since the route cache references the NCE */ DereferenceObject(NCE); - +#endif CurrentEntry = CurrentEntry->Flink; } diff --git a/reactos/drivers/net/tcpip/network/receive.c b/reactos/drivers/net/tcpip/network/receive.c index 080b1fb622e..4d56d6bbc23 100644 --- a/reactos/drivers/net/tcpip/network/receive.c +++ b/reactos/drivers/net/tcpip/network/receive.c @@ -210,6 +210,7 @@ PIP_PACKET ReassembleDatagram( IPPacket->Type = IP_ADDRESS_V4; IPPacket->RefCount = 1; IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize; + IPPacket->ContigSize = IPPacket->TotalSize; IPPacket->HeaderSize = IPDR->HeaderSize; IPPacket->Position = IPDR->HeaderSize; @@ -474,6 +475,8 @@ VOID ProcessFragment( return; } + DISPLAY_IP_PACKET(Datagram); + /* Give the packet to the protocol dispatcher */ IPDispatchProtocol(NTE, Datagram); @@ -540,7 +543,7 @@ VOID IPv4Receive( PNET_TABLE_ENTRY NTE; UINT AddressType; - TI_DbgPrint(MAX_TRACE, ("Received IPv4 datagram.\n")); + //TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n")); IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2; @@ -559,11 +562,11 @@ VOID IPv4Receive( return; } - TI_DbgPrint(MAX_TRACE, ("TotalSize (datalink) is (%d).\n", IPPacket->TotalSize)); +// TI_DbgPrint(DEBUG_IP, ("TotalSize (datalink) is (%d).\n", IPPacket->TotalSize)); IPPacket->TotalSize = WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength); - TI_DbgPrint(MAX_TRACE, ("TotalSize (IPv4) is (%d).\n", IPPacket->TotalSize)); +// TI_DbgPrint(DEBUG_IP, ("TotalSize (IPv4) is (%d).\n", IPPacket->TotalSize)); AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr); AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr); @@ -620,6 +623,7 @@ VOID IPReceive( /* Check that IP header has a supported version */ Version = (((PIPv4_HEADER)IPPacket->Header)->VerIHL >> 4); + switch (Version) { case 4: IPPacket->Type = IP_ADDRESS_V4; @@ -627,13 +631,10 @@ VOID IPReceive( break; case 6: IPPacket->Type = IP_ADDRESS_V6; - TI_DbgPrint(MIN_TRACE, ("Datagram of type IPv6 discarded.\n")); + TI_DbgPrint(MAX_TRACE, ("Datagram of type IPv6 discarded.\n")); return; default: - TI_DbgPrint(MIN_TRACE, ("Datagram has an unsupported IP version %d.\n", Version)); - - DISPLAY_IP_PACKET(IPPacket); - + TI_DbgPrint(MIN_TRACE, ("Datagram has an unsupported IP version %d.\n", Version)); return; } } diff --git a/reactos/drivers/net/tcpip/network/route.c b/reactos/drivers/net/tcpip/network/route.c index 89020f5a1b5..e69847e8002 100644 --- a/reactos/drivers/net/tcpip/network/route.c +++ b/reactos/drivers/net/tcpip/network/route.c @@ -15,7 +15,7 @@ /* This RCN is shared by all external nodes. It complicates things, - but the memory.requirements are reduced by approximately 50%. + but the memory requirements are reduced by approximately 50%. The RCN is protected by the route cache spin lock */ PROUTE_CACHE_NODE ExternalRCN; PROUTE_CACHE_NODE RouteCache; @@ -217,14 +217,12 @@ VOID RemoveRouteToDestination( RemNode->Parent = RCN; } else { /* The node has internal children */ -#if 0 - /* Normally we would replace - the item of RCN with the item of the leftmost external - node on the right subtree of RCN. This we cannot do here - because there may be references directly to that node. - Instead we swap pointer values (parent, left and right) - of the two nodes */ -#endif + + /* Normally we would replace the item of RCN with the item + of the leftmost external node on the right subtree of + RCN. This we cannot do here because there may be + references directly to that node. Instead we swap pointer + values (parent, left and right) of the two nodes */ RemNode = RCN->Right; do { Parent = RemNode; @@ -446,7 +444,11 @@ UINT RouteGetRouteToDestination( PNEIGHBOR_CACHE_ENTRY NCE; PIP_INTERFACE Interface; - TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) NTE (0x%X).\n", Destination, NTE)); + TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) NTE (0x%X).\n", + Destination, NTE)); + + TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NTE (%s).\n", + A2S(Destination), A2S(NTE->Address))); KeAcquireSpinLock(&RouteCacheLock, &OldIrql); @@ -552,12 +554,16 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination( KIRQL OldIrql; PROUTE_CACHE_NODE RCN; - TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) NTE (0x%X) IF (0x%X) NCE (0x%X).\n", Destination, NTE, IF, NCE)); + TI_DbgPrint(DEBUG_RCACHE, ("Called. Destination (0x%X) NTE (0x%X) IF (0x%X) NCE (0x%X).\n", + Destination, NTE, IF, NCE)); + + TI_DbgPrint(DEBUG_RCACHE, ("Destination (%s) NTE (%s) NCE (%s).\n", + A2S(Destination), A2S(NTE->Address), A2S(NCE->Address))); KeAcquireSpinLock(&RouteCacheLock, &OldIrql); /* Locate an external RCN we can expand */ - RCN = RouteCache; + RCN = RouteCache; ExternalRCN->Left = NULL; for (;;) { RCN = SearchRouteCache(Destination, RCN); @@ -572,7 +578,7 @@ PROUTE_CACHE_NODE RouteAddRouteToDestination( /* Expand the external node */ if (RCN == RouteCache) { - RCN = ExpandExternalRCN(); + RCN = ExpandExternalRCN(); RouteCache = RCN; } else RCN = ExpandExternalRCN(); diff --git a/reactos/drivers/net/tcpip/network/router.c b/reactos/drivers/net/tcpip/network/router.c index 90da67993aa..af5fc267f0e 100644 --- a/reactos/drivers/net/tcpip/network/router.c +++ b/reactos/drivers/net/tcpip/network/router.c @@ -27,6 +27,8 @@ VOID DestroyFIBE( * The forward information base lock must be held when called */ { + TI_DbgPrint(DEBUG_ROUTER, ("Called. FIBE (0x%X).\n", FIBE)); + /* Unlink the FIB entry from the list */ RemoveEntryList(&FIBE->ListEntry); @@ -92,7 +94,10 @@ UINT CommonPrefixLength( UINT i, j; UINT Bitmask; - TI_DbgPrint(DEBUG_RCACHE, ("Called. Address1 (0x%X) Address2 (0x%X).\n", Address1, Address2)); + TI_DbgPrint(DEBUG_ROUTER, ("Called. Address1 (0x%X) Address2 (0x%X).\n", Address1, Address2)); + + TI_DbgPrint(DEBUG_ROUTER, ("Address1 (%s) Address2 (%s).\n", + A2S(Address1), A2S(Address2))); if (Address1->Type == IP_ADDRESS_V4) Size = sizeof(IPv4_RAW_ADDRESS); @@ -142,7 +147,10 @@ BOOLEAN HasPrefix( PUCHAR pAddress = (PUCHAR)&Address->Address; PUCHAR pPrefix = (PUCHAR)&Prefix->Address; - TI_DbgPrint(DEBUG_RCACHE, ("Called. Address (0x%X) Prefix (0x%X) Length (%d).\n", Address, Prefix, Length)); + TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) Prefix (0x%X) Length (%d).\n", Address, Prefix, Length)); + + TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) Prefix (%s).\n", + A2S(Address), A2S(Prefix))); /* Check that initial integral bytes match */ while (Length > 8) { @@ -179,7 +187,9 @@ PNET_TABLE_ENTRY RouterFindBestNTE( UINT Length, BestLength = 0; PNET_TABLE_ENTRY BestNTE = NULL; - TI_DbgPrint(DEBUG_RCACHE, ("Called. Interface (0x%X) Destination (0x%X).\n", Interface, Destination)); + TI_DbgPrint(DEBUG_ROUTER, ("Called. Interface (0x%X) Destination (0x%X).\n", Interface, Destination)); + + TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s).\n", A2S(Destination))); KeAcquireSpinLock(&Interface->Lock, &OldIrql); @@ -226,7 +236,10 @@ PIP_INTERFACE RouterFindOnLinkInterface( PLIST_ENTRY CurrentEntry; PPREFIX_LIST_ENTRY Current; - TI_DbgPrint(DEBUG_RCACHE, ("Called. Address (0x%X) NTE (0x%X).\n", Address, NTE)); + TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X) NTE (0x%X).\n", Address, NTE)); + + TI_DbgPrint(DEBUG_ROUTER, ("Address (%s) NTE (%s).\n", + A2S(Address), A2S(NTE->Address))); CurrentEntry = PrefixListHead.Flink; while (CurrentEntry != &PrefixListHead) { @@ -270,6 +283,9 @@ PFIB_ENTRY RouterAddRoute( TI_DbgPrint(DEBUG_ROUTER, ("Called. NetworkAddress (0x%X) Netmask (0x%X) NTE (0x%X) " "Router (0x%X) Metric (%d).\n", NetworkAddress, Netmask, NTE, Router, Metric)); + TI_DbgPrint(DEBUG_ROUTER, ("NetworkAddress (%s) Netmask (%s) NTE (%s) Router (%s).\n", + A2S(NetworkAddress), A2S(Netmask), A2S(NTE->Address), A2S(Router->Address))); + FIBE = PoolAllocateBuffer(sizeof(FIB_ENTRY)); if (!FIBE) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); @@ -314,6 +330,9 @@ PNEIGHBOR_CACHE_ENTRY RouterGetRoute( TI_DbgPrint(DEBUG_ROUTER, ("Called. Destination (0x%X) NTE (0x%X).\n", Destination, NTE)); + TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s) NTE (%s).\n", + A2S(Destination), A2S(NTE->Address))); + KeAcquireSpinLock(&FIBLock, &OldIrql); CurrentEntry = FIBListHead.Flink; @@ -370,6 +389,8 @@ VOID RouterRemoveRoute( TI_DbgPrint(DEBUG_ROUTER, ("Called. FIBE (0x%X).\n", FIBE)); + TI_DbgPrint(DEBUG_ROUTER, ("FIBE (%s).\n", A2S(FIBE->NetworkAddress))); + KeAcquireSpinLock(&FIBLock, &OldIrql); DestroyFIBE(FIBE); KeReleaseSpinLock(&FIBLock, OldIrql); diff --git a/reactos/drivers/net/tcpip/network/transmit.c b/reactos/drivers/net/tcpip/network/transmit.c index a69938d091e..bf192eec3ec 100644 --- a/reactos/drivers/net/tcpip/network/transmit.c +++ b/reactos/drivers/net/tcpip/network/transmit.c @@ -33,7 +33,7 @@ BOOLEAN PrepareNextFragment( BOOLEAN MoreFragments; USHORT FragOfs; - TI_DbgPrint(MAX_TRACE, ("Called.\n")); + TI_DbgPrint(MAX_TRACE, ("Called. IFC (0x%X)\n", IFC)); if (IFC->BytesLeft != 0) { @@ -100,7 +100,8 @@ NTSTATUS SendFragments( NDIS_STATUS NdisStatus; PVOID Data; - TI_DbgPrint(MAX_TRACE, ("Called.\n")); + TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X) PathMTU (%d).\n", + IPPacket, NCE, PathMTU)); IFC = PoolAllocateBuffer(sizeof(IPFRAGMENT_CONTEXT)); if (!IFC) @@ -180,7 +181,8 @@ VOID IPSendComplete( * This routine is called when an IP datagram fragment has been sent */ { - TI_DbgPrint(MAX_TRACE, ("Called.\n")); + 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 */ @@ -225,7 +227,7 @@ NTSTATUS IPSendFragment( * Lowest level IP send routine */ { - TI_DbgPrint(MAX_TRACE, ("Called.\n")); + TI_DbgPrint(MAX_TRACE, ("Called. NdisPacket (0x%X) NCE (0x%X).\n", NdisPacket, NCE)); TI_DbgPrint(MAX_TRACE, ("NCE->State = %d.\n", NCE->State)); @@ -299,7 +301,9 @@ NTSTATUS IPSendDatagram( PNEIGHBOR_CACHE_ENTRY NCE; UINT PathMTU; - TI_DbgPrint(MAX_TRACE, ("Called.\n")); + TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) RCN (0x%X)\n", IPPacket, RCN)); + + DISPLAY_IP_PACKET(IPPacket); NCE = RCN->NCE; @@ -313,16 +317,20 @@ NTSTATUS IPSendDatagram( /* Fetch path MTU now, because it may change */ PathMTU = RCN->PathMTU; + if (IPPacket->TotalSize > PathMTU) { return SendFragments(IPPacket, NCE, PathMTU); } else { - /* Calculate checksum of IP header */ - ((PIPv4_HEADER)IPPacket->Header)->Checksum = 0; + if (IPPacket->Flags & IP_PACKET_FLAG_RAW == 0) { + /* Calculate checksum of IP header */ + ((PIPv4_HEADER)IPPacket->Header)->Checksum = 0; - ((PIPv4_HEADER)IPPacket->Header)->Checksum = (USHORT) - IPv4Checksum(IPPacket->Header, IPPacket->HeaderSize, 0); + ((PIPv4_HEADER)IPPacket->Header)->Checksum = (USHORT) + IPv4Checksum(IPPacket->Header, IPPacket->HeaderSize, 0); - TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n", WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength))); + TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n", + WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength))); + } return IPSendFragment(IPPacket->NdisPacket, NCE); } diff --git a/reactos/drivers/net/tcpip/tcpip/address.c b/reactos/drivers/net/tcpip/tcpip/address.c index 02d60f847a9..10ad1a6447c 100644 --- a/reactos/drivers/net/tcpip/tcpip/address.c +++ b/reactos/drivers/net/tcpip/tcpip/address.c @@ -12,13 +12,54 @@ #include #include +#ifdef DBG + +CHAR A2SStr[128]; + +PCHAR A2S( + PIP_ADDRESS Address) +/* + * FUNCTION: Convert an IP address to a string (for debugging) + * ARGUMENTS: + * Address = Pointer to an IP address structure + * RETURNS: + * Pointer to buffer with string representation of IP address + */ +{ + ULONG ip; + CHAR b[10]; + PCHAR p; + + p = A2SStr; + + if (!Address) { + TI_DbgPrint(MIN_TRACE, ("NULL address given.\n")); + strcpy(p, "(NULL)"); + return p; + } + + switch (Address->Type) { + case IP_ADDRESS_V4: + ip = DN2H(Address->Address.IPv4Address); + sprintf(p, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); + break; + + case IP_ADDRESS_V6: + /* FIXME: IPv6 is not supported */ + strcpy(p, "(IPv6 address not supported)"); + break; + } + return p; +} + +#endif /* DBG */ BOOLEAN AddrIsUnspecified( PIP_ADDRESS Address) /* * FUNCTION: Return wether IP address is an unspecified address * ARGUMENTS: - * Address = Pointer to an IP address structure + * Address = Pointer to an IP address structure * RETURNS: * TRUE if the IP address is an unspecified address, FALSE if not */ @@ -289,13 +330,13 @@ PADDRESS_FILE AddrSearchNext( IPAddress = Current->ADE->Address; - TI_DbgPrint(DEBUG_ADDRFILE, ("Comparing: ((%d, %d, 0x%X), (%d, %d, 0x%X)).\n", + TI_DbgPrint(DEBUG_ADDRFILE, ("Comparing: ((%d, %d, %s), (%d, %d, %s)).\n", Current->Port, Current->Protocol, - IPAddress->Address.IPv4Address, + A2S(IPAddress), SearchContext->Port, SearchContext->Protocol, - SearchContext->Address->Address.IPv4Address)); + A2S(SearchContext->Address))); /* See if this address matches the search criteria */ if (((Current->Port == SearchContext->Port) && diff --git a/reactos/drivers/net/tcpip/tcpip/dispatch.c b/reactos/drivers/net/tcpip/tcpip/dispatch.c index 8226fd1925c..5e06657bdba 100644 --- a/reactos/drivers/net/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/net/tcpip/tcpip/dispatch.c @@ -439,16 +439,19 @@ NTSTATUS DispTdiSendDatagram( TI_DbgPrint(DEBUG_IRP, ("Called.\n")); - IrpSp = IoGetCurrentIrpStackLocation(Irp); - DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters); - - TranContext = IrpSp->FileObject->FsContext; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters); + TranContext = IrpSp->FileObject->FsContext; + /* Initialize a send request */ Request.Handle.AddressHandle = TranContext->Handle.AddressHandle; Request.RequestNotifyObject = DispDataRequestComplete; Request.RequestContext = Irp; - Status = DispPrepareIrpForCancel(IrpSp->FileObject->FsContext, Irp, (PDRIVER_CANCEL)DispCancelRequest); + Status = DispPrepareIrpForCancel( + IrpSp->FileObject->FsContext, + Irp, + (PDRIVER_CANCEL)DispCancelRequest); if (NT_SUCCESS(Status)) { /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress @@ -459,7 +462,8 @@ NTSTATUS DispTdiSendDatagram( (PNDIS_BUFFER)Irp->MdlAddress, DgramInfo->SendLength); if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); - /* Return STATUS_PENDING because DispPrepareIrpForCancel marks Irp as pending */ + /* Return STATUS_PENDING because DispPrepareIrpForCancel + marks Irp as pending */ Status = STATUS_PENDING; } } diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index 0b24fa5a23d..d5702b9551c 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -213,6 +213,7 @@ NTSTATUS FileOpenAddress( /* Locate address entry. If specified address is 0, a random address is chosen */ + /* FIXME: IPv4 only */ IPv4Address = Address->Address[0].Address[0].in_addr; if (IPv4Address == 0) AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST); @@ -225,8 +226,8 @@ NTSTATUS FileOpenAddress( return STATUS_INVALID_PARAMETER; } - TI_DbgPrint(DEBUG_ADDRFILE, ("Opening address (0x%X) for communication.\n", - DN2H(AddrFile->ADE->Address->Address.IPv4Address))); + TI_DbgPrint(MID_TRACE, ("Opening address %s for communication.\n", + A2S(AddrFile->ADE->Address))); /* Protocol specific handling */ switch (Protocol) { @@ -247,6 +248,9 @@ NTSTATUS FileOpenAddress( break; } + TI_DbgPrint(MID_TRACE, ("IP protocol number for address file object is %d.\n", + Protocol)); + /* Set protocol */ AddrFile->Protocol = Protocol; diff --git a/reactos/drivers/net/tcpip/tcpip/main.c b/reactos/drivers/net/tcpip/tcpip/main.c index 38e387eb8ee..7c405ac1a7a 100644 --- a/reactos/drivers/net/tcpip/tcpip/main.c +++ b/reactos/drivers/net/tcpip/tcpip/main.c @@ -16,10 +16,10 @@ #include #include - #ifdef DBG /* See debug.h for debug/trace constants */ +//DWORD DebugTraceLevel = MAX_TRACE | DEBUG_CHECK | DEBUG_IRP | DEBUG_RCACHE | DEBUG_ROUTER | DEBUG_REFCOUNT; DWORD DebugTraceLevel = MIN_TRACE; #endif /* DBG */ @@ -102,6 +102,45 @@ VOID TiWriteErrorLog( } +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: @@ -120,6 +159,7 @@ NTSTATUS TiCreateFileObject( PTRANSPORT_CONTEXT Context; TDI_REQUEST Request; NTSTATUS Status; + ULONG Protocol; TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp)); @@ -164,14 +204,34 @@ NTSTATUS TiCreateFileObject( } /* Open address file object */ - /* FIXME: Protocol depends on device object */ - Status = FileOpenAddress(&Request, Address, IPPROTO_UDP, NULL); + + /* Protocol depends on device object so find the protocol */ + if (DeviceObject == TCPDeviceObject) + Protocol = IPPROTO_TCP; + else if (DeviceObject == UDPDeviceObject) + Protocol = IPPROTO_UDP; + else if (DeviceObject == IPDeviceObject) + Protocol = IPPROTO_RAW; + else if (DeviceObject == RawIPDeviceObject) { + Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol); + if (!NT_SUCCESS(Status)) { + TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n")); + ExFreePool(Context); + return STATUS_INVALID_PARAMETER; + } + } else { + TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject)); + ExFreePool(Context); + return STATUS_INVALID_PARAMETER; + } + + Status = FileOpenAddress(&Request, Address, Protocol, NULL); if (NT_SUCCESS(Status)) { IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE; Context->Handle.AddressHandle = Request.Handle.AddressHandle; } } else { - TI_DbgPrint(MIN_TRACE, ("Connection point, and control connections are not supported.\n")); + TI_DbgPrint(MIN_TRACE, ("Connection endpoint, and control connections are not supported.\n")); /* FIXME: Open a connection endpoint, or control connection */ Status = STATUS_NOT_IMPLEMENTED; } @@ -297,7 +357,11 @@ NTSTATUS TiCleanupFileObject( } -NTSTATUS TiDispatchOpenClose( +NTSTATUS +#ifndef _MSC_VER +STDCALL +#endif +TiDispatchOpenClose( PDEVICE_OBJECT DeviceObject, PIRP Irp) /* @@ -360,7 +424,11 @@ NTSTATUS TiDispatchOpenClose( } -NTSTATUS TiDispatchInternal( +NTSTATUS +#ifndef _MSC_VER +STDCALL +#endif +TiDispatchInternal( PDEVICE_OBJECT DeviceObject, PIRP Irp) /* @@ -459,11 +527,15 @@ NTSTATUS TiDispatchInternal( } -NTSTATUS TiDispatch( +NTSTATUS +#ifndef _MSC_VER +STDCALL +#endif +TiDispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp) /* - * FUNCTION: Dispath routine for IRP_MJ_DEVICE_CONTROL requests + * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests * ARGUMENTS: * DeviceObject = Pointer to a device object for this driver * Irp = Pointer to a I/O request packet @@ -702,23 +774,24 @@ DriverEntry( return STATUS_INSUFFICIENT_RESOURCES; } -#if 0 - /* Open underlying adapter(s) we are bound to */ + /* Open underlying adapter(s) we are bound to */ /* FIXME: Get binding information from registry */ /* Put your own NDIS adapter device name here */ - +#if 0 /* ReactOS */ NdisInitUnicodeString(&DeviceName, L"\\Device\\ne2000"); - /* NT4 */ + /* NT4 style */ //NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1"); - /* NT5 */ + /* NT5 style */ //NdisInitUnicodeString(&DeviceName, L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}"); NdisStatus = LANRegisterAdapter(&DeviceName, &Adapter); + + /* Skip network adapter if it does not exist */ if (!NT_SUCCESS(NdisStatus)) { TI_DbgPrint(MIN_TRACE, ("Failed to intialize adapter. Status (0x%X).\n", Status)); TiWriteErrorLog( @@ -733,7 +806,6 @@ DriverEntry( return STATUS_DEVICE_DOES_NOT_EXIST; } #endif - /* Setup network layer and transport layer entities */ EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * 2); if (!NT_SUCCESS(Status)) { diff --git a/reactos/drivers/net/tcpip/tcpip/routines.c b/reactos/drivers/net/tcpip/tcpip/routines.c index f64e64ef722..48fca6705eb 100644 --- a/reactos/drivers/net/tcpip/tcpip/routines.c +++ b/reactos/drivers/net/tcpip/tcpip/routines.c @@ -360,15 +360,9 @@ PVOID AdjustPacket( /* 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) { -#if 0 - (ULONG_PTR)(NdisBuffer->MappedSystemVa) += Adjust; - (ULONG_PTR)(NdisBuffer->StartVa) += Adjust; - NdisBuffer->ByteCount -= Adjust; -#else (ULONG_PTR)(NdisBuffer->MappedSystemVa) += Adjust; NdisBuffer->ByteOffset += Adjust; NdisBuffer->ByteCount -= Adjust; -#endif } return NdisBuffer->MappedSystemVa; @@ -401,6 +395,7 @@ UINT ResizePacket( } #ifdef DBG + VOID DisplayIPPacket( PIP_PACKET IPPacket) { @@ -410,9 +405,6 @@ VOID DisplayIPPacket( PNDIS_BUFFER Buffer; PNDIS_BUFFER NextBuffer; - if ((DebugTraceLevel & MAX_TRACE) == 0) - return; - if (!IPPacket) { TI_DbgPrint(MIN_TRACE, ("Cannot display null packet.\n")); return; @@ -424,11 +416,22 @@ VOID DisplayIPPacket( TI_DbgPrint(MIN_TRACE, ("ContigSize (%d).\n", IPPacket->ContigSize)); TI_DbgPrint(MIN_TRACE, ("NdisPacket (0x%X).\n", IPPacket->NdisPacket)); - NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, &Buffer, NULL); - for (; Buffer != NULL; Buffer = NextBuffer) { - NdisGetNextBuffer(Buffer, &NextBuffer); - NdisQueryBuffer(Buffer, (PVOID)&p, &Length); + if (IPPacket->NdisPacket) { + NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, &Buffer, NULL); + for (; Buffer != NULL; Buffer = NextBuffer) { + NdisGetNextBuffer(Buffer, &NextBuffer); + NdisQueryBuffer(Buffer, (PVOID)&p, &Length); + for (i = 0; i < Length; i++) { + if (i % 16 == 0) + DbgPrint("\n"); + DbgPrint("%02X ", (p[i]) & 0xFF); + } + DbgPrint("\n"); + } + } else { + p = IPPacket->Header; + Length = IPPacket->ContigSize; for (i = 0; i < Length; i++) { if (i % 16 == 0) DbgPrint("\n"); diff --git a/reactos/drivers/net/tcpip/transport/rawip/rawip.c b/reactos/drivers/net/tcpip/transport/rawip/rawip.c index bddebe2ad10..a3f635dbe41 100644 --- a/reactos/drivers/net/tcpip/transport/rawip/rawip.c +++ b/reactos/drivers/net/tcpip/transport/rawip/rawip.c @@ -8,6 +8,7 @@ * CSH 01/08-2000 Created */ #include +#include #include #include #include @@ -32,28 +33,75 @@ NTSTATUS BuildRawIPPacket( * Status of operation */ { + PVOID Header; PIP_PACKET Packet; NDIS_STATUS NdisStatus; + PNDIS_BUFFER HeaderBuffer; PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context; + TI_DbgPrint(MAX_TRACE, ("TCPIP.SYS: NDIS data buffer is at (0x%X).\n", SendRequest->Buffer)); + TI_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", SendRequest->Buffer->Next)); + TI_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", SendRequest->Buffer->Size)); + TI_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", SendRequest->Buffer->MappedSystemVa)); + TI_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", SendRequest->Buffer->StartVa)); + TI_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", SendRequest->Buffer->ByteCount)); + TI_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", SendRequest->Buffer->ByteOffset)); + /* Prepare packet */ Packet = PoolAllocateBuffer(sizeof(IP_PACKET)); - if (!Packet) + if (!Packet) { + TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet.\n")); return STATUS_INSUFFICIENT_RESOURCES; + } RtlZeroMemory(Packet, sizeof(IP_PACKET)); + Packet->Flags = IP_PACKET_FLAG_RAW; /* Don't touch IP header */ Packet->RefCount = 1; Packet->TotalSize = SendRequest->BufferSize; /* Allocate NDIS packet */ NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool); if (NdisStatus != NDIS_STATUS_SUCCESS) { + TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus)); PoolFreeBuffer(Packet); return STATUS_INSUFFICIENT_RESOURCES; } - /* Chain buffer to packet */ - NdisChainBufferAtFront(Packet->NdisPacket, SendRequest->Buffer); + if (MaxLLHeaderSize != 0) { + Header = PoolAllocateBuffer(MaxLLHeaderSize); + if (!Header) { + TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n")); + NdisFreePacket(Packet->NdisPacket); + PoolFreeBuffer(Packet); + return STATUS_INSUFFICIENT_RESOURCES; + } + + TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n", + MaxLLHeaderSize, Header)); + + /* Allocate NDIS buffer for maximum link level header */ + NdisAllocateBuffer(&NdisStatus, + &HeaderBuffer, + GlobalBufferPool, + Header, + MaxLLHeaderSize); + if (NdisStatus != NDIS_STATUS_SUCCESS) { + TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus)); + PoolFreeBuffer(Header); + NdisFreePacket(Packet->NdisPacket); + PoolFreeBuffer(Packet); + return STATUS_INSUFFICIENT_RESOURCES; + } + /* Chain header at front of packet */ + NdisChainBufferAtFront(Packet->NdisPacket, HeaderBuffer); + } + + TI_DbgPrint(MIN_TRACE, ("Chaining data NDIS buffer at back (0x%X)\n", SendRequest->Buffer)); + + /* Chain data after link level header if it exists */ + NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer); + + DISPLAY_IP_PACKET(Packet); *IPPacket = Packet;