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>
34 #define NET_PROTO_HDR(Buf, Type) ((Type *) ((Buf)->BlockOp[0].Head))
35 #define ICMP_ERRLEN(IpHdr) \
36 (sizeof(IP4_ICMP_HEAD) + EFI_IP4_HEADER_LEN(IpHdr) + 8)
38 NET_LIST_ENTRY mActiveIpIoList
= {
43 EFI_IP4_CONFIG_DATA mIpIoDefaultIpConfigData
= {
70 This function create an ip child ,open the IP protocol, return the opened
71 Ip protocol to Interface.
73 @param ControllerHandle The controller handle.
74 @param ImageHandle The image handle.
75 @param ChildHandle Pointer to the buffer to save the ip child handle.
76 @param Interface Pointer used to get the ip protocol interface.
78 @retval EFI_SUCCESS The ip child is created and the ip protocol
79 interface is retrieved.
80 @retval other The required operation failed.
85 IpIoCreateIpChildOpenProtocol (
86 IN EFI_HANDLE ControllerHandle
,
87 IN EFI_HANDLE ImageHandle
,
88 IN EFI_HANDLE
*ChildHandle
,
95 // Create an ip child.
97 Status
= NetLibCreateServiceChild (
100 &gEfiIp4ServiceBindingProtocolGuid
,
103 if (EFI_ERROR (Status
)) {
108 // Open the ip protocol installed on the *ChildHandle.
110 Status
= gBS
->OpenProtocol (
112 &gEfiIp4ProtocolGuid
,
116 EFI_OPEN_PROTOCOL_BY_DRIVER
118 if (EFI_ERROR (Status
)) {
120 // On failure, destroy the ip child.
122 NetLibDestroyServiceChild (
125 &gEfiIp4ServiceBindingProtocolGuid
,
135 This function close the previously openned ip protocol and destroy the ip child.
137 @param ControllerHandle The controller handle.
138 @param ImageHandle the image handle.
139 @param ChildHandle The child handle of the ip child.
141 @retval EFI_SUCCESS The ip protocol is closed and the relevant ip child
143 @retval other The required operation failed.
148 IpIoCloseProtocolDestroyIpChild (
149 IN EFI_HANDLE ControllerHandle
,
150 IN EFI_HANDLE ImageHandle
,
151 IN EFI_HANDLE ChildHandle
157 // Close the previously openned ip protocol.
161 &gEfiIp4ProtocolGuid
,
167 // Destroy the ip child.
169 Status
= NetLibDestroyServiceChild (
172 &gEfiIp4ServiceBindingProtocolGuid
,
183 @param IpIo Pointer to the IP_IO instance.
184 @param Pkt Pointer to the ICMP packet.
185 @param Session Pointer to the net session of this ICMP packet.
187 @retval EFI_SUCCESS The ICMP packet is handled successfully.
188 @retval EFI_ABORTED This type of ICMP packet is not supported.
196 IN EFI_NET_SESSION_DATA
*Session
199 IP4_ICMP_ERROR_HEAD
*IcmpHdr
;
200 EFI_IP4_HEADER
*IpHdr
;
207 IcmpHdr
= NET_PROTO_HDR (Pkt
, IP4_ICMP_ERROR_HEAD
);
208 IpHdr
= (EFI_IP4_HEADER
*) (&IcmpHdr
->IpHead
);
211 // Check the ICMP packet length.
213 if (Pkt
->TotalSize
< ICMP_ERRLEN (IpHdr
)) {
218 Type
= IcmpHdr
->Head
.Type
;
219 Code
= IcmpHdr
->Head
.Code
;
222 // Analyze the ICMP Error in this ICMP pkt
225 case ICMP_TYPE_UNREACH
:
227 case ICMP_CODE_UNREACH_NET
:
228 case ICMP_CODE_UNREACH_HOST
:
229 case ICMP_CODE_UNREACH_PROTOCOL
:
230 case ICMP_CODE_UNREACH_PORT
:
231 case ICMP_CODE_UNREACH_SRCFAIL
:
232 IcmpErr
= ICMP_ERR_UNREACH_NET
+ Code
;
236 case ICMP_CODE_UNREACH_NEEDFRAG
:
237 IcmpErr
= ICMP_ERR_MSGSIZE
;
241 case ICMP_CODE_UNREACH_NET_UNKNOWN
:
242 case ICMP_CODE_UNREACH_NET_PROHIB
:
243 case ICMP_CODE_UNREACH_TOSNET
:
244 IcmpErr
= ICMP_ERR_UNREACH_NET
;
248 case ICMP_CODE_UNREACH_HOST_UNKNOWN
:
249 case ICMP_CODE_UNREACH_ISOLATED
:
250 case ICMP_CODE_UNREACH_HOST_PROHIB
:
251 case ICMP_CODE_UNREACH_TOSHOST
:
252 IcmpErr
= ICMP_ERR_UNREACH_HOST
;
264 case ICMP_TYPE_TIMXCEED
:
269 IcmpErr
= Code
+ ICMP_ERR_TIMXCEED_INTRANS
;
273 case ICMP_TYPE_PARAMPROB
:
278 IcmpErr
= ICMP_ERR_PARAMPROB
;
282 case ICMP_TYPE_SOURCEQUENCH
:
287 IcmpErr
= ICMP_ERR_QUENCH
;
298 // Notify user the ICMP pkt only containing payload except
299 // IP and ICMP header
301 PayLoadHdr
= (UINT8
*) ((UINT8
*) IpHdr
+ EFI_IP4_HEADER_LEN (IpHdr
));
302 TrimBytes
= (UINT32
) (PayLoadHdr
- (UINT8
*) IcmpHdr
);
304 NetbufTrim (Pkt
, TrimBytes
, TRUE
);
306 IpIo
->PktRcvdNotify (EFI_ICMP_ERROR
, IcmpErr
, Session
, Pkt
, IpIo
->RcvdContext
);
313 Ext free function for net buffer. This function is
314 called when the net buffer is freed. It is used to
315 signal the recycle event to notify IP to recycle the
318 @param Event The event to be signaled.
329 gBS
->SignalEvent ((EFI_EVENT
) Event
);
334 Create a send entry to wrap a packet before sending
337 @param IpIo Pointer to the IP_IO instance.
338 @param Pkt Pointer to the packet.
339 @param Sender Pointer to the IP sender.
340 @param NotifyData Pointer to the notify data.
341 @param Dest Pointer to the destination IP address.
342 @param Override Pointer to the overriden IP_IO data.
344 @return Pointer to the data structure created to wrap the packet. If NULL,
345 @return resource limit occurred.
353 IN EFI_IP4_PROTOCOL
*Sender
,
354 IN VOID
*Context OPTIONAL
,
355 IN VOID
*NotifyData OPTIONAL
,
357 IN IP_IO_OVERRIDE
*Override
360 IP_IO_SEND_ENTRY
*SndEntry
;
361 EFI_IP4_COMPLETION_TOKEN
*SndToken
;
362 EFI_IP4_TRANSMIT_DATA
*TxData
;
364 EFI_IP4_OVERRIDE_DATA
*OverrideData
;
368 // Allocate resource for SndEntry
370 SndEntry
= NetAllocatePool (sizeof (IP_IO_SEND_ENTRY
));
371 if (NULL
== SndEntry
) {
376 // Allocate resource for SndToken
378 SndToken
= NetAllocatePool (sizeof (EFI_IP4_COMPLETION_TOKEN
));
379 if (NULL
== SndToken
) {
380 goto ReleaseSndEntry
;
383 Status
= gBS
->CreateEvent (
390 if (EFI_ERROR (Status
)) {
391 goto ReleaseSndToken
;
395 // Allocate resource for TxData
397 TxData
= NetAllocatePool (
398 sizeof (EFI_IP4_TRANSMIT_DATA
) +
399 sizeof (EFI_IP4_FRAGMENT_DATA
) * (Pkt
->BlockOpNum
- 1)
402 if (NULL
== TxData
) {
407 // Allocate resource for OverrideData if needed
410 if (NULL
!= Override
) {
412 OverrideData
= NetAllocatePool (sizeof (EFI_IP4_OVERRIDE_DATA
));
413 if (NULL
== OverrideData
) {
414 goto ReleaseResource
;
417 // Set the fields of OverrideData
419 *OverrideData
= * (EFI_IP4_OVERRIDE_DATA
*) Override
;
423 // Set the fields of TxData
425 EFI_IP4 (TxData
->DestinationAddress
) = Dest
;
426 TxData
->OverrideData
= OverrideData
;
427 TxData
->OptionsLength
= 0;
428 TxData
->OptionsBuffer
= NULL
;
429 TxData
->TotalDataLength
= Pkt
->TotalSize
;
430 TxData
->FragmentCount
= Pkt
->BlockOpNum
;
432 for (Index
= 0; Index
< Pkt
->BlockOpNum
; Index
++) {
434 TxData
->FragmentTable
[Index
].FragmentBuffer
= Pkt
->BlockOp
[Index
].Head
;
435 TxData
->FragmentTable
[Index
].FragmentLength
= Pkt
->BlockOp
[Index
].Size
;
439 // Set the fields of SndToken
441 SndToken
->Packet
.TxData
= TxData
;
444 // Set the fields of SndEntry
446 SndEntry
->IpIo
= IpIo
;
447 SndEntry
->Ip
= Sender
;
448 SndEntry
->Context
= Context
;
449 SndEntry
->NotifyData
= NotifyData
;
454 SndEntry
->SndToken
= SndToken
;
456 NetListInsertTail (&IpIo
->PendingSndList
, &SndEntry
->Entry
);
461 NetFreePool (TxData
);
464 gBS
->CloseEvent (SndToken
->Event
);
467 NetFreePool (SndToken
);
470 NetFreePool (SndEntry
);
477 Destroy the SndEntry.
479 @param SndEntry Pointer to the send entry to be destroyed.
486 IpIoDestroySndEntry (
487 IN IP_IO_SEND_ENTRY
*SndEntry
490 EFI_IP4_TRANSMIT_DATA
*TxData
;
492 TxData
= SndEntry
->SndToken
->Packet
.TxData
;
494 if (NULL
!= TxData
->OverrideData
) {
495 NetFreePool (TxData
->OverrideData
);
498 NetFreePool (TxData
);
499 NetbufFree (SndEntry
->Pkt
);
500 gBS
->CloseEvent (SndEntry
->SndToken
->Event
);
502 NetFreePool (SndEntry
->SndToken
);
503 NetListRemoveEntry (&SndEntry
->Entry
);
505 NetFreePool (SndEntry
);
510 Notify function for IP transmit token.
512 @param Event The event signaled.
513 @param Context The context passed in by the event notifier.
521 IpIoTransmitHandler (
527 IP_IO_SEND_ENTRY
*SndEntry
;
529 SndEntry
= (IP_IO_SEND_ENTRY
*) Context
;
531 IpIo
= SndEntry
->IpIo
;
533 if (IpIo
->PktSentNotify
&& SndEntry
->NotifyData
) {
534 IpIo
->PktSentNotify (
535 SndEntry
->SndToken
->Status
,
542 IpIoDestroySndEntry (SndEntry
);
547 The dummy handler for the dummy IP receive token.
549 @param Evt The event signaled.
550 @param Context The context passed in by the event notifier.
563 IP_IO_IP_INFO
*IpInfo
;
564 EFI_IP4_COMPLETION_TOKEN
*DummyToken
;
566 ASSERT (Event
&& Context
);
568 IpInfo
= (IP_IO_IP_INFO
*) Context
;
569 DummyToken
= &(IpInfo
->DummyRcvToken
);
571 if (EFI_SUCCESS
== DummyToken
->Status
) {
572 ASSERT (DummyToken
->Packet
.RxData
);
574 gBS
->SignalEvent (DummyToken
->Packet
.RxData
->RecycleSignal
);
577 IpInfo
->Ip
->Receive (IpInfo
->Ip
, DummyToken
);
582 Notify function for the IP receive token, used to process
583 the received IP packets.
585 @param Event The event signaled.
586 @param Context The context passed in by the event notifier.
601 EFI_IP4_RECEIVE_DATA
*RxData
;
602 EFI_IP4_PROTOCOL
*Ip
;
603 EFI_NET_SESSION_DATA Session
;
606 IpIo
= (IP_IO
*) Context
;
609 Status
= IpIo
->RcvToken
.Status
;
610 RxData
= IpIo
->RcvToken
.Packet
.RxData
;
612 if (((EFI_SUCCESS
!= Status
) && (EFI_ICMP_ERROR
!= Status
)) || (NULL
== RxData
)) {
614 // Only process the normal packets and the icmp error packets, if RxData is NULL
615 // with Status == EFI_SUCCESS or EFI_ICMP_ERROR, just resume the receive although
616 // this should be a bug of the low layer (IP).
621 if (NULL
== IpIo
->PktRcvdNotify
) {
625 if ((EFI_IP4 (RxData
->Header
->SourceAddress
) != 0) &&
626 !Ip4IsUnicast (EFI_NTOHL (RxData
->Header
->SourceAddress
), 0)) {
628 // The source address is not zero and it's not a unicast IP address, discard it.
634 // Create a netbuffer representing packet
636 Pkt
= NetbufFromExt (
637 (NET_FRAGMENT
*) RxData
->FragmentTable
,
638 RxData
->FragmentCount
,
642 RxData
->RecycleSignal
649 // Create a net session
651 Session
.Source
= EFI_IP4 (RxData
->Header
->SourceAddress
);
652 Session
.Dest
= EFI_IP4 (RxData
->Header
->DestinationAddress
);
653 Session
.IpHdr
= RxData
->Header
;
655 if (EFI_SUCCESS
== Status
) {
657 IpIo
->PktRcvdNotify (EFI_SUCCESS
, 0, &Session
, Pkt
, IpIo
->RcvdContext
);
660 // Status is EFI_ICMP_ERROR
662 Status
= IpIoIcmpHandler (IpIo
, Pkt
, &Session
);
663 if (EFI_ERROR (Status
)) {
671 gBS
->SignalEvent (RxData
->RecycleSignal
);
674 Ip
->Receive (Ip
, &(IpIo
->RcvToken
));
679 Create a new IP_IO instance.
681 @param Image The image handle of an IP_IO consumer protocol.
682 @param Controller The controller handle of an IP_IO consumer protocol
685 @return Pointer to a newly created IP_IO instance.
691 IN EFI_HANDLE Controller
697 IpIo
= NetAllocateZeroPool (sizeof (IP_IO
));
702 NetListInit (&(IpIo
->PendingSndList
));
703 NetListInit (&(IpIo
->IpList
));
704 IpIo
->Controller
= Controller
;
707 Status
= gBS
->CreateEvent (
712 &(IpIo
->RcvToken
.Event
)
714 if (EFI_ERROR (Status
)) {
719 // Create an IP child and open IP protocol
721 Status
= IpIoCreateIpChildOpenProtocol (
727 if (EFI_ERROR (Status
)) {
735 if (NULL
!= IpIo
->RcvToken
.Event
) {
736 gBS
->CloseEvent (IpIo
->RcvToken
.Event
);
746 Open an IP_IO instance for use.
748 @param IpIo Pointer to an IP_IO instance that needs to open.
749 @param OpenData The configuration data for the IP_IO instance.
751 @retval EFI_SUCCESS The IP_IO instance opened with OpenData
753 @retval other Error condition occurred.
759 IN IP_IO_OPEN_DATA
*OpenData
763 EFI_IP4_PROTOCOL
*Ip
;
764 EFI_IPv4_ADDRESS ZeroIp
;
766 if (IpIo
->IsConfigured
) {
767 return EFI_ACCESS_DENIED
;
775 Status
= Ip
->Configure (Ip
, &OpenData
->IpConfigData
);
776 if (EFI_ERROR (Status
)) {
781 // bugbug: to delete the default route entry in this Ip, if it is:
782 // (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified
785 EFI_IP4 (ZeroIp
) = 0;
786 Status
= Ip
->Routes (Ip
, TRUE
, &ZeroIp
, &ZeroIp
, &ZeroIp
);
788 if (EFI_ERROR (Status
) && (EFI_NOT_FOUND
!= Status
)) {
792 IpIo
->PktRcvdNotify
= OpenData
->PktRcvdNotify
;
793 IpIo
->PktSentNotify
= OpenData
->PktSentNotify
;
795 IpIo
->RcvdContext
= OpenData
->RcvdContext
;
796 IpIo
->SndContext
= OpenData
->SndContext
;
798 IpIo
->Protocol
= OpenData
->IpConfigData
.DefaultProtocol
;
801 // start to listen incoming packet
803 Status
= Ip
->Receive (Ip
, &(IpIo
->RcvToken
));
804 if (EFI_ERROR (Status
)) {
805 Ip
->Configure (Ip
, NULL
);
809 IpIo
->IsConfigured
= TRUE
;
810 NetListInsertTail (&mActiveIpIoList
, &IpIo
->Entry
);
819 Stop an IP_IO instance.
821 @param IpIo Pointer to the IP_IO instance that needs to stop.
823 @retval EFI_SUCCESS The IP_IO instance stopped successfully.
824 @retval other Error condition occurred.
833 EFI_IP4_PROTOCOL
*Ip
;
834 IP_IO_IP_INFO
*IpInfo
;
836 if (!IpIo
->IsConfigured
) {
841 // Remove the IpIo from the active IpIo list.
843 NetListRemoveEntry (&IpIo
->Entry
);
850 Status
= Ip
->Configure (Ip
, NULL
);
851 if (EFI_ERROR (Status
)) {
855 IpIo
->IsConfigured
= FALSE
;
858 // Detroy the Ip List used by IpIo
860 while (!NetListIsEmpty (&(IpIo
->IpList
))) {
861 IpInfo
= NET_LIST_HEAD (&(IpIo
->IpList
), IP_IO_IP_INFO
, Entry
);
863 IpIoRemoveIp (IpIo
, IpInfo
);
867 // All pending snd tokens should be flushed by reseting the IP instances.
869 ASSERT (NetListIsEmpty (&IpIo
->PendingSndList
));
872 // Close the receive event.
874 gBS
->CloseEvent (IpIo
->RcvToken
.Event
);
881 Destroy an IP_IO instance.
883 @param IpIo Pointer to the IP_IO instance that needs to
886 @retval EFI_SUCCESS The IP_IO instance destroyed successfully.
887 @retval other Error condition occurred.
901 // Close the IP protocol and destroy the child.
903 IpIoCloseProtocolDestroyIpChild (IpIo
->Controller
, IpIo
->Image
, IpIo
->ChildHandle
);
912 Send out an IP packet.
914 @param IpIo Pointer to an IP_IO instance used for sending IP
916 @param Pkt Pointer to the IP packet to be sent.
917 @param Sender The IP protocol instance used for sending.
919 @param Dest The destination IP address to send this packet to.
920 @param OverrideData The data to override some configuration of the IP
921 instance used for sending.
923 @retval EFI_SUCCESS The operation is completed successfully.
924 @retval EFI_NOT_STARTED The IpIo is not configured.
925 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
932 IN IP_IO_IP_INFO
*Sender
,
933 IN VOID
*Context OPTIONAL
,
934 IN VOID
*NotifyData OPTIONAL
,
936 IN IP_IO_OVERRIDE
*OverrideData
940 EFI_IP4_PROTOCOL
*Ip
;
941 IP_IO_SEND_ENTRY
*SndEntry
;
943 if (!IpIo
->IsConfigured
) {
944 return EFI_NOT_STARTED
;
947 Ip
= (NULL
== Sender
) ? IpIo
->Ip
: Sender
->Ip
;
950 // create a new SndEntry
952 SndEntry
= IpIoCreateSndEntry (IpIo
, Pkt
, Ip
, Context
, NotifyData
, Dest
, OverrideData
);
953 if (NULL
== SndEntry
) {
954 return EFI_OUT_OF_RESOURCES
;
960 Status
= Ip
->Transmit (Ip
, SndEntry
->SndToken
);
961 if (EFI_ERROR (Status
)) {
962 IpIoDestroySndEntry (SndEntry
);
970 Cancel the IP transmit token which wraps this Packet.
972 @param IpIo Pointer to the IP_IO instance.
973 @param Packet Pointer to the packet to cancel.
984 NET_LIST_ENTRY
*Node
;
985 IP_IO_SEND_ENTRY
*SndEntry
;
986 EFI_IP4_PROTOCOL
*Ip
;
988 ASSERT (IpIo
&& Packet
);
990 NET_LIST_FOR_EACH (Node
, &IpIo
->PendingSndList
) {
992 SndEntry
= NET_LIST_USER_STRUCT (Node
, IP_IO_SEND_ENTRY
, Entry
);
994 if (SndEntry
->Pkt
== Packet
) {
997 Ip
->Cancel (Ip
, SndEntry
->SndToken
);
1000 // Abort the user token.
1002 SndEntry
->SndToken
->Status
= EFI_ABORTED
;
1003 IpIoTransmitHandler (NULL
, SndEntry
);
1013 Add a new IP instance for sending data.
1015 @param IpIo Pointer to a IP_IO instance to add a new IP
1016 instance for sending purpose.
1018 @return Pointer to the created IP_IO_IP_INFO structure, NULL is failed.
1027 IP_IO_IP_INFO
*IpInfo
;
1031 IpInfo
= NetAllocatePool (sizeof (IP_IO_IP_INFO
));
1032 if (IpInfo
== NULL
) {
1037 // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP
1040 NetListInit (&IpInfo
->Entry
);
1041 IpInfo
->ChildHandle
= NULL
;
1043 IpInfo
->SubnetMask
= 0;
1047 // Create the IP instance and open the Ip4 protocol.
1049 Status
= IpIoCreateIpChildOpenProtocol (
1052 &IpInfo
->ChildHandle
,
1055 if (EFI_ERROR (Status
)) {
1060 // Create the event for the DummyRcvToken.
1062 Status
= gBS
->CreateEvent (
1067 &IpInfo
->DummyRcvToken
.Event
1069 if (EFI_ERROR (Status
)) {
1070 goto ReleaseIpChild
;
1074 // Link this IpInfo into the IpIo.
1076 NetListInsertTail (&IpIo
->IpList
, &IpInfo
->Entry
);
1082 IpIoCloseProtocolDestroyIpChild (
1090 NetFreePool (IpInfo
);
1097 Configure the IP instance of this IpInfo and start the receiving if Ip4ConfigData
1100 @param IpInfo Pointer to the IP_IO_IP_INFO instance.
1101 @param Ip4ConfigData The IP4 configure data used to configure the ip
1102 instance, if NULL the ip instance is reseted. If
1103 UseDefaultAddress is set to TRUE, and the configure
1104 operation succeeds, the default address information
1105 is written back in this Ip4ConfigData.
1107 @retval EFI_STATUS The status returned by IP4->Configure or
1113 IN IP_IO_IP_INFO
*IpInfo
,
1114 IN OUT EFI_IP4_CONFIG_DATA
*Ip4ConfigData OPTIONAL
1118 EFI_IP4_PROTOCOL
*Ip
;
1119 EFI_IP4_MODE_DATA Ip4ModeData
;
1123 if (IpInfo
->RefCnt
> 1) {
1125 // This IP instance is shared, don't reconfigure it until it has only one
1126 // consumer. Currently, only the tcp children cloned from their passive parent
1127 // will share the same IP. So this cases only happens while Ip4ConfigData is NULL,
1128 // let the last consumer clean the IP instance.
1135 Status
= Ip
->Configure (Ip
, Ip4ConfigData
);
1136 if (EFI_ERROR (Status
)) {
1140 if (Ip4ConfigData
!= NULL
) {
1142 if (Ip4ConfigData
->UseDefaultAddress
) {
1143 Ip
->GetModeData (Ip
, &Ip4ModeData
, NULL
, NULL
);
1145 Ip4ConfigData
->StationAddress
= Ip4ModeData
.ConfigData
.StationAddress
;
1146 Ip4ConfigData
->SubnetMask
= Ip4ModeData
.ConfigData
.SubnetMask
;
1149 IpInfo
->Addr
= EFI_IP4 (Ip4ConfigData
->StationAddress
);
1150 IpInfo
->SubnetMask
= EFI_IP4 (Ip4ConfigData
->SubnetMask
);
1152 Status
= Ip
->Receive (Ip
, &IpInfo
->DummyRcvToken
);
1153 if (EFI_ERROR (Status
)) {
1154 Ip
->Configure (Ip
, NULL
);
1159 // The IP instance is reseted, set the stored Addr and SubnetMask to zero.
1162 IpInfo
->SubnetMask
=0;
1172 Destroy an IP instance maintained in IpIo->IpList for
1175 @param IpIo Pointer to the IP_IO instance.
1176 @param IpInfo Pointer to the IpInfo to be removed.
1184 IN IP_IO_IP_INFO
*IpInfo
1187 ASSERT (IpInfo
->RefCnt
> 0);
1189 NET_PUT_REF (IpInfo
);
1191 if (IpInfo
->RefCnt
> 0) {
1196 NetListRemoveEntry (&IpInfo
->Entry
);
1198 IpInfo
->Ip
->Configure (IpInfo
->Ip
, NULL
);
1200 IpIoCloseProtocolDestroyIpChild (IpIo
->Controller
, IpIo
->Image
, IpInfo
->ChildHandle
);
1202 gBS
->CloseEvent (IpInfo
->DummyRcvToken
.Event
);
1204 NetFreePool (IpInfo
);
1209 Find the first IP protocol maintained in IpIo whose local
1210 address is the same with Src.
1212 @param IpIo Pointer to the pointer of the IP_IO instance.
1213 @param Src The local IP address.
1215 @return Pointer to the IP protocol can be used for sending purpose and its local
1216 @return address is the same with Src.
1221 IN OUT IP_IO
**IpIo
,
1225 NET_LIST_ENTRY
*IpIoEntry
;
1227 NET_LIST_ENTRY
*IpInfoEntry
;
1228 IP_IO_IP_INFO
*IpInfo
;
1230 NET_LIST_FOR_EACH (IpIoEntry
, &mActiveIpIoList
) {
1231 IpIoPtr
= NET_LIST_USER_STRUCT (IpIoEntry
, IP_IO
, Entry
);
1233 if ((*IpIo
!= NULL
) && (*IpIo
!= IpIoPtr
)) {
1237 NET_LIST_FOR_EACH (IpInfoEntry
, &IpIoPtr
->IpList
) {
1238 IpInfo
= NET_LIST_USER_STRUCT (IpInfoEntry
, IP_IO_IP_INFO
, Entry
);
1240 if (IpInfo
->Addr
== Src
) {
1255 Get the ICMP error map information, the ErrorStatus will be returned.
1256 The IsHard and Notify are optional. If they are not NULL, this rouine will
1258 We move IcmpErrMap[] to local variable to enable EBC build.
1260 @param IcmpError IcmpError Type
1261 @param IsHard Whether it is a hard error
1262 @param Notify Whether it need to notify SockError
1264 @return ICMP Error Status
1268 IpIoGetIcmpErrStatus (
1269 IN ICMP_ERROR IcmpError
,
1270 OUT BOOLEAN
*IsHard
, OPTIONAL
1271 OUT BOOLEAN
*Notify OPTIONAL
1274 ICMP_ERROR_INFO IcmpErrMap
[] = {
1275 { EFI_NETWORK_UNREACHABLE
, FALSE
, TRUE
}, // ICMP_ERR_UNREACH_NET
1276 { EFI_HOST_UNREACHABLE
, FALSE
, TRUE
}, // ICMP_ERR_UNREACH_HOST
1277 { EFI_PROTOCOL_UNREACHABLE
, TRUE
, TRUE
}, // ICMP_ERR_UNREACH_PROTOCOL
1278 { EFI_PORT_UNREACHABLE
, TRUE
, TRUE
}, // ICMP_ERR_UNREACH_PORT
1279 { EFI_ICMP_ERROR
, TRUE
, TRUE
}, // ICMP_ERR_MSGSIZE
1280 { EFI_ICMP_ERROR
, FALSE
, TRUE
}, // ICMP_ERR_UNREACH_SRCFAIL
1281 { EFI_HOST_UNREACHABLE
, FALSE
, TRUE
}, // ICMP_ERR_TIMXCEED_INTRANS
1282 { EFI_HOST_UNREACHABLE
, FALSE
, TRUE
}, // ICMP_ERR_TIMEXCEED_REASS
1283 { EFI_ICMP_ERROR
, FALSE
, FALSE
}, // ICMP_ERR_QUENCH
1284 { EFI_ICMP_ERROR
, FALSE
, TRUE
} // ICMP_ERR_PARAMPROB
1287 ASSERT ((IcmpError
>= ICMP_ERR_UNREACH_NET
) && (IcmpError
<= ICMP_ERR_PARAMPROB
));
1289 if (IsHard
!= NULL
) {
1290 *IsHard
= IcmpErrMap
[IcmpError
].IsHard
;
1293 if (Notify
!= NULL
) {
1294 *Notify
= IcmpErrMap
[IcmpError
].Notify
;
1297 return IcmpErrMap
[IcmpError
].Error
;