From b855c23983898c2650dcb4e7db62251c4159e719 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Mon, 5 Dec 2011 03:14:50 +0000 Subject: [PATCH] [TCPIP] - Massive IPPacket usage overhaul (fix missing frees, initializations, and double frees) - Make IP receive completely agnostic of the buffers and data location (part 2 of 2) - Use paged pool for the majority of allocations during receive and assembly - Implement ProtocolReceivePacket for faster performance with 3rd party NIC drivers - Fix a buffer overflow if an IPv4 packet is received with a header larger than 20 bytes - Many more improvements and bug fixes svn path=/trunk/; revision=54597 --- reactos/drivers/network/tcpip/datalink/lan.c | 221 ++++++++++++------ reactos/drivers/network/tcpip/include/ip.h | 3 +- .../drivers/network/tcpip/include/receive.h | 3 +- reactos/drivers/network/tcpip/tcpip/buffer.c | 23 -- reactos/lib/drivers/ip/network/arp.c | 69 +++++- reactos/lib/drivers/ip/network/icmp.c | 64 +++-- reactos/lib/drivers/ip/network/ip.c | 30 ++- reactos/lib/drivers/ip/network/loopback.c | 12 +- reactos/lib/drivers/ip/network/receive.c | 169 ++++++++------ reactos/lib/drivers/ip/network/router.c | 20 +- reactos/lib/drivers/ip/network/routines.c | 21 +- reactos/lib/drivers/ip/network/transmit.c | 18 +- .../lib/drivers/ip/transport/rawip/rawip.c | 47 ++-- reactos/lib/drivers/ip/transport/tcp/if.c | 15 +- reactos/lib/drivers/ip/transport/udp/udp.c | 54 +++-- 15 files changed, 467 insertions(+), 302 deletions(-) diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index 5fa298e241c..90c730e455a 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -12,35 +12,16 @@ UINT TransferDataCalled = 0; UINT TransferDataCompleteCalled = 0; -UINT LanReceiveWorkerCalled = 0; -BOOLEAN LanReceiveWorkerBusy = FALSE; #define CCS_ROOT L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet" #define TCPIP_GUID L"{4D36E972-E325-11CE-BFC1-08002BE10318}" -#define NGFP(_Packet) \ - { \ - PVOID _Header; \ - ULONG _ContigSize, _TotalSize; \ - PNDIS_BUFFER _NdisBuffer; \ - \ - TI_DbgPrint(MID_TRACE,("Checking Packet %x\n", _Packet)); \ - NdisGetFirstBufferFromPacket(_Packet, \ - &_NdisBuffer, \ - &_Header, \ - &_ContigSize, \ - &_TotalSize); \ - TI_DbgPrint(MID_TRACE,("NdisBuffer: %x\n", _NdisBuffer)); \ - TI_DbgPrint(MID_TRACE,("Header : %x\n", _Header)); \ - TI_DbgPrint(MID_TRACE,("ContigSize: %x\n", _ContigSize)); \ - TI_DbgPrint(MID_TRACE,("TotalSize : %x\n", _TotalSize)); \ - } - typedef struct _LAN_WQ_ITEM { LIST_ENTRY ListEntry; PNDIS_PACKET Packet; PLAN_ADAPTER Adapter; UINT BytesTransferred; + BOOLEAN LegacyReceive; } LAN_WQ_ITEM, *PLAN_WQ_ITEM; NDIS_HANDLE NdisProtocolHandle = (NDIS_HANDLE)NULL; @@ -99,6 +80,83 @@ NDIS_STATUS NDISCall( return NdisStatus; } +/* Used by legacy ProtocolReceive for packet type */ +NDIS_STATUS +GetPacketTypeFromHeaderBuffer(PLAN_ADAPTER Adapter, + PVOID HeaderBuffer, + ULONG HeaderBufferSize, + PULONG PacketType) +{ + PETH_HEADER EthHeader = HeaderBuffer; + + if (HeaderBufferSize < Adapter->HeaderSize) + { + TI_DbgPrint(DEBUG_DATALINK, ("Runt frame (size %d).\n", HeaderBufferSize)); + return NDIS_STATUS_NOT_ACCEPTED; + } + + switch (Adapter->Media) + { + case NdisMedium802_3: + /* Ethernet and IEEE 802.3 frames can be destinguished by + looking at the IEEE 802.3 length field. This field is + less than or equal to 1500 for a valid IEEE 802.3 frame + and larger than 1500 is it's a valid EtherType value. + See RFC 1122, section 2.3.3 for more information */ + + *PacketType = EthHeader->EType; + break; + + default: + TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n")); + + /* FIXME: Support other medias */ + return NDIS_STATUS_NOT_ACCEPTED; + } + + TI_DbgPrint(DEBUG_DATALINK, ("EtherType (0x%X).\n", *PacketType)); + + return NDIS_STATUS_SUCCESS; +} + +/* Used by ProtocolReceivePacket for packet type */ +NDIS_STATUS +GetPacketTypeFromNdisPacket(PLAN_ADAPTER Adapter, + PNDIS_PACKET NdisPacket, + PULONG PacketType) +{ + PVOID HeaderBuffer; + ULONG BytesCopied; + NDIS_STATUS Status; + + HeaderBuffer = ExAllocatePool(NonPagedPool, + Adapter->HeaderSize); + if (!HeaderBuffer) + return NDIS_STATUS_RESOURCES; + + /* Copy the media header */ + BytesCopied = CopyPacketToBuffer(HeaderBuffer, + NdisPacket, + 0, + Adapter->HeaderSize); + if (BytesCopied != Adapter->HeaderSize) + { + /* Runt frame */ + ExFreePool(HeaderBuffer); + TI_DbgPrint(DEBUG_DATALINK, ("Runt frame (size %d).\n", BytesCopied)); + return NDIS_STATUS_NOT_ACCEPTED; + } + + Status = GetPacketTypeFromHeaderBuffer(Adapter, + HeaderBuffer, + BytesCopied, + PacketType); + + ExFreePool(HeaderBuffer); + + return Status; +} + VOID FreeAdapter( PLAN_ADAPTER Adapter) @@ -235,48 +293,67 @@ VOID NTAPI ProtocolSendComplete( } VOID LanReceiveWorker( PVOID Context ) { - UINT PacketType; + ULONG PacketType; PLAN_WQ_ITEM WorkItem = (PLAN_WQ_ITEM)Context; PNDIS_PACKET Packet; PLAN_ADAPTER Adapter; UINT BytesTransferred; - PNDIS_BUFFER NdisBuffer; IP_PACKET IPPacket; + BOOLEAN LegacyReceive; + PIP_INTERFACE Interface; TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); Packet = WorkItem->Packet; Adapter = WorkItem->Adapter; BytesTransferred = WorkItem->BytesTransferred; + LegacyReceive = WorkItem->LegacyReceive; ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG); + Interface = Adapter->Context; + IPInitializePacket(&IPPacket, 0); IPPacket.NdisPacket = Packet; + IPPacket.ReturnPacket = !LegacyReceive; - NdisGetFirstBufferFromPacket(Packet, - &NdisBuffer, - &IPPacket.Header, - &IPPacket.ContigSize, - &IPPacket.TotalSize); + if (LegacyReceive) + { + /* Packet type is precomputed */ + PacketType = PC(IPPacket.NdisPacket)->PacketType; - IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; - /* Determine which upper layer protocol that should receive - this packet and pass it to the correct receive handler */ + /* Data is at position 0 */ + IPPacket.Position = 0; + + /* Packet size is determined by bytes transferred */ + IPPacket.TotalSize = BytesTransferred; + } + else + { + /* Determine packet type from media header */ + if (GetPacketTypeFromNdisPacket(Adapter, + IPPacket.NdisPacket, + &PacketType) != NDIS_STATUS_SUCCESS) + { + /* Bad packet */ + IPPacket.Free(&IPPacket); + return; + } - TI_DbgPrint(MID_TRACE, - ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", - IPPacket.ContigSize, IPPacket.TotalSize, - BytesTransferred)); + /* Data is at the end of the media header */ + IPPacket.Position = Adapter->HeaderSize; - PacketType = PC(IPPacket.NdisPacket)->PacketType; - IPPacket.Position = 0; + /* Calculate packet size (excluding media header) */ + NdisQueryPacketLength(IPPacket.NdisPacket, &IPPacket.TotalSize); + } TI_DbgPrint (DEBUG_DATALINK, - ("Ether Type = %x ContigSize = %d Total = %d\n", - PacketType, IPPacket.ContigSize, IPPacket.TotalSize)); + ("Ether Type = %x Total = %d\n", + PacketType, IPPacket.TotalSize)); + + Interface->Stats.InBytes += IPPacket.TotalSize; /* NDIS packet is freed in all of these cases */ switch (PacketType) { @@ -298,8 +375,8 @@ VOID LanReceiveWorker( PVOID Context ) { VOID LanSubmitReceiveWork( NDIS_HANDLE BindingContext, PNDIS_PACKET Packet, - NDIS_STATUS Status, - UINT BytesTransferred) { + UINT BytesTransferred, + BOOLEAN LegacyReceive) { PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM), WQ_CONTEXT_TAG); PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; @@ -311,6 +388,7 @@ VOID LanSubmitReceiveWork( WQItem->Packet = Packet; WQItem->Adapter = Adapter; WQItem->BytesTransferred = BytesTransferred; + WQItem->LegacyReceive = LegacyReceive; if (!ChewCreate( LanReceiveWorker, WQItem )) ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG); @@ -342,7 +420,30 @@ VOID NTAPI ProtocolTransferDataComplete( if( Status != NDIS_STATUS_SUCCESS ) return; - LanSubmitReceiveWork( BindingContext, Packet, Status, BytesTransferred ); + LanSubmitReceiveWork(BindingContext, + Packet, + BytesTransferred, + TRUE); +} + +INT NTAPI ProtocolReceivePacket( + NDIS_HANDLE BindingContext, + PNDIS_PACKET NdisPacket) +{ + PLAN_ADAPTER Adapter = BindingContext; + + if (Adapter->State != LAN_STATE_STARTED) { + TI_DbgPrint(DEBUG_DATALINK, ("Adapter is stopped.\n")); + return 0; + } + + LanSubmitReceiveWork(BindingContext, + NdisPacket, + 0, /* Unused */ + FALSE); + + /* Hold 1 reference on this packet */ + return 1; } NDIS_STATUS NTAPI ProtocolReceive( @@ -367,15 +468,12 @@ NDIS_STATUS NTAPI ProtocolReceive( * Status of operation */ { - USHORT EType; - UINT PacketType, BytesTransferred; - UINT temp; - //IP_PACKET IPPacket; + ULONG PacketType; + UINT BytesTransferred; PCHAR BufferData; NDIS_STATUS NdisStatus; PNDIS_PACKET NdisPacket; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; - PETH_HEADER EHeader = (PETH_HEADER)HeaderBuffer; TI_DbgPrint(DEBUG_DATALINK, ("Called. (packetsize %d)\n",PacketSize)); @@ -389,30 +487,17 @@ NDIS_STATUS NTAPI ProtocolReceive( return NDIS_STATUS_NOT_ACCEPTED; } - if (Adapter->Media == NdisMedium802_3) { - /* Ethernet and IEEE 802.3 frames can be destinguished by - looking at the IEEE 802.3 length field. This field is - less than or equal to 1500 for a valid IEEE 802.3 frame - and larger than 1500 is it's a valid EtherType value. - See RFC 1122, section 2.3.3 for more information */ - /* FIXME: Test for Ethernet and IEEE 802.3 frame */ - if (((EType = EHeader->EType) != ETYPE_IPv4) && (EType != ETYPE_ARP)) { - TI_DbgPrint(DEBUG_DATALINK, ("Not IP or ARP frame. EtherType (0x%X).\n", EType)); - return NDIS_STATUS_NOT_ACCEPTED; - } - /* We use EtherType constants to destinguish packet types */ - PacketType = EType; - } else { - TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n")); - /* FIXME: Support other medias */ + NdisStatus = GetPacketTypeFromHeaderBuffer(Adapter, + HeaderBuffer, + HeaderBufferSize, + &PacketType); + if (NdisStatus != NDIS_STATUS_SUCCESS) return NDIS_STATUS_NOT_ACCEPTED; - } - - /* Get a transfer data packet */ TI_DbgPrint(DEBUG_DATALINK, ("Adapter: %x (MTU %d)\n", Adapter, Adapter->MTU)); + /* Get a transfer data packet */ NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, PacketSize ); if( NdisStatus != NDIS_STATUS_SUCCESS ) { @@ -423,10 +508,7 @@ NDIS_STATUS NTAPI ProtocolReceive( TI_DbgPrint(DEBUG_DATALINK, ("pretransfer LookaheadBufferSize %d packsize %d\n",LookaheadBufferSize,PacketSize)); - GetDataPtr( NdisPacket, 0, &BufferData, &temp ); - - //IPPacket.NdisPacket = NdisPacket; - //IPPacket.Position = 0; + GetDataPtr( NdisPacket, 0, &BufferData, &PacketSize ); TransferDataCalled++; @@ -1486,6 +1568,7 @@ NTSTATUS LANRegisterProtocol( ProtChars.RequestCompleteHandler = ProtocolRequestComplete; ProtChars.SendCompleteHandler = ProtocolSendComplete; ProtChars.TransferDataCompleteHandler = ProtocolTransferDataComplete; + ProtChars.ReceivePacketHandler = ProtocolReceivePacket; ProtChars.ReceiveHandler = ProtocolReceive; ProtChars.ReceiveCompleteHandler = ProtocolReceiveComplete; ProtChars.StatusHandler = ProtocolStatus; diff --git a/reactos/drivers/network/tcpip/include/ip.h b/reactos/drivers/network/tcpip/include/ip.h index 9564d6f1757..b448b517c79 100644 --- a/reactos/drivers/network/tcpip/include/ip.h +++ b/reactos/drivers/network/tcpip/include/ip.h @@ -78,11 +78,12 @@ typedef struct _IP_PACKET { 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)*/ + BOOLEAN MappedHeader; /* States whether Header is from an MDL or allocated from pool */ + BOOLEAN ReturnPacket; /* States whether NdisPacket should be passed to NdisReturnPackets */ PVOID Header; /* Pointer to IP header for this packet */ UINT HeaderSize; /* Size of IP header */ PVOID Data; /* Current pointer into packet data */ UINT TotalSize; /* Total amount of data in packet (IP header and data) */ - UINT ContigSize; /* Number of contiguous bytes left in current buffer */ UINT Position; /* Current logical offset into packet */ PNDIS_PACKET NdisPacket; /* Pointer to NDIS packet */ IP_ADDRESS SrcAddr; /* Source address */ diff --git a/reactos/drivers/network/tcpip/include/receive.h b/reactos/drivers/network/tcpip/include/receive.h index c63f1346b8c..51a8bdad182 100644 --- a/reactos/drivers/network/tcpip/include/receive.h +++ b/reactos/drivers/network/tcpip/include/receive.h @@ -10,12 +10,13 @@ #include /* Number of seconds before destroying the IPDR */ -#define MAX_TIMEOUT_COUNT 5 +#define MAX_TIMEOUT_COUNT 3 /* IP datagram fragment descriptor. Used to store IP datagram fragments */ typedef struct IP_FRAGMENT { LIST_ENTRY ListEntry; /* Entry on list */ PNDIS_PACKET Packet; /* NDIS packet containing fragment data */ + BOOLEAN ReturnPacket; /* States whether to call NdisReturnPackets */ UINT PacketOffset; /* Offset into NDIS packet where data is */ UINT Offset; /* Offset into datagram where this fragment is */ UINT Size; /* Size of this fragment */ diff --git a/reactos/drivers/network/tcpip/tcpip/buffer.c b/reactos/drivers/network/tcpip/tcpip/buffer.c index 6858ddea984..d23da2c9d32 100644 --- a/reactos/drivers/network/tcpip/tcpip/buffer.c +++ b/reactos/drivers/network/tcpip/tcpip/buffer.c @@ -311,29 +311,6 @@ UINT ResizePacket( 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 = ExAllocatePoolWithTag( NonPagedPool, Length, PACKET_BUFFER_TAG ); - if( !NewBuf ) return NDIS_STATUS_RESOURCES; - RtlCopyMemory( NewBuf, Data, Length ); - } else NewBuf = Data; - - NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewBuf, Length ); - if( Status != NDIS_STATUS_SUCCESS ) { - if (Copy) ExFreePoolWithTag(NewBuf, PACKET_BUFFER_TAG); - return Status; - } - - NdisChainBufferAtFront( Packet, Buffer ); - - return STATUS_SUCCESS; -} - void GetDataPtr( PNDIS_PACKET Packet, UINT Offset, PCHAR *DataOut, diff --git a/reactos/lib/drivers/ip/network/arp.c b/reactos/lib/drivers/ip/network/arp.c index b24e381a289..6a7d862c44f 100644 --- a/reactos/lib/drivers/ip/network/arp.c +++ b/reactos/lib/drivers/ip/network/arp.c @@ -185,36 +185,88 @@ VOID ARPReceive( PARP_HEADER Header; IP_ADDRESS SrcAddress; IP_ADDRESS DstAddress; - PVOID SenderHWAddress; - PVOID SenderProtoAddress; - PVOID TargetProtoAddress; + PCHAR SenderHWAddress, SenderProtoAddress, TargetProtoAddress; PNEIGHBOR_CACHE_ENTRY NCE; PNDIS_PACKET NdisPacket; PIP_INTERFACE Interface = (PIP_INTERFACE)Context; + ULONG BytesCopied, DataSize; + PCHAR DataBuffer; + + PAGED_CODE(); TI_DbgPrint(DEBUG_ARP, ("Called.\n")); + Packet->Header = ExAllocatePoolWithTag(PagedPool, + sizeof(ARP_HEADER), + PACKET_BUFFER_TAG); + if (!Packet->Header) + { + TI_DbgPrint(DEBUG_ARP, ("Unable to allocate header buffer\n")); + Packet->Free(Packet); + return; + } + Packet->MappedHeader = FALSE; + + BytesCopied = CopyPacketToBuffer((PCHAR)Packet->Header, + Packet->NdisPacket, + Packet->Position, + sizeof(ARP_HEADER)); + if (BytesCopied != sizeof(ARP_HEADER)) + { + TI_DbgPrint(DEBUG_ARP, ("Unable to copy in header buffer\n")); + Packet->Free(Packet); + return; + } + Header = (PARP_HEADER)Packet->Header; /* FIXME: Ethernet only */ if (WN2H(Header->HWType) != 1) { TI_DbgPrint(DEBUG_ARP, ("Unknown ARP hardware type (0x%X).\n", WN2H(Header->HWType))); + Packet->Free(Packet); return; } /* Check protocol type */ if (Header->ProtoType != ETYPE_IPv4) { TI_DbgPrint(DEBUG_ARP, ("Unknown ARP protocol type (0x%X).\n", WN2H(Header->ProtoType))); + Packet->Free(Packet); return; } - SenderHWAddress = (PVOID)((ULONG_PTR)Header + sizeof(ARP_HEADER)); - SenderProtoAddress = (PVOID)((ULONG_PTR)SenderHWAddress + Header->HWAddrLen); - TargetProtoAddress = (PVOID)((ULONG_PTR)SenderProtoAddress + Header->ProtoAddrLen + Header->HWAddrLen); + DataSize = (2 * Header->HWAddrLen) + (2 * Header->ProtoAddrLen); + DataBuffer = ExAllocatePool(PagedPool, + DataSize); + if (!DataBuffer) + { + TI_DbgPrint(DEBUG_ARP, ("Unable to allocate data buffer\n")); + Packet->Free(Packet); + return; + } + + BytesCopied = CopyPacketToBuffer(DataBuffer, + Packet->NdisPacket, + Packet->Position + sizeof(ARP_HEADER), + DataSize); + if (BytesCopied != DataSize) + { + TI_DbgPrint(DEBUG_ARP, ("Unable to copy in data buffer\n")); + ExFreePool(DataBuffer); + Packet->Free(Packet); + return; + } + + SenderHWAddress = (PVOID)(DataBuffer); + SenderProtoAddress = (PVOID)(SenderHWAddress + Header->HWAddrLen); + TargetProtoAddress = (PVOID)(SenderProtoAddress + Header->ProtoAddrLen + Header->HWAddrLen); AddrInitIPv4(&DstAddress, *((PULONG)TargetProtoAddress)); if (!AddrIsEqual(&DstAddress, &Interface->Unicast)) + { + ExFreePool(DataBuffer); + Packet->Free(Packet); return; + } AddrInitIPv4(&SrcAddress, *((PULONG)SenderProtoAddress)); @@ -233,7 +285,11 @@ VOID ARPReceive( } if (Header->Opcode != ARP_OPCODE_REQUEST) + { + ExFreePool(DataBuffer); + Packet->Free(Packet); return; + } /* This is a request for our address. Swap the addresses and send an ARP reply back to the sender */ @@ -257,6 +313,7 @@ VOID ARPReceive( LAN_PROTO_ARP); } + ExFreePool(DataBuffer); Packet->Free(Packet); } diff --git a/reactos/lib/drivers/ip/network/icmp.c b/reactos/lib/drivers/ip/network/icmp.c index 6fdc69c8513..5af80866784 100644 --- a/reactos/lib/drivers/ip/network/icmp.c +++ b/reactos/lib/drivers/ip/network/icmp.c @@ -84,15 +84,16 @@ BOOLEAN PrepareICMPPacket( if( !NT_SUCCESS(NdisStatus) ) return FALSE; IPPacket->NdisPacket = NdisPacket; + IPPacket->MappedHeader = TRUE; GetDataPtr( IPPacket->NdisPacket, 0, - (PCHAR *)&IPPacket->Header, &IPPacket->ContigSize ); + (PCHAR *)&IPPacket->Header, &IPPacket->TotalSize ); + ASSERT(IPPacket->TotalSize == Size); TI_DbgPrint(DEBUG_ICMP, ("Size (%d). Data at (0x%X).\n", Size, Data)); TI_DbgPrint(DEBUG_ICMP, ("NdisPacket at (0x%X).\n", NdisPacket)); IPPacket->HeaderSize = sizeof(IPv4_HEADER); - IPPacket->TotalSize = Size; IPPacket->Data = ((PCHAR)IPPacket->Header) + IPPacket->HeaderSize; TI_DbgPrint(DEBUG_ICMP, ("Copying Address: %x -> %x\n", @@ -135,11 +136,6 @@ BOOLEAN PrepareICMPPacket( return TRUE; } -VOID ICMPSendPacketComplete -( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status ) { - FreeNdisPacket( Packet ); -} - NTSTATUS ICMPSendDatagram( PADDRESS_FILE AddrFile, PTDI_CONNECTION_INFORMATION ConnInfo, @@ -192,8 +188,8 @@ NTSTATUS ICMPSendDatagram( */ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - UnlockObject(AddrFile, OldIrql); - return STATUS_NETWORK_UNREACHABLE; + UnlockObject(AddrFile, OldIrql); + return STATUS_NETWORK_UNREACHABLE; } LocalAddress = NCE->Interface->Unicast; @@ -202,8 +198,8 @@ NTSTATUS ICMPSendDatagram( { if(!(NCE = NBLocateNeighbor( &LocalAddress ))) { - UnlockObject(AddrFile, OldIrql); - return STATUS_INVALID_PARAMETER; + UnlockObject(AddrFile, OldIrql); + return STATUS_INVALID_PARAMETER; } } @@ -217,14 +213,16 @@ NTSTATUS ICMPSendDatagram( UnlockObject(AddrFile, OldIrql); if( !NT_SUCCESS(Status) ) - return Status; + return Status; TI_DbgPrint(MID_TRACE,("About to send datagram\n")); Status = IPSendDatagram(&Packet, NCE); - FreeNdisPacket(Packet.NdisPacket); if (!NT_SUCCESS(Status)) + { + Packet.Free(&Packet); return Status; + } *DataUsed = DataSize; @@ -234,7 +232,6 @@ NTSTATUS ICMPSendDatagram( } - VOID ICMPReceive( PIP_INTERFACE Interface, PIP_PACKET IPPacket) @@ -261,8 +258,6 @@ VOID ICMPReceive( TI_DbgPrint(DEBUG_ICMP, ("Checksum (0x%X).\n", ICMPHeader->Checksum)); - RawIpReceive(Interface, IPPacket); - /* Checksum ICMP header and data */ if (!IPv4CorrectChecksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize)) { TI_DbgPrint(DEBUG_ICMP, ("Bad ICMP checksum.\n")); @@ -270,20 +265,22 @@ VOID ICMPReceive( return; } + RawIpReceive(Interface, IPPacket); + switch (ICMPHeader->Type) { - case ICMP_TYPE_ECHO_REQUEST: - ICMPReply( Interface, IPPacket, ICMP_TYPE_ECHO_REPLY, 0 ); - return; + case ICMP_TYPE_ECHO_REQUEST: + ICMPReply( Interface, IPPacket, ICMP_TYPE_ECHO_REPLY, 0 ); + break; - case ICMP_TYPE_ECHO_REPLY: - break; + case ICMP_TYPE_ECHO_REPLY: + break; - default: - TI_DbgPrint(DEBUG_ICMP, - ("Discarded ICMP datagram of unknown type %d.\n", - ICMPHeader->Type)); - /* Discard packet */ - break; + default: + TI_DbgPrint(DEBUG_ICMP, + ("Discarded ICMP datagram of unknown type %d.\n", + ICMPHeader->Type)); + /* Discard packet */ + break; } } @@ -300,7 +297,6 @@ VOID ICMPTransmit( */ { PNEIGHBOR_CACHE_ENTRY NCE; - NTSTATUS Status; TI_DbgPrint(DEBUG_ICMP, ("Called.\n")); @@ -311,14 +307,12 @@ VOID ICMPTransmit( /* Get a route to the destination address */ if ((NCE = RouteGetRouteToDestination(&IPPacket->DstAddr))) { /* Send the packet */ - Status = IPSendDatagram(IPPacket, NCE); - Complete(Context, IPPacket->NdisPacket, Status); + IPSendDatagram(IPPacket, NCE); } else { /* No route to destination (or no free resources) */ TI_DbgPrint(DEBUG_ICMP, ("No route to destination address 0x%X.\n", - IPPacket->DstAddr.Address.IPv4Address)); - /* Discard packet */ - Complete( Context, IPPacket->NdisPacket, NDIS_STATUS_NOT_ACCEPTED ); + IPPacket->DstAddr.Address.IPv4Address)); + IPPacket->Free(IPPacket); } } @@ -343,7 +337,7 @@ VOID ICMPReply( */ { UINT DataSize; - IP_PACKET NewPacket = *IPPacket; + IP_PACKET NewPacket; TI_DbgPrint(DEBUG_ICMP, ("Called. Type (%d) Code (%d).\n", Type, Code)); @@ -356,7 +350,7 @@ VOID ICMPReply( ((PICMP_HEADER)NewPacket.Data)->Code = Code; ((PICMP_HEADER)NewPacket.Data)->Checksum = 0; - ICMPTransmit(&NewPacket, SendICMPComplete, NULL); + ICMPTransmit(&NewPacket, NULL, NULL); } /* EOF */ diff --git a/reactos/lib/drivers/ip/network/ip.c b/reactos/lib/drivers/ip/network/ip.c index 89f981759b6..79ccacff26c 100644 --- a/reactos/lib/drivers/ip/network/ip.c +++ b/reactos/lib/drivers/ip/network/ip.c @@ -40,12 +40,40 @@ VOID DeinitializePacket( { PIP_PACKET IPPacket = Object; + TI_DbgPrint(MAX_TRACE, ("Freeing object: 0x%p\n", Object)); + /* Detect double free */ ASSERT(IPPacket->Type != 0xFF); IPPacket->Type = 0xFF; + /* Check if there's a packet to free */ if (IPPacket->NdisPacket != NULL) - FreeNdisPacket(IPPacket->NdisPacket); + { + if (IPPacket->ReturnPacket) + { + /* Return the packet to the miniport driver */ + TI_DbgPrint(MAX_TRACE, ("Returning packet 0x%p\n", + IPPacket->NdisPacket)); + NdisReturnPackets(&IPPacket->NdisPacket, 1); + } + else + { + /* Free it the conventional way */ + TI_DbgPrint(MAX_TRACE, ("Freeing packet 0x%p\n", + IPPacket->NdisPacket)); + FreeNdisPacket(IPPacket->NdisPacket); + } + } + + /* Check if we have a pool-allocated header */ + if (!IPPacket->MappedHeader && IPPacket->Header) + { + /* Free it */ + TI_DbgPrint(MAX_TRACE, ("Freeing header: 0x%p\n", + IPPacket->Header)); + ExFreePoolWithTag(IPPacket->Header, + PACKET_BUFFER_TAG); + } } VOID FreeIF( diff --git a/reactos/lib/drivers/ip/network/loopback.c b/reactos/lib/drivers/ip/network/loopback.c index ae9b32998f3..0bf62fd509d 100644 --- a/reactos/lib/drivers/ip/network/loopback.c +++ b/reactos/lib/drivers/ip/network/loopback.c @@ -44,7 +44,6 @@ VOID LoopTransmit( PNDIS_PACKET XmitPacket; NDIS_STATUS NdisStatus; PIP_PACKET IPPacket; - PNDIS_BUFFER NdisBuffer; ASSERT_KM_POINTER(NdisPacket); ASSERT_KM_POINTER(PC(NdisPacket)); @@ -65,11 +64,12 @@ VOID LoopTransmit( IPPacket->NdisPacket = XmitPacket; - NdisGetFirstBufferFromPacket(XmitPacket, - &NdisBuffer, - &IPPacket->Header, - &IPPacket->ContigSize, - &IPPacket->TotalSize); + GetDataPtr(IPPacket->NdisPacket, + 0, + (PCHAR*)&IPPacket->Header, + &IPPacket->TotalSize); + + IPPacket->MappedHeader = TRUE; if (!ChewCreate(LoopPassiveWorker, IPPacket)) { diff --git a/reactos/lib/drivers/ip/network/receive.c b/reactos/lib/drivers/ip/network/receive.c index d103d7bccdc..3273e272ac3 100644 --- a/reactos/lib/drivers/ip/network/receive.c +++ b/reactos/lib/drivers/ip/network/receive.c @@ -92,7 +92,14 @@ VOID FreeIPDR( TI_DbgPrint(DEBUG_IP, ("Freeing fragment packet at (0x%X).\n", CurrentF->Packet)); /* Free the fragment data buffer */ - FreeNdisPacket(CurrentF->Packet); + if (CurrentF->ReturnPacket) + { + NdisReturnPackets(&CurrentF->Packet, 1); + } + else + { + FreeNdisPacket(CurrentF->Packet); + } TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF)); @@ -189,27 +196,29 @@ ReassembleDatagram( PIP_FRAGMENT Fragment; PCHAR Data; + PAGED_CODE(); + TI_DbgPrint(DEBUG_IP, ("Reassembling datagram from IPDR at (0x%X).\n", IPDR)); TI_DbgPrint(DEBUG_IP, ("IPDR->HeaderSize = %d\n", IPDR->HeaderSize)); TI_DbgPrint(DEBUG_IP, ("IPDR->DataSize = %d\n", IPDR->DataSize)); IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize; - IPPacket->ContigSize = IPPacket->TotalSize; IPPacket->HeaderSize = IPDR->HeaderSize; RtlCopyMemory(&IPPacket->SrcAddr, &IPDR->SrcAddr, sizeof(IP_ADDRESS)); RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS)); /* Allocate space for full IP datagram */ - IPPacket->Header = ExAllocatePoolWithTag(NonPagedPool, IPPacket->TotalSize, PACKET_BUFFER_TAG); + IPPacket->Header = ExAllocatePoolWithTag(PagedPool, IPPacket->TotalSize, PACKET_BUFFER_TAG); if (!IPPacket->Header) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); (*IPPacket->Free)(IPPacket); return FALSE; } + IPPacket->MappedHeader = FALSE; /* Copy the header into the buffer */ - RtlCopyMemory(IPPacket->Header, &IPDR->IPv4Header, IPDR->HeaderSize); + RtlCopyMemory(IPPacket->Header, &IPDR->IPv4Header, sizeof(IPDR->IPv4Header)); Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPDR->HeaderSize); IPPacket->Data = Data; @@ -388,8 +397,8 @@ VOID ProcessFragment( TI_DbgPrint(DEBUG_IP, ("First fragment found. Header buffer is at (0x%X). " "Header size is (%d).\n", &IPDR->IPv4Header, IPPacket->HeaderSize)); - RtlCopyMemory(&IPDR->IPv4Header, IPPacket->Header, IPPacket->HeaderSize); - IPDR->HeaderSize = IPPacket->HeaderSize; + RtlCopyMemory(&IPDR->IPv4Header, IPPacket->Header, sizeof(IPDR->IPv4Header)); + IPDR->HeaderSize = sizeof(IPDR->IPv4Header); } /* Create a buffer, copy the data into it and put it @@ -406,6 +415,7 @@ VOID ProcessFragment( Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize; Fragment->Packet = IPPacket->NdisPacket; + Fragment->ReturnPacket = IPPacket->ReturnPacket; Fragment->PacketOffset = IPPacket->Position + IPPacket->HeaderSize; Fragment->Offset = FragFirst; @@ -428,15 +438,15 @@ VOID ProcessFragment( Assemble the datagram and pass it to an upper layer protocol */ TI_DbgPrint(DEBUG_IP, ("Complete datagram received.\n")); + + RemoveIPDR(IPDR); + TcpipReleaseSpinLock(&IPDR->Lock, OldIrql); /* FIXME: Assumes IPv4 */ IPInitializePacket(&Datagram, IP_ADDRESS_V4); Success = ReassembleDatagram(&Datagram, IPDR); - RemoveIPDR(IPDR); - TcpipReleaseSpinLock(&IPDR->Lock, OldIrql); - FreeIPDR(IPDR); if (!Success) @@ -448,12 +458,9 @@ VOID ProcessFragment( /* Give the packet to the protocol dispatcher */ IPDispatchProtocol(IF, &Datagram); - IF->Stats.InBytes += Datagram.TotalSize; - /* We're done with this datagram */ - ExFreePoolWithTag(Datagram.Header, PACKET_BUFFER_TAG); TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram)); - (*Datagram.Free)(&Datagram); + Datagram.Free(&Datagram); } else TcpipReleaseSpinLock(&IPDR->Lock, OldIrql); } @@ -535,69 +542,78 @@ VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket) * IPPacket = Pointer to IP packet */ { + UCHAR FirstByte; + ULONG BytesCopied; + TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n")); + + /* Read in the first IP header byte for size information */ + BytesCopied = CopyPacketToBuffer((PCHAR)&FirstByte, + IPPacket->NdisPacket, + IPPacket->Position, + sizeof(UCHAR)); + if (BytesCopied != sizeof(UCHAR)) + { + TI_DbgPrint(MIN_TRACE, ("Failed to copy in first byte\n")); + /* Discard packet */ + return; + } - IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2; + IPPacket->HeaderSize = (FirstByte & 0x0F) << 2; TI_DbgPrint(DEBUG_IP, ("IPPacket->HeaderSize = %d\n", IPPacket->HeaderSize)); if (IPPacket->HeaderSize > IPv4_MAX_HEADER_SIZE) { - TI_DbgPrint - (MIN_TRACE, - ("Datagram received with incorrect header size (%d).\n", + TI_DbgPrint(MIN_TRACE, ("Datagram received with incorrect header size (%d).\n", IPPacket->HeaderSize)); - /* Discard packet */ - return; + /* Discard packet */ + return; + } + + /* This is freed by IPPacket->Free() */ + IPPacket->Header = ExAllocatePoolWithTag(NonPagedPool, + IPPacket->HeaderSize, + PACKET_BUFFER_TAG); + if (!IPPacket->Header) + { + TI_DbgPrint(MIN_TRACE, ("No resources to allocate header\n")); + /* Discard packet */ + return; + } + + IPPacket->MappedHeader = FALSE; + + BytesCopied = CopyPacketToBuffer((PCHAR)IPPacket->Header, + IPPacket->NdisPacket, + IPPacket->Position, + IPPacket->HeaderSize); + if (BytesCopied != IPPacket->HeaderSize) + { + TI_DbgPrint(MIN_TRACE, ("Failed to copy in header\n")); + /* Discard packet */ + return; } /* Checksum IPv4 header */ if (!IPv4CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) { - TI_DbgPrint - (MIN_TRACE, - ("Datagram received with bad checksum. Checksum field (0x%X)\n", + TI_DbgPrint(MIN_TRACE, ("Datagram received with bad checksum. Checksum field (0x%X)\n", WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum))); - /* Discard packet */ - return; + /* Discard packet */ + return; } IPPacket->TotalSize = WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength); AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr); AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr); - - IPPacket->Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize); - + TI_DbgPrint(MID_TRACE,("IPPacket->Position = %d\n", - IPPacket->Position)); - - //OskitDumpBuffer(IPPacket->Header, IPPacket->TotalSize); + IPPacket->Position)); /* FIXME: Possibly forward packets with multicast addresses */ /* FIXME: Should we allow packets to be received on the wrong interface? */ /* XXX Find out if this packet is destined for us */ ProcessFragment(IF, IPPacket); -#if 0 - } else { - /* This packet is not destined for us. If we are a router, - try to find a route and forward the packet */ - - /* FIXME: Check if acting as a router */ - NCE = NULL; - if (NCE) { - PROUTE_CACHE_NODE RCN; - - /* FIXME: Possibly fragment datagram */ - /* Forward the packet */ - 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)); - - /* FIXME: Send ICMP error code */ - } - } -#endif } @@ -609,26 +625,39 @@ VOID IPReceive( PIP_INTERFACE IF, PIP_PACKET IPPacket ) * IPPacket = Pointer to IP packet */ { - UINT Version; - - /* Check that IP header has a supported version */ - Version = (((PIPv4_HEADER)IPPacket->Header)->VerIHL >> 4); + UCHAR FirstByte; + UINT Version, BytesCopied; + + /* Read in the first IP header byte for version information */ + BytesCopied = CopyPacketToBuffer((PCHAR)&FirstByte, + IPPacket->NdisPacket, + IPPacket->Position, + sizeof(UCHAR)); + if (BytesCopied != sizeof(UCHAR)) + { + TI_DbgPrint(MIN_TRACE, ("Failed to copy in first byte\n")); + IPPacket->Free(IPPacket); + return; + } - switch (Version) { - case 4: - IPPacket->Type = IP_ADDRESS_V4; - IPv4Receive(IF, IPPacket); - break; - case 6: - IPPacket->Type = IP_ADDRESS_V6; - TI_DbgPrint(MAX_TRACE, ("Datagram of type IPv6 discarded.\n")); - break; - default: - TI_DbgPrint(MIN_TRACE, ("Datagram has an unsupported IP version %d.\n", Version)); - break; - } + /* Check that IP header has a supported version */ + Version = (FirstByte >> 4); + + switch (Version) { + case 4: + IPPacket->Type = IP_ADDRESS_V4; + IPv4Receive(IF, IPPacket); + break; + case 6: + IPPacket->Type = IP_ADDRESS_V6; + TI_DbgPrint(MAX_TRACE, ("Datagram of type IPv6 discarded.\n")); + break; + default: + TI_DbgPrint(MIN_TRACE, ("Datagram has an unsupported IP version %d.\n", Version)); + break; + } - IPPacket->Free(IPPacket); + IPPacket->Free(IPPacket); } /* EOF */ diff --git a/reactos/lib/drivers/ip/network/router.c b/reactos/lib/drivers/ip/network/router.c index 3dac6cbda1b..46f6795490c 100644 --- a/reactos/lib/drivers/ip/network/router.c +++ b/reactos/lib/drivers/ip/network/router.c @@ -382,8 +382,8 @@ NTSTATUS RouterRemoveRoute(PIP_ADDRESS Target, PIP_ADDRESS Router) } if( Found ) { - TI_DbgPrint(DEBUG_ROUTER, ("Deleting route\n")); - DestroyFIBE( Current ); + TI_DbgPrint(DEBUG_ROUTER, ("Deleting route\n")); + DestroyFIBE( Current ); } RouterDumpRoutes(); @@ -427,18 +427,18 @@ PFIB_ENTRY RouterCreateRoute( CurrentEntry = FIBListHead.Flink; while (CurrentEntry != &FIBListHead) { NextEntry = CurrentEntry->Flink; - Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); + Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry); NCE = Current->Router; - if( AddrIsEqual(NetworkAddress, &Current->NetworkAddress) && - AddrIsEqual(Netmask, &Current->Netmask) ) { - TI_DbgPrint(DEBUG_ROUTER,("Attempting to add duplicate route to %s\n", A2S(NetworkAddress))); - TcpipReleaseSpinLock(&FIBLock, OldIrql); - return NULL; - } + if( AddrIsEqual(NetworkAddress, &Current->NetworkAddress) && + AddrIsEqual(Netmask, &Current->Netmask) ) { + TI_DbgPrint(DEBUG_ROUTER,("Attempting to add duplicate route to %s\n", A2S(NetworkAddress))); + TcpipReleaseSpinLock(&FIBLock, OldIrql); + return NULL; + } - CurrentEntry = NextEntry; + CurrentEntry = NextEntry; } TcpipReleaseSpinLock(&FIBLock, OldIrql); diff --git a/reactos/lib/drivers/ip/network/routines.c b/reactos/lib/drivers/ip/network/routines.c index db32eee6207..48af20b210d 100644 --- a/reactos/lib/drivers/ip/network/routines.c +++ b/reactos/lib/drivers/ip/network/routines.c @@ -60,10 +60,7 @@ VOID DisplayIPPacket( PIP_PACKET IPPacket) { #if DBG - PCHAR p; UINT Length; - PNDIS_BUFFER Buffer; - PNDIS_BUFFER NextBuffer; PCHAR CharBuffer; if ((DbgQueryDebugFilterState(DPFLTR_TCPIP_ID, DEBUG_PBUFFER | DPFLTR_MASK) != TRUE) || @@ -76,28 +73,14 @@ VOID DisplayIPPacket( return; } - TI_DbgPrint(MIN_TRACE, ("IPPacket is at (0x%X).\n", IPPacket)); + TI_DbgPrint(MIN_TRACE, ("IPPacket is at (0x%X).\n", IPPacket)); TI_DbgPrint(MIN_TRACE, ("Header buffer is at (0x%X).\n", IPPacket->Header)); TI_DbgPrint(MIN_TRACE, ("Header size is (%d).\n", IPPacket->HeaderSize)); TI_DbgPrint(MIN_TRACE, ("TotalSize (%d).\n", IPPacket->TotalSize)); - TI_DbgPrint(MIN_TRACE, ("ContigSize (%d).\n", IPPacket->ContigSize)); TI_DbgPrint(MIN_TRACE, ("NdisPacket (0x%X).\n", IPPacket->NdisPacket)); - if (IPPacket->NdisPacket) { - NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, &Buffer, NULL); - for (; Buffer != NULL; Buffer = NextBuffer) { - NdisGetNextBuffer(Buffer, &NextBuffer); - NdisQueryBuffer(Buffer, (PVOID)&p, &Length); - //OskitDumpBuffer( p, Length ); - } - } else { - p = IPPacket->Header; - Length = IPPacket->ContigSize; - //OskitDumpBuffer( p, Length ); - } - CharBuffer = IPPacket->Header; - Length = IPPacket->ContigSize; + Length = IPPacket->HeaderSize; DisplayIPHeader(CharBuffer, Length); #endif } diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index f2a6edb0545..78fa43b8cae 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -155,22 +155,26 @@ NTSTATUS SendFragments( IPPacket, NCE, PathMTU)); /* Make a smaller buffer if we will only send one fragment */ - GetDataPtr( IPPacket->NdisPacket, 0, &InData, &InSize ); + GetDataPtr( IPPacket->NdisPacket, IPPacket->Position, &InData, &InSize ); if( InSize < BufferSize ) BufferSize = InSize; TI_DbgPrint(MAX_TRACE, ("Fragment buffer is %d bytes\n", BufferSize)); IFC = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT), IFC_TAG); if (IFC == NULL) + { + IPPacket->Free(IPPacket); return STATUS_INSUFFICIENT_RESOURCES; + } /* Allocate NDIS packet */ NdisStatus = AllocatePacketWithBuffer ( &IFC->NdisPacket, NULL, BufferSize ); if( !NT_SUCCESS(NdisStatus) ) { - ExFreePoolWithTag( IFC, IFC_TAG ); - return NdisStatus; + IPPacket->Free(IPPacket); + ExFreePoolWithTag( IFC, IFC_TAG ); + return NdisStatus; } GetDataPtr( IFC->NdisPacket, 0, (PCHAR *)&Data, &InSize ); @@ -211,6 +215,7 @@ NTSTATUS SendFragments( FreeNdisPacket(IFC->NdisPacket); ExFreePoolWithTag(IFC, IFC_TAG); + IPPacket->Free(IPPacket); return NdisStatus; } @@ -234,16 +239,11 @@ NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE) TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X)\n", IPPacket, NCE)); DISPLAY_IP_PACKET(IPPacket); - /*OskitDumpBuffer( IPPacket->Header, IPPacket->TotalSize );*/ /* Fetch path MTU now, because it may change */ TI_DbgPrint(MID_TRACE,("PathMTU: %d\n", NCE->Interface->MTU)); - NdisQueryPacket(IPPacket->NdisPacket, - NULL, - NULL, - NULL, - &PacketSize); + NdisQueryPacketLength(IPPacket->NdisPacket, &PacketSize); NCE->Interface->Stats.OutBytes += PacketSize; diff --git a/reactos/lib/drivers/ip/transport/rawip/rawip.c b/reactos/lib/drivers/ip/transport/rawip/rawip.c index f2718b90696..f003f6f64d5 100644 --- a/reactos/lib/drivers/ip/transport/rawip/rawip.c +++ b/reactos/lib/drivers/ip/transport/rawip/rawip.c @@ -43,7 +43,8 @@ NTSTATUS AddGenericHeaderIPv4( GetDataPtr( IPPacket->NdisPacket, 0, (PCHAR *)&IPPacket->Header, - &IPPacket->ContigSize ); + &IPPacket->TotalSize ); + IPPacket->MappedHeader = TRUE; IPPacket->HeaderSize = 20; @@ -144,10 +145,10 @@ NTSTATUS BuildRawIpPacket( } if( !NT_SUCCESS(Status) ) { - TI_DbgPrint(MIN_TRACE, ("Cannot add header. Status = (0x%X)\n", - Status)); - FreeNdisPacket(Packet->NdisPacket); - return Status; + TI_DbgPrint(MIN_TRACE, ("Cannot add header. Status = (0x%X)\n", + Status)); + Packet->Free(Packet); + return Status; } TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n", @@ -199,16 +200,16 @@ NTSTATUS RawIPSendDatagram( TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa)); switch( RemoteAddressTa->Address[0].AddressType ) { - case TDI_ADDRESS_TYPE_IP: - RemoteAddress.Type = IP_ADDRESS_V4; - RemoteAddress.Address.IPv4Address = - RemoteAddressTa->Address[0].Address[0].in_addr; - RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port; - break; - - default: - UnlockObject(AddrFile, OldIrql); - return STATUS_UNSUCCESSFUL; + case TDI_ADDRESS_TYPE_IP: + RemoteAddress.Type = IP_ADDRESS_V4; + RemoteAddress.Address.IPv4Address = + RemoteAddressTa->Address[0].Address[0].in_addr; + RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port; + break; + + default: + UnlockObject(AddrFile, OldIrql); + return STATUS_UNSUCCESSFUL; } TI_DbgPrint(MID_TRACE,("About to get route to destination\n")); @@ -221,8 +222,8 @@ NTSTATUS RawIPSendDatagram( * interface we're sending over */ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - UnlockObject(AddrFile, OldIrql); - return STATUS_NETWORK_UNREACHABLE; + UnlockObject(AddrFile, OldIrql); + return STATUS_NETWORK_UNREACHABLE; } LocalAddress = NCE->Interface->Unicast; @@ -230,8 +231,8 @@ NTSTATUS RawIPSendDatagram( else { if(!(NCE = NBLocateNeighbor( &LocalAddress ))) { - UnlockObject(AddrFile, OldIrql); - return STATUS_INVALID_PARAMETER; + UnlockObject(AddrFile, OldIrql); + return STATUS_INVALID_PARAMETER; } } @@ -247,15 +248,17 @@ NTSTATUS RawIPSendDatagram( UnlockObject(AddrFile, OldIrql); if( !NT_SUCCESS(Status) ) - return Status; + return Status; TI_DbgPrint(MID_TRACE,("About to send datagram\n")); Status = IPSendDatagram(&Packet, NCE); - FreeNdisPacket(Packet.NdisPacket); if (!NT_SUCCESS(Status)) + { + Packet.Free(&Packet); return Status; - + } + *DataUsed = DataSize; TI_DbgPrint(MID_TRACE,("Leaving\n")); diff --git a/reactos/lib/drivers/ip/transport/tcp/if.c b/reactos/lib/drivers/ip/transport/tcp/if.c index f8ef99d541b..16c993ba1cb 100644 --- a/reactos/lib/drivers/ip/transport/tcp/if.c +++ b/reactos/lib/drivers/ip/transport/tcp/if.c @@ -12,7 +12,7 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest) { NDIS_STATUS NdisStatus; PNEIGHBOR_CACHE_ENTRY NCE; - IP_PACKET Packet = { 0 }; + IP_PACKET Packet; IP_ADDRESS RemoteAddress, LocalAddress; PIPv4_HEADER Header; @@ -33,6 +33,8 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest) return ERR_IF; } + IPInitializePacket(&Packet, LocalAddress.Type); + if (!(NCE = RouteGetRouteToDestination(&RemoteAddress))) { return ERR_RTE; @@ -43,11 +45,12 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest) { return ERR_MEM; } - - GetDataPtr(Packet.NdisPacket, 0, (PCHAR*)&Packet.Header, &Packet.ContigSize); + + GetDataPtr(Packet.NdisPacket, 0, (PCHAR*)&Packet.Header, &Packet.TotalSize); + Packet.MappedHeader = TRUE; ASSERT(p->tot_len == p->len); - ASSERT(Packet.ContigSize == p->len); + ASSERT(Packet.TotalSize == p->len); RtlCopyMemory(Packet.Header, p->payload, p->len); @@ -57,12 +60,12 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest) Packet.DstAddr = RemoteAddress; NdisStatus = IPSendDatagram(&Packet, NCE); - FreeNdisPacket(Packet.NdisPacket); if (!NT_SUCCESS(NdisStatus)) { + Packet.Free(&Packet); return ERR_RTE; } - + return 0; } diff --git a/reactos/lib/drivers/ip/transport/udp/udp.c b/reactos/lib/drivers/ip/transport/udp/udp.c index dd856ee64b1..a22ff028fa0 100644 --- a/reactos/lib/drivers/ip/transport/udp/udp.c +++ b/reactos/lib/drivers/ip/transport/udp/udp.c @@ -105,33 +105,37 @@ NTSTATUS BuildUDPPacket( Packet->TotalSize = sizeof(IPv4_HEADER) + sizeof(UDP_HEADER) + DataLen; /* Prepare packet */ - Status = AllocatePacketWithBuffer( &Packet->NdisPacket, - NULL, - Packet->TotalSize ); + Status = AllocatePacketWithBuffer(&Packet->NdisPacket, + NULL, + Packet->TotalSize ); - if( !NT_SUCCESS(Status) ) return Status; + if( !NT_SUCCESS(Status) ) + { + Packet->Free(Packet); + return Status; + } TI_DbgPrint(MID_TRACE, ("Allocated packet: %x\n", Packet->NdisPacket)); TI_DbgPrint(MID_TRACE, ("Local Addr : %s\n", A2S(LocalAddress))); TI_DbgPrint(MID_TRACE, ("Remote Addr: %s\n", A2S(RemoteAddress))); switch (RemoteAddress->Type) { - case IP_ADDRESS_V4: - Status = AddUDPHeaderIPv4(AddrFile, RemoteAddress, RemotePort, - LocalAddress, LocalPort, Packet, DataBuffer, DataLen); - break; - case IP_ADDRESS_V6: - /* FIXME: Support IPv6 */ - TI_DbgPrint(MIN_TRACE, ("IPv6 UDP datagrams are not supported.\n")); - default: - Status = STATUS_UNSUCCESSFUL; - break; + case IP_ADDRESS_V4: + Status = AddUDPHeaderIPv4(AddrFile, RemoteAddress, RemotePort, + LocalAddress, LocalPort, Packet, DataBuffer, DataLen); + break; + case IP_ADDRESS_V6: + /* FIXME: Support IPv6 */ + TI_DbgPrint(MIN_TRACE, ("IPv6 UDP datagrams are not supported.\n")); + default: + Status = STATUS_UNSUCCESSFUL; + break; } if (!NT_SUCCESS(Status)) { - TI_DbgPrint(MIN_TRACE, ("Cannot add UDP header. Status = (0x%X)\n", - Status)); - FreeNdisPacket(Packet->NdisPacket); - return Status; + TI_DbgPrint(MIN_TRACE, ("Cannot add UDP header. Status = (0x%X)\n", + Status)); + Packet->Free(Packet); + return Status; } TI_DbgPrint(MID_TRACE, ("Displaying packet\n")); @@ -196,8 +200,8 @@ NTSTATUS UDPSendDatagram( * interface we're sending over */ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - UnlockObject(AddrFile, OldIrql); - return STATUS_NETWORK_UNREACHABLE; + UnlockObject(AddrFile, OldIrql); + return STATUS_NETWORK_UNREACHABLE; } LocalAddress = NCE->Interface->Unicast; @@ -205,8 +209,8 @@ NTSTATUS UDPSendDatagram( else { if(!(NCE = NBLocateNeighbor( &LocalAddress ))) { - UnlockObject(AddrFile, OldIrql); - return STATUS_INVALID_PARAMETER; + UnlockObject(AddrFile, OldIrql); + return STATUS_INVALID_PARAMETER; } } @@ -225,10 +229,12 @@ NTSTATUS UDPSendDatagram( return Status; Status = IPSendDatagram(&Packet, NCE); - FreeNdisPacket(Packet.NdisPacket); if (!NT_SUCCESS(Status)) + { + Packet.Free(&Packet); return Status; - + } + *DataUsed = DataSize; return STATUS_SUCCESS; -- 2.17.1