- Don't add the media-specific header until right before transmission

- Previously we would store the largest media-specific header size and add that value when creating a packet
 - Makes loopback packets smaller because they have no need for a media-specific header
 - Would fix packet corruption if interfaces with different media-specific headers were installed (if we supported that)
 - Makes adding support for other media types easier

svn path=/trunk/; revision=43287
This commit is contained in:
Cameron Gutman 2009-10-04 19:23:53 +00:00
parent 698c0e253d
commit 6f249378c9
12 changed files with 45 additions and 62 deletions

View file

@ -231,12 +231,7 @@ VOID NTAPI ProtocolSendComplete(
* Status = Status of the operation
*/
{
TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n"));
ASSERT_KM_POINTER(Packet);
ASSERT_KM_POINTER(PC(Packet));
ASSERT_KM_POINTER(PC(Packet)->DLComplete);
(*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
FreeNdisPacket(Packet);
}
VOID LanReceiveWorker( PVOID Context ) {
@ -418,7 +413,7 @@ NDIS_STATUS NTAPI ProtocolReceive(
Adapter, Adapter->MTU));
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL,
PacketSize + HeaderBufferSize );
PacketSize );
if( NdisStatus != NDIS_STATUS_SUCCESS ) {
return NDIS_STATUS_NOT_ACCEPTED;
}
@ -599,18 +594,18 @@ VOID LANTransmit(
{
NDIS_STATUS NdisStatus;
PETH_HEADER EHeader;
PCHAR Data;
UINT Size;
PCHAR Data, OldData;
UINT Size, OldSize;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
KIRQL OldIrql;
UINT PacketLength;
PNDIS_PACKET XmitPacket;
TI_DbgPrint(DEBUG_DATALINK,
("Called( NdisPacket %x, Offset %d, Adapter %x )\n",
NdisPacket, Offset, Adapter));
if (Adapter->State != LAN_STATE_STARTED) {
ProtocolSendComplete(Context, NdisPacket, NDIS_STATUS_NOT_ACCEPTED);
(*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_NOT_ACCEPTED);
return;
}
@ -623,9 +618,19 @@ VOID LANTransmit(
Adapter->HWAddress[4] & 0xff,
Adapter->HWAddress[5] & 0xff));
/* XXX arty -- Handled adjustment in a saner way than before ...
* not needed immediately */
GetDataPtr( NdisPacket, 0, &Data, &Size );
GetDataPtr( NdisPacket, 0, &OldData, &OldSize );
NdisStatus = AllocatePacketWithBuffer(&XmitPacket, NULL, OldSize + Adapter->HeaderSize);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
(*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_RESOURCES);
return;
}
GetDataPtr(XmitPacket, 0, &Data, &Size);
RtlCopyMemory(Data + Adapter->HeaderSize, OldData, OldSize);
(*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_SUCCESS);
switch (Adapter->Media) {
case NdisMedium802_3:
@ -652,14 +657,7 @@ VOID LANTransmit(
EHeader->EType = ETYPE_IPv6;
break;
default:
#if DBG
/* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown LAN protocol.\n"));
ProtocolSendComplete((NDIS_HANDLE)Context,
NdisPacket,
NDIS_STATUS_FAILURE);
#endif
ASSERT(FALSE);
return;
}
break;
@ -682,9 +680,7 @@ VOID LANTransmit(
((PCHAR)LinkAddress)[5] & 0xff));
}
NdisQueryPacketLength(NdisPacket, &PacketLength);
if (Adapter->MTU < PacketLength) {
if (Adapter->MTU < Size) {
/* This is NOT a pointer. MSDN explicitly says so. */
NDIS_PER_PACKET_INFO_FROM_PACKET(NdisPacket,
TcpLargeSendPacketInfo) = (PVOID)((ULONG)Adapter->MTU);
@ -692,7 +688,7 @@ VOID LANTransmit(
TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
TI_DbgPrint(MID_TRACE, ("NdisSend\n"));
NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket);
NdisSend(&NdisStatus, Adapter->NdisHandle, XmitPacket);
TI_DbgPrint(MID_TRACE, ("NdisSend %s\n",
NdisStatus == NDIS_STATUS_PENDING ?
"Pending" : "Complete"));
@ -703,7 +699,7 @@ VOID LANTransmit(
* status_pending is returned. Note that this is different from
* the situation with IRPs. */
if (NdisStatus != NDIS_STATUS_PENDING)
ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NdisStatus);
ProtocolSendComplete((NDIS_HANDLE)Context, XmitPacket, NdisStatus);
}
static NTSTATUS

View file

@ -208,8 +208,6 @@ extern LIST_ENTRY InterfaceListHead;
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY NetTableListHead;
extern KSPIN_LOCK NetTableListLock;
extern UINT MaxLLHeaderSize;
extern UINT MinLLFrameSize;
extern BOOLEAN IpWorkItemQueued;
PIP_PACKET IPCreatePacket(

View file

@ -11,6 +11,7 @@
#include "precomp.h"
PNDIS_PACKET PrepareARPPacket(
PIP_INTERFACE IF,
USHORT HardwareType,
USHORT ProtocolType,
UCHAR LinkAddressLength,
@ -45,11 +46,10 @@ PNDIS_PACKET PrepareARPPacket(
TI_DbgPrint(DEBUG_ARP, ("Called.\n"));
/* Prepare ARP packet */
Size = MaxLLHeaderSize +
sizeof(ARP_HEADER) +
Size = sizeof(ARP_HEADER) +
2 * LinkAddressLength + /* Hardware address length */
2 * ProtoAddressLength; /* Protocol address length */
Size = MAX(Size, MinLLFrameSize);
Size = MAX(Size, IF->MinFrameSize - IF->HeaderSize);
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Size );
if( !NT_SUCCESS(NdisStatus) ) return NULL;
@ -58,7 +58,7 @@ PNDIS_PACKET PrepareARPPacket(
ASSERT(DataBuffer);
RtlZeroMemory(DataBuffer, Size);
Header = (PARP_HEADER)((ULONG_PTR)DataBuffer + MaxLLHeaderSize);
Header = (PARP_HEADER)((ULONG_PTR)DataBuffer);
Header->HWType = HardwareType;
Header->ProtoType = ProtocolType;
Header->HWAddrLen = LinkAddressLength;
@ -145,6 +145,7 @@ BOOLEAN ARPTransmit(PIP_ADDRESS Address, PIP_INTERFACE Interface)
}
NdisPacket = PrepareARPPacket(
Interface,
WN2H(0x0001), /* FIXME: Ethernet only */
ProtoType, /* Protocol type */
(UCHAR)Interface->AddressLength, /* Hardware address length */
@ -164,7 +165,7 @@ BOOLEAN ARPTransmit(PIP_ADDRESS Address, PIP_INTERFACE Interface)
TI_DbgPrint(DEBUG_ARP,("Sending ARP Packet\n"));
(*Interface->Transmit)(Interface->Context, NdisPacket,
MaxLLHeaderSize, NULL, LAN_PROTO_ARP);
0, NULL, LAN_PROTO_ARP);
return TRUE;
}
@ -230,6 +231,7 @@ VOID ARPReceive(
/* This is a request for our address. Swap the addresses and
send an ARP reply back to the sender */
NdisPacket = PrepareARPPacket(
Interface,
Header->HWType, /* Hardware type */
Header->ProtoType, /* Protocol type */
(UCHAR)Interface->AddressLength, /* Hardware address length */
@ -243,7 +245,7 @@ VOID ARPReceive(
PC(NdisPacket)->DLComplete = ARPTransmitComplete;
(*Interface->Transmit)(Interface->Context,
NdisPacket,
MaxLLHeaderSize,
0,
SenderHWAddress,
LAN_PROTO_ARP);
}

View file

@ -75,7 +75,7 @@ BOOLEAN PrepareICMPPacket(
/* No special flags */
IPPacket->Flags = 0;
Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) + DataSize;
Size = sizeof(IPv4_HEADER) + DataSize;
/* Allocate NDIS packet */
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Size );
@ -84,14 +84,14 @@ BOOLEAN PrepareICMPPacket(
IPPacket->NdisPacket = NdisPacket;
GetDataPtr( IPPacket->NdisPacket, MaxLLHeaderSize,
GetDataPtr( IPPacket->NdisPacket, 0,
(PCHAR *)&IPPacket->Header, &IPPacket->ContigSize );
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 - MaxLLHeaderSize;
IPPacket->TotalSize = Size;
IPPacket->Data = ((PCHAR)IPPacket->Header) + IPPacket->HeaderSize;
TI_DbgPrint(DEBUG_ICMP, ("Copying Address: %x -> %x\n",

View file

@ -15,8 +15,6 @@ LIST_ENTRY InterfaceListHead;
KSPIN_LOCK InterfaceListLock;
LIST_ENTRY NetTableListHead;
KSPIN_LOCK NetTableListLock;
UINT MaxLLHeaderSize; /* Largest maximum header size */
UINT MinLLFrameSize; /* Largest minimum frame size */
BOOLEAN IPInitialized = FALSE;
BOOLEAN IpWorkItemQueued = FALSE;
/* Work around calling timer at Dpc level */
@ -153,13 +151,7 @@ PIP_INTERFACE IPCreateInterface(
IF->Free = FreeIF;
IF->Context = BindInfo->Context;
IF->HeaderSize = BindInfo->HeaderSize;
if (IF->HeaderSize > MaxLLHeaderSize)
MaxLLHeaderSize = IF->HeaderSize;
IF->MinFrameSize = BindInfo->MinFrameSize;
if (IF->MinFrameSize > MinLLFrameSize)
MinLLFrameSize = IF->MinFrameSize;
IF->MTU = BindInfo->MTU;
IF->Address = BindInfo->Address;
IF->AddressLength = BindInfo->AddressLength;
@ -361,9 +353,6 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath)
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
MaxLLHeaderSize = 0;
MinLLFrameSize = 0;
/* Initialize lookaside lists */
ExInitializeNPagedLookasideList(
&IPDRList, /* Lookaside list */

View file

@ -41,7 +41,7 @@ VOID LoopTransmit(
TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
GetDataPtr( NdisPacket, MaxLLHeaderSize, &PacketBuffer, &PacketLength );
GetDataPtr( NdisPacket, 0, &PacketBuffer, &PacketLength );
NdisStatus = AllocatePacketWithBuffer
( &XmitPacket, PacketBuffer, PacketLength );

View file

@ -55,7 +55,7 @@ VOID NBSendPackets( PNEIGHBOR_CACHE_ENTRY NCE ) {
NCE->Interface->Transmit
( NCE->Interface->Context,
Packet->Packet,
MaxLLHeaderSize,
0,
NCE->LinkAddress,
LAN_PROTO_IPv4 );
}

View file

@ -115,10 +115,9 @@ VOID DisplayTCPPacket(
if (IPPacket->NdisPacket) {
NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
Length -= MaxLLHeaderSize;
Buffer = exAllocatePool(NonPagedPool, Length);
if (Buffer) {
Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, MaxLLHeaderSize, Length);
Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length);
DisplayTCPHeader(Buffer, Length);
exFreePool(Buffer);
}

View file

@ -166,7 +166,7 @@ NTSTATUS SendFragments(
PIPFRAGMENT_CONTEXT IFC;
NDIS_STATUS NdisStatus;
PVOID Data;
UINT BufferSize = MaxLLHeaderSize + PathMTU, InSize;
UINT BufferSize = PathMTU, InSize;
PCHAR InData;
TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X) PathMTU (%d).\n",
@ -193,7 +193,7 @@ NTSTATUS SendFragments(
GetDataPtr( IFC->NdisPacket, 0, (PCHAR *)&Data, &InSize );
IFC->Header = ((PCHAR)Data) + MaxLLHeaderSize;
IFC->Header = ((PCHAR)Data);
IFC->Datagram = IPPacket->NdisPacket;
IFC->DatagramData = ((PCHAR)IPPacket->Header) + IPPacket->HeaderSize;
IFC->HeaderSize = IPPacket->HeaderSize;

View file

@ -37,10 +37,10 @@ NTSTATUS AddGenericHeaderIPv4(
TI_DbgPrint(MID_TRACE, ("Packet: %x NdisPacket %x\n",
IPPacket, IPPacket->NdisPacket));
BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) + ExtraLength;
BufferSize = sizeof(IPv4_HEADER) + ExtraLength;
GetDataPtr( IPPacket->NdisPacket,
MaxLLHeaderSize,
0,
(PCHAR *)&IPPacket->Header,
&IPPacket->ContigSize );
@ -113,7 +113,7 @@ NTSTATUS BuildRawIpPacket(
/* Prepare packet */
Status = AllocatePacketWithBuffer( &Packet->NdisPacket,
NULL,
Packet->TotalSize + MaxLLHeaderSize );
Packet->TotalSize );
if( !NT_SUCCESS(Status) ) return Status;

View file

@ -86,15 +86,14 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
return OSK_EADDRNOTAVAIL;
}
NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL,
MaxLLHeaderSize + len );
NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL, len );
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_TCP, ("Error from NDIS: %08x\n", NdisStatus));
return OSK_ENOBUFS;
}
GetDataPtr( Packet.NdisPacket, MaxLLHeaderSize,
GetDataPtr( Packet.NdisPacket, 0,
(PCHAR *)&Packet.Header, &Packet.ContigSize );
RtlCopyMemory( Packet.Header, data, len );

View file

@ -94,7 +94,7 @@ NTSTATUS BuildUDPPacket(
/* Prepare packet */
Status = AllocatePacketWithBuffer( &Packet->NdisPacket,
NULL,
Packet->TotalSize + MaxLLHeaderSize );
Packet->TotalSize );
if( !NT_SUCCESS(Status) ) return Status;