[TCPIP]
authorCameron Gutman <aicommander@gmail.com>
Mon, 5 Dec 2011 03:14:50 +0000 (03:14 +0000)
committerCameron Gutman <aicommander@gmail.com>
Mon, 5 Dec 2011 03:14:50 +0000 (03:14 +0000)
- 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

15 files changed:
reactos/drivers/network/tcpip/datalink/lan.c
reactos/drivers/network/tcpip/include/ip.h
reactos/drivers/network/tcpip/include/receive.h
reactos/drivers/network/tcpip/tcpip/buffer.c
reactos/lib/drivers/ip/network/arp.c
reactos/lib/drivers/ip/network/icmp.c
reactos/lib/drivers/ip/network/ip.c
reactos/lib/drivers/ip/network/loopback.c
reactos/lib/drivers/ip/network/receive.c
reactos/lib/drivers/ip/network/router.c
reactos/lib/drivers/ip/network/routines.c
reactos/lib/drivers/ip/network/transmit.c
reactos/lib/drivers/ip/transport/rawip/rawip.c
reactos/lib/drivers/ip/transport/tcp/if.c
reactos/lib/drivers/ip/transport/udp/udp.c

index 5fa298e..90c730e 100644 (file)
 
 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;
index 9564d6f..b448b51 100644 (file)
@@ -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 */
index c63f134..51a8bda 100644 (file)
 #include <ip.h>
 
 /* 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 */
index 6858dde..d23da2c 100644 (file)
@@ -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,
index b24e381..6a7d862 100644 (file)
@@ -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);
 }
 
index 6fdc69c..5af8086 100644 (file)
@@ -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 */
index 89f9817..79ccacf 100644 (file)
@@ -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(
index ae9b329..0bf62fd 100644 (file)
@@ -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))
             {
index d103d7b..3273e27 100644 (file)
@@ -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 */
index 3dac6cb..46f6795 100644 (file)
@@ -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);
index db32eee..48af20b 100644 (file)
@@ -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
 }
index f2a6edb..78fa43b 100644 (file)
@@ -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;
 
index f2718b9..f003f6f 100644 (file)
@@ -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"));
index f8ef99d..16c993b 100644 (file)
@@ -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;
 }
 
index dd856ee..a22ff02 100644 (file)
@@ -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;