mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[TCPIP]
- Massive IPPacket usage overhaul (fix missing frees, initializations, and double frees) - Make IP receive completely agnostic of the buffers and data location (part 2 of 2) - Use paged pool for the majority of allocations during receive and assembly - Implement ProtocolReceivePacket for faster performance with 3rd party NIC drivers - Fix a buffer overflow if an IPv4 packet is received with a header larger than 20 bytes - Many more improvements and bug fixes svn path=/trunk/; revision=54597
This commit is contained in:
parent
fc99fd13d2
commit
b855c23983
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue