ReactOS  0.4.13-dev-73-gcfe54aa
receive.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS TCP/IP protocol driver
4  * FILE: network/receive.c
5  * PURPOSE: Internet Protocol receive routines
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * NOTES: The IP datagram reassembly algorithm is taken from
8  * from RFC 815
9  * REVISIONS:
10  * CSH 01/08-2000 Created
11  */
12 
13 #include "precomp.h"
14 
20 
22  ULONG First,
23  ULONG Last)
24 /*
25  * FUNCTION: Returns a pointer to a IP datagram hole descriptor
26  * ARGUMENTS:
27  * First = Offset of first octet of the hole
28  * Last = Offset of last octet of the hole
29  * RETURNS:
30  * Pointer to descriptor, NULL if there was not enough free
31  * resources
32  */
33 {
34  PIPDATAGRAM_HOLE Hole;
35 
36  TI_DbgPrint(DEBUG_IP, ("Called. First (%d) Last (%d).\n", First, Last));
37 
38  Hole = ExAllocateFromNPagedLookasideList(&IPHoleList);
39  if (!Hole) {
40  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
41  return NULL;
42  }
43 
44  Hole->First = First;
45  Hole->Last = Last;
46 
47  TI_DbgPrint(DEBUG_IP, ("Returning hole descriptor at (0x%X).\n", Hole));
48 
49  return Hole;
50 }
51 
52 
55 /*
56  * FUNCTION: Frees an IP datagram reassembly structure
57  * ARGUMENTS:
58  * IPDR = Pointer to IP datagram reassembly structure
59  */
60 {
61  PLIST_ENTRY CurrentEntry;
62  PLIST_ENTRY NextEntry;
63  PIPDATAGRAM_HOLE CurrentH;
64  PIP_FRAGMENT CurrentF;
65 
66  TI_DbgPrint(DEBUG_IP, ("Freeing IP datagram reassembly descriptor (0x%X).\n", IPDR));
67 
68  /* Free all descriptors */
69  CurrentEntry = IPDR->HoleListHead.Flink;
70  while (CurrentEntry != &IPDR->HoleListHead) {
71  NextEntry = CurrentEntry->Flink;
72  CurrentH = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
73  /* Unlink it from the list */
74  RemoveEntryList(CurrentEntry);
75 
76  TI_DbgPrint(DEBUG_IP, ("Freeing hole descriptor at (0x%X).\n", CurrentH));
77 
78  /* And free the hole descriptor */
79  ExFreeToNPagedLookasideList(&IPHoleList, CurrentH);
80 
81  CurrentEntry = NextEntry;
82  }
83 
84  /* Free all fragments */
85  CurrentEntry = IPDR->FragmentListHead.Flink;
86  while (CurrentEntry != &IPDR->FragmentListHead) {
87  NextEntry = CurrentEntry->Flink;
88  CurrentF = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
89  /* Unlink it from the list */
90  RemoveEntryList(CurrentEntry);
91 
92  TI_DbgPrint(DEBUG_IP, ("Freeing fragment packet at (0x%X).\n", CurrentF->Packet));
93 
94  /* Free the fragment data buffer */
95  if (CurrentF->ReturnPacket)
96  {
97  NdisReturnPackets(&CurrentF->Packet, 1);
98  }
99  else
100  {
101  FreeNdisPacket(CurrentF->Packet);
102  }
103 
104  TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF));
105 
106  /* And free the fragment descriptor */
107  ExFreeToNPagedLookasideList(&IPFragmentList, CurrentF);
108  CurrentEntry = NextEntry;
109  }
110 
111  if (IPDR->IPv4Header)
112  {
113  TI_DbgPrint(DEBUG_IP, ("Freeing IPDR header at (0x%X).\n", IPDR->IPv4Header));
115  }
116 
117  TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR));
118 
119  ExFreeToNPagedLookasideList(&IPDRList, IPDR);
120 }
121 
122 
125 /*
126  * FUNCTION: Removes an IP datagram reassembly structure from the global list
127  * ARGUMENTS:
128  * IPDR = Pointer to IP datagram reassembly structure
129  */
130 {
131  KIRQL OldIrql;
132 
133  TI_DbgPrint(DEBUG_IP, ("Removing IPDR at (0x%X).\n", IPDR));
134 
136  RemoveEntryList(&IPDR->ListEntry);
138 }
139 
140 
142  PIP_PACKET IPPacket)
143 /*
144  * FUNCTION: Returns a pointer to an IP datagram reassembly structure
145  * ARGUMENTS:
146  * IPPacket = Pointer to IP packet
147  * NOTES:
148  * A datagram is identified by four paramters, which are
149  * Source and destination address, protocol number and
150  * identification number
151  */
152 {
153  KIRQL OldIrql;
154  PLIST_ENTRY CurrentEntry;
155  PIPDATAGRAM_REASSEMBLY Current;
156  PIPv4_HEADER Header = (PIPv4_HEADER)IPPacket->Header;
157 
158  TI_DbgPrint(DEBUG_IP, ("Searching for IPDR for IP packet at (0x%X).\n", IPPacket));
159 
161 
162  /* FIXME: Assume IPv4 */
163 
164  CurrentEntry = ReassemblyListHead.Flink;
165  while (CurrentEntry != &ReassemblyListHead) {
166  Current = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_REASSEMBLY, ListEntry);
167  if (AddrIsEqual(&IPPacket->SrcAddr, &Current->SrcAddr) &&
168  (Header->Id == Current->Id) &&
169  (Header->Protocol == Current->Protocol) &&
170  (AddrIsEqual(&IPPacket->DstAddr, &Current->DstAddr))) {
172 
173  return Current;
174  }
175  CurrentEntry = CurrentEntry->Flink;
176  }
177 
179 
180  return NULL;
181 }
182 
183 
184 BOOLEAN
186  PIP_PACKET IPPacket,
188 /*
189  * FUNCTION: Reassembles an IP datagram
190  * ARGUMENTS:
191  * IPDR = Pointer to IP datagram reassembly structure
192  * NOTES:
193  * This routine concatenates fragments into a complete IP datagram.
194  * The lock is held when this routine is called
195  * RETURNS:
196  * Pointer to IP packet, NULL if there was not enough free resources
197  * NOTES:
198  * At this point, header is expected to point to the IP header
199  */
200 {
201  PLIST_ENTRY CurrentEntry;
202  PIP_FRAGMENT Fragment;
203  PCHAR Data;
204 
205  PAGED_CODE();
206 
207  TI_DbgPrint(DEBUG_IP, ("Reassembling datagram from IPDR at (0x%X).\n", IPDR));
208  TI_DbgPrint(DEBUG_IP, ("IPDR->HeaderSize = %d\n", IPDR->HeaderSize));
209  TI_DbgPrint(DEBUG_IP, ("IPDR->DataSize = %d\n", IPDR->DataSize));
210 
211  IPPacket->TotalSize = IPDR->HeaderSize + IPDR->DataSize;
212  IPPacket->HeaderSize = IPDR->HeaderSize;
213 
214  RtlCopyMemory(&IPPacket->SrcAddr, &IPDR->SrcAddr, sizeof(IP_ADDRESS));
215  RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS));
216 
217  /* Allocate space for full IP datagram */
219  if (!IPPacket->Header) {
220  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
221  (*IPPacket->Free)(IPPacket);
222  return FALSE;
223  }
224  IPPacket->MappedHeader = FALSE;
225 
226  /* Copy the header into the buffer */
227  RtlCopyMemory(IPPacket->Header, IPDR->IPv4Header, IPDR->HeaderSize);
228 
229  Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPDR->HeaderSize);
230  IPPacket->Data = Data;
231 
232  /* Copy data from all fragments into buffer */
233  CurrentEntry = IPDR->FragmentListHead.Flink;
234  while (CurrentEntry != &IPDR->FragmentListHead) {
235  Fragment = CONTAINING_RECORD(CurrentEntry, IP_FRAGMENT, ListEntry);
236 
237  /* Copy fragment data into datagram buffer */
238  CopyPacketToBuffer(Data + Fragment->Offset,
239  Fragment->Packet,
240  Fragment->PacketOffset,
241  Fragment->Size);
242 
243  CurrentEntry = CurrentEntry->Flink;
244  }
245 
246  return TRUE;
247 }
248 
249 
250 __inline VOID Cleanup(
252  KIRQL OldIrql,
254 /*
255  * FUNCTION: Performs cleaning operations on errors
256  * ARGUMENTS:
257  * Lock = Pointer to spin lock to be released
258  * OldIrql = Value of IRQL when spin lock was acquired
259  * IPDR = Pointer to IP datagram reassembly structure to free
260  * Buffer = Optional pointer to a buffer to free
261  */
262 {
263  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
264 
266  RemoveIPDR(IPDR);
267  FreeIPDR(IPDR);
268 }
269 
270 
272  PIP_INTERFACE IF,
273  PIP_PACKET IPPacket)
274 /*
275  * FUNCTION: Processes an IP datagram or fragment
276  * ARGUMENTS:
277  * IF = Pointer to IP interface packet was receive on
278  * IPPacket = Pointer to IP packet
279  * NOTES:
280  * This routine reassembles fragments and, if a whole datagram can
281  * be assembled, passes the datagram on to the IP protocol dispatcher
282  */
283 {
284  KIRQL OldIrql;
286  PLIST_ENTRY CurrentEntry;
287  PIPDATAGRAM_HOLE Hole, NewHole;
288  USHORT FragFirst;
289  USHORT FragLast;
290  BOOLEAN MoreFragments;
291  PIPv4_HEADER IPv4Header;
292  IP_PACKET Datagram;
293  PIP_FRAGMENT Fragment;
295 
296  /* FIXME: Assume IPv4 */
297 
298  IPv4Header = (PIPv4_HEADER)IPPacket->Header;
299 
300  /* Check if we already have an reassembly structure for this datagram */
301  IPDR = GetReassemblyInfo(IPPacket);
302  if (IPDR) {
303  TI_DbgPrint(DEBUG_IP, ("Continueing assembly.\n"));
304  /* We have a reassembly structure */
306 
307  /* Reset the timeout since we received a fragment */
308  IPDR->TimeoutCount = 0;
309  } else {
310  TI_DbgPrint(DEBUG_IP, ("Starting new assembly.\n"));
311 
312  /* We don't have a reassembly structure, create one */
313  IPDR = ExAllocateFromNPagedLookasideList(&IPDRList);
314  if (!IPDR)
315  /* We don't have the resources to process this packet, discard it */
316  return;
317 
318  /* Create a descriptor spanning from zero to infinity.
319  Actually, we use a value slightly greater than the
320  maximum number of octets an IP datagram can contain */
321  Hole = CreateHoleDescriptor(0, 65536);
322  if (!Hole) {
323  /* We don't have the resources to process this packet, discard it */
324  ExFreeToNPagedLookasideList(&IPDRList, IPDR);
325  return;
326  }
327  AddrInitIPv4(&IPDR->SrcAddr, IPv4Header->SrcAddr);
328  AddrInitIPv4(&IPDR->DstAddr, IPv4Header->DstAddr);
329  IPDR->Id = IPv4Header->Id;
330  IPDR->Protocol = IPv4Header->Protocol;
331  IPDR->TimeoutCount = 0;
334  InsertTailList(&IPDR->HoleListHead, &Hole->ListEntry);
335 
337 
339 
340  /* Update the reassembly list */
343  &IPDR->ListEntry,
345  }
346 
347  FragFirst = (WN2H(IPv4Header->FlagsFragOfs) & IPv4_FRAGOFS_MASK) << 3;
348  FragLast = FragFirst + WN2H(IPv4Header->TotalLength);
349  MoreFragments = (WN2H(IPv4Header->FlagsFragOfs) & IPv4_MF_MASK) > 0;
350 
351  CurrentEntry = IPDR->HoleListHead.Flink;
352  for (;;) {
353  if (CurrentEntry == &IPDR->HoleListHead)
354  break;
355 
356  Hole = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_HOLE, ListEntry);
357 
358  TI_DbgPrint(DEBUG_IP, ("Comparing Fragment (%d,%d) to Hole (%d,%d).\n",
359  FragFirst, FragLast, Hole->First, Hole->Last));
360 
361  if ((FragFirst > Hole->Last) || (FragLast < Hole->First)) {
362  TI_DbgPrint(MID_TRACE, ("No overlap.\n"));
363  /* The fragment does not overlap with the hole, try next
364  descriptor in the list */
365 
366  CurrentEntry = CurrentEntry->Flink;
367  continue;
368  }
369 
370  /* The fragment overlap with the hole, unlink the descriptor */
371  RemoveEntryList(CurrentEntry);
372 
373  if (FragFirst > Hole->First) {
374  NewHole = CreateHoleDescriptor(Hole->First, FragFirst - 1);
375  if (!NewHole) {
376  /* We don't have the resources to process this packet, discard it */
377  ExFreeToNPagedLookasideList(&IPHoleList, Hole);
378  Cleanup(&IPDR->Lock, OldIrql, IPDR);
379  return;
380  }
381 
382  /* Put the new descriptor in the list */
383  InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry);
384  }
385 
386  if ((FragLast < Hole->Last) && MoreFragments) {
387  NewHole = CreateHoleDescriptor(FragLast + 1, Hole->Last);
388  if (!NewHole) {
389  /* We don't have the resources to process this packet, discard it */
390  ExFreeToNPagedLookasideList(&IPHoleList, Hole);
391  Cleanup(&IPDR->Lock, OldIrql, IPDR);
392  return;
393  }
394 
395  /* Put the new hole descriptor in the list */
396  InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry);
397  }
398 
399  ExFreeToNPagedLookasideList(&IPHoleList, Hole);
400 
401  /* If this is the first fragment, save the IP header */
402  if (FragFirst == 0) {
404  IPPacket->HeaderSize,
406  if (!IPDR->IPv4Header)
407  {
408  Cleanup(&IPDR->Lock, OldIrql, IPDR);
409  return;
410  }
411 
412  RtlCopyMemory(IPDR->IPv4Header, IPPacket->Header, IPPacket->HeaderSize);
413  IPDR->HeaderSize = IPPacket->HeaderSize;
414 
415  TI_DbgPrint(DEBUG_IP, ("First fragment found. Header buffer is at (0x%X). "
416  "Header size is (%d).\n", &IPDR->IPv4Header, IPPacket->HeaderSize));
417 
418  }
419 
420  /* Create a buffer, copy the data into it and put it
421  in the fragment list */
422 
423  Fragment = ExAllocateFromNPagedLookasideList(&IPFragmentList);
424  if (!Fragment) {
425  /* We don't have the resources to process this packet, discard it */
426  Cleanup(&IPDR->Lock, OldIrql, IPDR);
427  return;
428  }
429 
430  TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment));
431 
432  Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize;
433  Fragment->Packet = IPPacket->NdisPacket;
434  Fragment->ReturnPacket = IPPacket->ReturnPacket;
435  Fragment->PacketOffset = IPPacket->Position + IPPacket->HeaderSize;
436  Fragment->Offset = FragFirst;
437 
438  /* Disassociate the NDIS packet so it isn't freed upon return from IPReceive() */
439  IPPacket->NdisPacket = NULL;
440 
441  /* If this is the last fragment, compute and save the datagram data size */
442  if (!MoreFragments)
443  IPDR->DataSize = FragFirst + Fragment->Size;
444 
445  /* Put the fragment in the list */
446  InsertTailList(&IPDR->FragmentListHead, &Fragment->ListEntry);
447  break;
448  }
449 
450  TI_DbgPrint(DEBUG_IP, ("Done searching for hole descriptor.\n"));
451 
452  if (IsListEmpty(&IPDR->HoleListHead)) {
453  /* Hole list is empty which means a complete datagram can be assembled.
454  Assemble the datagram and pass it to an upper layer protocol */
455 
456  TI_DbgPrint(DEBUG_IP, ("Complete datagram received.\n"));
457 
458  RemoveIPDR(IPDR);
460 
461  /* FIXME: Assumes IPv4 */
462  IPInitializePacket(&Datagram, IP_ADDRESS_V4);
463 
464  Success = ReassembleDatagram(&Datagram, IPDR);
465 
466  FreeIPDR(IPDR);
467 
468  if (!Success)
469  /* Not enough free resources, discard the packet */
470  return;
471 
472  DISPLAY_IP_PACKET(&Datagram);
473 
474  /* Give the packet to the protocol dispatcher */
475  IPDispatchProtocol(IF, &Datagram);
476 
477  /* We're done with this datagram */
478  TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram));
479  Datagram.Free(&Datagram);
480  } else
482 }
483 
484 
486  VOID)
487 /*
488  * FUNCTION: Frees all IP datagram reassembly structures in the list
489  */
490 {
491  KIRQL OldIrql;
492  PLIST_ENTRY CurrentEntry, NextEntry;
493  PIPDATAGRAM_REASSEMBLY Current;
494 
496 
497  CurrentEntry = ReassemblyListHead.Flink;
498  while (CurrentEntry != &ReassemblyListHead) {
499  NextEntry = CurrentEntry->Flink;
500  Current = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_REASSEMBLY, ListEntry);
501 
502  /* Unlink it from the list */
503  RemoveEntryList(CurrentEntry);
504 
505  /* And free the descriptor */
506  FreeIPDR(Current);
507 
508  CurrentEntry = NextEntry;
509  }
510 
512 }
513 
514 
516  VOID)
517 /*
518  * FUNCTION: IP datagram reassembly timeout handler
519  * NOTES:
520  * This routine is called by IPTimeout to free any resources used
521  * to hold IP fragments that have taken too long to reassemble
522  */
523 {
524  PLIST_ENTRY CurrentEntry, NextEntry;
525  PIPDATAGRAM_REASSEMBLY CurrentIPDR;
526 
528 
529  CurrentEntry = ReassemblyListHead.Flink;
530  while (CurrentEntry != &ReassemblyListHead)
531  {
532  NextEntry = CurrentEntry->Flink;
533  CurrentIPDR = CONTAINING_RECORD(CurrentEntry, IPDATAGRAM_REASSEMBLY, ListEntry);
534 
535  TcpipAcquireSpinLockAtDpcLevel(&CurrentIPDR->Lock);
536 
537  if (++CurrentIPDR->TimeoutCount == MAX_TIMEOUT_COUNT)
538  {
539  TcpipReleaseSpinLockFromDpcLevel(&CurrentIPDR->Lock);
540  RemoveEntryList(CurrentEntry);
541  FreeIPDR(CurrentIPDR);
542  }
543  else
544  {
545  ASSERT(CurrentIPDR->TimeoutCount < MAX_TIMEOUT_COUNT);
546  TcpipReleaseSpinLockFromDpcLevel(&CurrentIPDR->Lock);
547  }
548 
549  CurrentEntry = NextEntry;
550  }
551 
553 }
554 
556 /*
557  * FUNCTION: Receives an IPv4 datagram (or fragment)
558  * ARGUMENTS:
559  * Context = Pointer to context information (IP_INTERFACE)
560  * IPPacket = Pointer to IP packet
561  */
562 {
563  UCHAR FirstByte;
565 
566  TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
567 
568  /* Read in the first IP header byte for size information */
569  BytesCopied = CopyPacketToBuffer((PCHAR)&FirstByte,
570  IPPacket->NdisPacket,
571  IPPacket->Position,
572  sizeof(UCHAR));
573  if (BytesCopied != sizeof(UCHAR))
574  {
575  TI_DbgPrint(MIN_TRACE, ("Failed to copy in first byte\n"));
576  /* Discard packet */
577  return;
578  }
579 
580  IPPacket->HeaderSize = (FirstByte & 0x0F) << 2;
581  TI_DbgPrint(DEBUG_IP, ("IPPacket->HeaderSize = %d\n", IPPacket->HeaderSize));
582 
583  if (IPPacket->HeaderSize > IPv4_MAX_HEADER_SIZE) {
584  TI_DbgPrint(MIN_TRACE, ("Datagram received with incorrect header size (%d).\n",
585  IPPacket->HeaderSize));
586  /* Discard packet */
587  return;
588  }
589 
590  /* This is freed by IPPacket->Free() */
592  IPPacket->HeaderSize,
594  if (!IPPacket->Header)
595  {
596  TI_DbgPrint(MIN_TRACE, ("No resources to allocate header\n"));
597  /* Discard packet */
598  return;
599  }
600 
601  IPPacket->MappedHeader = FALSE;
602 
604  IPPacket->NdisPacket,
605  IPPacket->Position,
606  IPPacket->HeaderSize);
607  if (BytesCopied != IPPacket->HeaderSize)
608  {
609  TI_DbgPrint(MIN_TRACE, ("Failed to copy in header\n"));
610  /* Discard packet */
611  return;
612  }
613 
614  /* Checksum IPv4 header */
615  if (!IPv4CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) {
616  TI_DbgPrint(MIN_TRACE, ("Datagram received with bad checksum. Checksum field (0x%X)\n",
617  WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
618  /* Discard packet */
619  return;
620  }
621 
622  IPPacket->TotalSize = WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength);
623 
624  AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr);
625  AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr);
626 
627  TI_DbgPrint(MID_TRACE,("IPPacket->Position = %d\n",
628  IPPacket->Position));
629 
630  /* FIXME: Possibly forward packets with multicast addresses */
631 
632  /* FIXME: Should we allow packets to be received on the wrong interface? */
633  /* XXX Find out if this packet is destined for us */
634  ProcessFragment(IF, IPPacket);
635 }
636 
637 
639 /*
640  * FUNCTION: Receives an IP datagram (or fragment)
641  * ARGUMENTS:
642  * IF = Interface
643  * IPPacket = Pointer to IP packet
644  */
645 {
646  UCHAR FirstByte;
648 
649  /* Read in the first IP header byte for version information */
650  BytesCopied = CopyPacketToBuffer((PCHAR)&FirstByte,
651  IPPacket->NdisPacket,
652  IPPacket->Position,
653  sizeof(UCHAR));
654  if (BytesCopied != sizeof(UCHAR))
655  {
656  TI_DbgPrint(MIN_TRACE, ("Failed to copy in first byte\n"));
657  IPPacket->Free(IPPacket);
658  return;
659  }
660 
661  /* Check that IP header has a supported version */
662  Version = (FirstByte >> 4);
663 
664  switch (Version) {
665  case 4:
666  IPPacket->Type = IP_ADDRESS_V4;
667  IPv4Receive(IF, IPPacket);
668  break;
669  case 6:
670  IPPacket->Type = IP_ADDRESS_V6;
671  TI_DbgPrint(MAX_TRACE, ("Datagram of type IPv6 discarded.\n"));
672  break;
673  default:
674  TI_DbgPrint(MIN_TRACE, ("Datagram has an unsupported IP version %d.\n", Version));
675  break;
676  }
677 
678  IPPacket->Free(IPPacket);
679 }
680 
681 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
PIP_HEADER IPv4Header
Definition: receive.h:41
VOID IPDispatchProtocol(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
Definition: ip.c:142
UINT Offset
Definition: receive.h:21
#define DISPLAY_IP_PACKET(x)
Definition: routines.h:69
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
#define MID_TRACE
Definition: debug.h:15
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST NPAGED_LOOKASIDE_LIST
UINT Size
Definition: receive.h:22
LIST_ENTRY ReassemblyListHead
Definition: receive.c:15
PNDIS_PACKET Packet
Definition: receive.h:18
LIST_ENTRY HoleListHead
Definition: receive.h:44
IP_ADDRESS SrcAddr
Definition: receive.h:37
IP_ADDRESS SrcAddr
Definition: ip.h:89
UINT PacketOffset
Definition: receive.h:20
USHORT TotalLength
Definition: ip.h:40
#define FreeNdisPacket(x)
Definition: memtrack.h:8
NPAGED_LOOKASIDE_LIST IPHoleList
Definition: receive.c:19
LIST_ENTRY ListEntry
Definition: receive.h:34
KSPIN_LOCK * PKSPIN_LOCK
Definition: env_spec_w32.h:73
VOID IPDatagramReassemblyTimeout(VOID)
Definition: receive.c:515
#define InsertTailList(ListHead, Entry)
OBJECT_FREE_ROUTINE Free
Definition: ip.h:78
VOID TcpipReleaseSpinLock(PKSPIN_LOCK SpinLock, KIRQL Irql)
Definition: lock.c:26
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID TcpipAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL Irql)
Definition: lock.c:18
#define PAGED_CODE()
Definition: video.h:57
#define MAX_TIMEOUT_COUNT
Definition: receive.h:13
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID Data
Definition: ip.h:85
Definition: ip.h:23
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
WCHAR First[]
Definition: FormatMessage.c:11
NPAGED_LOOKASIDE_LIST IPFragmentList
Definition: receive.c:18
UCHAR KIRQL
Definition: env_spec_w32.h:591
USHORT FlagsFragOfs
Definition: ip.h:42
#define IP_ADDRESS_V4
Definition: ip.h:32
Definition: Header.h:8
PIP_PACKET IPInitializePacket(PIP_PACKET IPPacket, ULONG Type)
Definition: ip.c:92
IP_ADDRESS DstAddr
Definition: receive.h:38
PVOID Header
Definition: ip.h:83
unsigned char BOOLEAN
_In_ UINT _In_ UINT _In_ PNDIS_PACKET _In_ UINT _Out_ PUINT BytesCopied
Definition: ndis.h:3149
smooth NULL
Definition: ftsmooth.c:416
VOID IPv4Receive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
Definition: receive.c:555
KSPIN_LOCK ReassemblyListLock
Definition: receive.c:16
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define DEBUG_IP
Definition: debug.h:26
void * PVOID
Definition: retypes.h:9
#define IP_ADDRESS_V6
Definition: ip.h:33
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
LIST_ENTRY ListEntry
Definition: receive.h:27
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
VOID ProcessFragment(PIP_INTERFACE IF, PIP_PACKET IPPacket)
Definition: receive.c:271
VOID RemoveIPDR(PIPDATAGRAM_REASSEMBLY IPDR)
Definition: receive.c:123
#define AddrInitIPv4(IPAddress, RawAddress)
Definition: address.h:16
#define IPv4_MF_MASK
Definition: ip.h:66
UINT Position
Definition: ip.h:87
UINT TotalSize
Definition: ip.h:86
UCHAR Type
Definition: ip.h:79
IPv4_RAW_ADDRESS DstAddr
Definition: ip.h:47
BOOLEAN ReassembleDatagram(PIP_PACKET IPPacket, PIPDATAGRAM_REASSEMBLY IPDR)
Definition: receive.c:185
#define WN2H(w)
Definition: addrconv.c:35
VOID EXPORT NdisReturnPackets(IN PNDIS_PACKET *PacketsToReturn, IN UINT NumberOfPackets)
Definition: miniport.c:257
UCHAR Protocol
Definition: ip.h:44
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID TcpipReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock)
Definition: lock.c:30
UINT HeaderSize
Definition: ip.h:84
NPAGED_LOOKASIDE_LIST IPDRList
Definition: receive.c:17
BOOLEAN AddrIsEqual(PIP_ADDRESS Address1, PIP_ADDRESS Address2)
Definition: address.c:221
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define IPv4_MAX_HEADER_SIZE
Definition: ip.h:68
VOID TcpipInterlockedInsertTailList(PLIST_ENTRY ListHead, PLIST_ENTRY Item, PKSPIN_LOCK Lock)
Definition: lock.c:34
Definition: typedefs.h:117
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
VOID IPFreeReassemblyList(VOID)
Definition: receive.c:485
PIPDATAGRAM_HOLE CreateHoleDescriptor(ULONG First, ULONG Last)
Definition: receive.c:21
PIPDATAGRAM_REASSEMBLY GetReassemblyInfo(PIP_PACKET IPPacket)
Definition: receive.c:141
VOID IPReceive(PIP_INTERFACE IF, PIP_PACKET IPPacket)
Definition: receive.c:638
#define IPv4_FRAGOFS_MASK
Definition: ip.h:65
VOID FreeIPDR(PIPDATAGRAM_REASSEMBLY IPDR)
Definition: receive.c:53
#define MAX_TRACE
Definition: debug.h:16
IPv4_RAW_ADDRESS SrcAddr
Definition: ip.h:46
unsigned short USHORT
Definition: pedump.c:61
UINT CopyPacketToBuffer(PUCHAR DstData, PNDIS_PACKET SrcPacket, UINT SrcOffset, UINT Length)
Definition: buffer.c:170
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
VOID TcpipInitializeSpinLock(PKSPIN_LOCK SpinLock)
Definition: lock.c:14
BOOLEAN ReturnPacket
Definition: ip.h:82
unsigned int UINT
Definition: ndis.h:50
PNDIS_PACKET NdisPacket
Definition: ip.h:88
Definition: ip.h:37
BOOLEAN ReturnPacket
Definition: receive.h:19
LIST_ENTRY FragmentListHead
Definition: receive.h:43
VOID TcpipAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock)
Definition: lock.c:22
BOOLEAN MappedHeader
Definition: ip.h:81
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
IP_ADDRESS DstAddr
Definition: ip.h:90
Definition: ip.h:77
KSPIN_LOCK Lock
Definition: receive.h:35
LIST_ENTRY ListEntry
Definition: receive.h:17
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
USHORT Id
Definition: ip.h:41
struct IPv4_HEADER * PIPv4_HEADER
#define PACKET_BUFFER_TAG
Definition: tags.h:27
__inline VOID Cleanup(PKSPIN_LOCK Lock, KIRQL OldIrql, PIPDATAGRAM_REASSEMBLY IPDR)
Definition: receive.c:250
#define IPv4CorrectChecksum(Data, Count)
Definition: checksum.h:38