TianoCore EDK2 master
Loading...
Searching...
No Matches
DxeIpIoLib.c
Go to the documentation of this file.
1
9#include <Uefi.h>
10
11#include <Protocol/Udp4.h>
12
13#include <Library/IpIoLib.h>
14#include <Library/BaseLib.h>
15#include <Library/DebugLib.h>
19#include <Library/DpcLib.h>
20
22 &mActiveIpIoList,
23 &mActiveIpIoList
24};
25
26GLOBAL_REMOVE_IF_UNREFERENCED EFI_IP4_CONFIG_DATA mIp4IoDefaultIpConfigData = {
27 EFI_IP_PROTO_UDP,
28 FALSE,
29 TRUE,
30 FALSE,
31 FALSE,
32 FALSE,
33 {
34 { 0, 0, 0, 0 }
35 },
36 {
37 { 0, 0, 0, 0 }
38 },
39 0,
40 255,
41 FALSE,
42 FALSE,
43 0,
44 0
45};
46
47GLOBAL_REMOVE_IF_UNREFERENCED EFI_IP6_CONFIG_DATA mIp6IoDefaultIpConfigData = {
48 EFI_IP_PROTO_UDP,
49 FALSE,
50 TRUE,
51 FALSE,
52 {
53 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
54 },
55 {
56 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
57 },
58 0,
59 255,
60 0,
61 0,
62 0
63};
64
66 { FALSE, TRUE }, // ICMP_ERR_UNREACH_NET
67 { FALSE, TRUE }, // ICMP_ERR_UNREACH_HOST
68 { TRUE, TRUE }, // ICMP_ERR_UNREACH_PROTOCOL
69 { TRUE, TRUE }, // ICMP_ERR_UNREACH_PORT
70 { TRUE, TRUE }, // ICMP_ERR_MSGSIZE
71 { FALSE, TRUE }, // ICMP_ERR_UNREACH_SRCFAIL
72 { FALSE, TRUE }, // ICMP_ERR_TIMXCEED_INTRANS
73 { FALSE, TRUE }, // ICMP_ERR_TIMEXCEED_REASS
74 { FALSE, FALSE }, // ICMP_ERR_QUENCH
75 { FALSE, TRUE } // ICMP_ERR_PARAMPROB
76};
77
79 { FALSE, TRUE }, // ICMP6_ERR_UNREACH_NET
80 { FALSE, TRUE }, // ICMP6_ERR_UNREACH_HOST
81 { TRUE, TRUE }, // ICMP6_ERR_UNREACH_PROTOCOL
82 { TRUE, TRUE }, // ICMP6_ERR_UNREACH_PORT
83 { TRUE, TRUE }, // ICMP6_ERR_PACKAGE_TOOBIG
84 { FALSE, TRUE }, // ICMP6_ERR_TIMXCEED_HOPLIMIT
85 { FALSE, TRUE }, // ICMP6_ERR_TIMXCEED_REASS
86 { FALSE, TRUE }, // ICMP6_ERR_PARAMPROB_HEADER
87 { FALSE, TRUE }, // ICMP6_ERR_PARAMPROB_NEXHEADER
88 { FALSE, TRUE } // ICMP6_ERR_PARAMPROB_IPV6OPTION
89};
90
97VOID
98EFIAPI
100 IN VOID *Context
101 );
102
110VOID
111EFIAPI
113 IN EFI_EVENT Event,
114 IN VOID *Context
115 );
116
136 IN EFI_HANDLE ControllerHandle,
137 IN EFI_HANDLE ImageHandle,
138 IN EFI_HANDLE *ChildHandle,
139 IN UINT8 IpVersion,
140 OUT VOID **Interface
141 )
142{
143 EFI_STATUS Status;
144 EFI_GUID *ServiceBindingGuid;
145 EFI_GUID *IpProtocolGuid;
146
147 if (IpVersion == IP_VERSION_4) {
148 ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;
149 IpProtocolGuid = &gEfiIp4ProtocolGuid;
150 } else if (IpVersion == IP_VERSION_6) {
151 ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid;
152 IpProtocolGuid = &gEfiIp6ProtocolGuid;
153 } else {
154 return EFI_UNSUPPORTED;
155 }
156
157 //
158 // Create an IP child.
159 //
160 Status = NetLibCreateServiceChild (
161 ControllerHandle,
162 ImageHandle,
163 ServiceBindingGuid,
164 ChildHandle
165 );
166 if (EFI_ERROR (Status)) {
167 return Status;
168 }
169
170 //
171 // Open the IP protocol installed on the *ChildHandle.
172 //
173 Status = gBS->OpenProtocol (
174 *ChildHandle,
175 IpProtocolGuid,
176 Interface,
177 ImageHandle,
178 ControllerHandle,
179 EFI_OPEN_PROTOCOL_BY_DRIVER
180 );
181 if (EFI_ERROR (Status)) {
182 //
183 // On failure, destroy the IP child.
184 //
186 ControllerHandle,
187 ImageHandle,
188 ServiceBindingGuid,
189 *ChildHandle
190 );
191 }
192
193 return Status;
194}
195
213 IN EFI_HANDLE ControllerHandle,
214 IN EFI_HANDLE ImageHandle,
215 IN EFI_HANDLE ChildHandle,
216 IN UINT8 IpVersion
217 )
218{
219 EFI_STATUS Status;
220 EFI_GUID *ServiceBindingGuid;
221 EFI_GUID *IpProtocolGuid;
222
223 if (IpVersion == IP_VERSION_4) {
224 ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;
225 IpProtocolGuid = &gEfiIp4ProtocolGuid;
226 } else if (IpVersion == IP_VERSION_6) {
227 ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid;
228 IpProtocolGuid = &gEfiIp6ProtocolGuid;
229 } else {
230 return EFI_UNSUPPORTED;
231 }
232
233 //
234 // Close the previously opened IP protocol.
235 //
236 Status = gBS->CloseProtocol (
237 ChildHandle,
238 IpProtocolGuid,
239 ImageHandle,
240 ControllerHandle
241 );
242 if (EFI_ERROR (Status)) {
243 return Status;
244 }
245
246 //
247 // Destroy the IP child.
248 //
250 ControllerHandle,
251 ImageHandle,
252 ServiceBindingGuid,
253 ChildHandle
254 );
255}
256
271 IN IP_IO *IpIo,
272 IN OUT NET_BUF *Pkt,
273 IN EFI_NET_SESSION_DATA *Session
274 )
275{
276 IP4_ICMP_ERROR_HEAD *IcmpHdr;
277 EFI_IP4_HEADER *IpHdr;
278 UINT8 IcmpErr;
279 UINT8 *PayLoadHdr;
280 UINT8 Type;
281 UINT8 Code;
282 UINT32 TrimBytes;
283
284 ASSERT (IpIo != NULL);
285 ASSERT (Pkt != NULL);
286 ASSERT (Session != NULL);
287 ASSERT (IpIo->IpVersion == IP_VERSION_4);
288
289 //
290 // Check the ICMP packet length.
291 //
292 if (Pkt->TotalSize < sizeof (IP4_ICMP_ERROR_HEAD)) {
293 return EFI_ABORTED;
294 }
295
296 IcmpHdr = NET_PROTO_HDR (Pkt, IP4_ICMP_ERROR_HEAD);
297 IpHdr = (EFI_IP4_HEADER *)(&IcmpHdr->IpHead);
298
299 if (Pkt->TotalSize < ICMP_ERRLEN (IpHdr)) {
300 return EFI_ABORTED;
301 }
302
303 Type = IcmpHdr->Head.Type;
304 Code = IcmpHdr->Head.Code;
305
306 //
307 // Analyze the ICMP Error in this ICMP pkt
308 //
309 switch (Type) {
310 case ICMP_TYPE_UNREACH:
311 switch (Code) {
312 case ICMP_CODE_UNREACH_NET:
313 case ICMP_CODE_UNREACH_HOST:
314 case ICMP_CODE_UNREACH_PROTOCOL:
315 case ICMP_CODE_UNREACH_PORT:
316 case ICMP_CODE_UNREACH_SRCFAIL:
317 IcmpErr = (UINT8)(ICMP_ERR_UNREACH_NET + Code);
318
319 break;
320
321 case ICMP_CODE_UNREACH_NEEDFRAG:
322 IcmpErr = ICMP_ERR_MSGSIZE;
323
324 break;
325
326 case ICMP_CODE_UNREACH_NET_UNKNOWN:
327 case ICMP_CODE_UNREACH_NET_PROHIB:
328 case ICMP_CODE_UNREACH_TOSNET:
329 IcmpErr = ICMP_ERR_UNREACH_NET;
330
331 break;
332
333 case ICMP_CODE_UNREACH_HOST_UNKNOWN:
334 case ICMP_CODE_UNREACH_ISOLATED:
335 case ICMP_CODE_UNREACH_HOST_PROHIB:
336 case ICMP_CODE_UNREACH_TOSHOST:
337 IcmpErr = ICMP_ERR_UNREACH_HOST;
338
339 break;
340
341 default:
342 return EFI_ABORTED;
343 }
344
345 break;
346
347 case ICMP_TYPE_TIMXCEED:
348 if (Code > 1) {
349 return EFI_ABORTED;
350 }
351
352 IcmpErr = (UINT8)(Code + ICMP_ERR_TIMXCEED_INTRANS);
353
354 break;
355
356 case ICMP_TYPE_PARAMPROB:
357 if (Code > 1) {
358 return EFI_ABORTED;
359 }
360
361 IcmpErr = ICMP_ERR_PARAMPROB;
362
363 break;
364
365 case ICMP_TYPE_SOURCEQUENCH:
366 if (Code != 0) {
367 return EFI_ABORTED;
368 }
369
370 IcmpErr = ICMP_ERR_QUENCH;
371
372 break;
373
374 default:
375 return EFI_ABORTED;
376 }
377
378 //
379 // Notify user the ICMP pkt only containing payload except
380 // IP and ICMP header
381 //
382 PayLoadHdr = (UINT8 *)((UINT8 *)IpHdr + EFI_IP4_HEADER_LEN (IpHdr));
383 TrimBytes = (UINT32)(PayLoadHdr - (UINT8 *)IcmpHdr);
384
385 NetbufTrim (Pkt, TrimBytes, TRUE);
386
387 //
388 // If the input packet has invalid format, and TrimBytes is larger than
389 // the packet size, the NetbufTrim might trim the packet to zero.
390 //
391 if (Pkt->TotalSize != 0) {
392 IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext);
393 }
394
395 return EFI_SUCCESS;
396}
397
412 IN IP_IO *IpIo,
413 IN OUT NET_BUF *Pkt,
414 IN EFI_NET_SESSION_DATA *Session
415 )
416{
417 IP6_ICMP_ERROR_HEAD *IcmpHdr;
418 EFI_IP6_HEADER *IpHdr;
419 UINT8 IcmpErr;
420 UINT8 *PayLoadHdr;
421 UINT8 Type;
422 UINT8 Code;
423 UINT8 NextHeader;
424 UINT32 TrimBytes;
425 BOOLEAN Flag;
426
427 ASSERT (IpIo != NULL);
428 ASSERT (Pkt != NULL);
429 ASSERT (Session != NULL);
430 ASSERT (IpIo->IpVersion == IP_VERSION_6);
431
432 //
433 // Check the ICMPv6 packet length.
434 //
435 if (Pkt->TotalSize < sizeof (IP6_ICMP_ERROR_HEAD)) {
436 return EFI_ABORTED;
437 }
438
439 IcmpHdr = NET_PROTO_HDR (Pkt, IP6_ICMP_ERROR_HEAD);
440 Type = IcmpHdr->Head.Type;
441 Code = IcmpHdr->Head.Code;
442
443 //
444 // Analyze the ICMPv6 Error in this ICMPv6 packet
445 //
446 switch (Type) {
448 switch (Code) {
450 case ICMP_V6_BEYOND_SCOPE:
451 case ICMP_V6_ROUTE_REJECTED:
452 IcmpErr = ICMP6_ERR_UNREACH_NET;
453
454 break;
455
456 case ICMP_V6_COMM_PROHIBITED:
457 case ICMP_V6_ADDR_UNREACHABLE:
458 case ICMP_V6_SOURCE_ADDR_FAILED:
459 IcmpErr = ICMP6_ERR_UNREACH_HOST;
460
461 break;
462
463 case ICMP_V6_PORT_UNREACHABLE:
464 IcmpErr = ICMP6_ERR_UNREACH_PORT;
465
466 break;
467
468 default:
469 return EFI_ABORTED;
470 }
471
472 break;
473
474 case ICMP_V6_PACKET_TOO_BIG:
475 if (Code >= 1) {
476 return EFI_ABORTED;
477 }
478
479 IcmpErr = ICMP6_ERR_PACKAGE_TOOBIG;
480
481 break;
482
483 case ICMP_V6_TIME_EXCEEDED:
484 if (Code > 1) {
485 return EFI_ABORTED;
486 }
487
488 IcmpErr = (UINT8)(ICMP6_ERR_TIMXCEED_HOPLIMIT + Code);
489
490 break;
491
492 case ICMP_V6_PARAMETER_PROBLEM:
493 if (Code > 3) {
494 return EFI_ABORTED;
495 }
496
497 IcmpErr = (UINT8)(ICMP6_ERR_PARAMPROB_HEADER + Code);
498
499 break;
500
501 default:
502
503 return EFI_ABORTED;
504 }
505
506 //
507 // Notify user the ICMPv6 packet only containing payload except
508 // IPv6 basic header, extension header and ICMP header
509 //
510
511 IpHdr = (EFI_IP6_HEADER *)(&IcmpHdr->IpHead);
512 NextHeader = IpHdr->NextHeader;
513 PayLoadHdr = (UINT8 *)((UINT8 *)IcmpHdr + sizeof (IP6_ICMP_ERROR_HEAD));
514 Flag = TRUE;
515
516 do {
517 switch (NextHeader) {
518 case EFI_IP_PROTO_UDP:
519 case EFI_IP_PROTO_TCP:
520 case EFI_IP_PROTO_ICMP:
521 case IP6_NO_NEXT_HEADER:
522 Flag = FALSE;
523
524 break;
525
526 case IP6_HOP_BY_HOP:
527 case IP6_DESTINATION:
528 //
529 // The Hdr Ext Len is 8-bit unsigned integer in 8-octet units, not including
530 // the first 8 octets.
531 //
532 NextHeader = *(PayLoadHdr);
533 PayLoadHdr = (UINT8 *)(PayLoadHdr + (*(PayLoadHdr + 1) + 1) * 8);
534
535 break;
536
537 case IP6_FRAGMENT:
538 //
539 // The Fragment Header Length is 8 octets.
540 //
541 NextHeader = *(PayLoadHdr);
542 PayLoadHdr = (UINT8 *)(PayLoadHdr + 8);
543
544 break;
545
546 default:
547
548 return EFI_ABORTED;
549 }
550 } while (Flag);
551
552 TrimBytes = (UINT32)(PayLoadHdr - (UINT8 *)IcmpHdr);
553
554 NetbufTrim (Pkt, TrimBytes, TRUE);
555
556 //
557 // If the input packet has invalid format, and TrimBytes is larger than
558 // the packet size, the NetbufTrim might trim the packet to zero.
559 //
560 if (Pkt->TotalSize != 0) {
561 IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext);
562 }
563
564 return EFI_SUCCESS;
565}
566
581 IN IP_IO *IpIo,
582 IN OUT NET_BUF *Pkt,
583 IN EFI_NET_SESSION_DATA *Session
584 )
585{
586 if (IpIo->IpVersion == IP_VERSION_4) {
587 return IpIoIcmpv4Handler (IpIo, Pkt, Session);
588 } else if (IpIo->IpVersion == IP_VERSION_6) {
589 return IpIoIcmpv6Handler (IpIo, Pkt, Session);
590 } else {
591 return EFI_UNSUPPORTED;
592 }
593}
594
603VOID
604EFIAPI
606 IN VOID *Event
607 )
608{
609 gBS->SignalEvent ((EFI_EVENT)Event);
610}
611
630 IN OUT IP_IO *IpIo,
631 IN OUT NET_BUF *Pkt,
632 IN IP_IO_IP_PROTOCOL Sender,
633 IN VOID *Context OPTIONAL,
634 IN VOID *NotifyData OPTIONAL,
635 IN EFI_IP_ADDRESS *Dest OPTIONAL,
636 IN IP_IO_OVERRIDE *Override
637 )
638{
639 IP_IO_SEND_ENTRY *SndEntry;
640 EFI_EVENT Event;
641 EFI_STATUS Status;
642 NET_FRAGMENT *ExtFragment;
643 UINT32 FragmentCount;
644 IP_IO_OVERRIDE *OverrideData;
645 IP_IO_IP_TX_DATA *TxData;
646 EFI_IP4_TRANSMIT_DATA *Ip4TxData;
647 EFI_IP6_TRANSMIT_DATA *Ip6TxData;
648
649 if ((IpIo->IpVersion != IP_VERSION_4) && (IpIo->IpVersion != IP_VERSION_6)) {
650 return NULL;
651 }
652
653 Event = NULL;
654 TxData = NULL;
655 OverrideData = NULL;
656
657 //
658 // Allocate resource for SndEntry
659 //
660 SndEntry = AllocatePool (sizeof (IP_IO_SEND_ENTRY));
661 if (NULL == SndEntry) {
662 return NULL;
663 }
664
665 Status = gBS->CreateEvent (
666 EVT_NOTIFY_SIGNAL,
667 TPL_NOTIFY,
669 SndEntry,
670 &Event
671 );
672 if (EFI_ERROR (Status)) {
673 goto ON_ERROR;
674 }
675
676 FragmentCount = Pkt->BlockOpNum;
677
678 //
679 // Allocate resource for TxData
680 //
681 TxData = (IP_IO_IP_TX_DATA *)AllocatePool (
682 sizeof (IP_IO_IP_TX_DATA) + sizeof (NET_FRAGMENT) * (FragmentCount - 1)
683 );
684
685 if (NULL == TxData) {
686 goto ON_ERROR;
687 }
688
689 //
690 // Build a fragment table to contain the fragments in the packet.
691 //
692 if (IpIo->IpVersion == IP_VERSION_4) {
693 ExtFragment = (NET_FRAGMENT *)TxData->Ip4TxData.FragmentTable;
694 } else {
695 ExtFragment = (NET_FRAGMENT *)TxData->Ip6TxData.FragmentTable;
696 }
697
698 NetbufBuildExt (Pkt, ExtFragment, &FragmentCount);
699
700 //
701 // Allocate resource for OverrideData if needed
702 //
703 if (NULL != Override) {
704 OverrideData = AllocateCopyPool (sizeof (IP_IO_OVERRIDE), Override);
705 if (NULL == OverrideData) {
706 goto ON_ERROR;
707 }
708 }
709
710 //
711 // Set other fields of TxData except the fragment table
712 //
713 if (IpIo->IpVersion == IP_VERSION_4) {
714 Ip4TxData = &TxData->Ip4TxData;
715
716 IP4_COPY_ADDRESS (&Ip4TxData->DestinationAddress, Dest);
717
718 Ip4TxData->OverrideData = &OverrideData->Ip4OverrideData;
719 Ip4TxData->OptionsLength = 0;
720 Ip4TxData->OptionsBuffer = NULL;
721 Ip4TxData->TotalDataLength = Pkt->TotalSize;
722 Ip4TxData->FragmentCount = FragmentCount;
723
724 //
725 // Set the fields of SndToken
726 //
727 SndEntry->SndToken.Ip4Token.Event = Event;
728 SndEntry->SndToken.Ip4Token.Packet.TxData = Ip4TxData;
729 } else {
730 Ip6TxData = &TxData->Ip6TxData;
731
732 if (Dest != NULL) {
733 CopyMem (&Ip6TxData->DestinationAddress, Dest, sizeof (EFI_IPv6_ADDRESS));
734 } else {
735 ZeroMem (&Ip6TxData->DestinationAddress, sizeof (EFI_IPv6_ADDRESS));
736 }
737
738 Ip6TxData->OverrideData = &OverrideData->Ip6OverrideData;
739 Ip6TxData->DataLength = Pkt->TotalSize;
740 Ip6TxData->FragmentCount = FragmentCount;
741 Ip6TxData->ExtHdrsLength = 0;
742 Ip6TxData->ExtHdrs = NULL;
743
744 //
745 // Set the fields of SndToken
746 //
747 SndEntry->SndToken.Ip6Token.Event = Event;
748 SndEntry->SndToken.Ip6Token.Packet.TxData = Ip6TxData;
749 }
750
751 //
752 // Set the fields of SndEntry
753 //
754 SndEntry->IpIo = IpIo;
755 SndEntry->Ip = Sender;
756 SndEntry->Context = Context;
757 SndEntry->NotifyData = NotifyData;
758
759 SndEntry->Pkt = Pkt;
760 NET_GET_REF (Pkt);
761
762 InsertTailList (&IpIo->PendingSndList, &SndEntry->Entry);
763
764 return SndEntry;
765
766ON_ERROR:
767
768 if (OverrideData != NULL) {
769 FreePool (OverrideData);
770 }
771
772 if (TxData != NULL) {
773 FreePool (TxData);
774 }
775
776 if (SndEntry != NULL) {
777 FreePool (SndEntry);
778 }
779
780 if (Event != NULL) {
781 gBS->CloseEvent (Event);
782 }
783
784 return NULL;
785}
786
795VOID
797 IN IP_IO_SEND_ENTRY *SndEntry
798 )
799{
800 EFI_EVENT Event;
801 IP_IO_IP_TX_DATA *TxData;
802 IP_IO_OVERRIDE *Override;
803
804 if (SndEntry->IpIo->IpVersion == IP_VERSION_4) {
805 Event = SndEntry->SndToken.Ip4Token.Event;
806 TxData = (IP_IO_IP_TX_DATA *)SndEntry->SndToken.Ip4Token.Packet.TxData;
807 Override = (IP_IO_OVERRIDE *)TxData->Ip4TxData.OverrideData;
808 } else if (SndEntry->IpIo->IpVersion == IP_VERSION_6) {
809 Event = SndEntry->SndToken.Ip6Token.Event;
810 TxData = (IP_IO_IP_TX_DATA *)SndEntry->SndToken.Ip6Token.Packet.TxData;
811 Override = (IP_IO_OVERRIDE *)TxData->Ip6TxData.OverrideData;
812 } else {
813 return;
814 }
815
816 gBS->CloseEvent (Event);
817
818 FreePool (TxData);
819
820 if (NULL != Override) {
821 FreePool (Override);
822 }
823
824 NetbufFree (SndEntry->Pkt);
825
826 RemoveEntryList (&SndEntry->Entry);
827
828 FreePool (SndEntry);
829}
830
837VOID
838EFIAPI
840 IN VOID *Context
841 )
842{
843 IP_IO *IpIo;
844 IP_IO_SEND_ENTRY *SndEntry;
845 EFI_STATUS Status;
846
847 SndEntry = (IP_IO_SEND_ENTRY *)Context;
848
849 IpIo = SndEntry->IpIo;
850
851 if (IpIo->IpVersion == IP_VERSION_4) {
852 Status = SndEntry->SndToken.Ip4Token.Status;
853 } else if (IpIo->IpVersion == IP_VERSION_6) {
854 Status = SndEntry->SndToken.Ip6Token.Status;
855 } else {
856 return;
857 }
858
859 if ((IpIo->PktSentNotify != NULL) && (SndEntry->NotifyData != NULL)) {
860 IpIo->PktSentNotify (
861 Status,
862 SndEntry->Context,
863 SndEntry->Ip,
864 SndEntry->NotifyData
865 );
866 }
867
868 IpIoDestroySndEntry (SndEntry);
869}
870
878VOID
879EFIAPI
881 IN EFI_EVENT Event,
882 IN VOID *Context
883 )
884{
885 //
886 // Request IpIoTransmitHandlerDpc as a DPC at TPL_CALLBACK
887 //
888 QueueDpc (TPL_CALLBACK, IpIoTransmitHandlerDpc, Context);
889}
890
897VOID
898EFIAPI
900 IN VOID *Context
901 )
902{
903 IP_IO_IP_INFO *IpInfo;
904 EFI_STATUS Status;
905 EFI_EVENT RecycleEvent;
906
907 IpInfo = (IP_IO_IP_INFO *)Context;
908
909 if ((IpInfo->IpVersion != IP_VERSION_4) && (IpInfo->IpVersion != IP_VERSION_6)) {
910 return;
911 }
912
913 RecycleEvent = NULL;
914
915 if (IpInfo->IpVersion == IP_VERSION_4) {
916 Status = IpInfo->DummyRcvToken.Ip4Token.Status;
917
918 if (IpInfo->DummyRcvToken.Ip4Token.Packet.RxData != NULL) {
919 RecycleEvent = IpInfo->DummyRcvToken.Ip4Token.Packet.RxData->RecycleSignal;
920 }
921 } else {
922 Status = IpInfo->DummyRcvToken.Ip6Token.Status;
923
924 if (IpInfo->DummyRcvToken.Ip6Token.Packet.RxData != NULL) {
925 RecycleEvent = IpInfo->DummyRcvToken.Ip6Token.Packet.RxData->RecycleSignal;
926 }
927 }
928
929 if (EFI_ABORTED == Status) {
930 //
931 // The reception is actively aborted by the consumer, directly return.
932 //
933 return;
934 } else if (EFI_SUCCESS == Status) {
935 //
936 // Recycle the RxData.
937 //
938 ASSERT (RecycleEvent != NULL);
939
940 gBS->SignalEvent (RecycleEvent);
941 }
942
943 //
944 // Continue the receive.
945 //
946 if (IpInfo->IpVersion == IP_VERSION_4) {
947 IpInfo->Ip.Ip4->Receive (
948 IpInfo->Ip.Ip4,
949 &IpInfo->DummyRcvToken.Ip4Token
950 );
951 } else {
952 IpInfo->Ip.Ip6->Receive (
953 IpInfo->Ip.Ip6,
954 &IpInfo->DummyRcvToken.Ip6Token
955 );
956 }
957}
958
966VOID
967EFIAPI
969 IN EFI_EVENT Event,
970 IN VOID *Context
971 )
972{
973 //
974 // Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK
975 //
976 QueueDpc (TPL_CALLBACK, IpIoDummyHandlerDpc, Context);
977}
978
986VOID
987EFIAPI
989 IN VOID *Context
990 )
991{
992 IP_IO *IpIo;
993 EFI_STATUS Status;
994 IP_IO_IP_RX_DATA *RxData;
995 EFI_NET_SESSION_DATA Session;
996 NET_BUF *Pkt;
997
998 IpIo = (IP_IO *)Context;
999
1000 if (IpIo->IpVersion == IP_VERSION_4) {
1001 Status = IpIo->RcvToken.Ip4Token.Status;
1002 RxData = (IP_IO_IP_RX_DATA *)IpIo->RcvToken.Ip4Token.Packet.RxData;
1003 } else if (IpIo->IpVersion == IP_VERSION_6) {
1004 Status = IpIo->RcvToken.Ip6Token.Status;
1005 RxData = (IP_IO_IP_RX_DATA *)IpIo->RcvToken.Ip6Token.Packet.RxData;
1006 } else {
1007 return;
1008 }
1009
1010 if (EFI_ABORTED == Status) {
1011 //
1012 // The reception is actively aborted by the consumer, directly return.
1013 //
1014 return;
1015 }
1016
1017 if ((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) {
1018 //
1019 // Only process the normal packets and the icmp error packets.
1020 //
1021 if (RxData != NULL) {
1022 goto CleanUp;
1023 } else {
1024 goto Resume;
1025 }
1026 }
1027
1028 //
1029 // if RxData is NULL with Status == EFI_SUCCESS or EFI_ICMP_ERROR, this should be a code issue in the low layer (IP).
1030 //
1031 ASSERT (RxData != NULL);
1032 if (RxData == NULL) {
1033 goto Resume;
1034 }
1035
1036 if (NULL == IpIo->PktRcvdNotify) {
1037 goto CleanUp;
1038 }
1039
1040 if (IpIo->IpVersion == IP_VERSION_4) {
1041 ASSERT (RxData->Ip4RxData.Header != NULL);
1042 if (IP4_IS_LOCAL_BROADCAST (EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress))) {
1043 //
1044 // The source address is a broadcast address, discard it.
1045 //
1046 goto CleanUp;
1047 }
1048
1049 if ((EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress) != 0) &&
1050 (IpIo->SubnetMask != 0) &&
1051 IP4_NET_EQUAL (IpIo->StationIp, EFI_NTOHL (((EFI_IP4_RECEIVE_DATA *)RxData)->Header->SourceAddress), IpIo->SubnetMask) &&
1052 !NetIp4IsUnicast (EFI_NTOHL (((EFI_IP4_RECEIVE_DATA *)RxData)->Header->SourceAddress), IpIo->SubnetMask))
1053 {
1054 //
1055 // The source address doesn't match StationIp and it's not a unicast IP address, discard it.
1056 //
1057 goto CleanUp;
1058 }
1059
1060 if (RxData->Ip4RxData.DataLength == 0) {
1061 //
1062 // Discard zero length data payload packet.
1063 //
1064 goto CleanUp;
1065 }
1066
1067 //
1068 // The fragment should always be valid for non-zero length packet.
1069 //
1070 ASSERT (RxData->Ip4RxData.FragmentCount != 0);
1071
1072 //
1073 // Create a netbuffer representing IPv4 packet
1074 //
1075 Pkt = NetbufFromExt (
1076 (NET_FRAGMENT *)RxData->Ip4RxData.FragmentTable,
1077 RxData->Ip4RxData.FragmentCount,
1078 0,
1079 0,
1081 RxData->Ip4RxData.RecycleSignal
1082 );
1083 if (NULL == Pkt) {
1084 goto CleanUp;
1085 }
1086
1087 //
1088 // Create a net session
1089 //
1090 Session.Source.Addr[0] = EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress);
1091 Session.Dest.Addr[0] = EFI_IP4 (RxData->Ip4RxData.Header->DestinationAddress);
1092 Session.IpHdr.Ip4Hdr = RxData->Ip4RxData.Header;
1093 Session.IpHdrLen = RxData->Ip4RxData.HeaderLength;
1094 Session.IpVersion = IP_VERSION_4;
1095 } else {
1096 ASSERT (RxData->Ip6RxData.Header != NULL);
1097 if (!NetIp6IsValidUnicast (&RxData->Ip6RxData.Header->SourceAddress)) {
1098 goto CleanUp;
1099 }
1100
1101 if (RxData->Ip6RxData.DataLength == 0) {
1102 //
1103 // Discard zero length data payload packet.
1104 //
1105 goto CleanUp;
1106 }
1107
1108 //
1109 // The fragment should always be valid for non-zero length packet.
1110 //
1111 ASSERT (RxData->Ip6RxData.FragmentCount != 0);
1112
1113 //
1114 // Create a netbuffer representing IPv6 packet
1115 //
1116 Pkt = NetbufFromExt (
1117 (NET_FRAGMENT *)RxData->Ip6RxData.FragmentTable,
1118 RxData->Ip6RxData.FragmentCount,
1119 0,
1120 0,
1122 RxData->Ip6RxData.RecycleSignal
1123 );
1124 if (NULL == Pkt) {
1125 goto CleanUp;
1126 }
1127
1128 //
1129 // Create a net session
1130 //
1131 CopyMem (
1132 &Session.Source,
1133 &RxData->Ip6RxData.Header->SourceAddress,
1134 sizeof (EFI_IPv6_ADDRESS)
1135 );
1136 CopyMem (
1137 &Session.Dest,
1138 &RxData->Ip6RxData.Header->DestinationAddress,
1139 sizeof (EFI_IPv6_ADDRESS)
1140 );
1141 Session.IpHdr.Ip6Hdr = RxData->Ip6RxData.Header;
1142 Session.IpHdrLen = RxData->Ip6RxData.HeaderLength;
1143 Session.IpVersion = IP_VERSION_6;
1144 }
1145
1146 if (EFI_SUCCESS == Status) {
1147 IpIo->PktRcvdNotify (EFI_SUCCESS, 0, &Session, Pkt, IpIo->RcvdContext);
1148 } else {
1149 //
1150 // Status is EFI_ICMP_ERROR
1151 //
1152 Status = IpIoIcmpHandler (IpIo, Pkt, &Session);
1153 if (EFI_ERROR (Status)) {
1154 NetbufFree (Pkt);
1155 }
1156 }
1157
1158 goto Resume;
1159
1160CleanUp:
1161
1162 if (IpIo->IpVersion == IP_VERSION_4) {
1163 gBS->SignalEvent (RxData->Ip4RxData.RecycleSignal);
1164 } else {
1165 gBS->SignalEvent (RxData->Ip6RxData.RecycleSignal);
1166 }
1167
1168Resume:
1169
1170 if (IpIo->IpVersion == IP_VERSION_4) {
1171 IpIo->Ip.Ip4->Receive (IpIo->Ip.Ip4, &(IpIo->RcvToken.Ip4Token));
1172 } else {
1173 IpIo->Ip.Ip6->Receive (IpIo->Ip.Ip6, &(IpIo->RcvToken.Ip6Token));
1174 }
1175}
1176
1184VOID
1185EFIAPI
1187 IN EFI_EVENT Event,
1188 IN VOID *Context
1189 )
1190{
1191 //
1192 // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK
1193 //
1194 QueueDpc (TPL_CALLBACK, IpIoListenHandlerDpc, Context);
1195}
1196
1215IP_IO *
1216EFIAPI
1218 IN EFI_HANDLE Image,
1219 IN EFI_HANDLE Controller,
1220 IN UINT8 IpVersion
1221 )
1222{
1223 EFI_STATUS Status;
1224 IP_IO *IpIo;
1225 EFI_EVENT Event;
1226
1227 ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
1228
1229 IpIo = AllocateZeroPool (sizeof (IP_IO));
1230 if (NULL == IpIo) {
1231 return NULL;
1232 }
1233
1235 InitializeListHead (&(IpIo->IpList));
1236 IpIo->Controller = Controller;
1237 IpIo->Image = Image;
1238 IpIo->IpVersion = IpVersion;
1239 Event = NULL;
1240
1241 Status = gBS->CreateEvent (
1242 EVT_NOTIFY_SIGNAL,
1243 TPL_NOTIFY,
1245 IpIo,
1246 &Event
1247 );
1248 if (EFI_ERROR (Status)) {
1249 goto ReleaseIpIo;
1250 }
1251
1252 if (IpVersion == IP_VERSION_4) {
1253 IpIo->RcvToken.Ip4Token.Event = Event;
1254 } else {
1255 IpIo->RcvToken.Ip6Token.Event = Event;
1256 }
1257
1258 //
1259 // Create an IP child and open IP protocol
1260 //
1262 Controller,
1263 Image,
1264 &IpIo->ChildHandle,
1265 IpVersion,
1266 (VOID **)&(IpIo->Ip)
1267 );
1268 if (EFI_ERROR (Status)) {
1269 goto ReleaseIpIo;
1270 }
1271
1272 return IpIo;
1273
1274ReleaseIpIo:
1275
1276 if (Event != NULL) {
1277 gBS->CloseEvent (Event);
1278 }
1279
1280 gBS->FreePool (IpIo);
1281
1282 return NULL;
1283}
1284
1309EFIAPI
1311 IN OUT IP_IO *IpIo,
1312 IN IP_IO_OPEN_DATA *OpenData
1313 )
1314{
1315 EFI_STATUS Status;
1316 UINT8 IpVersion;
1317
1318 if ((IpIo == NULL) || (OpenData == NULL)) {
1319 return EFI_INVALID_PARAMETER;
1320 }
1321
1322 if (IpIo->IsConfigured) {
1323 return EFI_ACCESS_DENIED;
1324 }
1325
1326 IpVersion = IpIo->IpVersion;
1327
1328 ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
1329
1330 //
1331 // configure ip
1332 //
1333 if (IpVersion == IP_VERSION_4) {
1334 //
1335 // RawData mode is no supported.
1336 //
1337 ASSERT (!OpenData->IpConfigData.Ip4CfgData.RawData);
1338 if (OpenData->IpConfigData.Ip4CfgData.RawData) {
1339 return EFI_UNSUPPORTED;
1340 }
1341
1342 if (!OpenData->IpConfigData.Ip4CfgData.UseDefaultAddress) {
1343 IpIo->StationIp = EFI_NTOHL (OpenData->IpConfigData.Ip4CfgData.StationAddress);
1344 IpIo->SubnetMask = EFI_NTOHL (OpenData->IpConfigData.Ip4CfgData.SubnetMask);
1345 }
1346
1347 Status = IpIo->Ip.Ip4->Configure (
1348 IpIo->Ip.Ip4,
1349 &OpenData->IpConfigData.Ip4CfgData
1350 );
1351 } else {
1352 Status = IpIo->Ip.Ip6->Configure (
1353 IpIo->Ip.Ip6,
1354 &OpenData->IpConfigData.Ip6CfgData
1355 );
1356 }
1357
1358 if (EFI_ERROR (Status)) {
1359 return Status;
1360 }
1361
1362 //
1363 // @bug To delete the default route entry in this Ip, if it is:
1364 // @bug (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified
1365 // @bug its code
1366 //
1367 if (IpVersion == IP_VERSION_4) {
1368 Status = IpIo->Ip.Ip4->Routes (
1369 IpIo->Ip.Ip4,
1370 TRUE,
1371 &mZeroIp4Addr,
1372 &mZeroIp4Addr,
1373 &mZeroIp4Addr
1374 );
1375
1376 if (EFI_ERROR (Status) && (EFI_NOT_FOUND != Status)) {
1377 return Status;
1378 }
1379 }
1380
1381 IpIo->PktRcvdNotify = OpenData->PktRcvdNotify;
1382 IpIo->PktSentNotify = OpenData->PktSentNotify;
1383
1384 IpIo->RcvdContext = OpenData->RcvdContext;
1385 IpIo->SndContext = OpenData->SndContext;
1386
1387 if (IpVersion == IP_VERSION_4) {
1388 IpIo->Protocol = OpenData->IpConfigData.Ip4CfgData.DefaultProtocol;
1389
1390 //
1391 // start to listen incoming packet
1392 //
1393 Status = IpIo->Ip.Ip4->Receive (
1394 IpIo->Ip.Ip4,
1395 &(IpIo->RcvToken.Ip4Token)
1396 );
1397 if (EFI_ERROR (Status)) {
1398 IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL);
1399 return Status;
1400 }
1401 } else {
1402 IpIo->Protocol = OpenData->IpConfigData.Ip6CfgData.DefaultProtocol;
1403 Status = IpIo->Ip.Ip6->Receive (
1404 IpIo->Ip.Ip6,
1405 &(IpIo->RcvToken.Ip6Token)
1406 );
1407 if (EFI_ERROR (Status)) {
1408 IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL);
1409 return Status;
1410 }
1411 }
1412
1413 IpIo->IsConfigured = TRUE;
1414 InsertTailList (&mActiveIpIoList, &IpIo->Entry);
1415
1416 return Status;
1417}
1418
1435EFIAPI
1437 IN OUT IP_IO *IpIo
1438 )
1439{
1440 EFI_STATUS Status;
1441 IP_IO_IP_INFO *IpInfo;
1442 UINT8 IpVersion;
1443
1444 if (IpIo == NULL) {
1445 return EFI_INVALID_PARAMETER;
1446 }
1447
1448 if (!IpIo->IsConfigured) {
1449 return EFI_SUCCESS;
1450 }
1451
1452 IpVersion = IpIo->IpVersion;
1453
1454 ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
1455
1456 //
1457 // Remove the IpIo from the active IpIo list.
1458 //
1459 RemoveEntryList (&IpIo->Entry);
1460
1461 //
1462 // Configure NULL Ip
1463 //
1464 if (IpVersion == IP_VERSION_4) {
1465 Status = IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL);
1466 } else {
1467 Status = IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL);
1468 }
1469
1470 if (EFI_ERROR (Status)) {
1471 return Status;
1472 }
1473
1474 IpIo->IsConfigured = FALSE;
1475
1476 //
1477 // Destroy the Ip List used by IpIo
1478 //
1479
1480 while (!IsListEmpty (&(IpIo->IpList))) {
1481 IpInfo = NET_LIST_HEAD (&(IpIo->IpList), IP_IO_IP_INFO, Entry);
1482
1483 IpIoRemoveIp (IpIo, IpInfo);
1484 }
1485
1486 //
1487 // All pending send tokens should be flushed by resetting the IP instances.
1488 //
1489 ASSERT (IsListEmpty (&IpIo->PendingSndList));
1490
1491 //
1492 // Close the receive event.
1493 //
1494 if (IpVersion == IP_VERSION_4) {
1495 gBS->CloseEvent (IpIo->RcvToken.Ip4Token.Event);
1496 } else {
1497 gBS->CloseEvent (IpIo->RcvToken.Ip6Token.Event);
1498 }
1499
1500 return EFI_SUCCESS;
1501}
1502
1517EFIAPI
1519 IN OUT IP_IO *IpIo
1520 )
1521{
1522 EFI_STATUS Status;
1523
1524 //
1525 // Stop the IpIo.
1526 //
1527 Status = IpIoStop (IpIo);
1528 if (EFI_ERROR (Status)) {
1529 return Status;
1530 }
1531
1532 //
1533 // Close the IP protocol and destroy the child.
1534 //
1536 IpIo->Controller,
1537 IpIo->Image,
1538 IpIo->ChildHandle,
1539 IpIo->IpVersion
1540 );
1541 if (EFI_ERROR (Status)) {
1542 return Status;
1543 }
1544
1545 gBS->FreePool (IpIo);
1546
1547 return EFI_SUCCESS;
1548}
1549
1577EFIAPI
1579 IN OUT IP_IO *IpIo,
1580 IN OUT NET_BUF *Pkt,
1581 IN IP_IO_IP_INFO *Sender OPTIONAL,
1582 IN VOID *Context OPTIONAL,
1583 IN VOID *NotifyData OPTIONAL,
1584 IN EFI_IP_ADDRESS *Dest OPTIONAL,
1585 IN IP_IO_OVERRIDE *OverrideData OPTIONAL
1586 )
1587{
1588 EFI_STATUS Status;
1590 IP_IO_SEND_ENTRY *SndEntry;
1591
1592 if ((IpIo == NULL) || (Pkt == NULL)) {
1593 return EFI_INVALID_PARAMETER;
1594 }
1595
1596 if ((IpIo->IpVersion == IP_VERSION_4) && (Dest == NULL)) {
1597 return EFI_INVALID_PARAMETER;
1598 }
1599
1600 if (!IpIo->IsConfigured) {
1601 return EFI_NOT_STARTED;
1602 }
1603
1604 Ip = (NULL == Sender) ? IpIo->Ip : Sender->Ip;
1605
1606 //
1607 // create a new SndEntry
1608 //
1609 SndEntry = IpIoCreateSndEntry (IpIo, Pkt, Ip, Context, NotifyData, Dest, OverrideData);
1610 if (NULL == SndEntry) {
1611 return EFI_OUT_OF_RESOURCES;
1612 }
1613
1614 //
1615 // Send this Packet
1616 //
1617 if (IpIo->IpVersion == IP_VERSION_4) {
1618 Status = Ip.Ip4->Transmit (
1619 Ip.Ip4,
1620 &SndEntry->SndToken.Ip4Token
1621 );
1622 } else {
1623 Status = Ip.Ip6->Transmit (
1624 Ip.Ip6,
1625 &SndEntry->SndToken.Ip6Token
1626 );
1627 }
1628
1629 if (EFI_ERROR (Status)) {
1630 IpIoDestroySndEntry (SndEntry);
1631 }
1632
1633 return Status;
1634}
1635
1646VOID
1647EFIAPI
1649 IN IP_IO *IpIo,
1650 IN VOID *Packet
1651 )
1652{
1653 LIST_ENTRY *Node;
1654 IP_IO_SEND_ENTRY *SndEntry;
1656
1657 ASSERT ((IpIo != NULL) && (Packet != NULL));
1658
1659 NET_LIST_FOR_EACH (Node, &IpIo->PendingSndList) {
1660 SndEntry = NET_LIST_USER_STRUCT (Node, IP_IO_SEND_ENTRY, Entry);
1661
1662 if (SndEntry->Pkt == Packet) {
1663 Ip = SndEntry->Ip;
1664
1665 if (IpIo->IpVersion == IP_VERSION_4) {
1666 Ip.Ip4->Cancel (
1667 Ip.Ip4,
1668 &SndEntry->SndToken.Ip4Token
1669 );
1670 } else {
1671 Ip.Ip6->Cancel (
1672 Ip.Ip6,
1673 &SndEntry->SndToken.Ip6Token
1674 );
1675 }
1676
1677 break;
1678 }
1679 }
1680}
1681
1699EFIAPI
1701 IN OUT IP_IO *IpIo
1702 )
1703{
1704 EFI_STATUS Status;
1705 IP_IO_IP_INFO *IpInfo;
1706 EFI_EVENT Event;
1707
1708 ASSERT (IpIo != NULL);
1709 ASSERT ((IpIo->IpVersion == IP_VERSION_4) || (IpIo->IpVersion == IP_VERSION_6));
1710
1711 IpInfo = AllocatePool (sizeof (IP_IO_IP_INFO));
1712 if (IpInfo == NULL) {
1713 return NULL;
1714 }
1715
1716 //
1717 // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP
1718 // instance.
1719 //
1720 InitializeListHead (&IpInfo->Entry);
1721 IpInfo->ChildHandle = NULL;
1722 ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr));
1723 ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask));
1724
1725 IpInfo->RefCnt = 1;
1726 IpInfo->IpVersion = IpIo->IpVersion;
1727
1728 //
1729 // Create the IP instance and open the IP protocol.
1730 //
1732 IpIo->Controller,
1733 IpIo->Image,
1734 &IpInfo->ChildHandle,
1735 IpInfo->IpVersion,
1736 (VOID **)&IpInfo->Ip
1737 );
1738 if (EFI_ERROR (Status)) {
1739 goto ReleaseIpInfo;
1740 }
1741
1742 //
1743 // Create the event for the DummyRcvToken.
1744 //
1745 Status = gBS->CreateEvent (
1746 EVT_NOTIFY_SIGNAL,
1747 TPL_NOTIFY,
1749 IpInfo,
1750 &Event
1751 );
1752 if (EFI_ERROR (Status)) {
1753 goto ReleaseIpChild;
1754 }
1755
1756 if (IpInfo->IpVersion == IP_VERSION_4) {
1757 IpInfo->DummyRcvToken.Ip4Token.Event = Event;
1758 } else {
1759 IpInfo->DummyRcvToken.Ip6Token.Event = Event;
1760 }
1761
1762 //
1763 // Link this IpInfo into the IpIo.
1764 //
1765 InsertTailList (&IpIo->IpList, &IpInfo->Entry);
1766
1767 return IpInfo;
1768
1769ReleaseIpChild:
1770
1772 IpIo->Controller,
1773 IpIo->Image,
1774 IpInfo->ChildHandle,
1775 IpInfo->IpVersion
1776 );
1777
1778ReleaseIpInfo:
1779
1780 gBS->FreePool (IpInfo);
1781
1782 return NULL;
1783}
1784
1805EFIAPI
1807 IN OUT IP_IO_IP_INFO *IpInfo,
1808 IN OUT VOID *IpConfigData OPTIONAL
1809 )
1810{
1811 EFI_STATUS Status;
1813 UINT8 IpVersion;
1814 EFI_IP4_MODE_DATA Ip4ModeData;
1815 EFI_IP6_MODE_DATA Ip6ModeData;
1816
1817 ASSERT (IpInfo != NULL);
1818
1819 if (IpInfo->RefCnt > 1) {
1820 //
1821 // This IP instance is shared, don't reconfigure it until it has only one
1822 // consumer. Currently, only the tcp children cloned from their passive parent
1823 // will share the same IP. So this cases only happens while IpConfigData is NULL,
1824 // let the last consumer clean the IP instance.
1825 //
1826 return EFI_SUCCESS;
1827 }
1828
1829 IpVersion = IpInfo->IpVersion;
1830 ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
1831
1832 Ip = IpInfo->Ip;
1833
1834 if (IpInfo->IpVersion == IP_VERSION_4) {
1835 Status = Ip.Ip4->Configure (Ip.Ip4, IpConfigData);
1836 } else {
1837 Status = Ip.Ip6->Configure (Ip.Ip6, IpConfigData);
1838 }
1839
1840 if (EFI_ERROR (Status)) {
1841 return Status;
1842 }
1843
1844 if (IpConfigData != NULL) {
1845 if (IpInfo->IpVersion == IP_VERSION_4) {
1846 if (((EFI_IP4_CONFIG_DATA *)IpConfigData)->UseDefaultAddress) {
1847 Status = Ip.Ip4->GetModeData (
1848 Ip.Ip4,
1849 &Ip4ModeData,
1850 NULL,
1851 NULL
1852 );
1853 if (EFI_ERROR (Status)) {
1854 Ip.Ip4->Configure (Ip.Ip4, NULL);
1855 return Status;
1856 }
1857
1858 IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA *)IpConfigData)->StationAddress, &Ip4ModeData.ConfigData.StationAddress);
1859 IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA *)IpConfigData)->SubnetMask, &Ip4ModeData.ConfigData.SubnetMask);
1860 }
1861
1862 CopyMem (
1863 &IpInfo->Addr.Addr,
1864 &((EFI_IP4_CONFIG_DATA *)IpConfigData)->StationAddress,
1865 sizeof (IP4_ADDR)
1866 );
1867 CopyMem (
1868 &IpInfo->PreMask.SubnetMask,
1869 &((EFI_IP4_CONFIG_DATA *)IpConfigData)->SubnetMask,
1870 sizeof (IP4_ADDR)
1871 );
1872
1873 Status = Ip.Ip4->Receive (
1874 Ip.Ip4,
1875 &IpInfo->DummyRcvToken.Ip4Token
1876 );
1877 if (EFI_ERROR (Status)) {
1878 Ip.Ip4->Configure (Ip.Ip4, NULL);
1879 }
1880 } else {
1881 Status = Ip.Ip6->GetModeData (
1882 Ip.Ip6,
1883 &Ip6ModeData,
1884 NULL,
1885 NULL
1886 );
1887 if (EFI_ERROR (Status)) {
1888 Ip.Ip6->Configure (Ip.Ip6, NULL);
1889 return Status;
1890 }
1891
1892 if (Ip6ModeData.IsConfigured) {
1893 CopyMem (
1894 &((EFI_IP6_CONFIG_DATA *)IpConfigData)->StationAddress,
1895 &Ip6ModeData.ConfigData.StationAddress,
1896 sizeof (EFI_IPv6_ADDRESS)
1897 );
1898
1899 if (Ip6ModeData.AddressList != NULL) {
1900 FreePool (Ip6ModeData.AddressList);
1901 }
1902
1903 if (Ip6ModeData.GroupTable != NULL) {
1904 FreePool (Ip6ModeData.GroupTable);
1905 }
1906
1907 if (Ip6ModeData.RouteTable != NULL) {
1908 FreePool (Ip6ModeData.RouteTable);
1909 }
1910
1911 if (Ip6ModeData.NeighborCache != NULL) {
1912 FreePool (Ip6ModeData.NeighborCache);
1913 }
1914
1915 if (Ip6ModeData.PrefixTable != NULL) {
1916 FreePool (Ip6ModeData.PrefixTable);
1917 }
1918
1919 if (Ip6ModeData.IcmpTypeList != NULL) {
1920 FreePool (Ip6ModeData.IcmpTypeList);
1921 }
1922 } else {
1923 Status = EFI_NO_MAPPING;
1924 return Status;
1925 }
1926
1927 CopyMem (
1928 &IpInfo->Addr,
1929 &Ip6ModeData.ConfigData.StationAddress,
1930 sizeof (EFI_IPv6_ADDRESS)
1931 );
1932
1933 Status = Ip.Ip6->Receive (
1934 Ip.Ip6,
1935 &IpInfo->DummyRcvToken.Ip6Token
1936 );
1937 if (EFI_ERROR (Status)) {
1938 Ip.Ip6->Configure (Ip.Ip6, NULL);
1939 }
1940 }
1941 } else {
1942 //
1943 // The IP instance is reset, set the stored Addr and SubnetMask to zero.
1944 //
1945 ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr));
1946 ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask));
1947 }
1948
1949 return Status;
1950}
1951
1966VOID
1967EFIAPI
1969 IN IP_IO *IpIo,
1970 IN IP_IO_IP_INFO *IpInfo
1971 )
1972{
1973 UINT8 IpVersion;
1974
1975 if ((IpIo == NULL) || (IpInfo == NULL)) {
1976 return;
1977 }
1978
1979 ASSERT (IpInfo->RefCnt > 0);
1980
1981 NET_PUT_REF (IpInfo);
1982
1983 if (IpInfo->RefCnt > 0) {
1984 return;
1985 }
1986
1987 IpVersion = IpIo->IpVersion;
1988
1989 ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));
1990
1991 RemoveEntryList (&IpInfo->Entry);
1992
1993 if (IpVersion == IP_VERSION_4) {
1994 IpInfo->Ip.Ip4->Configure (
1995 IpInfo->Ip.Ip4,
1996 NULL
1997 );
1999 IpIo->Controller,
2000 IpIo->Image,
2001 IpInfo->ChildHandle,
2002 IP_VERSION_4
2003 );
2004
2005 gBS->CloseEvent (IpInfo->DummyRcvToken.Ip4Token.Event);
2006 } else {
2007 IpInfo->Ip.Ip6->Configure (
2008 IpInfo->Ip.Ip6,
2009 NULL
2010 );
2011
2013 IpIo->Controller,
2014 IpIo->Image,
2015 IpInfo->ChildHandle,
2016 IP_VERSION_6
2017 );
2018
2019 gBS->CloseEvent (IpInfo->DummyRcvToken.Ip6Token.Event);
2020 }
2021
2022 FreePool (IpInfo);
2023}
2024
2042EFIAPI
2044 IN OUT IP_IO **IpIo,
2045 IN UINT8 IpVersion,
2046 IN EFI_IP_ADDRESS *Src
2047 )
2048{
2049 LIST_ENTRY *IpIoEntry;
2050 IP_IO *IpIoPtr;
2051 LIST_ENTRY *IpInfoEntry;
2052 IP_IO_IP_INFO *IpInfo;
2053
2054 if ((IpIo == NULL) || (Src == NULL)) {
2055 return NULL;
2056 }
2057
2058 if ((IpVersion != IP_VERSION_4) && (IpVersion != IP_VERSION_6)) {
2059 return NULL;
2060 }
2061
2062 NET_LIST_FOR_EACH (IpIoEntry, &mActiveIpIoList) {
2063 IpIoPtr = NET_LIST_USER_STRUCT (IpIoEntry, IP_IO, Entry);
2064
2065 if (((*IpIo != NULL) && (*IpIo != IpIoPtr)) || (IpIoPtr->IpVersion != IpVersion)) {
2066 continue;
2067 }
2068
2069 NET_LIST_FOR_EACH (IpInfoEntry, &IpIoPtr->IpList) {
2070 IpInfo = NET_LIST_USER_STRUCT (IpInfoEntry, IP_IO_IP_INFO, Entry);
2071 if (IpInfo->IpVersion == IP_VERSION_4) {
2072 if (EFI_IP4_EQUAL (&IpInfo->Addr.v4, &Src->v4)) {
2073 *IpIo = IpIoPtr;
2074 return IpInfo;
2075 }
2076 } else {
2077 if (EFI_IP6_EQUAL (&IpInfo->Addr.v6, &Src->v6)) {
2078 *IpIo = IpIoPtr;
2079 return IpInfo;
2080 }
2081 }
2082 }
2083 }
2084
2085 //
2086 // No match.
2087 //
2088 return NULL;
2089}
2090
2108EFIAPI
2110 IN UINT8 IcmpError,
2111 IN UINT8 IpVersion,
2112 OUT BOOLEAN *IsHard OPTIONAL,
2113 OUT BOOLEAN *Notify OPTIONAL
2114 )
2115{
2116 if (IpVersion == IP_VERSION_4 ) {
2117 ASSERT (IcmpError <= ICMP_ERR_PARAMPROB);
2118
2119 if (IsHard != NULL) {
2120 *IsHard = mIcmpErrMap[IcmpError].IsHard;
2121 }
2122
2123 if (Notify != NULL) {
2124 *Notify = mIcmpErrMap[IcmpError].Notify;
2125 }
2126
2127 switch (IcmpError) {
2130
2131 case ICMP_ERR_TIMXCEED_INTRANS:
2132 case ICMP_ERR_TIMXCEED_REASS:
2133 case ICMP_ERR_UNREACH_HOST:
2134 return EFI_HOST_UNREACHABLE;
2135
2136 case ICMP_ERR_UNREACH_PROTOCOL:
2137 return EFI_PROTOCOL_UNREACHABLE;
2138
2139 case ICMP_ERR_UNREACH_PORT:
2140 return EFI_PORT_UNREACHABLE;
2141
2142 case ICMP_ERR_MSGSIZE:
2143 case ICMP_ERR_UNREACH_SRCFAIL:
2144 case ICMP_ERR_QUENCH:
2145 case ICMP_ERR_PARAMPROB:
2146 return EFI_ICMP_ERROR;
2147
2148 default:
2149 ASSERT (FALSE);
2150 return EFI_UNSUPPORTED;
2151 }
2152 } else if (IpVersion == IP_VERSION_6) {
2153 ASSERT (IcmpError <= ICMP6_ERR_PARAMPROB_IPV6OPTION);
2154
2155 if (IsHard != NULL) {
2156 *IsHard = mIcmp6ErrMap[IcmpError].IsHard;
2157 }
2158
2159 if (Notify != NULL) {
2160 *Notify = mIcmp6ErrMap[IcmpError].Notify;
2161 }
2162
2163 switch (IcmpError) {
2164 case ICMP6_ERR_UNREACH_NET:
2166
2167 case ICMP6_ERR_UNREACH_HOST:
2168 case ICMP6_ERR_TIMXCEED_HOPLIMIT:
2169 case ICMP6_ERR_TIMXCEED_REASS:
2170 return EFI_HOST_UNREACHABLE;
2171
2172 case ICMP6_ERR_UNREACH_PROTOCOL:
2173 return EFI_PROTOCOL_UNREACHABLE;
2174
2175 case ICMP6_ERR_UNREACH_PORT:
2176 return EFI_PORT_UNREACHABLE;
2177
2178 case ICMP6_ERR_PACKAGE_TOOBIG:
2179 case ICMP6_ERR_PARAMPROB_HEADER:
2180 case ICMP6_ERR_PARAMPROB_NEXHEADER:
2181 case ICMP6_ERR_PARAMPROB_IPV6OPTION:
2182 return EFI_ICMP_ERROR;
2183
2184 default:
2185 ASSERT (FALSE);
2186 return EFI_UNSUPPORTED;
2187 }
2188 } else {
2189 //
2190 // Should never be here
2191 //
2192 ASSERT (FALSE);
2193 return EFI_UNSUPPORTED;
2194 }
2195}
2196
2223EFIAPI
2225 IN IP_IO *IpIo,
2226 IN EFI_IP_ADDRESS *Neighbor,
2227 IN UINT32 Timeout
2228 )
2229{
2230 EFI_IP6_PROTOCOL *Ip;
2231
2232 if (!IpIo->IsConfigured) {
2233 return EFI_NOT_STARTED;
2234 }
2235
2236 if (IpIo->IpVersion != IP_VERSION_6) {
2237 return EFI_UNSUPPORTED;
2238 }
2239
2240 Ip = IpIo->Ip.Ip6;
2241
2242 return Ip->Neighbors (Ip, FALSE, &Neighbor->v6, NULL, Timeout, TRUE);
2243}
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
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)
EFI_STATUS EFIAPI QueueDpc(IN EFI_TPL DpcTpl, IN EFI_DPC_PROCEDURE DpcProcedure, IN VOID *DpcContext OPTIONAL)
Definition: DpcLib.c:62
VOID EFIAPI IpIoListenHandler(IN EFI_EVENT Event, IN VOID *Context)
Definition: DxeIpIoLib.c:1186
EFI_STATUS EFIAPI IpIoRefreshNeighbor(IN IP_IO *IpIo, IN EFI_IP_ADDRESS *Neighbor, IN UINT32 Timeout)
Definition: DxeIpIoLib.c:2224
EFI_STATUS EFIAPI IpIoDestroy(IN OUT IP_IO *IpIo)
Definition: DxeIpIoLib.c:1518
IP_IO *EFIAPI IpIoCreate(IN EFI_HANDLE Image, IN EFI_HANDLE Controller, IN UINT8 IpVersion)
Definition: DxeIpIoLib.c:1217
VOID EFIAPI IpIoRemoveIp(IN IP_IO *IpIo, IN IP_IO_IP_INFO *IpInfo)
Definition: DxeIpIoLib.c:1968
EFI_STATUS IpIoIcmpv6Handler(IN IP_IO *IpIo, IN OUT NET_BUF *Pkt, IN EFI_NET_SESSION_DATA *Session)
Definition: DxeIpIoLib.c:411
EFI_STATUS IpIoIcmpv4Handler(IN IP_IO *IpIo, IN OUT NET_BUF *Pkt, IN EFI_NET_SESSION_DATA *Session)
Definition: DxeIpIoLib.c:270
VOID EFIAPI IpIoTransmitHandlerDpc(IN VOID *Context)
Definition: DxeIpIoLib.c:839
VOID EFIAPI IpIoExtFree(IN VOID *Event)
Definition: DxeIpIoLib.c:605
EFI_STATUS EFIAPI IpIoStop(IN OUT IP_IO *IpIo)
Definition: DxeIpIoLib.c:1436
VOID EFIAPI IpIoListenHandlerDpc(IN VOID *Context)
Definition: DxeIpIoLib.c:988
EFI_STATUS EFIAPI IpIoOpen(IN OUT IP_IO *IpIo, IN IP_IO_OPEN_DATA *OpenData)
Definition: DxeIpIoLib.c:1310
VOID IpIoDestroySndEntry(IN IP_IO_SEND_ENTRY *SndEntry)
Definition: DxeIpIoLib.c:796
EFI_STATUS EFIAPI IpIoSend(IN OUT IP_IO *IpIo, IN OUT NET_BUF *Pkt, IN IP_IO_IP_INFO *Sender OPTIONAL, IN VOID *Context OPTIONAL, IN VOID *NotifyData OPTIONAL, IN EFI_IP_ADDRESS *Dest OPTIONAL, IN IP_IO_OVERRIDE *OverrideData OPTIONAL)
Definition: DxeIpIoLib.c:1578
VOID EFIAPI IpIoCancelTxToken(IN IP_IO *IpIo, IN VOID *Packet)
Definition: DxeIpIoLib.c:1648
EFI_STATUS EFIAPI IpIoConfigIp(IN OUT IP_IO_IP_INFO *IpInfo, IN OUT VOID *IpConfigData OPTIONAL)
Definition: DxeIpIoLib.c:1806
VOID EFIAPI IpIoTransmitHandler(IN EFI_EVENT Event, IN VOID *Context)
Definition: DxeIpIoLib.c:880
IP_IO_IP_INFO *EFIAPI IpIoAddIp(IN OUT IP_IO *IpIo)
Definition: DxeIpIoLib.c:1700
EFI_STATUS IpIoCreateIpChildOpenProtocol(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE *ChildHandle, IN UINT8 IpVersion, OUT VOID **Interface)
Definition: DxeIpIoLib.c:135
IP_IO_SEND_ENTRY * IpIoCreateSndEntry(IN OUT IP_IO *IpIo, IN OUT NET_BUF *Pkt, IN IP_IO_IP_PROTOCOL Sender, IN VOID *Context OPTIONAL, IN VOID *NotifyData OPTIONAL, IN EFI_IP_ADDRESS *Dest OPTIONAL, IN IP_IO_OVERRIDE *Override)
Definition: DxeIpIoLib.c:629
EFI_STATUS IpIoCloseProtocolDestroyIpChild(IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ChildHandle, IN UINT8 IpVersion)
Definition: DxeIpIoLib.c:212
VOID EFIAPI IpIoDummyHandlerDpc(IN VOID *Context)
Definition: DxeIpIoLib.c:899
EFI_STATUS IpIoIcmpHandler(IN IP_IO *IpIo, IN OUT NET_BUF *Pkt, IN EFI_NET_SESSION_DATA *Session)
Definition: DxeIpIoLib.c:580
IP_IO_IP_INFO *EFIAPI IpIoFindSender(IN OUT IP_IO **IpIo, IN UINT8 IpVersion, IN EFI_IP_ADDRESS *Src)
Definition: DxeIpIoLib.c:2043
EFI_STATUS EFIAPI IpIoGetIcmpErrStatus(IN UINT8 IcmpError, IN UINT8 IpVersion, OUT BOOLEAN *IsHard OPTIONAL, OUT BOOLEAN *Notify OPTIONAL)
Definition: DxeIpIoLib.c:2109
VOID EFIAPI IpIoDummyHandler(IN EFI_EVENT Event, IN VOID *Context)
Definition: DxeIpIoLib.c:968
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define ICMP_V6_NO_ROUTE_TO_DEST
Definition: Ip6.h:107
#define ICMP_V6_DEST_UNREACHABLE
Definition: Ip6.h:80
#define EFI_IP4_HEADER_LEN(HdrPtr)
Definition: IpIoLib.h:50
#define ICMP_ERRLEN(IpHdr)
Definition: IpIoLib.h:61
#define NET_PROTO_HDR(Buf, Type)
Definition: IpIoLib.h:72
#define ICMP_ERR_UNREACH_NET
Definition: IpIoLib.h:83
#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
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:195
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
BOOLEAN EFIAPI NetIp4IsUnicast(IN IP4_ADDR Ip, IN IP4_ADDR NetMask)
Definition: DxeNetLib.c:683
BOOLEAN EFIAPI NetIp6IsValidUnicast(IN EFI_IPv6_ADDRESS *Ip6)
Definition: DxeNetLib.c:725
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
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 *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_NETWORK_UNREACHABLE
Definition: UefiBaseType.h:166
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
UINT32 HeaderLength
Definition: Ip6.h:437
UINT32 FragmentCount
Definition: Ip6.h:452
EFI_IP6_HEADER * Header
Definition: Ip6.h:443
UINT32 DataLength
Definition: Ip6.h:448
EFI_EVENT RecycleSignal
Definition: Ip6.h:432
EFI_IP6_FRAGMENT_DATA FragmentTable[1]
Definition: Ip6.h:456
UINT32 DataLength
Definition: Ip6.h:502
UINT32 ExtHdrsLength
Definition: Ip6.h:487
EFI_IP6_FRAGMENT_DATA FragmentTable[1]
Definition: Ip6.h:510
EFI_IP6_OVERRIDE_DATA * OverrideData
Definition: Ip6.h:482
UINT32 FragmentCount
Definition: Ip6.h:506
EFI_IPv6_ADDRESS DestinationAddress
Definition: Ip6.h:478
UINT8 IpVersion
The IP version of the received packet.
Definition: IpIoLib.h:165
EFI_IP_ADDRESS Source
Source IP of the received packet.
Definition: IpIoLib.h:157
EFI_IP_ADDRESS Dest
Destination IP of the received packet.
Definition: IpIoLib.h:158
IP_IO_IP_HEADER IpHdr
IP header of the received packet.
Definition: IpIoLib.h:159
PKT_RCVD_NOTIFY PktRcvdNotify
See IP_IO_OPEN_DATA::PktRcvdNotify.
Definition: IpIoLib.h:253
VOID * RcvdContext
See IP_IO_OPEN_DATA::RcvdContext.
Definition: IpIoLib.h:251
IP_IO_IP_COMPLETION_TOKEN RcvToken
Definition: IpIoLib.h:241
LIST_ENTRY IpList
Definition: IpIoLib.h:222
LIST_ENTRY PendingSndList
Definition: IpIoLib.h:246
PKT_SENT_NOTIFY PktSentNotify
See IP_IO_OPEN_DATA::PktSentNotify.
Definition: IpIoLib.h:254
EFI_EVENT Event
Definition: Ip4.h:244
EFI_IP4_RECEIVE_DATA * RxData
Definition: Ip4.h:254
EFI_STATUS Status
Definition: Ip4.h:249
EFI_IP4_TRANSMIT_DATA * TxData
Definition: Ip4.h:258
EFI_IPv4_ADDRESS SubnetMask
Definition: Ip4.h:98
EFI_IPv4_ADDRESS StationAddress
Definition: Ip4.h:94
EFI_IP4_CONFIG_DATA ConfigData
Definition: Ip4.h:153
EFI_STATUS Status
Definition: Ip6.h:536
EFI_EVENT Event
Definition: Ip6.h:522
EFI_IP6_RECEIVE_DATA * RxData
Definition: Ip6.h:541
EFI_IP6_TRANSMIT_DATA * TxData
Definition: Ip6.h:545
EFI_IPv6_ADDRESS StationAddress
Definition: Ip6.h:188
EFI_IP6_NEIGHBOR_CACHE * NeighborCache
Definition: Ip6.h:366
EFI_IP6_ICMP_TYPE * IcmpTypeList
Definition: Ip6.h:386
EFI_IP6_ADDRESS_INFO * AddressList
Definition: Ip6.h:336
EFI_IP6_ROUTE_TABLE * RouteTable
Definition: Ip6.h:356
EFI_IPv6_ADDRESS * GroupTable
Definition: Ip6.h:347
EFI_IP6_CONFIG_DATA ConfigData
Definition: Ip6.h:319
EFI_IP6_ADDRESS_INFO * PrefixTable
Definition: Ip6.h:376
BOOLEAN IsConfigured
Definition: Ip6.h:326
Definition: Base.h:213