3 Copyright (c) 2005 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 The implementation of the IpIo layer.
25 #include <Protocol/Udp4.h>
27 #include <Library/IpIoLib.h>
28 #include <Library/BaseLib.h>
29 #include <Library/DebugLib.h>
30 #include <Library/UefiBootServicesTableLib.h>
31 #include <Library/MemoryAllocationLib.h>
32 #include <Library/BaseMemoryLib.h>
35 #define NET_PROTO_HDR(Buf, Type) ((Type *) ((Buf)->BlockOp[0].Head))
36 #define ICMP_ERRLEN(IpHdr) \
37 (sizeof(IP4_ICMP_HEAD) + EFI_IP4_HEADER_LEN(IpHdr) + 8)
39 NET_LIST_ENTRY mActiveIpIoList
= {
44 EFI_IP4_CONFIG_DATA mIpIoDefaultIpConfigData
= {
61 STATIC ICMP_ERROR_INFO mIcmpErrMap
[10] = {
84 This function create an ip child ,open the IP protocol, return the opened
85 Ip protocol to Interface.
87 @param ControllerHandle The controller handle.
88 @param ImageHandle The image handle.
89 @param ChildHandle Pointer to the buffer to save the ip child handle.
90 @param Interface Pointer used to get the ip protocol interface.
92 @retval EFI_SUCCESS The ip child is created and the ip protocol
93 interface is retrieved.
94 @retval other The required operation failed.
99 IpIoCreateIpChildOpenProtocol (
100 IN EFI_HANDLE ControllerHandle
,
101 IN EFI_HANDLE ImageHandle
,
102 IN EFI_HANDLE
*ChildHandle
,
109 // Create an ip child.
111 Status
= NetLibCreateServiceChild (
114 &gEfiIp4ServiceBindingProtocolGuid
,
117 if (EFI_ERROR (Status
)) {
122 // Open the ip protocol installed on the *ChildHandle.
124 Status
= gBS
->OpenProtocol (
126 &gEfiIp4ProtocolGuid
,
130 EFI_OPEN_PROTOCOL_BY_DRIVER
132 if (EFI_ERROR (Status
)) {
134 // On failure, destroy the ip child.
136 NetLibDestroyServiceChild (
139 &gEfiIp4ServiceBindingProtocolGuid
,
149 This function close the previously openned ip protocol and destroy the ip child.
151 @param ControllerHandle The controller handle.
152 @param ImageHandle the image handle.
153 @param ChildHandle The child handle of the ip child.
155 @retval EFI_SUCCESS The ip protocol is closed and the relevant ip child
157 @retval other The required operation failed.
162 IpIoCloseProtocolDestroyIpChild (
163 IN EFI_HANDLE ControllerHandle
,
164 IN EFI_HANDLE ImageHandle
,
165 IN EFI_HANDLE ChildHandle
171 // Close the previously openned ip protocol.
175 &gEfiIp4ProtocolGuid
,
181 // Destroy the ip child.
183 Status
= NetLibDestroyServiceChild (
186 &gEfiIp4ServiceBindingProtocolGuid
,
197 @param IpIo Pointer to the IP_IO instance.
198 @param Pkt Pointer to the ICMP packet.
199 @param Session Pointer to the net session of this ICMP packet.
201 @retval EFI_SUCCESS The ICMP packet is handled successfully.
202 @retval EFI_ABORTED This type of ICMP packet is not supported.
210 IN EFI_NET_SESSION_DATA
*Session
213 IP4_ICMP_ERROR_HEAD
*IcmpHdr
;
214 EFI_IP4_HEADER
*IpHdr
;
221 IcmpHdr
= NET_PROTO_HDR (Pkt
, IP4_ICMP_ERROR_HEAD
);
222 IpHdr
= (EFI_IP4_HEADER
*) (&IcmpHdr
->IpHead
);
225 // Check the ICMP packet length.
227 if (Pkt
->TotalSize
< ICMP_ERRLEN (IpHdr
)) {
232 Type
= IcmpHdr
->Head
.Type
;
233 Code
= IcmpHdr
->Head
.Code
;
236 // Analyze the ICMP Error in this ICMP pkt
239 case ICMP_TYPE_UNREACH
:
241 case ICMP_CODE_UNREACH_NET
:
242 case ICMP_CODE_UNREACH_HOST
:
243 case ICMP_CODE_UNREACH_PROTOCOL
:
244 case ICMP_CODE_UNREACH_PORT
:
245 case ICMP_CODE_UNREACH_SRCFAIL
:
246 IcmpErr
= (ICMP_ERROR
) (ICMP_ERR_UNREACH_NET
+ Code
);
250 case ICMP_CODE_UNREACH_NEEDFRAG
:
251 IcmpErr
= ICMP_ERR_MSGSIZE
;
255 case ICMP_CODE_UNREACH_NET_UNKNOWN
:
256 case ICMP_CODE_UNREACH_NET_PROHIB
:
257 case ICMP_CODE_UNREACH_TOSNET
:
258 IcmpErr
= ICMP_ERR_UNREACH_NET
;
262 case ICMP_CODE_UNREACH_HOST_UNKNOWN
:
263 case ICMP_CODE_UNREACH_ISOLATED
:
264 case ICMP_CODE_UNREACH_HOST_PROHIB
:
265 case ICMP_CODE_UNREACH_TOSHOST
:
266 IcmpErr
= ICMP_ERR_UNREACH_HOST
;
278 case ICMP_TYPE_TIMXCEED
:
283 IcmpErr
= (ICMP_ERROR
) (Code
+ ICMP_ERR_TIMXCEED_INTRANS
);
287 case ICMP_TYPE_PARAMPROB
:
292 IcmpErr
= ICMP_ERR_PARAMPROB
;
296 case ICMP_TYPE_SOURCEQUENCH
:
301 IcmpErr
= ICMP_ERR_QUENCH
;
312 // Notify user the ICMP pkt only containing payload except
313 // IP and ICMP header
315 PayLoadHdr
= (UINT8
*) ((UINT8
*) IpHdr
+ EFI_IP4_HEADER_LEN (IpHdr
));
316 TrimBytes
= (UINT32
) (PayLoadHdr
- (UINT8
*) IcmpHdr
);
318 NetbufTrim (Pkt
, TrimBytes
, TRUE
);
320 IpIo
->PktRcvdNotify (EFI_ICMP_ERROR
, IcmpErr
, Session
, Pkt
, IpIo
->RcvdContext
);
327 Ext free function for net buffer. This function is
328 called when the net buffer is freed. It is used to
329 signal the recycle event to notify IP to recycle the
332 @param Event The event to be signaled.
343 gBS
->SignalEvent ((EFI_EVENT
) Event
);
348 Create a send entry to wrap a packet before sending
351 @param IpIo Pointer to the IP_IO instance.
352 @param Pkt Pointer to the packet.
353 @param Sender Pointer to the IP sender.
354 @param NotifyData Pointer to the notify data.
355 @param Dest Pointer to the destination IP address.
356 @param Override Pointer to the overriden IP_IO data.
358 @return Pointer to the data structure created to wrap the packet. If NULL,
359 @return resource limit occurred.
367 IN EFI_IP4_PROTOCOL
*Sender
,
368 IN VOID
*Context OPTIONAL
,
369 IN VOID
*NotifyData OPTIONAL
,
371 IN IP_IO_OVERRIDE
*Override
374 IP_IO_SEND_ENTRY
*SndEntry
;
375 EFI_IP4_COMPLETION_TOKEN
*SndToken
;
376 EFI_IP4_TRANSMIT_DATA
*TxData
;
378 EFI_IP4_OVERRIDE_DATA
*OverrideData
;
379 volatile UINT32 Index
;
382 // Allocate resource for SndEntry
384 SndEntry
= NetAllocatePool (sizeof (IP_IO_SEND_ENTRY
));
385 if (NULL
== SndEntry
) {
390 // Allocate resource for SndToken
392 SndToken
= NetAllocatePool (sizeof (EFI_IP4_COMPLETION_TOKEN
));
393 if (NULL
== SndToken
) {
394 goto ReleaseSndEntry
;
397 Status
= gBS
->CreateEvent (
404 if (EFI_ERROR (Status
)) {
405 goto ReleaseSndToken
;
409 // Allocate resource for TxData
411 TxData
= NetAllocatePool (
412 sizeof (EFI_IP4_TRANSMIT_DATA
) +
413 sizeof (EFI_IP4_FRAGMENT_DATA
) * (Pkt
->BlockOpNum
- 1)
416 if (NULL
== TxData
) {
421 // Allocate resource for OverrideData if needed
424 if (NULL
!= Override
) {
426 OverrideData
= NetAllocatePool (sizeof (EFI_IP4_OVERRIDE_DATA
));
427 if (NULL
== OverrideData
) {
428 goto ReleaseResource
;
431 // Set the fields of OverrideData
433 NetCopyMem (OverrideData
, Override
, sizeof (*OverrideData
));
437 // Set the fields of TxData
439 NetCopyMem (&TxData
->DestinationAddress
, &Dest
, sizeof (EFI_IPv4_ADDRESS
));
440 TxData
->OverrideData
= OverrideData
;
441 TxData
->OptionsLength
= 0;
442 TxData
->OptionsBuffer
= NULL
;
443 TxData
->TotalDataLength
= Pkt
->TotalSize
;
444 TxData
->FragmentCount
= Pkt
->BlockOpNum
;
447 for (Index
= 0; Index
< Pkt
->BlockOpNum
; Index
++) {
448 TxData
->FragmentTable
[Index
].FragmentBuffer
= Pkt
->BlockOp
[Index
].Head
;
449 TxData
->FragmentTable
[Index
].FragmentLength
= Pkt
->BlockOp
[Index
].Size
;
453 // Set the fields of SndToken
455 SndToken
->Packet
.TxData
= TxData
;
458 // Set the fields of SndEntry
460 SndEntry
->IpIo
= IpIo
;
461 SndEntry
->Ip
= Sender
;
462 SndEntry
->Context
= Context
;
463 SndEntry
->NotifyData
= NotifyData
;
468 SndEntry
->SndToken
= SndToken
;
470 NetListInsertTail (&IpIo
->PendingSndList
, &SndEntry
->Entry
);
475 NetFreePool (TxData
);
478 gBS
->CloseEvent (SndToken
->Event
);
481 NetFreePool (SndToken
);
484 NetFreePool (SndEntry
);
491 Destroy the SndEntry.
493 @param SndEntry Pointer to the send entry to be destroyed.
500 IpIoDestroySndEntry (
501 IN IP_IO_SEND_ENTRY
*SndEntry
504 EFI_IP4_TRANSMIT_DATA
*TxData
;
506 TxData
= SndEntry
->SndToken
->Packet
.TxData
;
508 if (NULL
!= TxData
->OverrideData
) {
509 NetFreePool (TxData
->OverrideData
);
512 NetFreePool (TxData
);
513 NetbufFree (SndEntry
->Pkt
);
514 gBS
->CloseEvent (SndEntry
->SndToken
->Event
);
516 NetFreePool (SndEntry
->SndToken
);
517 NetListRemoveEntry (&SndEntry
->Entry
);
519 NetFreePool (SndEntry
);
524 Notify function for IP transmit token.
526 @param Event The event signaled.
527 @param Context The context passed in by the event notifier.
535 IpIoTransmitHandler (
541 IP_IO_SEND_ENTRY
*SndEntry
;
543 SndEntry
= (IP_IO_SEND_ENTRY
*) Context
;
545 IpIo
= SndEntry
->IpIo
;
547 if (IpIo
->PktSentNotify
&& SndEntry
->NotifyData
) {
548 IpIo
->PktSentNotify (
549 SndEntry
->SndToken
->Status
,
556 IpIoDestroySndEntry (SndEntry
);
561 The dummy handler for the dummy IP receive token.
563 @param Evt The event signaled.
564 @param Context The context passed in by the event notifier.
577 IP_IO_IP_INFO
*IpInfo
;
578 EFI_IP4_COMPLETION_TOKEN
*DummyToken
;
580 ASSERT (Event
&& Context
);
582 IpInfo
= (IP_IO_IP_INFO
*) Context
;
583 DummyToken
= &(IpInfo
->DummyRcvToken
);
585 if (EFI_SUCCESS
== DummyToken
->Status
) {
586 ASSERT (DummyToken
->Packet
.RxData
);
588 gBS
->SignalEvent (DummyToken
->Packet
.RxData
->RecycleSignal
);
591 IpInfo
->Ip
->Receive (IpInfo
->Ip
, DummyToken
);
596 Notify function for the IP receive token, used to process
597 the received IP packets.
599 @param Event The event signaled.
600 @param Context The context passed in by the event notifier.
615 EFI_IP4_RECEIVE_DATA
*RxData
;
616 EFI_IP4_PROTOCOL
*Ip
;
617 EFI_NET_SESSION_DATA Session
;
620 IpIo
= (IP_IO
*) Context
;
623 Status
= IpIo
->RcvToken
.Status
;
624 RxData
= IpIo
->RcvToken
.Packet
.RxData
;
626 if (((EFI_SUCCESS
!= Status
) && (EFI_ICMP_ERROR
!= Status
)) || (NULL
== RxData
)) {
628 // Only process the normal packets and the icmp error packets, if RxData is NULL
629 // with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although
630 // this should be a bug of the low layer (IP).
635 if (NULL
== IpIo
->PktRcvdNotify
) {
639 if ((EFI_IP4 (RxData
->Header
->SourceAddress
) != 0) &&
640 !Ip4IsUnicast (EFI_NTOHL (RxData
->Header
->SourceAddress
), 0)) {
642 // The source address is not zero and it's not a unicast IP address, discard it.
648 // Create a netbuffer representing packet
650 Pkt
= NetbufFromExt (
651 (NET_FRAGMENT
*) RxData
->FragmentTable
,
652 RxData
->FragmentCount
,
656 RxData
->RecycleSignal
663 // Create a net session
665 Session
.Source
= EFI_IP4 (RxData
->Header
->SourceAddress
);
666 Session
.Dest
= EFI_IP4 (RxData
->Header
->DestinationAddress
);
667 Session
.IpHdr
= RxData
->Header
;
669 if (EFI_SUCCESS
== Status
) {
671 IpIo
->PktRcvdNotify (EFI_SUCCESS
, (ICMP_ERROR
) 0, &Session
, Pkt
, IpIo
->RcvdContext
);
674 // Status is EFI_ICMP_ERROR
676 Status
= IpIoIcmpHandler (IpIo
, Pkt
, &Session
);
677 if (EFI_ERROR (Status
)) {
685 gBS
->SignalEvent (RxData
->RecycleSignal
);
688 Ip
->Receive (Ip
, &(IpIo
->RcvToken
));
693 Create a new IP_IO instance.
695 @param Image The image handle of an IP_IO consumer protocol.
696 @param Controller The controller handle of an IP_IO consumer protocol
699 @return Pointer to a newly created IP_IO instance.
705 IN EFI_HANDLE Controller
711 IpIo
= NetAllocateZeroPool (sizeof (IP_IO
));
716 NetListInit (&(IpIo
->PendingSndList
));
717 NetListInit (&(IpIo
->IpList
));
718 IpIo
->Controller
= Controller
;
721 Status
= gBS
->CreateEvent (
726 &(IpIo
->RcvToken
.Event
)
728 if (EFI_ERROR (Status
)) {
733 // Create an IP child and open IP protocol
735 Status
= IpIoCreateIpChildOpenProtocol (
741 if (EFI_ERROR (Status
)) {
749 if (NULL
!= IpIo
->RcvToken
.Event
) {
750 gBS
->CloseEvent (IpIo
->RcvToken
.Event
);
760 Open an IP_IO instance for use.
762 @param IpIo Pointer to an IP_IO instance that needs to open.
763 @param OpenData The configuration data for the IP_IO instance.
765 @retval EFI_SUCCESS The IP_IO instance opened with OpenData
767 @retval other Error condition occurred.
773 IN IP_IO_OPEN_DATA
*OpenData
777 EFI_IP4_PROTOCOL
*Ip
;
779 if (IpIo
->IsConfigured
) {
780 return EFI_ACCESS_DENIED
;
788 Status
= Ip
->Configure (Ip
, &OpenData
->IpConfigData
);
789 if (EFI_ERROR (Status
)) {
794 // bugbug: to delete the default route entry in this Ip, if it is:
795 // (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified
798 Status
= Ip
->Routes (Ip
, TRUE
, &mZeroIp4Addr
, &mZeroIp4Addr
, &mZeroIp4Addr
);
800 if (EFI_ERROR (Status
) && (EFI_NOT_FOUND
!= Status
)) {
804 IpIo
->PktRcvdNotify
= OpenData
->PktRcvdNotify
;
805 IpIo
->PktSentNotify
= OpenData
->PktSentNotify
;
807 IpIo
->RcvdContext
= OpenData
->RcvdContext
;
808 IpIo
->SndContext
= OpenData
->SndContext
;
810 IpIo
->Protocol
= OpenData
->IpConfigData
.DefaultProtocol
;
813 // start to listen incoming packet
815 Status
= Ip
->Receive (Ip
, &(IpIo
->RcvToken
));
816 if (EFI_ERROR (Status
)) {
817 Ip
->Configure (Ip
, NULL
);
821 IpIo
->IsConfigured
= TRUE
;
822 NetListInsertTail (&mActiveIpIoList
, &IpIo
->Entry
);
831 Stop an IP_IO instance.
833 @param IpIo Pointer to the IP_IO instance that needs to stop.
835 @retval EFI_SUCCESS The IP_IO instance stopped successfully.
836 @retval other Error condition occurred.
845 EFI_IP4_PROTOCOL
*Ip
;
846 IP_IO_IP_INFO
*IpInfo
;
848 if (!IpIo
->IsConfigured
) {
853 // Remove the IpIo from the active IpIo list.
855 NetListRemoveEntry (&IpIo
->Entry
);
862 Status
= Ip
->Configure (Ip
, NULL
);
863 if (EFI_ERROR (Status
)) {
867 IpIo
->IsConfigured
= FALSE
;
870 // Detroy the Ip List used by IpIo
873 while (!NetListIsEmpty (&(IpIo
->IpList
))) {
874 IpInfo
= NET_LIST_HEAD (&(IpIo
->IpList
), IP_IO_IP_INFO
, Entry
);
876 IpIoRemoveIp (IpIo
, IpInfo
);
880 // All pending snd tokens should be flushed by reseting the IP instances.
882 ASSERT (NetListIsEmpty (&IpIo
->PendingSndList
));
885 // Close the receive event.
887 gBS
->CloseEvent (IpIo
->RcvToken
.Event
);
894 Destroy an IP_IO instance.
896 @param IpIo Pointer to the IP_IO instance that needs to
899 @retval EFI_SUCCESS The IP_IO instance destroyed successfully.
900 @retval other Error condition occurred.
914 // Close the IP protocol and destroy the child.
916 IpIoCloseProtocolDestroyIpChild (IpIo
->Controller
, IpIo
->Image
, IpIo
->ChildHandle
);
925 Send out an IP packet.
927 @param IpIo Pointer to an IP_IO instance used for sending IP
929 @param Pkt Pointer to the IP packet to be sent.
930 @param Sender The IP protocol instance used for sending.
932 @param Dest The destination IP address to send this packet to.
933 @param OverrideData The data to override some configuration of the IP
934 instance used for sending.
936 @retval EFI_SUCCESS The operation is completed successfully.
937 @retval EFI_NOT_STARTED The IpIo is not configured.
938 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
945 IN IP_IO_IP_INFO
*Sender
,
946 IN VOID
*Context OPTIONAL
,
947 IN VOID
*NotifyData OPTIONAL
,
949 IN IP_IO_OVERRIDE
*OverrideData
953 EFI_IP4_PROTOCOL
*Ip
;
954 IP_IO_SEND_ENTRY
*SndEntry
;
956 if (!IpIo
->IsConfigured
) {
957 return EFI_NOT_STARTED
;
960 Ip
= (NULL
== Sender
) ? IpIo
->Ip
: Sender
->Ip
;
963 // create a new SndEntry
965 SndEntry
= IpIoCreateSndEntry (IpIo
, Pkt
, Ip
, Context
, NotifyData
, Dest
, OverrideData
);
966 if (NULL
== SndEntry
) {
967 return EFI_OUT_OF_RESOURCES
;
973 Status
= Ip
->Transmit (Ip
, SndEntry
->SndToken
);
974 if (EFI_ERROR (Status
)) {
975 IpIoDestroySndEntry (SndEntry
);
983 Cancel the IP transmit token which wraps this Packet.
985 @param IpIo Pointer to the IP_IO instance.
986 @param Packet Pointer to the packet to cancel.
997 NET_LIST_ENTRY
*Node
;
998 IP_IO_SEND_ENTRY
*SndEntry
;
999 EFI_IP4_PROTOCOL
*Ip
;
1001 ASSERT (IpIo
&& Packet
);
1003 NET_LIST_FOR_EACH (Node
, &IpIo
->PendingSndList
) {
1005 SndEntry
= NET_LIST_USER_STRUCT (Node
, IP_IO_SEND_ENTRY
, Entry
);
1007 if (SndEntry
->Pkt
== Packet
) {
1010 Ip
->Cancel (Ip
, SndEntry
->SndToken
);
1013 // Abort the user token.
1015 SndEntry
->SndToken
->Status
= EFI_ABORTED
;
1016 IpIoTransmitHandler (NULL
, SndEntry
);
1026 Add a new IP instance for sending data.
1028 @param IpIo Pointer to a IP_IO instance to add a new IP
1029 instance for sending purpose.
1031 @return Pointer to the created IP_IO_IP_INFO structure, NULL is failed.
1040 IP_IO_IP_INFO
*IpInfo
;
1044 IpInfo
= NetAllocatePool (sizeof (IP_IO_IP_INFO
));
1045 if (IpInfo
== NULL
) {
1050 // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP
1053 NetListInit (&IpInfo
->Entry
);
1054 IpInfo
->ChildHandle
= NULL
;
1056 IpInfo
->SubnetMask
= 0;
1060 // Create the IP instance and open the Ip4 protocol.
1062 Status
= IpIoCreateIpChildOpenProtocol (
1065 &IpInfo
->ChildHandle
,
1066 (VOID
**) &IpInfo
->Ip
1068 if (EFI_ERROR (Status
)) {
1073 // Create the event for the DummyRcvToken.
1075 Status
= gBS
->CreateEvent (
1080 &IpInfo
->DummyRcvToken
.Event
1082 if (EFI_ERROR (Status
)) {
1083 goto ReleaseIpChild
;
1087 // Link this IpInfo into the IpIo.
1089 NetListInsertTail (&IpIo
->IpList
, &IpInfo
->Entry
);
1095 IpIoCloseProtocolDestroyIpChild (
1103 NetFreePool (IpInfo
);
1110 Configure the IP instance of this IpInfo and start the receiving if Ip4ConfigData
1113 @param IpInfo Pointer to the IP_IO_IP_INFO instance.
1114 @param Ip4ConfigData The IP4 configure data used to configure the ip
1115 instance, if NULL the ip instance is reseted. If
1116 UseDefaultAddress is set to TRUE, and the configure
1117 operation succeeds, the default address information
1118 is written back in this Ip4ConfigData.
1120 @retval EFI_STATUS The status returned by IP4->Configure or
1126 IN IP_IO_IP_INFO
*IpInfo
,
1127 IN OUT EFI_IP4_CONFIG_DATA
*Ip4ConfigData OPTIONAL
1131 EFI_IP4_PROTOCOL
*Ip
;
1132 EFI_IP4_MODE_DATA Ip4ModeData
;
1136 if (IpInfo
->RefCnt
> 1) {
1138 // This IP instance is shared, don't reconfigure it until it has only one
1139 // consumer. Currently, only the tcp children cloned from their passive parent
1140 // will share the same IP. So this cases only happens while Ip4ConfigData is NULL,
1141 // let the last consumer clean the IP instance.
1148 Status
= Ip
->Configure (Ip
, Ip4ConfigData
);
1149 if (EFI_ERROR (Status
)) {
1153 if (Ip4ConfigData
!= NULL
) {
1155 if (Ip4ConfigData
->UseDefaultAddress
) {
1156 Ip
->GetModeData (Ip
, &Ip4ModeData
, NULL
, NULL
);
1158 Ip4ConfigData
->StationAddress
= Ip4ModeData
.ConfigData
.StationAddress
;
1159 Ip4ConfigData
->SubnetMask
= Ip4ModeData
.ConfigData
.SubnetMask
;
1162 NetCopyMem (&IpInfo
->Addr
, &Ip4ConfigData
->StationAddress
, sizeof (IP4_ADDR
));
1163 NetCopyMem (&IpInfo
->SubnetMask
, &Ip4ConfigData
->SubnetMask
, sizeof (IP4_ADDR
));
1165 Status
= Ip
->Receive (Ip
, &IpInfo
->DummyRcvToken
);
1166 if (EFI_ERROR (Status
)) {
1167 Ip
->Configure (Ip
, NULL
);
1172 // The IP instance is reseted, set the stored Addr and SubnetMask to zero.
1175 IpInfo
->SubnetMask
=0;
1185 Destroy an IP instance maintained in IpIo->IpList for
1188 @param IpIo Pointer to the IP_IO instance.
1189 @param IpInfo Pointer to the IpInfo to be removed.
1197 IN IP_IO_IP_INFO
*IpInfo
1200 ASSERT (IpInfo
->RefCnt
> 0);
1202 NET_PUT_REF (IpInfo
);
1204 if (IpInfo
->RefCnt
> 0) {
1209 NetListRemoveEntry (&IpInfo
->Entry
);
1211 IpInfo
->Ip
->Configure (IpInfo
->Ip
, NULL
);
1213 IpIoCloseProtocolDestroyIpChild (IpIo
->Controller
, IpIo
->Image
, IpInfo
->ChildHandle
);
1215 gBS
->CloseEvent (IpInfo
->DummyRcvToken
.Event
);
1217 NetFreePool (IpInfo
);
1222 Find the first IP protocol maintained in IpIo whose local
1223 address is the same with Src.
1225 @param IpIo Pointer to the pointer of the IP_IO instance.
1226 @param Src The local IP address.
1228 @return Pointer to the IP protocol can be used for sending purpose and its local
1229 @return address is the same with Src.
1234 IN OUT IP_IO
**IpIo
,
1238 NET_LIST_ENTRY
*IpIoEntry
;
1240 NET_LIST_ENTRY
*IpInfoEntry
;
1241 IP_IO_IP_INFO
*IpInfo
;
1243 NET_LIST_FOR_EACH (IpIoEntry
, &mActiveIpIoList
) {
1244 IpIoPtr
= NET_LIST_USER_STRUCT (IpIoEntry
, IP_IO
, Entry
);
1246 if ((*IpIo
!= NULL
) && (*IpIo
!= IpIoPtr
)) {
1250 NET_LIST_FOR_EACH (IpInfoEntry
, &IpIoPtr
->IpList
) {
1251 IpInfo
= NET_LIST_USER_STRUCT (IpInfoEntry
, IP_IO_IP_INFO
, Entry
);
1253 if (IpInfo
->Addr
== Src
) {
1268 Get the ICMP error map information, the ErrorStatus will be returned.
1269 The IsHard and Notify are optional. If they are not NULL, this rouine will
1271 We move IcmpErrMap[] to local variable to enable EBC build.
1273 @param IcmpError IcmpError Type
1274 @param IsHard Whether it is a hard error
1275 @param Notify Whether it need to notify SockError
1277 @return ICMP Error Status
1281 IpIoGetIcmpErrStatus (
1282 IN ICMP_ERROR IcmpError
,
1283 OUT BOOLEAN
*IsHard
, OPTIONAL
1284 OUT BOOLEAN
*Notify OPTIONAL
1287 ASSERT ((IcmpError
>= ICMP_ERR_UNREACH_NET
) && (IcmpError
<= ICMP_ERR_PARAMPROB
));
1289 if (IsHard
!= NULL
) {
1290 *IsHard
= mIcmpErrMap
[IcmpError
].IsHard
;
1293 if (Notify
!= NULL
) {
1294 *Notify
= mIcmpErrMap
[IcmpError
].Notify
;
1297 switch (IcmpError
) {
1298 case ICMP_ERR_UNREACH_NET
:
1299 return EFI_NETWORK_UNREACHABLE
;
1301 case ICMP_ERR_TIMXCEED_INTRANS
:
1302 case ICMP_ERR_TIMXCEED_REASS
:
1303 case ICMP_ERR_UNREACH_HOST
:
1304 return EFI_HOST_UNREACHABLE
;
1306 case ICMP_ERR_UNREACH_PROTOCOL
:
1307 return EFI_PROTOCOL_UNREACHABLE
;
1309 case ICMP_ERR_UNREACH_PORT
:
1310 return EFI_PORT_UNREACHABLE
;
1312 case ICMP_ERR_MSGSIZE
:
1313 case ICMP_ERR_UNREACH_SRCFAIL
:
1314 case ICMP_ERR_QUENCH
:
1315 case ICMP_ERR_PARAMPROB
:
1316 return EFI_ICMP_ERROR
;
1320 // will never run here!
1323 return EFI_UNSUPPORTED
;