TianoCore EDK2 master
Loading...
Searching...
No Matches
Ip4Input.c
Go to the documentation of this file.
1
11#include "Ip4Impl.h"
12
29 IN IP4_ADDR Dst,
30 IN IP4_ADDR Src,
31 IN UINT16 Id,
32 IN UINT8 Protocol
33 )
34{
35 IP4_ASSEMBLE_ENTRY *Assemble;
36
37 Assemble = AllocatePool (sizeof (IP4_ASSEMBLE_ENTRY));
38
39 if (Assemble == NULL) {
40 return NULL;
41 }
42
43 InitializeListHead (&Assemble->Link);
44 InitializeListHead (&Assemble->Fragments);
45
46 Assemble->Dst = Dst;
47 Assemble->Src = Src;
48 Assemble->Id = Id;
49 Assemble->Protocol = Protocol;
50 Assemble->TotalLen = 0;
51 Assemble->CurLen = 0;
52 Assemble->Head = NULL;
53 Assemble->Info = NULL;
54 Assemble->Life = IP4_FRAGMENT_LIFE;
55
56 return Assemble;
57}
58
65VOID
67 IN IP4_ASSEMBLE_ENTRY *Assemble
68 )
69{
70 LIST_ENTRY *Entry;
71 LIST_ENTRY *Next;
72 NET_BUF *Fragment;
73
74 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Assemble->Fragments) {
75 Fragment = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
76
77 RemoveEntryList (Entry);
78 NetbufFree (Fragment);
79 }
80
81 FreePool (Assemble);
82}
83
91VOID
94 )
95{
96 UINT32 Index;
97
98 for (Index = 0; Index < IP4_ASSEMLE_HASH_SIZE; Index++) {
99 InitializeListHead (&Table->Bucket[Index]);
100 }
101}
102
110VOID
113 )
114{
115 LIST_ENTRY *Entry;
116 LIST_ENTRY *Next;
117 IP4_ASSEMBLE_ENTRY *Assemble;
118 UINT32 Index;
119
120 for (Index = 0; Index < IP4_ASSEMLE_HASH_SIZE; Index++) {
121 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Table->Bucket[Index]) {
122 Assemble = NET_LIST_USER_STRUCT (Entry, IP4_ASSEMBLE_ENTRY, Link);
123
124 RemoveEntryList (Entry);
125 Ip4FreeAssembleEntry (Assemble);
126 }
127 }
128}
129
139VOID
141 IN OUT NET_BUF *Packet,
142 IN INTN Start,
143 IN INTN End
144 )
145{
146 IP4_CLIP_INFO *Info;
147 INTN Len;
148
149 Info = IP4_GET_CLIP_INFO (Packet);
150
151 ASSERT (Info->Start + Info->Length == Info->End);
152 ASSERT ((Info->Start < End) && (Start < Info->End));
153
154 if (Info->Start < Start) {
155 Len = Start - Info->Start;
156
157 NetbufTrim (Packet, (UINT32)Len, NET_BUF_HEAD);
158 Info->Start = Start;
159 Info->Length -= Len;
160 }
161
162 if (End < Info->End) {
163 Len = End - Info->End;
164
165 NetbufTrim (Packet, (UINT32)Len, NET_BUF_TAIL);
166 Info->End = End;
167 Info->Length -= Len;
168 }
169}
170
179VOID
180EFIAPI
182 IN VOID *Arg
183 )
184{
186}
187
203NET_BUF *
206 IN OUT NET_BUF *Packet
207 )
208{
209 IP4_HEAD *IpHead;
210 IP4_CLIP_INFO *This;
211 IP4_CLIP_INFO *Node;
212 IP4_ASSEMBLE_ENTRY *Assemble;
213 LIST_ENTRY *Head;
214 LIST_ENTRY *Prev;
215 LIST_ENTRY *Cur;
216 NET_BUF *Fragment;
217 NET_BUF *NewPacket;
218 INTN Index;
219
220 IpHead = Packet->Ip.Ip4;
221 This = IP4_GET_CLIP_INFO (Packet);
222
223 ASSERT (IpHead != NULL);
224
225 //
226 // First: find the related assemble entry
227 //
228 Assemble = NULL;
229 Index = IP4_ASSEMBLE_HASH (IpHead->Dst, IpHead->Src, IpHead->Id, IpHead->Protocol);
230
231 NET_LIST_FOR_EACH (Cur, &Table->Bucket[Index]) {
232 Assemble = NET_LIST_USER_STRUCT (Cur, IP4_ASSEMBLE_ENTRY, Link);
233
234 if ((Assemble->Dst == IpHead->Dst) && (Assemble->Src == IpHead->Src) &&
235 (Assemble->Id == IpHead->Id) && (Assemble->Protocol == IpHead->Protocol))
236 {
237 break;
238 }
239 }
240
241 //
242 // Create a new assemble entry if no assemble entry is related to this packet
243 //
244 if (Cur == &Table->Bucket[Index]) {
245 Assemble = Ip4CreateAssembleEntry (
246 IpHead->Dst,
247 IpHead->Src,
248 IpHead->Id,
249 IpHead->Protocol
250 );
251
252 if (Assemble == NULL) {
253 goto DROP;
254 }
255
256 InsertHeadList (&Table->Bucket[Index], &Assemble->Link);
257 }
258
259 //
260 // Assemble shouldn't be NULL here
261 //
262 ASSERT (Assemble != NULL);
263
264 //
265 // Find the point to insert the packet: before the first
266 // fragment with THIS.Start < CUR.Start. the previous one
267 // has PREV.Start <= THIS.Start < CUR.Start.
268 //
269 Head = &Assemble->Fragments;
270
271 NET_LIST_FOR_EACH (Cur, Head) {
272 Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);
273
274 if (This->Start < IP4_GET_CLIP_INFO (Fragment)->Start) {
275 break;
276 }
277 }
278
279 //
280 // Check whether the current fragment overlaps with the previous one.
281 // It holds that: PREV.Start <= THIS.Start < THIS.End. Only need to
282 // check whether THIS.Start < PREV.End for overlap. If two fragments
283 // overlaps, trim the overlapped part off THIS fragment.
284 //
285 if ((Prev = Cur->BackLink) != Head) {
286 Fragment = NET_LIST_USER_STRUCT (Prev, NET_BUF, List);
287 Node = IP4_GET_CLIP_INFO (Fragment);
288
289 if (This->Start < Node->End) {
290 if (This->End <= Node->End) {
291 NetbufFree (Packet);
292 return NULL;
293 }
294
295 Ip4TrimPacket (Packet, Node->End, This->End);
296 }
297 }
298
299 //
300 // Insert the fragment into the packet. The fragment may be removed
301 // from the list by the following checks.
302 //
303 NetListInsertBefore (Cur, &Packet->List);
304
305 //
306 // Check the packets after the insert point. It holds that:
307 // THIS.Start <= NODE.Start < NODE.End. The equality holds
308 // if PREV and NEXT are continuous. THIS fragment may fill
309 // several holes. Remove the completely overlapped fragments
310 //
311 while (Cur != Head) {
312 Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List);
313 Node = IP4_GET_CLIP_INFO (Fragment);
314
315 //
316 // Remove fragments completely overlapped by this fragment
317 //
318 if (Node->End <= This->End) {
319 Cur = Cur->ForwardLink;
320
321 RemoveEntryList (&Fragment->List);
322 Assemble->CurLen -= Node->Length;
323
324 NetbufFree (Fragment);
325 continue;
326 }
327
328 //
329 // The conditions are: THIS.Start <= NODE.Start, and THIS.End <
330 // NODE.End. Two fragments overlaps if NODE.Start < THIS.End.
331 // If two fragments start at the same offset, remove THIS fragment
332 // because ((THIS.Start == NODE.Start) && (THIS.End < NODE.End)).
333 //
334 if (Node->Start < This->End) {
335 if (This->Start == Node->Start) {
336 RemoveEntryList (&Packet->List);
337 goto DROP;
338 }
339
340 Ip4TrimPacket (Packet, This->Start, Node->Start);
341 }
342
343 break;
344 }
345
346 //
347 // Update the assemble info: increase the current length. If it is
348 // the frist fragment, update the packet's IP head and per packet
349 // info. If it is the last fragment, update the total length.
350 //
351 Assemble->CurLen += This->Length;
352
353 if (This->Start == 0) {
354 //
355 // Once the first fragment is enqueued, it can't be removed
356 // from the fragment list. So, Assemble->Head always point
357 // to valid memory area.
358 //
359 ASSERT (Assemble->Head == NULL);
360
361 Assemble->Head = IpHead;
362 Assemble->Info = IP4_GET_CLIP_INFO (Packet);
363 }
364
365 //
366 // Don't update the length more than once.
367 //
368 if (IP4_LAST_FRAGMENT (IpHead->Fragment) && (Assemble->TotalLen == 0)) {
369 Assemble->TotalLen = This->End;
370 }
371
372 //
373 // Deliver the whole packet if all the fragments received.
374 // All fragments received if:
375 // 1. received the last one, so, the total length is know
376 // 2. received all the data. If the last fragment on the
377 // queue ends at the total length, all data is received.
378 //
379 if ((Assemble->TotalLen != 0) && (Assemble->CurLen >= Assemble->TotalLen)) {
380 RemoveEntryList (&Assemble->Link);
381
382 //
383 // If the packet is properly formatted, the last fragment's End
384 // equals to the packet's total length. Otherwise, the packet
385 // is a fake, drop it now.
386 //
387 Fragment = NET_LIST_USER_STRUCT (Head->BackLink, NET_BUF, List);
388
389 if (IP4_GET_CLIP_INFO (Fragment)->End != Assemble->TotalLen) {
390 Ip4FreeAssembleEntry (Assemble);
391 return NULL;
392 }
393
394 //
395 // Wrap the packet in a net buffer then deliver it up
396 //
397 NewPacket = NetbufFromBufList (
398 &Assemble->Fragments,
399 0,
400 0,
402 Assemble
403 );
404
405 if (NewPacket == NULL) {
406 Ip4FreeAssembleEntry (Assemble);
407 return NULL;
408 }
409
410 NewPacket->Ip.Ip4 = Assemble->Head;
411
412 ASSERT (Assemble->Info != NULL);
413
414 CopyMem (
415 IP4_GET_CLIP_INFO (NewPacket),
416 Assemble->Info,
417 sizeof (*IP4_GET_CLIP_INFO (NewPacket))
418 );
419
420 return NewPacket;
421 }
422
423 return NULL;
424
425DROP:
426 NetbufFree (Packet);
427 return NULL;
428}
429
437VOID
438EFIAPI
440 IN VOID *Arg
441 )
442{
443 IP4_IPSEC_WRAP *Wrap;
444
445 Wrap = (IP4_IPSEC_WRAP *)Arg;
446
447 if (Wrap->IpSecRecycleSignal != NULL) {
448 gBS->SignalEvent (Wrap->IpSecRecycleSignal);
449 }
450
451 NetbufFree (Wrap->Packet);
452
453 FreePool (Wrap);
454
455 return;
456}
457
483 IN IP4_SERVICE *IpSb,
484 IN OUT IP4_HEAD **Head,
485 IN OUT NET_BUF **Netbuf,
486 IN OUT UINT8 **Options,
487 IN OUT UINT32 *OptionsLen,
488 IN EFI_IPSEC_TRAFFIC_DIR Direction,
489 IN VOID *Context
490 )
491{
492 NET_FRAGMENT *FragmentTable;
493 NET_FRAGMENT *OriginalFragmentTable;
494 UINT32 FragmentCount;
495 UINT32 OriginalFragmentCount;
496 EFI_EVENT RecycleEvent;
497 NET_BUF *Packet;
498 IP4_TXTOKEN_WRAP *TxWrap;
499 IP4_IPSEC_WRAP *IpSecWrap;
500 EFI_STATUS Status;
501 IP4_HEAD ZeroHead;
502
503 Status = EFI_SUCCESS;
504
505 if (!mIpSec2Installed) {
506 goto ON_EXIT;
507 }
508
509 ASSERT (mIpSec != NULL);
510
511 Packet = *Netbuf;
512 RecycleEvent = NULL;
513 IpSecWrap = NULL;
514 FragmentTable = NULL;
515 TxWrap = (IP4_TXTOKEN_WRAP *)Context;
516 FragmentCount = Packet->BlockOpNum;
517
518 ZeroMem (&ZeroHead, sizeof (IP4_HEAD));
519
520 //
521 // Check whether the IPsec enable variable is set.
522 //
523 if (mIpSec->DisabledFlag) {
524 //
525 // If IPsec is disabled, restore the original MTU
526 //
527 IpSb->MaxPacketSize = IpSb->OldMaxPacketSize;
528 goto ON_EXIT;
529 } else {
530 //
531 // If IPsec is enabled, use the MTU which reduce the IPsec header length.
532 //
533 IpSb->MaxPacketSize = IpSb->OldMaxPacketSize - IP4_MAX_IPSEC_HEADLEN;
534 }
535
536 //
537 // Rebuild fragment table from netbuf to ease IPsec process.
538 //
539 FragmentTable = AllocateZeroPool (FragmentCount * sizeof (NET_FRAGMENT));
540
541 if (FragmentTable == NULL) {
542 Status = EFI_OUT_OF_RESOURCES;
543 goto ON_EXIT;
544 }
545
546 Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount);
547
548 //
549 // Record the original FragmentTable and count.
550 //
551 OriginalFragmentTable = FragmentTable;
552 OriginalFragmentCount = FragmentCount;
553
554 if (EFI_ERROR (Status)) {
555 FreePool (FragmentTable);
556 goto ON_EXIT;
557 }
558
559 //
560 // Convert host byte order to network byte order
561 //
562 Ip4NtohHead (*Head);
563
564 Status = mIpSec->ProcessExt (
565 mIpSec,
566 IpSb->Controller,
567 IP_VERSION_4,
568 (VOID *)(*Head),
569 &(*Head)->Protocol,
570 (VOID **)Options,
571 OptionsLen,
572 (EFI_IPSEC_FRAGMENT_DATA **)(&FragmentTable),
573 &FragmentCount,
574 Direction,
575 &RecycleEvent
576 );
577 //
578 // Convert back to host byte order
579 //
580 Ip4NtohHead (*Head);
581
582 if (EFI_ERROR (Status)) {
583 FreePool (OriginalFragmentTable);
584 goto ON_EXIT;
585 }
586
587 if ((OriginalFragmentTable == FragmentTable) && (OriginalFragmentCount == FragmentCount)) {
588 //
589 // For ByPass Packet
590 //
591 FreePool (FragmentTable);
592 goto ON_EXIT;
593 } else {
594 //
595 // Free the FragmentTable which allocated before calling the IPsec.
596 //
597 FreePool (OriginalFragmentTable);
598 }
599
600 if ((Direction == EfiIPsecOutBound) && (TxWrap != NULL)) {
601 TxWrap->IpSecRecycleSignal = RecycleEvent;
602 TxWrap->Packet = NetbufFromExt (
603 FragmentTable,
604 FragmentCount,
605 IP4_MAX_HEADLEN,
606 0,
608 TxWrap
609 );
610 if (TxWrap->Packet == NULL) {
611 //
612 // Recover the TxWrap->Packet, if meet a error, and the caller will free
613 // the TxWrap.
614 //
615 TxWrap->Packet = *Netbuf;
616 Status = EFI_OUT_OF_RESOURCES;
617 goto ON_EXIT;
618 }
619
620 //
621 // Free original Netbuf.
622 //
623 NetIpSecNetbufFree (*Netbuf);
624 *Netbuf = TxWrap->Packet;
625 } else {
626 IpSecWrap = AllocateZeroPool (sizeof (IP4_IPSEC_WRAP));
627
628 if (IpSecWrap == NULL) {
629 Status = EFI_OUT_OF_RESOURCES;
630 gBS->SignalEvent (RecycleEvent);
631 goto ON_EXIT;
632 }
633
634 IpSecWrap->IpSecRecycleSignal = RecycleEvent;
635 IpSecWrap->Packet = Packet;
636 Packet = NetbufFromExt (
637 FragmentTable,
638 FragmentCount,
639 IP4_MAX_HEADLEN,
640 0,
642 IpSecWrap
643 );
644
645 if (Packet == NULL) {
646 Packet = IpSecWrap->Packet;
647 gBS->SignalEvent (RecycleEvent);
648 FreePool (IpSecWrap);
649 Status = EFI_OUT_OF_RESOURCES;
650 goto ON_EXIT;
651 }
652
653 if ((Direction == EfiIPsecInBound) && (0 != CompareMem (*Head, &ZeroHead, sizeof (IP4_HEAD)))) {
654 Ip4PrependHead (Packet, *Head, *Options, *OptionsLen);
655 Ip4NtohHead (Packet->Ip.Ip4);
656 NetbufTrim (Packet, ((*Head)->HeadLen << 2), TRUE);
657
658 CopyMem (
659 IP4_GET_CLIP_INFO (Packet),
660 IP4_GET_CLIP_INFO (IpSecWrap->Packet),
661 sizeof (IP4_CLIP_INFO)
662 );
663 }
664
665 *Netbuf = Packet;
666 }
667
668ON_EXIT:
669 return Status;
670}
671
690 IN IP4_SERVICE *IpSb,
691 IN OUT NET_BUF **Packet,
692 IN IP4_HEAD *Head,
693 IN UINT8 *Option,
694 IN UINT32 OptionLen,
695 IN UINT32 Flag
696 )
697{
698 IP4_CLIP_INFO *Info;
699 UINT32 HeadLen;
700 UINT32 TotalLen;
701 UINT16 Checksum;
702
703 //
704 // Check if the IP4 header is correctly formatted.
705 //
706 HeadLen = (Head->HeadLen << 2);
707 TotalLen = NTOHS (Head->TotalLen);
708
709 //
710 // Mnp may deliver frame trailer sequence up, trim it off.
711 //
712 if (TotalLen < (*Packet)->TotalSize) {
713 NetbufTrim (*Packet, (*Packet)->TotalSize - TotalLen, FALSE);
714 }
715
716 if ((Head->Ver != 4) || (HeadLen < IP4_MIN_HEADLEN) ||
717 (TotalLen < HeadLen) || (TotalLen != (*Packet)->TotalSize))
718 {
719 return EFI_INVALID_PARAMETER;
720 }
721
722 //
723 // Some OS may send IP packets without checksum.
724 //
725 Checksum = (UINT16)(~NetblockChecksum ((UINT8 *)Head, HeadLen));
726
727 if ((Head->Checksum != 0) && (Checksum != 0)) {
728 return EFI_INVALID_PARAMETER;
729 }
730
731 //
732 // Convert the IP header to host byte order, then get the per packet info.
733 //
734 (*Packet)->Ip.Ip4 = Ip4NtohHead (Head);
735
736 Info = IP4_GET_CLIP_INFO (*Packet);
737 Info->LinkFlag = Flag;
738 Info->CastType = Ip4GetHostCast (IpSb, Head->Dst, Head->Src);
739 Info->Start = (Head->Fragment & IP4_HEAD_OFFSET_MASK) << 3;
740 Info->Length = Head->TotalLen - HeadLen;
741 Info->End = Info->Start + Info->Length;
742 Info->Status = EFI_SUCCESS;
743
744 //
745 // The packet is destinated to us if the CastType is non-zero.
746 //
747 if ((Info->CastType == 0) || (Info->End > IP4_MAX_PACKET_SIZE)) {
748 return EFI_INVALID_PARAMETER;
749 }
750
751 //
752 // Validate the options. Don't call the Ip4OptionIsValid if
753 // there is no option to save some CPU process.
754 //
755
756 if ((OptionLen > 0) && !Ip4OptionIsValid (Option, OptionLen, TRUE)) {
757 return EFI_INVALID_PARAMETER;
758 }
759
760 //
761 // Trim the head off, after this point, the packet is headless,
762 // and Packet->TotalLen == Info->Length.
763 //
764 NetbufTrim (*Packet, HeadLen, TRUE);
765
766 //
767 // Reassemble the packet if this is a fragment. The packet is a
768 // fragment if its head has MF (more fragment) set, or it starts
769 // at non-zero byte.
770 //
771 if (((Head->Fragment & IP4_HEAD_MF_MASK) != 0) || (Info->Start != 0)) {
772 //
773 // Drop the fragment if DF is set but it is fragmented. Gateway
774 // need to send a type 4 destination unreache ICMP message here.
775 //
776 if ((Head->Fragment & IP4_HEAD_DF_MASK) != 0) {
777 return EFI_INVALID_PARAMETER;
778 }
779
780 //
781 // The length of all but the last fragments is in the unit of 8 bytes.
782 //
783 if (((Head->Fragment & IP4_HEAD_MF_MASK) != 0) && (Info->Length % 8 != 0)) {
784 return EFI_INVALID_PARAMETER;
785 }
786
787 *Packet = Ip4Reassemble (&IpSb->Assemble, *Packet);
788
789 //
790 // Packet assembly isn't complete, start receive more packet.
791 //
792 if (*Packet == NULL) {
793 return EFI_INVALID_PARAMETER;
794 }
795 }
796
797 return EFI_SUCCESS;
798}
799
809BOOLEAN
811 IN NET_BUF *Packet
812 )
813{
814 //
815 // Check the IP4 packet length.
816 //
817 if (Packet->TotalSize < IP4_MIN_HEADLEN) {
818 return FALSE;
819 }
820
821 return TRUE;
822}
823
837VOID
839 IN IP4_PROTOCOL *Ip4Instance,
840 IN NET_BUF *Packet,
841 IN EFI_STATUS IoStatus,
842 IN UINT32 Flag,
843 IN VOID *Context
844 )
845{
846 IP4_SERVICE *IpSb;
847 IP4_HEAD *Head;
848 EFI_STATUS Status;
849 IP4_HEAD ZeroHead;
850 UINT8 *Option;
851 UINT32 OptionLen;
852
853 IpSb = (IP4_SERVICE *)Context;
854 Option = NULL;
855
856 if (EFI_ERROR (IoStatus) || (IpSb->State == IP4_SERVICE_DESTROY)) {
857 goto DROP;
858 }
859
860 if (!Ip4IsValidPacketLength (Packet)) {
861 goto RESTART;
862 }
863
864 Head = (IP4_HEAD *)NetbufGetByte (Packet, 0, NULL);
865 ASSERT (Head != NULL);
866 OptionLen = (Head->HeadLen << 2) - IP4_MIN_HEADLEN;
867 if (OptionLen > 0) {
868 Option = (UINT8 *)(Head + 1);
869 }
870
871 //
872 // Validate packet format and reassemble packet if it is necessary.
873 //
874 Status = Ip4PreProcessPacket (
875 IpSb,
876 &Packet,
877 Head,
878 Option,
879 OptionLen,
880 Flag
881 );
882
883 if (EFI_ERROR (Status)) {
884 goto RESTART;
885 }
886
887 //
888 // After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer,
889 // and no need consider any other ahead ext headers.
890 //
891 Status = Ip4IpSecProcessPacket (
892 IpSb,
893 &Head,
894 &Packet,
895 &Option,
896 &OptionLen,
898 NULL
899 );
900
901 if (EFI_ERROR (Status)) {
902 goto RESTART;
903 }
904
905 //
906 // If the packet is protected by tunnel mode, parse the inner Ip Packet.
907 //
908 ZeroMem (&ZeroHead, sizeof (IP4_HEAD));
909 if (0 == CompareMem (Head, &ZeroHead, sizeof (IP4_HEAD))) {
910 // Packet may have been changed. Head, HeadLen, TotalLen, and
911 // info must be reloaded before use. The ownership of the packet
912 // is transferred to the packet process logic.
913 //
914 if (!Ip4IsValidPacketLength (Packet)) {
915 goto RESTART;
916 }
917
918 Head = (IP4_HEAD *)NetbufGetByte (Packet, 0, NULL);
919 ASSERT (Head != NULL);
920 Status = Ip4PreProcessPacket (
921 IpSb,
922 &Packet,
923 Head,
924 Option,
925 OptionLen,
926 Flag
927 );
928 if (EFI_ERROR (Status)) {
929 goto RESTART;
930 }
931 }
932
933 ASSERT (Packet != NULL);
934 Head = Packet->Ip.Ip4;
935 IP4_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS;
936
937 switch (Head->Protocol) {
938 case EFI_IP_PROTO_ICMP:
939 Ip4IcmpHandle (IpSb, Head, Packet);
940 break;
941
942 case IP4_PROTO_IGMP:
943 Ip4IgmpHandle (IpSb, Head, Packet);
944 break;
945
946 default:
947 Ip4Demultiplex (IpSb, Head, Packet, Option, OptionLen);
948 }
949
950 Packet = NULL;
951
952 //
953 // Dispatch the DPCs queued by the NotifyFunction of the rx token's events
954 // which are signaled with received data.
955 //
956 DispatchDpc ();
957
958RESTART:
959 Ip4ReceiveFrame (IpSb->DefaultInterface, NULL, Ip4AccpetFrame, IpSb);
960
961DROP:
962 if (Packet != NULL) {
963 NetbufFree (Packet);
964 }
965
966 return;
967}
968
980BOOLEAN
982 IN IP4_PROTOCOL *IpInstance,
983 IN IP4_HEAD *Head,
984 IN NET_BUF *Packet
985 )
986{
988 EFI_IP4_CONFIG_DATA *Config;
989 IP4_CLIP_INFO *Info;
990 UINT16 Proto;
991 UINT32 Index;
992
993 Config = &IpInstance->ConfigData;
994
995 //
996 // Dirty trick for the Tiano UEFI network stack implementation. If
997 // ReceiveTimeout == -1, the receive of the packet for this instance
998 // is disabled. The UEFI spec don't have such capability. We add
999 // this to improve the performance because IP will make a copy of
1000 // the received packet for each accepting instance. Some IP instances
1001 // used by UDP/TCP only send packets, they don't wants to receive.
1002 //
1003 if (Config->ReceiveTimeout == (UINT32)(-1)) {
1004 return FALSE;
1005 }
1006
1007 if (Config->AcceptPromiscuous) {
1008 return TRUE;
1009 }
1010
1011 //
1012 // Use protocol from the IP header embedded in the ICMP error
1013 // message to filter, instead of ICMP itself. ICMP handle will
1014 // call Ip4Demultiplex to deliver ICMP errors.
1015 //
1016 Proto = Head->Protocol;
1017
1018 if ((Proto == EFI_IP_PROTO_ICMP) && (!Config->AcceptAnyProtocol) && (Proto != Config->DefaultProtocol)) {
1019 NetbufCopy (Packet, 0, sizeof (Icmp.Head), (UINT8 *)&Icmp.Head);
1020
1021 if (mIcmpClass[Icmp.Head.Type].IcmpClass == ICMP_ERROR_MESSAGE) {
1022 if (!Config->AcceptIcmpErrors) {
1023 return FALSE;
1024 }
1025
1026 NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *)&Icmp);
1027 Proto = Icmp.IpHead.Protocol;
1028 }
1029 }
1030
1031 //
1032 // Match the protocol
1033 //
1034 if (!Config->AcceptAnyProtocol && (Proto != Config->DefaultProtocol)) {
1035 return FALSE;
1036 }
1037
1038 //
1039 // Check for broadcast, the caller has computed the packet's
1040 // cast type for this child's interface.
1041 //
1042 Info = IP4_GET_CLIP_INFO (Packet);
1043
1044 if (IP4_IS_BROADCAST (Info->CastType)) {
1045 return Config->AcceptBroadcast;
1046 }
1047
1048 //
1049 // If it is a multicast packet, check whether we are in the group.
1050 //
1051 if (Info->CastType == IP4_MULTICAST) {
1052 //
1053 // Receive the multicast if the instance wants to receive all packets.
1054 //
1055 if (!IpInstance->ConfigData.UseDefaultAddress && (IpInstance->Interface->Ip == 0)) {
1056 return TRUE;
1057 }
1058
1059 for (Index = 0; Index < IpInstance->GroupCount; Index++) {
1060 if (IpInstance->Groups[Index] == HTONL (Head->Dst)) {
1061 break;
1062 }
1063 }
1064
1065 return (BOOLEAN)(Index < IpInstance->GroupCount);
1066 }
1067
1068 return TRUE;
1069}
1070
1088 IN IP4_PROTOCOL *IpInstance,
1089 IN IP4_HEAD *Head,
1090 IN NET_BUF *Packet
1091 )
1092{
1093 IP4_CLIP_INFO *Info;
1094 NET_BUF *Clone;
1095
1096 //
1097 // Check whether the packet is acceptable to this instance.
1098 //
1099 if (IpInstance->State != IP4_STATE_CONFIGED) {
1100 return EFI_NOT_STARTED;
1101 }
1102
1103 if (!Ip4InstanceFrameAcceptable (IpInstance, Head, Packet)) {
1104 return EFI_INVALID_PARAMETER;
1105 }
1106
1107 //
1108 // Enqueue a shared copy of the packet.
1109 //
1110 Clone = NetbufClone (Packet);
1111
1112 if (Clone == NULL) {
1113 return EFI_OUT_OF_RESOURCES;
1114 }
1115
1116 //
1117 // Set the receive time out for the assembled packet. If it expires,
1118 // packet will be removed from the queue.
1119 //
1120 Info = IP4_GET_CLIP_INFO (Clone);
1121 Info->Life = IP4_US_TO_SEC (IpInstance->ConfigData.ReceiveTimeout);
1122
1123 InsertTailList (&IpInstance->Received, &Clone->List);
1124 return EFI_SUCCESS;
1125}
1126
1136VOID
1137EFIAPI
1139 IN EFI_EVENT Event,
1140 IN VOID *Context
1141 )
1142{
1143 IP4_RXDATA_WRAP *Wrap;
1144
1145 Wrap = (IP4_RXDATA_WRAP *)Context;
1146
1147 EfiAcquireLockOrFail (&Wrap->IpInstance->RecycleLock);
1148 RemoveEntryList (&Wrap->Link);
1149 EfiReleaseLock (&Wrap->IpInstance->RecycleLock);
1150
1151 ASSERT (!NET_BUF_SHARED (Wrap->Packet));
1152 NetbufFree (Wrap->Packet);
1153
1154 gBS->CloseEvent (Wrap->RxData.RecycleSignal);
1155 FreePool (Wrap);
1156}
1157
1175 IN IP4_PROTOCOL *IpInstance,
1176 IN NET_BUF *Packet
1177 )
1178{
1179 IP4_RXDATA_WRAP *Wrap;
1180 EFI_IP4_RECEIVE_DATA *RxData;
1181 EFI_STATUS Status;
1182 BOOLEAN RawData;
1183
1184 Wrap = AllocatePool (IP4_RXDATA_WRAP_SIZE (Packet->BlockOpNum));
1185
1186 if (Wrap == NULL) {
1187 return NULL;
1188 }
1189
1190 InitializeListHead (&Wrap->Link);
1191
1192 Wrap->IpInstance = IpInstance;
1193 Wrap->Packet = Packet;
1194 RxData = &Wrap->RxData;
1195
1196 ZeroMem (RxData, sizeof (EFI_IP4_RECEIVE_DATA));
1197
1198 Status = gBS->CreateEvent (
1199 EVT_NOTIFY_SIGNAL,
1200 TPL_NOTIFY,
1202 Wrap,
1203 &RxData->RecycleSignal
1204 );
1205
1206 if (EFI_ERROR (Status)) {
1207 FreePool (Wrap);
1208 return NULL;
1209 }
1210
1211 ASSERT (Packet->Ip.Ip4 != NULL);
1212
1213 ASSERT (IpInstance != NULL);
1214 RawData = IpInstance->ConfigData.RawData;
1215
1216 //
1217 // The application expects a network byte order header.
1218 //
1219 if (!RawData) {
1220 RxData->HeaderLength = (Packet->Ip.Ip4->HeadLen << 2);
1221 RxData->Header = (EFI_IP4_HEADER *)Ip4NtohHead (Packet->Ip.Ip4);
1222 RxData->OptionsLength = RxData->HeaderLength - IP4_MIN_HEADLEN;
1223 RxData->Options = NULL;
1224
1225 if (RxData->OptionsLength != 0) {
1226 RxData->Options = (VOID *)(RxData->Header + 1);
1227 }
1228 }
1229
1230 RxData->DataLength = Packet->TotalSize;
1231
1232 //
1233 // Build the fragment table to be delivered up.
1234 //
1235 RxData->FragmentCount = Packet->BlockOpNum;
1236 NetbufBuildExt (Packet, (NET_FRAGMENT *)RxData->FragmentTable, &RxData->FragmentCount);
1237
1238 return Wrap;
1239}
1240
1257 IN IP4_PROTOCOL *IpInstance
1258 )
1259{
1261 IP4_RXDATA_WRAP *Wrap;
1262 NET_BUF *Packet;
1263 NET_BUF *Dup;
1264 UINT8 *Head;
1265 UINT32 HeadLen;
1266
1267 //
1268 // Deliver a packet if there are both a packet and a receive token.
1269 //
1270 while (!IsListEmpty (&IpInstance->Received) &&
1271 !NetMapIsEmpty (&IpInstance->RxTokens))
1272 {
1273 Packet = NET_LIST_HEAD (&IpInstance->Received, NET_BUF, List);
1274
1275 if (!NET_BUF_SHARED (Packet)) {
1276 //
1277 // If this is the only instance that wants the packet, wrap it up.
1278 //
1279 Wrap = Ip4WrapRxData (IpInstance, Packet);
1280
1281 if (Wrap == NULL) {
1282 return EFI_OUT_OF_RESOURCES;
1283 }
1284
1285 RemoveEntryList (&Packet->List);
1286 } else {
1287 //
1288 // Create a duplicated packet if this packet is shared
1289 //
1290 if (IpInstance->ConfigData.RawData) {
1291 HeadLen = 0;
1292 } else {
1293 HeadLen = IP4_MAX_HEADLEN;
1294 }
1295
1296 Dup = NetbufDuplicate (Packet, NULL, HeadLen);
1297
1298 if (Dup == NULL) {
1299 return EFI_OUT_OF_RESOURCES;
1300 }
1301
1302 if (!IpInstance->ConfigData.RawData) {
1303 //
1304 // Copy the IP head over. The packet to deliver up is
1305 // headless. Trim the head off after copy. The IP head
1306 // may be not continuous before the data.
1307 //
1308 Head = NetbufAllocSpace (Dup, IP4_MAX_HEADLEN, NET_BUF_HEAD);
1309 ASSERT (Head != NULL);
1310
1311 Dup->Ip.Ip4 = (IP4_HEAD *)Head;
1312
1313 CopyMem (Head, Packet->Ip.Ip4, Packet->Ip.Ip4->HeadLen << 2);
1314 NetbufTrim (Dup, IP4_MAX_HEADLEN, TRUE);
1315 }
1316
1317 Wrap = Ip4WrapRxData (IpInstance, Dup);
1318
1319 if (Wrap == NULL) {
1320 NetbufFree (Dup);
1321 return EFI_OUT_OF_RESOURCES;
1322 }
1323
1324 RemoveEntryList (&Packet->List);
1325 NetbufFree (Packet);
1326
1327 Packet = Dup;
1328 }
1329
1330 //
1331 // Insert it into the delivered packet, then get a user's
1332 // receive token, pass the wrapped packet up.
1333 //
1334 EfiAcquireLockOrFail (&IpInstance->RecycleLock);
1335 InsertHeadList (&IpInstance->Delivered, &Wrap->Link);
1336 EfiReleaseLock (&IpInstance->RecycleLock);
1337
1338 Token = NetMapRemoveHead (&IpInstance->RxTokens, NULL);
1339 Token->Status = IP4_GET_CLIP_INFO (Packet)->Status;
1340 Token->Packet.RxData = &Wrap->RxData;
1341
1342 gBS->SignalEvent (Token->Event);
1343 }
1344
1345 return EFI_SUCCESS;
1346}
1347
1362INTN
1364 IN IP4_SERVICE *IpSb,
1365 IN IP4_HEAD *Head,
1366 IN NET_BUF *Packet,
1367 IN UINT8 *Option,
1368 IN UINT32 OptionLen,
1369 IN IP4_INTERFACE *IpIf
1370 )
1371{
1372 IP4_PROTOCOL *IpInstance;
1373 IP4_CLIP_INFO *Info;
1374 LIST_ENTRY *Entry;
1375 INTN Enqueued;
1376 INTN LocalType;
1377 INTN SavedType;
1378
1379 //
1380 // First, check that the packet is acceptable to this interface
1381 // and find the local cast type for the interface. A packet sent
1382 // to say 192.168.1.1 should NOT be deliver to 10.0.0.1 unless
1383 // promiscuous receiving.
1384 //
1385 LocalType = 0;
1386 Info = IP4_GET_CLIP_INFO (Packet);
1387
1388 if ((Info->CastType == IP4_MULTICAST) || (Info->CastType == IP4_LOCAL_BROADCAST)) {
1389 //
1390 // If the CastType is multicast, don't need to filter against
1391 // the group address here, Ip4InstanceFrameAcceptable will do
1392 // that later.
1393 //
1394 LocalType = Info->CastType;
1395 } else {
1396 //
1397 // Check the destination against local IP. If the station
1398 // address is 0.0.0.0, it means receiving all the IP destined
1399 // to local non-zero IP. Otherwise, it is necessary to compare
1400 // the destination to the interface's IP address.
1401 //
1402 if (IpIf->Ip == IP4_ALLZERO_ADDRESS) {
1403 LocalType = IP4_LOCAL_HOST;
1404 } else {
1405 LocalType = Ip4GetNetCast (Head->Dst, IpIf);
1406
1407 if ((LocalType == 0) && IpIf->PromiscRecv) {
1408 LocalType = IP4_PROMISCUOUS;
1409 }
1410 }
1411 }
1412
1413 if (LocalType == 0) {
1414 return 0;
1415 }
1416
1417 //
1418 // Iterate through the ip instances on the interface, enqueue
1419 // the packet if filter passed. Save the original cast type,
1420 // and pass the local cast type to the IP children on the
1421 // interface. The global cast type will be restored later.
1422 //
1423 SavedType = Info->CastType;
1424 Info->CastType = LocalType;
1425
1426 Enqueued = 0;
1427
1428 NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
1429 IpInstance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink);
1430 NET_CHECK_SIGNATURE (IpInstance, IP4_PROTOCOL_SIGNATURE);
1431
1432 //
1433 // In RawData mode, add IPv4 headers and options back to packet.
1434 //
1435 if ((IpInstance->ConfigData.RawData) && (Option != NULL) && (OptionLen != 0)) {
1436 Ip4PrependHead (Packet, Head, Option, OptionLen);
1437 }
1438
1439 if (Ip4InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) {
1440 Enqueued++;
1441 }
1442 }
1443
1444 Info->CastType = SavedType;
1445 return Enqueued;
1446}
1447
1459 IN IP4_SERVICE *IpSb,
1460 IN IP4_INTERFACE *IpIf
1461 )
1462{
1463 IP4_PROTOCOL *Ip4Instance;
1464 LIST_ENTRY *Entry;
1465
1466 NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) {
1467 Ip4Instance = NET_LIST_USER_STRUCT (Entry, IP4_PROTOCOL, AddrLink);
1468 Ip4InstanceDeliverPacket (Ip4Instance);
1469 }
1470
1471 return EFI_SUCCESS;
1472}
1473
1496 IN IP4_SERVICE *IpSb,
1497 IN IP4_HEAD *Head,
1498 IN NET_BUF *Packet,
1499 IN UINT8 *Option,
1500 IN UINT32 OptionLen
1501 )
1502{
1503 LIST_ENTRY *Entry;
1504 IP4_INTERFACE *IpIf;
1505 INTN Enqueued;
1506
1507 //
1508 // Two pass delivery: first, enqueue a shared copy of the packet
1509 // to each instance that accept the packet.
1510 //
1511 Enqueued = 0;
1512
1513 NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
1514 IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);
1515
1516 if (IpIf->Configured) {
1517 Enqueued += Ip4InterfaceEnquePacket (
1518 IpSb,
1519 Head,
1520 Packet,
1521 Option,
1522 OptionLen,
1523 IpIf
1524 );
1525 }
1526 }
1527
1528 //
1529 // Second: deliver a duplicate of the packet to each instance.
1530 // Release the local reference first, so that the last instance
1531 // getting the packet will not copy the data.
1532 //
1533 NetbufFree (Packet);
1534
1535 if (Enqueued == 0) {
1536 return EFI_NOT_FOUND;
1537 }
1538
1539 NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
1540 IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);
1541
1542 if (IpIf->Configured) {
1543 Ip4InterfaceDeliverPacket (IpSb, IpIf);
1544 }
1545 }
1546
1547 return EFI_SUCCESS;
1548}
1549
1556VOID
1558 IN IP4_SERVICE *IpSb
1559 )
1560{
1561 LIST_ENTRY *InstanceEntry;
1562 LIST_ENTRY *Entry;
1563 LIST_ENTRY *Next;
1564 IP4_PROTOCOL *IpInstance;
1565 IP4_ASSEMBLE_ENTRY *Assemble;
1566 NET_BUF *Packet;
1567 IP4_CLIP_INFO *Info;
1568 UINT32 Index;
1569
1570 //
1571 // First, time out the fragments. The packet's life is counting down
1572 // once the first-arrived fragment was received.
1573 //
1574 for (Index = 0; Index < IP4_ASSEMLE_HASH_SIZE; Index++) {
1575 NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->Assemble.Bucket[Index]) {
1576 Assemble = NET_LIST_USER_STRUCT (Entry, IP4_ASSEMBLE_ENTRY, Link);
1577
1578 if ((Assemble->Life > 0) && (--Assemble->Life == 0)) {
1579 RemoveEntryList (Entry);
1580 Ip4FreeAssembleEntry (Assemble);
1581 }
1582 }
1583 }
1584
1585 NET_LIST_FOR_EACH (InstanceEntry, &IpSb->Children) {
1586 IpInstance = NET_LIST_USER_STRUCT (InstanceEntry, IP4_PROTOCOL, Link);
1587
1588 //
1589 // Second, time out the assembled packets enqueued on each IP child.
1590 //
1591 NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpInstance->Received) {
1592 Packet = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
1593 Info = IP4_GET_CLIP_INFO (Packet);
1594
1595 if ((Info->Life > 0) && (--Info->Life == 0)) {
1596 RemoveEntryList (Entry);
1597 NetbufFree (Packet);
1598 }
1599 }
1600
1601 //
1602 // Third: time out the transmitted packets.
1603 //
1604 NetMapIterate (&IpInstance->TxTokens, Ip4SentPacketTicking, NULL);
1605 }
1606}
INT64 INTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI DispatchDpc(VOID)
Definition: DpcLib.c:86
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
INTN Ip4GetHostCast(IN IP4_SERVICE *IpSb, IN IP4_ADDR Dst, IN IP4_ADDR Src)
Definition: Ip4Common.c:59
INTN Ip4GetNetCast(IN IP4_ADDR IpAddr, IN IP4_INTERFACE *IpIf)
Definition: Ip4Common.c:26
IP4_HEAD * Ip4NtohHead(IN IP4_HEAD *Head)
Definition: Ip4Common.c:241
#define IP4_US_TO_SEC(Us)
Definition: Ip4Common.h:69
EFI_STATUS Ip4IcmpHandle(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet)
Definition: Ip4Icmp.c:322
EFI_STATUS Ip4ReceiveFrame(IN IP4_INTERFACE *Interface, IN IP4_PROTOCOL *IpInstance OPTIONAL, IN IP4_FRAME_CALLBACK CallBack, IN VOID *Context)
Definition: Ip4If.c:1303
EFI_STATUS Ip4IgmpHandle(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet)
Definition: Ip4Igmp.c:401
VOID EFIAPI Ip4FreeTxToken(IN VOID *Context)
Definition: Ip4Impl.c:1455
EFI_STATUS EFIAPI Ip4SentPacketTicking(IN NET_MAP *Map, IN NET_MAP_ITEM *Item, IN VOID *Context)
Definition: Ip4Impl.c:2213
INTN Ip4InterfaceEnquePacket(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet, IN UINT8 *Option, IN UINT32 OptionLen, IN IP4_INTERFACE *IpIf)
Definition: Ip4Input.c:1363
NET_BUF * Ip4Reassemble(IN OUT IP4_ASSEMBLE_TABLE *Table, IN OUT NET_BUF *Packet)
Definition: Ip4Input.c:204
EFI_STATUS Ip4InterfaceDeliverPacket(IN IP4_SERVICE *IpSb, IN IP4_INTERFACE *IpIf)
Definition: Ip4Input.c:1458
IP4_ASSEMBLE_ENTRY * Ip4CreateAssembleEntry(IN IP4_ADDR Dst, IN IP4_ADDR Src, IN UINT16 Id, IN UINT8 Protocol)
Definition: Ip4Input.c:28
BOOLEAN Ip4InstanceFrameAcceptable(IN IP4_PROTOCOL *IpInstance, IN IP4_HEAD *Head, IN NET_BUF *Packet)
Definition: Ip4Input.c:981
EFI_STATUS Ip4InstanceDeliverPacket(IN IP4_PROTOCOL *IpInstance)
Definition: Ip4Input.c:1256
VOID EFIAPI Ip4OnFreeFragments(IN VOID *Arg)
Definition: Ip4Input.c:181
VOID Ip4CleanAssembleTable(IN IP4_ASSEMBLE_TABLE *Table)
Definition: Ip4Input.c:111
VOID Ip4FreeAssembleEntry(IN IP4_ASSEMBLE_ENTRY *Assemble)
Definition: Ip4Input.c:66
EFI_STATUS Ip4InstanceEnquePacket(IN IP4_PROTOCOL *IpInstance, IN IP4_HEAD *Head, IN NET_BUF *Packet)
Definition: Ip4Input.c:1087
VOID EFIAPI Ip4IpSecFree(IN VOID *Arg)
Definition: Ip4Input.c:439
VOID Ip4InitAssembleTable(IN OUT IP4_ASSEMBLE_TABLE *Table)
Definition: Ip4Input.c:92
EFI_STATUS Ip4Demultiplex(IN IP4_SERVICE *IpSb, IN IP4_HEAD *Head, IN NET_BUF *Packet, IN UINT8 *Option, IN UINT32 OptionLen)
Definition: Ip4Input.c:1495
EFI_STATUS Ip4IpSecProcessPacket(IN IP4_SERVICE *IpSb, IN OUT IP4_HEAD **Head, IN OUT NET_BUF **Netbuf, IN OUT UINT8 **Options, IN OUT UINT32 *OptionsLen, IN EFI_IPSEC_TRAFFIC_DIR Direction, IN VOID *Context)
Definition: Ip4Input.c:482
EFI_STATUS Ip4PreProcessPacket(IN IP4_SERVICE *IpSb, IN OUT NET_BUF **Packet, IN IP4_HEAD *Head, IN UINT8 *Option, IN UINT32 OptionLen, IN UINT32 Flag)
Definition: Ip4Input.c:689
IP4_RXDATA_WRAP * Ip4WrapRxData(IN IP4_PROTOCOL *IpInstance, IN NET_BUF *Packet)
Definition: Ip4Input.c:1174
VOID EFIAPI Ip4OnRecyclePacket(IN EFI_EVENT Event, IN VOID *Context)
Definition: Ip4Input.c:1138
VOID Ip4AccpetFrame(IN IP4_PROTOCOL *Ip4Instance, IN NET_BUF *Packet, IN EFI_STATUS IoStatus, IN UINT32 Flag, IN VOID *Context)
Definition: Ip4Input.c:838
VOID Ip4PacketTimerTicking(IN IP4_SERVICE *IpSb)
Definition: Ip4Input.c:1557
VOID Ip4TrimPacket(IN OUT NET_BUF *Packet, IN INTN Start, IN INTN End)
Definition: Ip4Input.c:140
BOOLEAN Ip4IsValidPacketLength(IN NET_BUF *Packet)
Definition: Ip4Input.c:810
#define IP4_MAX_IPSEC_HEADLEN
Definition: Ip4Input.h:16
BOOLEAN Ip4OptionIsValid(IN UINT8 *Option, IN UINT32 OptionLen, IN BOOLEAN Rcvd)
Definition: Ip4Option.c:25
EFI_STATUS Ip4PrependHead(IN OUT NET_BUF *Packet, IN IP4_HEAD *Head, IN UINT8 *Option, IN UINT32 OptLen)
Definition: Ip4Output.c:32
EFI_IPSEC_TRAFFIC_DIR
Definition: IpSecConfig.h:129
@ EfiIPsecInBound
Definition: IpSecConfig.h:135
@ EfiIPsecOutBound
Definition: IpSecConfig.h:141
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:195
NET_BUF *EFIAPI NetbufClone(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:229
UINT32 EFIAPI NetbufTrim(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
Definition: NetBuffer.c:1134
EFI_STATUS EFIAPI NetbufBuildExt(IN NET_BUF *Nbuf, IN OUT NET_FRAGMENT *ExtFragment, IN OUT UINT32 *ExtNum)
Definition: NetBuffer.c:866
UINT16 EFIAPI NetblockChecksum(IN UINT8 *Bulk, IN UINT32 Len)
Definition: NetBuffer.c:1615
UINT32 EFIAPI NetbufCopy(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT8 *Dest)
Definition: NetBuffer.c:1206
NET_BUF *EFIAPI NetbufFromExt(IN NET_FRAGMENT *ExtFragment, IN UINT32 ExtNum, IN UINT32 HeadSpace, IN UINT32 HeadLen, IN NET_VECTOR_EXT_FREE ExtFree, IN VOID *Arg OPTIONAL)
Definition: NetBuffer.c:693
NET_BUF *EFIAPI NetbufFromBufList(IN LIST_ENTRY *BufList, IN UINT32 HeadSpace, IN UINT32 HeaderLen, IN NET_VECTOR_EXT_FREE ExtFree, IN VOID *Arg OPTIONAL)
Definition: NetBuffer.c:914
VOID NetIpSecNetbufFree(NET_BUF *Nbuf)
Definition: NetBuffer.c:1812
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
Definition: NetBuffer.c:1015
NET_BUF *EFIAPI NetbufDuplicate(IN NET_BUF *Nbuf, IN OUT NET_BUF *Duplicate OPTIONAL, IN UINT32 HeadSpace)
Definition: NetBuffer.c:280
BOOLEAN EFIAPI NetMapIsEmpty(IN NET_MAP *Map)
Definition: DxeNetLib.c:1413
UINT8 *EFIAPI NetbufGetByte(IN NET_BUF *Nbuf, IN UINT32 Offset, OUT UINT32 *Index OPTIONAL)
Definition: NetBuffer.c:359
VOID *EFIAPI NetMapRemoveHead(IN OUT NET_MAP *Map, OUT VOID **Value OPTIONAL)
Definition: DxeNetLib.c:1710
EFI_STATUS EFIAPI NetMapIterate(IN NET_MAP *Map, IN NET_MAP_CALLBACK CallBack, IN VOID *Arg OPTIONAL)
Definition: DxeNetLib.c:1800
VOID EFIAPI NetListInsertBefore(IN OUT LIST_ENTRY *PostEntry, IN OUT LIST_ENTRY *NewEntry)
Definition: DxeNetLib.c:1199
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
VOID EFIAPI EfiReleaseLock(IN EFI_LOCK *Lock)
Definition: UefiLib.c:499
EFI_STATUS EFIAPI EfiAcquireLockOrFail(IN EFI_LOCK *Lock)
Definition: UefiLib.c:463
EFI_EVENT Event
Definition: Ip4.h:244
EFI_IP4_RECEIVE_DATA * RxData
Definition: Ip4.h:254
EFI_STATUS Status
Definition: Ip4.h:249
BOOLEAN AcceptBroadcast
Definition: Ip4.h:80
UINT32 ReceiveTimeout
Definition: Ip4.h:121
BOOLEAN AcceptPromiscuous
Definition: Ip4.h:86
BOOLEAN AcceptAnyProtocol
Definition: Ip4.h:69
UINT8 DefaultProtocol
Definition: Ip4.h:63
BOOLEAN AcceptIcmpErrors
Definition: Ip4.h:74
BOOLEAN RawData
Definition: Ip4.h:115