TianoCore EDK2 master
Loading...
Searching...
No Matches
NetBuffer.c
Go to the documentation of this file.
1
8#include <Uefi.h>
9
10#include <Library/NetLib.h>
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
16
31NET_BUF *
33 IN UINT32 BlockNum,
34 IN UINT32 BlockOpNum
35 )
36{
37 NET_BUF *Nbuf;
38 NET_VECTOR *Vector;
39
40 ASSERT (BlockOpNum >= 1);
41
42 //
43 // Allocate three memory blocks.
44 //
45 Nbuf = AllocateZeroPool (NET_BUF_SIZE (BlockOpNum));
46
47 if (Nbuf == NULL) {
48 return NULL;
49 }
50
51 Nbuf->Signature = NET_BUF_SIGNATURE;
52 Nbuf->RefCnt = 1;
53 Nbuf->BlockOpNum = BlockOpNum;
54 InitializeListHead (&Nbuf->List);
55
56 if (BlockNum != 0) {
57 Vector = AllocateZeroPool (NET_VECTOR_SIZE (BlockNum));
58
59 if (Vector == NULL) {
60 goto FreeNbuf;
61 }
62
63 Vector->Signature = NET_VECTOR_SIGNATURE;
64 Vector->RefCnt = 1;
65 Vector->BlockNum = BlockNum;
66 Nbuf->Vector = Vector;
67 }
68
69 return Nbuf;
70
71FreeNbuf:
72
73 FreePool (Nbuf);
74 return NULL;
75}
76
87NET_BUF *
88EFIAPI
90 IN UINT32 Len
91 )
92{
93 NET_BUF *Nbuf;
94 NET_VECTOR *Vector;
95 UINT8 *Bulk;
96
97 ASSERT (Len > 0);
98
99 Nbuf = NetbufAllocStruct (1, 1);
100
101 if (Nbuf == NULL) {
102 return NULL;
103 }
104
105 Bulk = AllocatePool (Len);
106
107 if (Bulk == NULL) {
108 goto FreeNBuf;
109 }
110
111 Vector = Nbuf->Vector;
112 Vector->Len = Len;
113
114 Vector->Block[0].Bulk = Bulk;
115 Vector->Block[0].Len = Len;
116
117 Nbuf->BlockOp[0].BlockHead = Bulk;
118 Nbuf->BlockOp[0].BlockTail = Bulk + Len;
119
120 Nbuf->BlockOp[0].Head = Bulk;
121 Nbuf->BlockOp[0].Tail = Bulk;
122 Nbuf->BlockOp[0].Size = 0;
123
124 return Nbuf;
125
126FreeNBuf:
127 FreePool (Nbuf);
128 return NULL;
129}
130
141VOID
143 IN NET_VECTOR *Vector
144 )
145{
146 UINT32 Index;
147
148 ASSERT (Vector != NULL);
149 NET_CHECK_SIGNATURE (Vector, NET_VECTOR_SIGNATURE);
150 ASSERT (Vector->RefCnt > 0);
151
152 Vector->RefCnt--;
153
154 if (Vector->RefCnt > 0) {
155 return;
156 }
157
158 if (Vector->Free != NULL) {
159 //
160 // Call external free function to free the vector if it
161 // isn't NULL. If NET_VECTOR_OWN_FIRST is set, release the
162 // first block since it is allocated by us
163 //
164 if ((Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {
165 gBS->FreePool (Vector->Block[0].Bulk);
166 }
167
168 Vector->Free (Vector->Arg);
169 } else {
170 //
171 // Free each memory block associated with the Vector
172 //
173 for (Index = 0; Index < Vector->BlockNum; Index++) {
174 gBS->FreePool (Vector->Block[Index].Bulk);
175 }
176 }
177
178 FreePool (Vector);
179}
180
193VOID
194EFIAPI
196 IN NET_BUF *Nbuf
197 )
198{
199 ASSERT (Nbuf != NULL);
200 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
201 ASSERT (Nbuf->RefCnt > 0);
202
203 Nbuf->RefCnt--;
204
205 if (Nbuf->RefCnt == 0) {
206 //
207 // Update Vector only when NBuf is to be released. That is,
208 // all the sharing of Nbuf increse Vector's RefCnt by one
209 //
210 NetbufFreeVector (Nbuf->Vector);
211 FreePool (Nbuf);
212 }
213}
214
227NET_BUF *
228EFIAPI
230 IN NET_BUF *Nbuf
231 )
232{
233 NET_BUF *Clone;
234
235 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
236
237 Clone = AllocatePool (NET_BUF_SIZE (Nbuf->BlockOpNum));
238
239 if (Clone == NULL) {
240 return NULL;
241 }
242
243 Clone->Signature = NET_BUF_SIGNATURE;
244 Clone->RefCnt = 1;
245 InitializeListHead (&Clone->List);
246
247 Clone->Ip = Nbuf->Ip;
248 Clone->Tcp = Nbuf->Tcp;
249
250 CopyMem (Clone->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);
251
252 NET_GET_REF (Nbuf->Vector);
253
254 Clone->Vector = Nbuf->Vector;
255 Clone->BlockOpNum = Nbuf->BlockOpNum;
256 Clone->TotalSize = Nbuf->TotalSize;
257 CopyMem (Clone->BlockOp, Nbuf->BlockOp, sizeof (NET_BLOCK_OP) * Nbuf->BlockOpNum);
258
259 return Clone;
260}
261
278NET_BUF *
279EFIAPI
281 IN NET_BUF *Nbuf,
282 IN OUT NET_BUF *Duplicate OPTIONAL,
283 IN UINT32 HeadSpace
284 )
285{
286 UINT8 *Dst;
287
288 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
289
290 if (Duplicate == NULL) {
291 Duplicate = NetbufAlloc (Nbuf->TotalSize + HeadSpace);
292 }
293
294 if (Duplicate == NULL) {
295 return NULL;
296 }
297
298 //
299 // Don't set the IP and TCP head point, since it is most
300 // like that they are pointing to the memory of Nbuf.
301 //
302 CopyMem (Duplicate->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);
303 NetbufReserve (Duplicate, HeadSpace);
304
305 Dst = NetbufAllocSpace (Duplicate, Nbuf->TotalSize, NET_BUF_TAIL);
306 NetbufCopy (Nbuf, 0, Nbuf->TotalSize, Dst);
307
308 return Duplicate;
309}
310
317VOID
318EFIAPI
320 IN OUT LIST_ENTRY *Head
321 )
322{
323 LIST_ENTRY *Entry;
324 LIST_ENTRY *Next;
325 NET_BUF *Nbuf;
326
327 Entry = Head->ForwardLink;
328
329 NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
330 Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
331 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
332
333 RemoveEntryList (Entry);
334 NetbufFree (Nbuf);
335 }
336
337 ASSERT (IsListEmpty (Head));
338}
339
357UINT8 *
358EFIAPI
360 IN NET_BUF *Nbuf,
361 IN UINT32 Offset,
362 OUT UINT32 *Index OPTIONAL
363 )
364{
365 NET_BLOCK_OP *BlockOp;
366 UINT32 Loop;
367 UINT32 Len;
368
369 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
370
371 if (Offset >= Nbuf->TotalSize) {
372 return NULL;
373 }
374
375 BlockOp = Nbuf->BlockOp;
376 Len = 0;
377
378 for (Loop = 0; Loop < Nbuf->BlockOpNum; Loop++) {
379 if (Len + BlockOp[Loop].Size <= Offset) {
380 Len += BlockOp[Loop].Size;
381 continue;
382 }
383
384 if (Index != NULL) {
385 *Index = Loop;
386 }
387
388 return BlockOp[Loop].Head + (Offset - Len);
389 }
390
391 return NULL;
392}
393
409VOID
411 IN OUT NET_BUF *Nbuf,
412 IN UINT8 *Bulk,
413 IN UINT32 Len,
414 IN UINT32 Index
415 )
416{
417 NET_BLOCK_OP *BlockOp;
418 NET_BLOCK *Block;
419
420 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
421 NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
422 ASSERT (Index < Nbuf->BlockOpNum);
423
424 Block = &(Nbuf->Vector->Block[Index]);
425 BlockOp = &(Nbuf->BlockOp[Index]);
426 Block->Len = Len;
427 Block->Bulk = Bulk;
428 BlockOp->BlockHead = Bulk;
429 BlockOp->BlockTail = Bulk + Len;
430 BlockOp->Head = Bulk;
431 BlockOp->Tail = Bulk + Len;
432 BlockOp->Size = Len;
433}
434
449VOID
451 IN OUT NET_BUF *Nbuf,
452 IN UINT8 *Bulk,
453 IN UINT32 Len,
454 IN UINT32 Index
455 )
456{
457 NET_BLOCK_OP *BlockOp;
458
459 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
460 ASSERT (Index < Nbuf->BlockOpNum);
461
462 BlockOp = &(Nbuf->BlockOp[Index]);
463 BlockOp->BlockHead = Bulk;
464 BlockOp->BlockTail = Bulk + Len;
465 BlockOp->Head = Bulk;
466 BlockOp->Tail = Bulk + Len;
467 BlockOp->Size = Len;
468}
469
479VOID
480EFIAPI
482 IN VOID *Arg
483 )
484{
485 NET_VECTOR *Vector;
486
487 Vector = (NET_VECTOR *)Arg;
488 NetbufFreeVector (Vector);
489}
490
508NET_BUF *
509EFIAPI
511 IN NET_BUF *Nbuf,
512 IN UINT32 Offset,
513 IN UINT32 Len,
514 IN UINT32 HeadSpace
515 )
516{
517 NET_BUF *Child;
518 NET_VECTOR *Vector;
519 NET_BLOCK_OP *BlockOp;
520 UINT32 CurBlockOp;
521 UINT32 BlockOpNum;
522 UINT8 *FirstBulk;
523 UINT32 Index;
524 UINT32 First;
525 UINT32 Last;
526 UINT32 FirstSkip;
527 UINT32 FirstLen;
528 UINT32 LastLen;
529 UINT32 Cur;
530
531 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
532
533 if ((Len == 0) || (Offset + Len > Nbuf->TotalSize)) {
534 return NULL;
535 }
536
537 //
538 // First find the first and last BlockOp that contains
539 // the valid data, and compute the offset of the first
540 // BlockOp and length of the last BlockOp
541 //
542 BlockOp = Nbuf->BlockOp;
543 Cur = 0;
544
545 for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
546 if (Offset < Cur + BlockOp[Index].Size) {
547 break;
548 }
549
550 Cur += BlockOp[Index].Size;
551 }
552
553 //
554 // First is the index of the first BlockOp, FirstSkip is
555 // the offset of the first byte in the first BlockOp.
556 //
557 First = Index;
558 FirstSkip = Offset - Cur;
559 FirstLen = BlockOp[Index].Size - FirstSkip;
560
561 Last = 0;
562 LastLen = 0;
563
564 if (Len > FirstLen) {
565 Cur += BlockOp[Index].Size;
566 Index++;
567
568 for ( ; Index < Nbuf->BlockOpNum; Index++) {
569 if (Offset + Len <= Cur + BlockOp[Index].Size) {
570 Last = Index;
571 LastLen = Offset + Len - Cur;
572 break;
573 }
574
575 Cur += BlockOp[Index].Size;
576 }
577 } else {
578 Last = First;
579 LastLen = Len;
580 FirstLen = Len;
581 }
582
583 ASSERT (Last >= First);
584 BlockOpNum = Last - First + 1;
585 CurBlockOp = 0;
586
587 if (HeadSpace != 0) {
588 //
589 // Allocate an extra block to accommodate the head space.
590 //
591 BlockOpNum++;
592
593 Child = NetbufAllocStruct (1, BlockOpNum);
594
595 if (Child == NULL) {
596 return NULL;
597 }
598
599 FirstBulk = AllocatePool (HeadSpace);
600
601 if (FirstBulk == NULL) {
602 goto FreeChild;
603 }
604
605 Vector = Child->Vector;
606 Vector->Free = NetbufGetFragmentFree;
607 Vector->Arg = Nbuf->Vector;
608 Vector->Flag = NET_VECTOR_OWN_FIRST;
609 Vector->Len = HeadSpace;
610
611 //
612 // Reserve the head space in the first block
613 //
614 NetbufSetBlock (Child, FirstBulk, HeadSpace, 0);
615 Child->BlockOp[0].Head += HeadSpace;
616 Child->BlockOp[0].Size = 0;
617 CurBlockOp++;
618 } else {
619 Child = NetbufAllocStruct (0, BlockOpNum);
620
621 if (Child == NULL) {
622 return NULL;
623 }
624
625 Child->Vector = Nbuf->Vector;
626 }
627
628 NET_GET_REF (Nbuf->Vector);
629 Child->TotalSize = Len;
630
631 //
632 // Set all the BlockOp up, the first and last one are special
633 // and need special process.
634 //
636 Child,
637 Nbuf->BlockOp[First].Head + FirstSkip,
638 FirstLen,
639 CurBlockOp++
640 );
641
642 for (Index = First + 1; Index < Last; Index++) {
644 Child,
645 BlockOp[Index].Head,
646 BlockOp[Index].Size,
647 CurBlockOp++
648 );
649 }
650
651 if (First != Last) {
653 Child,
654 BlockOp[Last].Head,
655 LastLen,
656 CurBlockOp
657 );
658 }
659
660 CopyMem (Child->ProtoData, Nbuf->ProtoData, NET_PROTO_DATA);
661 return Child;
662
663FreeChild:
664
665 FreePool (Child);
666 return NULL;
667}
668
691NET_BUF *
692EFIAPI
694 IN NET_FRAGMENT *ExtFragment,
695 IN UINT32 ExtNum,
696 IN UINT32 HeadSpace,
697 IN UINT32 HeadLen,
698 IN NET_VECTOR_EXT_FREE ExtFree,
699 IN VOID *Arg OPTIONAL
700 )
701{
702 NET_BUF *Nbuf;
703 NET_VECTOR *Vector;
704 NET_FRAGMENT SavedFragment;
705 UINT32 SavedIndex;
706 UINT32 TotalLen;
707 UINT32 BlockNum;
708 UINT8 *FirstBlock;
709 UINT32 FirstBlockLen;
710 UINT8 *Header;
711 UINT32 CurBlock;
712 UINT32 Index;
713 UINT32 Len;
714 UINT32 Copied;
715
716 ASSERT ((ExtFragment != NULL) && (ExtNum > 0) && (ExtFree != NULL));
717
718 SavedFragment.Bulk = NULL;
719 SavedFragment.Len = 0;
720
721 FirstBlockLen = 0;
722 FirstBlock = NULL;
723 BlockNum = ExtNum;
724 Index = 0;
725 TotalLen = 0;
726 SavedIndex = 0;
727 Len = 0;
728 Copied = 0;
729
730 //
731 // No need to consolidate the header if the first block is
732 // longer than the header length or there is only one block.
733 //
734 if ((ExtFragment[0].Len >= HeadLen) || (ExtNum == 1)) {
735 HeadLen = 0;
736 }
737
738 //
739 // Allocate an extra block if we need to:
740 // 1. Allocate some header space
741 // 2. aggreate the packet header
742 //
743 if ((HeadSpace != 0) || (HeadLen != 0)) {
744 FirstBlockLen = HeadLen + HeadSpace;
745 FirstBlock = AllocatePool (FirstBlockLen);
746
747 if (FirstBlock == NULL) {
748 return NULL;
749 }
750
751 BlockNum++;
752 }
753
754 //
755 // Copy the header to the first block, reduce the NET_BLOCK
756 // to allocate by one for each block that is completely covered
757 // by the first bulk.
758 //
759 if (HeadLen != 0) {
760 Len = HeadLen;
761 Header = FirstBlock + HeadSpace;
762
763 for (Index = 0; Index < ExtNum; Index++) {
764 if (Len >= ExtFragment[Index].Len) {
765 CopyMem (Header, ExtFragment[Index].Bulk, ExtFragment[Index].Len);
766
767 Copied += ExtFragment[Index].Len;
768 Len -= ExtFragment[Index].Len;
769 Header += ExtFragment[Index].Len;
770 TotalLen += ExtFragment[Index].Len;
771 BlockNum--;
772
773 if (Len == 0) {
774 //
775 // Increment the index number to point to the next
776 // non-empty fragment.
777 //
778 Index++;
779 break;
780 }
781 } else {
782 CopyMem (Header, ExtFragment[Index].Bulk, Len);
783
784 Copied += Len;
785 TotalLen += Len;
786
787 //
788 // Adjust the block structure to exclude the data copied,
789 // So, the left-over block can be processed as other blocks.
790 // But it must be recovered later. (SavedIndex > 0) always
791 // holds since we don't aggreate the header if the first block
792 // is bigger enough that the header is continuous
793 //
794 SavedIndex = Index;
795 SavedFragment = ExtFragment[Index];
796 ExtFragment[Index].Bulk += Len;
797 ExtFragment[Index].Len -= Len;
798 break;
799 }
800 }
801 }
802
803 Nbuf = NetbufAllocStruct (BlockNum, BlockNum);
804
805 if (Nbuf == NULL) {
806 goto FreeFirstBlock;
807 }
808
809 Vector = Nbuf->Vector;
810 Vector->Free = ExtFree;
811 Vector->Arg = Arg;
812 Vector->Flag = ((FirstBlockLen != 0) ? NET_VECTOR_OWN_FIRST : 0);
813
814 //
815 // Set the first block up which may contain
816 // some head space and aggregated header
817 //
818 CurBlock = 0;
819
820 if (FirstBlockLen != 0) {
821 NetbufSetBlock (Nbuf, FirstBlock, HeadSpace + Copied, 0);
822 Nbuf->BlockOp[0].Head += HeadSpace;
823 Nbuf->BlockOp[0].Size = Copied;
824
825 CurBlock++;
826 }
827
828 for ( ; Index < ExtNum; Index++) {
829 NetbufSetBlock (Nbuf, ExtFragment[Index].Bulk, ExtFragment[Index].Len, CurBlock);
830 TotalLen += ExtFragment[Index].Len;
831 CurBlock++;
832 }
833
834 Vector->Len = TotalLen + HeadSpace;
835 Nbuf->TotalSize = TotalLen;
836
837 if (SavedIndex != 0) {
838 ExtFragment[SavedIndex] = SavedFragment;
839 }
840
841 return Nbuf;
842
843FreeFirstBlock:
844 if (FirstBlock != NULL) {
845 FreePool (FirstBlock);
846 }
847
848 return NULL;
849}
850
865EFIAPI
867 IN NET_BUF *Nbuf,
868 IN OUT NET_FRAGMENT *ExtFragment,
869 IN OUT UINT32 *ExtNum
870 )
871{
872 UINT32 Index;
873 UINT32 Current;
874
875 Current = 0;
876
877 for (Index = 0; (Index < Nbuf->BlockOpNum); Index++) {
878 if (Nbuf->BlockOp[Index].Size == 0) {
879 continue;
880 }
881
882 if (Current < *ExtNum) {
883 ExtFragment[Current].Bulk = Nbuf->BlockOp[Index].Head;
884 ExtFragment[Current].Len = Nbuf->BlockOp[Index].Size;
885 Current++;
886 } else {
887 return EFI_BUFFER_TOO_SMALL;
888 }
889 }
890
891 *ExtNum = Current;
892 return EFI_SUCCESS;
893}
894
912NET_BUF *
913EFIAPI
915 IN LIST_ENTRY *BufList,
916 IN UINT32 HeadSpace,
917 IN UINT32 HeaderLen,
918 IN NET_VECTOR_EXT_FREE ExtFree,
919 IN VOID *Arg OPTIONAL
920 )
921{
922 NET_FRAGMENT *Fragment;
923 UINT32 FragmentNum;
924 LIST_ENTRY *Entry;
925 NET_BUF *Nbuf;
926 UINT32 Index;
927 UINT32 Current;
928
929 //
930 // Compute how many blocks are there
931 //
932 FragmentNum = 0;
933
934 NET_LIST_FOR_EACH (Entry, BufList) {
935 Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
936 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
937 FragmentNum += Nbuf->BlockOpNum;
938 }
939
940 //
941 // Allocate and copy block points
942 //
943 Fragment = AllocatePool (sizeof (NET_FRAGMENT) * FragmentNum);
944
945 if (Fragment == NULL) {
946 return NULL;
947 }
948
949 Current = 0;
950
951 NET_LIST_FOR_EACH (Entry, BufList) {
952 Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
953 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
954
955 for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
956 if (Nbuf->BlockOp[Index].Size != 0) {
957 Fragment[Current].Bulk = Nbuf->BlockOp[Index].Head;
958 Fragment[Current].Len = Nbuf->BlockOp[Index].Size;
959 Current++;
960 }
961 }
962 }
963
964 Nbuf = NetbufFromExt (Fragment, Current, HeadSpace, HeaderLen, ExtFree, Arg);
965 FreePool (Fragment);
966
967 return Nbuf;
968}
969
982VOID
983EFIAPI
985 IN OUT NET_BUF *Nbuf,
986 IN UINT32 Len
987 )
988{
989 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
990 NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
991
992 ASSERT ((Nbuf->BlockOpNum == 1) && (Nbuf->TotalSize == 0));
993 ASSERT ((Nbuf->Vector->Free == NULL) && (Nbuf->Vector->Len >= Len));
994
995 Nbuf->BlockOp[0].Head += Len;
996 Nbuf->BlockOp[0].Tail += Len;
997
998 ASSERT (Nbuf->BlockOp[0].Tail <= Nbuf->BlockOp[0].BlockTail);
999}
1000
1013UINT8 *
1014EFIAPI
1016 IN OUT NET_BUF *Nbuf,
1017 IN UINT32 Len,
1018 IN BOOLEAN FromHead
1019 )
1020{
1021 NET_BLOCK_OP *BlockOp;
1022 UINT32 Index;
1023 UINT8 *SavedTail;
1024
1025 Index = 0;
1026
1027 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
1028 NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
1029
1030 ASSERT (Len > 0);
1031
1032 if (FromHead) {
1033 //
1034 // Allocate some space from head. If the buffer is empty,
1035 // allocate from the first block. If it isn't, allocate
1036 // from the first non-empty block, or the block before that.
1037 //
1038 if (Nbuf->TotalSize == 0) {
1039 Index = 0;
1040 } else {
1041 NetbufGetByte (Nbuf, 0, &Index);
1042
1043 if ((Index != 0) && (NET_HEADSPACE (&(Nbuf->BlockOp[Index])) < Len)) {
1044 Index--;
1045 }
1046 }
1047
1048 BlockOp = &(Nbuf->BlockOp[Index]);
1049
1050 if (NET_HEADSPACE (BlockOp) < Len) {
1051 return NULL;
1052 }
1053
1054 BlockOp->Head -= Len;
1055 BlockOp->Size += Len;
1056 Nbuf->TotalSize += Len;
1057
1058 return BlockOp->Head;
1059 } else {
1060 //
1061 // Allocate some space from the tail. If the buffer is empty,
1062 // allocate from the first block. If it isn't, allocate
1063 // from the last non-empty block, or the block after that.
1064 //
1065 if (Nbuf->TotalSize == 0) {
1066 Index = 0;
1067 } else {
1068 NetbufGetByte (Nbuf, Nbuf->TotalSize - 1, &Index);
1069
1070 if ((NET_TAILSPACE (&(Nbuf->BlockOp[Index])) < Len) &&
1071 (Index < Nbuf->BlockOpNum - 1))
1072 {
1073 Index++;
1074 }
1075 }
1076
1077 BlockOp = &(Nbuf->BlockOp[Index]);
1078
1079 if (NET_TAILSPACE (BlockOp) < Len) {
1080 return NULL;
1081 }
1082
1083 SavedTail = BlockOp->Tail;
1084
1085 BlockOp->Tail += Len;
1086 BlockOp->Size += Len;
1087 Nbuf->TotalSize += Len;
1088
1089 return SavedTail;
1090 }
1091}
1092
1102VOID
1104 IN OUT NET_BLOCK_OP *BlockOp,
1105 IN UINT32 Len,
1106 IN BOOLEAN FromHead
1107 )
1108{
1109 ASSERT ((BlockOp != NULL) && (BlockOp->Size >= Len));
1110
1111 BlockOp->Size -= Len;
1112
1113 if (FromHead) {
1114 BlockOp->Head += Len;
1115 } else {
1116 BlockOp->Tail -= Len;
1117 }
1118}
1119
1132UINT32
1133EFIAPI
1135 IN OUT NET_BUF *Nbuf,
1136 IN UINT32 Len,
1137 IN BOOLEAN FromHead
1138 )
1139{
1140 NET_BLOCK_OP *BlockOp;
1141 UINT32 Index;
1142 UINT32 Trimmed;
1143
1144 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
1145
1146 if ((Len == 0) || (Nbuf->TotalSize == 0)) {
1147 return 0;
1148 }
1149
1150 if (Len > Nbuf->TotalSize) {
1151 Len = Nbuf->TotalSize;
1152 }
1153
1154 //
1155 // If FromTail is true, iterate backward. That
1156 // is, init Index to NBuf->BlockNum - 1, and
1157 // decrease it by 1 during each loop. Otherwise,
1158 // iterate forward. That is, init Index to 0, and
1159 // increase it by 1 during each loop.
1160 //
1161 Trimmed = 0;
1162 Nbuf->TotalSize -= Len;
1163
1164 Index = (FromHead ? 0 : Nbuf->BlockOpNum - 1);
1165 BlockOp = Nbuf->BlockOp;
1166
1167 for ( ; ;) {
1168 if (BlockOp[Index].Size == 0) {
1169 Index += (FromHead ? 1 : -1);
1170 continue;
1171 }
1172
1173 if (Len > BlockOp[Index].Size) {
1174 Len -= BlockOp[Index].Size;
1175 Trimmed += BlockOp[Index].Size;
1176 NetblockTrim (&BlockOp[Index], BlockOp[Index].Size, FromHead);
1177 } else {
1178 Trimmed += Len;
1179 NetblockTrim (&BlockOp[Index], Len, FromHead);
1180 break;
1181 }
1182
1183 Index += (FromHead ? 1 : -1);
1184 }
1185
1186 return Trimmed;
1187}
1188
1204UINT32
1205EFIAPI
1207 IN NET_BUF *Nbuf,
1208 IN UINT32 Offset,
1209 IN UINT32 Len,
1210 IN UINT8 *Dest
1211 )
1212{
1213 NET_BLOCK_OP *BlockOp;
1214 UINT32 Skip;
1215 UINT32 Left;
1216 UINT32 Copied;
1217 UINT32 Index;
1218 UINT32 Cur;
1219
1220 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
1221 ASSERT (Dest);
1222
1223 if ((Len == 0) || (Nbuf->TotalSize <= Offset)) {
1224 return 0;
1225 }
1226
1227 if (Nbuf->TotalSize - Offset < Len) {
1228 Len = Nbuf->TotalSize - Offset;
1229 }
1230
1231 BlockOp = Nbuf->BlockOp;
1232
1233 //
1234 // Skip to the offset. Don't make "Offset-By-One" error here.
1235 // Cur + BLOCK.SIZE is the first sequence number of next block.
1236 // So, (Offset < Cur + BLOCK.SIZE) means that the first byte
1237 // is in the current block. if (Offset == Cur + BLOCK.SIZE), the
1238 // first byte is the next block's first byte.
1239 //
1240 Cur = 0;
1241
1242 for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
1243 if (BlockOp[Index].Size == 0) {
1244 continue;
1245 }
1246
1247 if (Offset < Cur + BlockOp[Index].Size) {
1248 break;
1249 }
1250
1251 Cur += BlockOp[Index].Size;
1252 }
1253
1254 //
1255 // Cur is the sequence number of the first byte in the block
1256 // Offset - Cur is the number of bytes before first byte to
1257 // to copy in the current block.
1258 //
1259 Skip = Offset - Cur;
1260 Left = BlockOp[Index].Size - Skip;
1261
1262 if (Len <= Left) {
1263 CopyMem (Dest, BlockOp[Index].Head + Skip, Len);
1264 return Len;
1265 }
1266
1267 CopyMem (Dest, BlockOp[Index].Head + Skip, Left);
1268
1269 Dest += Left;
1270 Len -= Left;
1271 Copied = Left;
1272
1273 Index++;
1274
1275 for ( ; Index < Nbuf->BlockOpNum; Index++) {
1276 if (Len > BlockOp[Index].Size) {
1277 Len -= BlockOp[Index].Size;
1278 Copied += BlockOp[Index].Size;
1279
1280 CopyMem (Dest, BlockOp[Index].Head, BlockOp[Index].Size);
1281 Dest += BlockOp[Index].Size;
1282 } else {
1283 Copied += Len;
1284 CopyMem (Dest, BlockOp[Index].Head, Len);
1285 break;
1286 }
1287 }
1288
1289 return Copied;
1290}
1291
1298VOID
1299EFIAPI
1301 IN OUT NET_BUF_QUEUE *NbufQue
1302 )
1303{
1304 NbufQue->Signature = NET_QUE_SIGNATURE;
1305 NbufQue->RefCnt = 1;
1306 InitializeListHead (&NbufQue->List);
1307
1308 InitializeListHead (&NbufQue->BufList);
1309 NbufQue->BufSize = 0;
1310 NbufQue->BufNum = 0;
1311}
1312
1321EFIAPI
1323 VOID
1324 )
1325{
1326 NET_BUF_QUEUE *NbufQue;
1327
1328 NbufQue = AllocatePool (sizeof (NET_BUF_QUEUE));
1329 if (NbufQue == NULL) {
1330 return NULL;
1331 }
1332
1333 NetbufQueInit (NbufQue);
1334
1335 return NbufQue;
1336}
1337
1348VOID
1349EFIAPI
1351 IN NET_BUF_QUEUE *NbufQue
1352 )
1353{
1354 ASSERT (NbufQue != NULL);
1355 NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
1356
1357 NbufQue->RefCnt--;
1358
1359 if (NbufQue->RefCnt == 0) {
1360 NetbufQueFlush (NbufQue);
1361 FreePool (NbufQue);
1362 }
1363}
1364
1372VOID
1373EFIAPI
1375 IN OUT NET_BUF_QUEUE *NbufQue,
1376 IN OUT NET_BUF *Nbuf
1377 )
1378{
1379 NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
1380 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
1381
1382 InsertTailList (&NbufQue->BufList, &Nbuf->List);
1383
1384 NbufQue->BufSize += Nbuf->TotalSize;
1385 NbufQue->BufNum++;
1386}
1387
1397NET_BUF *
1398EFIAPI
1400 IN OUT NET_BUF_QUEUE *NbufQue
1401 )
1402{
1403 NET_BUF *First;
1404
1405 NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
1406
1407 if (NbufQue->BufNum == 0) {
1408 return NULL;
1409 }
1410
1411 First = NET_LIST_USER_STRUCT (NbufQue->BufList.ForwardLink, NET_BUF, List);
1412
1413 NetListRemoveHead (&NbufQue->BufList);
1414
1415 NbufQue->BufSize -= First->TotalSize;
1416 NbufQue->BufNum--;
1417 return First;
1418}
1419
1436UINT32
1437EFIAPI
1439 IN NET_BUF_QUEUE *NbufQue,
1440 IN UINT32 Offset,
1441 IN UINT32 Len,
1442 OUT UINT8 *Dest
1443 )
1444{
1445 LIST_ENTRY *Entry;
1446 NET_BUF *Nbuf;
1447 UINT32 Skip;
1448 UINT32 Left;
1449 UINT32 Cur;
1450 UINT32 Copied;
1451
1452 NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
1453 ASSERT (Dest != NULL);
1454
1455 if ((Len == 0) || (NbufQue->BufSize <= Offset)) {
1456 return 0;
1457 }
1458
1459 if (NbufQue->BufSize - Offset < Len) {
1460 Len = NbufQue->BufSize - Offset;
1461 }
1462
1463 //
1464 // skip to the Offset
1465 //
1466 Cur = 0;
1467 Nbuf = NULL;
1468
1469 NET_LIST_FOR_EACH (Entry, &NbufQue->BufList) {
1470 Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
1471
1472 if (Offset < Cur + Nbuf->TotalSize) {
1473 break;
1474 }
1475
1476 Cur += Nbuf->TotalSize;
1477 }
1478
1479 ASSERT (Nbuf != NULL);
1480
1481 //
1482 // Copy the data in the first buffer.
1483 //
1484 Skip = Offset - Cur;
1485 Left = Nbuf->TotalSize - Skip;
1486
1487 if (Len < Left) {
1488 return NetbufCopy (Nbuf, Skip, Len, Dest);
1489 }
1490
1491 NetbufCopy (Nbuf, Skip, Left, Dest);
1492 Dest += Left;
1493 Len -= Left;
1494 Copied = Left;
1495
1496 //
1497 // Iterate over the others
1498 //
1499 Entry = Entry->ForwardLink;
1500
1501 while ((Len > 0) && (Entry != &NbufQue->BufList)) {
1502 Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
1503
1504 if (Len > Nbuf->TotalSize) {
1505 Len -= Nbuf->TotalSize;
1506 Copied += Nbuf->TotalSize;
1507
1508 NetbufCopy (Nbuf, 0, Nbuf->TotalSize, Dest);
1509 Dest += Nbuf->TotalSize;
1510 } else {
1511 NetbufCopy (Nbuf, 0, Len, Dest);
1512 Copied += Len;
1513 break;
1514 }
1515
1516 Entry = Entry->ForwardLink;
1517 }
1518
1519 return Copied;
1520}
1521
1535UINT32
1536EFIAPI
1538 IN OUT NET_BUF_QUEUE *NbufQue,
1539 IN UINT32 Len
1540 )
1541{
1542 LIST_ENTRY *Entry;
1543 LIST_ENTRY *Next;
1544 NET_BUF *Nbuf;
1545 UINT32 Trimmed;
1546
1547 NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
1548
1549 if (Len == 0) {
1550 return 0;
1551 }
1552
1553 if (Len > NbufQue->BufSize) {
1554 Len = NbufQue->BufSize;
1555 }
1556
1557 NbufQue->BufSize -= Len;
1558 Trimmed = 0;
1559
1560 NET_LIST_FOR_EACH_SAFE (Entry, Next, &NbufQue->BufList) {
1561 Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);
1562
1563 if (Len >= Nbuf->TotalSize) {
1564 Trimmed += Nbuf->TotalSize;
1565 Len -= Nbuf->TotalSize;
1566
1567 RemoveEntryList (Entry);
1568 NetbufFree (Nbuf);
1569
1570 NbufQue->BufNum--;
1571
1572 if (Len == 0) {
1573 break;
1574 }
1575 } else {
1576 Trimmed += NetbufTrim (Nbuf, Len, NET_BUF_HEAD);
1577 break;
1578 }
1579 }
1580
1581 return Trimmed;
1582}
1583
1590VOID
1591EFIAPI
1593 IN OUT NET_BUF_QUEUE *NbufQue
1594 )
1595{
1596 NET_CHECK_SIGNATURE (NbufQue, NET_QUE_SIGNATURE);
1597
1598 NetbufFreeList (&NbufQue->BufList);
1599
1600 NbufQue->BufNum = 0;
1601 NbufQue->BufSize = 0;
1602}
1603
1613UINT16
1614EFIAPI
1616 IN UINT8 *Bulk,
1617 IN UINT32 Len
1618 )
1619{
1620 register UINT32 Sum;
1621
1622 Sum = 0;
1623
1624 //
1625 // Add left-over byte, if any
1626 //
1627 if (Len % 2 != 0) {
1628 Sum += *(Bulk + Len - 1);
1629 }
1630
1631 while (Len > 1) {
1632 Sum += *(UINT16 *)Bulk;
1633 Bulk += 2;
1634 Len -= 2;
1635 }
1636
1637 //
1638 // Fold 32-bit sum to 16 bits
1639 //
1640 while ((Sum >> 16) != 0) {
1641 Sum = (Sum & 0xffff) + (Sum >> 16);
1642 }
1643
1644 return (UINT16)Sum;
1645}
1646
1656UINT16
1657EFIAPI
1659 IN UINT16 Checksum1,
1660 IN UINT16 Checksum2
1661 )
1662{
1663 UINT32 Sum;
1664
1665 Sum = Checksum1 + Checksum2;
1666
1667 //
1668 // two UINT16 can only add up to a carry of 1.
1669 //
1670 if ((Sum >> 16) != 0) {
1671 Sum = (Sum & 0xffff) + 1;
1672 }
1673
1674 return (UINT16)Sum;
1675}
1676
1685UINT16
1686EFIAPI
1688 IN NET_BUF *Nbuf
1689 )
1690{
1691 NET_BLOCK_OP *BlockOp;
1692 UINT32 Offset;
1693 UINT16 TotalSum;
1694 UINT16 BlockSum;
1695 UINT32 Index;
1696
1697 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
1698
1699 TotalSum = 0;
1700 Offset = 0;
1701 BlockOp = Nbuf->BlockOp;
1702
1703 for (Index = 0; Index < Nbuf->BlockOpNum; Index++) {
1704 if (BlockOp[Index].Size == 0) {
1705 continue;
1706 }
1707
1708 BlockSum = NetblockChecksum (BlockOp[Index].Head, BlockOp[Index].Size);
1709
1710 if ((Offset & 0x01) != 0) {
1711 //
1712 // The checksum starts with an odd byte, swap
1713 // the checksum before added to total checksum
1714 //
1715 BlockSum = SwapBytes16 (BlockSum);
1716 }
1717
1718 TotalSum = NetAddChecksum (BlockSum, TotalSum);
1719 Offset += BlockOp[Index].Size;
1720 }
1721
1722 return TotalSum;
1723}
1724
1738UINT16
1739EFIAPI
1741 IN IP4_ADDR Src,
1742 IN IP4_ADDR Dst,
1743 IN UINT8 Proto,
1744 IN UINT16 Len
1745 )
1746{
1747 NET_PSEUDO_HDR Hdr;
1748
1749 //
1750 // Zero the memory to relieve align problems
1751 //
1752 ZeroMem (&Hdr, sizeof (Hdr));
1753
1754 Hdr.SrcIp = Src;
1755 Hdr.DstIp = Dst;
1756 Hdr.Protocol = Proto;
1757 Hdr.Len = HTONS (Len);
1758
1759 return NetblockChecksum ((UINT8 *)&Hdr, sizeof (Hdr));
1760}
1761
1775UINT16
1776EFIAPI
1778 IN EFI_IPv6_ADDRESS *Src,
1779 IN EFI_IPv6_ADDRESS *Dst,
1780 IN UINT8 NextHeader,
1781 IN UINT32 Len
1782 )
1783{
1785
1786 //
1787 // Zero the memory to relieve align problems
1788 //
1789 ZeroMem (&Hdr, sizeof (Hdr));
1790
1791 IP6_COPY_ADDRESS (&Hdr.SrcIp, Src);
1792 IP6_COPY_ADDRESS (&Hdr.DstIp, Dst);
1793
1794 Hdr.NextHeader = NextHeader;
1795 Hdr.Len = HTONL (Len);
1796
1797 return NetblockChecksum ((UINT8 *)&Hdr, sizeof (Hdr));
1798}
1799
1811VOID
1813 NET_BUF *Nbuf
1814 )
1815{
1816 NET_CHECK_SIGNATURE (Nbuf, NET_BUF_SIGNATURE);
1817 ASSERT (Nbuf->RefCnt > 0);
1818
1819 Nbuf->RefCnt--;
1820
1821 if (Nbuf->RefCnt == 0) {
1822 //
1823 // Update Vector only when NBuf is to be released. That is,
1824 // all the sharing of Nbuf increse Vector's RefCnt by one
1825 //
1826 NET_CHECK_SIGNATURE (Nbuf->Vector, NET_VECTOR_SIGNATURE);
1827 ASSERT (Nbuf->Vector->RefCnt > 0);
1828
1829 Nbuf->Vector->RefCnt--;
1830
1831 if (Nbuf->Vector->RefCnt > 0) {
1832 return;
1833 }
1834
1835 //
1836 // If NET_VECTOR_OWN_FIRST is set, release the first block since it is
1837 // allocated by us
1838 //
1839 if ((Nbuf->Vector->Flag & NET_VECTOR_OWN_FIRST) != 0) {
1840 FreePool (Nbuf->Vector->Block[0].Bulk);
1841 }
1842
1843 FreePool (Nbuf->Vector);
1844 FreePool (Nbuf);
1845 }
1846}
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
UINT16 EFIAPI SwapBytes16(IN UINT16 Value)
Definition: SwapBytes16.c:25
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
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
NODE Child(IN NODE LoopVar6, IN UINT8 LoopVar5)
Definition: Compress.c:265
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:195
VOID EFIAPI NetbufQueInit(IN OUT NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1300
VOID EFIAPI NetbufReserve(IN OUT NET_BUF *Nbuf, IN UINT32 Len)
Definition: NetBuffer.c:984
UINT16 EFIAPI NetIp6PseudoHeadChecksum(IN EFI_IPv6_ADDRESS *Src, IN EFI_IPv6_ADDRESS *Dst, IN UINT8 NextHeader, IN UINT32 Len)
Definition: NetBuffer.c:1777
VOID NetbufFreeVector(IN NET_VECTOR *Vector)
Definition: NetBuffer.c:142
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
UINT16 EFIAPI NetbufChecksum(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:1687
EFI_STATUS EFIAPI NetbufBuildExt(IN NET_BUF *Nbuf, IN OUT NET_FRAGMENT *ExtFragment, IN OUT UINT32 *ExtNum)
Definition: NetBuffer.c:866
UINT32 EFIAPI NetbufQueTrim(IN OUT NET_BUF_QUEUE *NbufQue, IN UINT32 Len)
Definition: NetBuffer.c:1537
UINT16 EFIAPI NetblockChecksum(IN UINT8 *Bulk, IN UINT32 Len)
Definition: NetBuffer.c:1615
UINT32 EFIAPI NetbufQueCopy(IN NET_BUF_QUEUE *NbufQue, IN UINT32 Offset, IN UINT32 Len, OUT UINT8 *Dest)
Definition: NetBuffer.c:1438
VOID EFIAPI NetbufQueFlush(IN OUT NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1592
UINT32 EFIAPI NetbufCopy(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT8 *Dest)
Definition: NetBuffer.c:1206
VOID NetblockTrim(IN OUT NET_BLOCK_OP *BlockOp, IN UINT32 Len, IN BOOLEAN FromHead)
Definition: NetBuffer.c:1103
UINT16 EFIAPI NetAddChecksum(IN UINT16 Checksum1, IN UINT16 Checksum2)
Definition: NetBuffer.c:1658
NET_BUF_QUEUE *EFIAPI NetbufQueAlloc(VOID)
Definition: NetBuffer.c:1322
NET_BUF *EFIAPI NetbufAlloc(IN UINT32 Len)
Definition: NetBuffer.c:89
NET_BUF *EFIAPI NetbufGetFragment(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT32 HeadSpace)
Definition: NetBuffer.c:510
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
VOID NetbufSetBlock(IN OUT NET_BUF *Nbuf, IN UINT8 *Bulk, IN UINT32 Len, IN UINT32 Index)
Definition: NetBuffer.c:410
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
NET_BUF * NetbufAllocStruct(IN UINT32 BlockNum, IN UINT32 BlockOpNum)
Definition: NetBuffer.c:32
VOID NetIpSecNetbufFree(NET_BUF *Nbuf)
Definition: NetBuffer.c:1812
VOID NetbufSetBlockOp(IN OUT NET_BUF *Nbuf, IN UINT8 *Bulk, IN UINT32 Len, IN UINT32 Index)
Definition: NetBuffer.c:450
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
VOID EFIAPI NetbufFreeList(IN OUT LIST_ENTRY *Head)
Definition: NetBuffer.c:319
VOID EFIAPI NetbufQueFree(IN NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1350
UINT16 EFIAPI NetPseudoHeadChecksum(IN IP4_ADDR Src, IN IP4_ADDR Dst, IN UINT8 Proto, IN UINT16 Len)
Definition: NetBuffer.c:1740
UINT8 *EFIAPI NetbufGetByte(IN NET_BUF *Nbuf, IN UINT32 Offset, OUT UINT32 *Index OPTIONAL)
Definition: NetBuffer.c:359
VOID EFIAPI NetbufQueAppend(IN OUT NET_BUF_QUEUE *NbufQue, IN OUT NET_BUF *Nbuf)
Definition: NetBuffer.c:1374
VOID EFIAPI NetbufGetFragmentFree(IN VOID *Arg)
Definition: NetBuffer.c:481
NET_BUF *EFIAPI NetbufQueRemove(IN OUT NET_BUF_QUEUE *NbufQue)
Definition: NetBuffer.c:1399
LIST_ENTRY *EFIAPI NetListRemoveHead(IN OUT LIST_ENTRY *Head)
Definition: DxeNetLib.c:1090
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS