- 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
This commit is contained in:
Cameron Gutman 2011-12-05 03:14:50 +00:00
parent fc99fd13d2
commit b855c23983
15 changed files with 465 additions and 300 deletions

View file

@ -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;
TI_DbgPrint(MID_TRACE,
("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
IPPacket.ContigSize, IPPacket.TotalSize,
BytesTransferred));
/* 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;
}
PacketType = PC(IPPacket.NdisPacket)->PacketType;
IPPacket.Position = 0;
/* Data is at the end of the media header */
IPPacket.Position = Adapter->HeaderSize;
/* 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;

View 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 */

View file

@ -10,12 +10,13 @@
#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 */

View 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,

View 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);
}

View 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 */

View 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(

View 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))
{

View 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;
UCHAR FirstByte;
UINT Version, BytesCopied;
/* Check that IP header has a supported version */
Version = (((PIPv4_HEADER)IPPacket->Header)->VerIHL >> 4);
/* 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);
IPPacket->Free(IPPacket);
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);
}
/* EOF */

View 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);

View 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
}

View 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;

View 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;
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;
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"));

View 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;
}

View 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;