4 Copyright (c) 2005 - 2007, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Protocol/ServiceBinding.h>
17 #include <Protocol/SimpleNetwork.h>
18 #include <Protocol/NicIp4Config.h>
19 #include <Protocol/ComponentName.h>
20 #include <Protocol/ComponentName2.h>
21 #include <Protocol/Dpc.h>
23 #include <Library/NetLib.h>
24 #include <Library/BaseLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/UefiBootServicesTableLib.h>
28 #include <Library/UefiRuntimeServicesTableLib.h>
29 #include <Library/MemoryAllocationLib.h>
30 #include <Library/DevicePathLib.h>
32 EFI_DPC_PROTOCOL
*mDpc
= NULL
;
34 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mNetLibHexStr
[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
37 // All the supported IP4 maskes in host byte order.
39 IP4_ADDR gIp4AllMasks
[IP4_MASK_NUM
] = {
78 EFI_IPv4_ADDRESS mZeroIp4Addr
= {{0, 0, 0, 0}};
81 Return the length of the mask.
83 Return the length of the mask, the correct value is from 0 to 32.
84 If the mask is invalid, return the invalid length 33, which is IP4_MASK_NUM.
85 NetMask is in the host byte order.
87 @param[in] NetMask The netmask to get the length from.
89 @return The length of the netmask, IP4_MASK_NUM if the mask is invalid.
100 for (Index
= 0; Index
< IP4_MASK_NUM
; Index
++) {
101 if (NetMask
== gIp4AllMasks
[Index
]) {
112 Return the class of the IP address, such as class A, B, C.
113 Addr is in host byte order.
115 The address of class A starts with 0.
116 If the address belong to class A, return IP4_ADDR_CLASSA.
117 The address of class B starts with 10.
118 If the address belong to class B, return IP4_ADDR_CLASSB.
119 The address of class C starts with 110.
120 If the address belong to class C, return IP4_ADDR_CLASSC.
121 The address of class D starts with 1110.
122 If the address belong to class D, return IP4_ADDR_CLASSD.
123 The address of class E starts with 1111.
124 If the address belong to class E, return IP4_ADDR_CLASSE.
127 @param[in] Addr The address to get the class from.
129 @return IP address class, such as IP4_ADDR_CLASSA.
140 ByteOne
= (UINT8
) (Addr
>> 24);
142 if ((ByteOne
& 0x80) == 0) {
143 return IP4_ADDR_CLASSA
;
145 } else if ((ByteOne
& 0xC0) == 0x80) {
146 return IP4_ADDR_CLASSB
;
148 } else if ((ByteOne
& 0xE0) == 0xC0) {
149 return IP4_ADDR_CLASSC
;
151 } else if ((ByteOne
& 0xF0) == 0xE0) {
152 return IP4_ADDR_CLASSD
;
155 return IP4_ADDR_CLASSE
;
162 Check whether the IP is a valid unicast address according to
163 the netmask. If NetMask is zero, use the IP address's class to get the default mask.
165 If Ip is 0, IP is not a valid unicast address.
166 Class D address is used for multicasting and class E address is reserved for future. If Ip
167 belongs to class D or class E, IP is not a valid unicast address.
168 If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address.
170 @param[in] Ip The IP to check against.
171 @param[in] NetMask The mask of the IP.
173 @return TRUE if IP is a valid unicast address on the network, otherwise FALSE.
185 Class
= NetGetIpClass (Ip
);
187 if ((Ip
== 0) || (Class
>= IP4_ADDR_CLASSD
)) {
192 NetMask
= gIp4AllMasks
[Class
<< 3];
195 if (((Ip
&~NetMask
) == ~NetMask
) || ((Ip
&~NetMask
) == 0)) {
204 Initialize a random seed using current time.
206 Get current time first. Then initialize a random seed based on some basic
207 mathematics operation on the hour, day, minute, second, nanosecond and year
210 @return The random seed initialized with current time.
222 gRT
->GetTime (&Time
, NULL
);
223 Seed
= (~Time
.Hour
<< 24 | Time
.Day
<< 16 | Time
.Minute
<< 8 | Time
.Second
);
224 Seed
^= Time
.Nanosecond
;
225 Seed
^= Time
.Year
<< 7;
232 Extract a UINT32 from a byte stream.
234 Copy a UINT32 from a byte stream, then converts it from Network
235 byte order to host byte order. Use this function to avoid alignment error.
237 @param[in] Buf The buffer to extract the UINT32.
239 @return The UINT32 extracted.
250 CopyMem (&Value
, Buf
, sizeof (UINT32
));
251 return NTOHL (Value
);
256 Put a UINT32 to the byte stream in network byte order.
258 Converts a UINT32 from host byte order to network byte order. Then copy it to the
261 @param[in, out] Buf The buffer to put the UINT32.
262 @param[in] Data The data to put.
273 CopyMem (Buf
, &Data
, sizeof (UINT32
));
278 Remove the first node entry on the list, and return the removed node entry.
280 Removes the first node Entry from a doubly linked list. It is up to the caller of
281 this function to release the memory used by the first node if that is required. On
282 exit, the removed node is returned.
284 If Head is NULL, then ASSERT().
285 If Head was not initialized, then ASSERT().
286 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
287 linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,
290 @param[in, out] Head The list header.
292 @return The first node entry that is removed from the list, NULL if the list is empty.
298 IN OUT LIST_ENTRY
*Head
303 ASSERT (Head
!= NULL
);
305 if (IsListEmpty (Head
)) {
309 First
= Head
->ForwardLink
;
310 Head
->ForwardLink
= First
->ForwardLink
;
311 First
->ForwardLink
->BackLink
= Head
;
314 First
->ForwardLink
= (LIST_ENTRY
*) NULL
;
315 First
->BackLink
= (LIST_ENTRY
*) NULL
;
323 Remove the last node entry on the list and and return the removed node entry.
325 Removes the last node entry from a doubly linked list. It is up to the caller of
326 this function to release the memory used by the first node if that is required. On
327 exit, the removed node is returned.
329 If Head is NULL, then ASSERT().
330 If Head was not initialized, then ASSERT().
331 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
332 linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,
335 @param[in, out] Head The list head.
337 @return The last node entry that is removed from the list, NULL if the list is empty.
343 IN OUT LIST_ENTRY
*Head
348 ASSERT (Head
!= NULL
);
350 if (IsListEmpty (Head
)) {
354 Last
= Head
->BackLink
;
355 Head
->BackLink
= Last
->BackLink
;
356 Last
->BackLink
->ForwardLink
= Head
;
359 Last
->ForwardLink
= (LIST_ENTRY
*) NULL
;
360 Last
->BackLink
= (LIST_ENTRY
*) NULL
;
368 Insert a new node entry after a designated node entry of a doubly linked list.
370 Inserts a new node entry donated by NewEntry after the node entry donated by PrevEntry
371 of the doubly linked list.
373 @param[in, out] PrevEntry The previous entry to insert after.
374 @param[in, out] NewEntry The new entry to insert.
380 IN OUT LIST_ENTRY
*PrevEntry
,
381 IN OUT LIST_ENTRY
*NewEntry
384 NewEntry
->BackLink
= PrevEntry
;
385 NewEntry
->ForwardLink
= PrevEntry
->ForwardLink
;
386 PrevEntry
->ForwardLink
->BackLink
= NewEntry
;
387 PrevEntry
->ForwardLink
= NewEntry
;
392 Insert a new node entry before a designated node entry of a doubly linked list.
394 Inserts a new node entry donated by NewEntry after the node entry donated by PostEntry
395 of the doubly linked list.
397 @param[in, out] PostEntry The entry to insert before.
398 @param[in, out] NewEntry The new entry to insert.
403 NetListInsertBefore (
404 IN OUT LIST_ENTRY
*PostEntry
,
405 IN OUT LIST_ENTRY
*NewEntry
408 NewEntry
->ForwardLink
= PostEntry
;
409 NewEntry
->BackLink
= PostEntry
->BackLink
;
410 PostEntry
->BackLink
->ForwardLink
= NewEntry
;
411 PostEntry
->BackLink
= NewEntry
;
416 Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.
418 Initialize the forward and backward links of two head nodes donated by Map->Used
419 and Map->Recycled of two doubly linked lists.
420 Initializes the count of the <Key, Value> pairs in the netmap to zero.
422 If Map is NULL, then ASSERT().
423 If the address of Map->Used is NULL, then ASSERT().
424 If the address of Map->Recycled is NULl, then ASSERT().
426 @param[in, out] Map The netmap to initialize.
435 ASSERT (Map
!= NULL
);
437 InitializeListHead (&Map
->Used
);
438 InitializeListHead (&Map
->Recycled
);
444 To clean up the netmap, that is, release allocated memories.
446 Removes all nodes of the Used doubly linked list and free memory of all related netmap items.
447 Removes all nodes of the Recycled doubly linked list and free memory of all related netmap items.
448 The number of the <Key, Value> pairs in the netmap is set to be zero.
450 If Map is NULL, then ASSERT().
452 @param[in, out] Map The netmap to clean up.
465 ASSERT (Map
!= NULL
);
467 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Used
) {
468 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
470 RemoveEntryList (&Item
->Link
);
473 gBS
->FreePool (Item
);
476 ASSERT ((Map
->Count
== 0) && IsListEmpty (&Map
->Used
));
478 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, &Map
->Recycled
) {
479 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
481 RemoveEntryList (&Item
->Link
);
482 gBS
->FreePool (Item
);
485 ASSERT (IsListEmpty (&Map
->Recycled
));
490 Test whether the netmap is empty and return true if it is.
492 If the number of the <Key, Value> pairs in the netmap is zero, return TRUE.
494 If Map is NULL, then ASSERT().
497 @param[in] Map The net map to test.
499 @return TRUE if the netmap is empty, otherwise FALSE.
508 ASSERT (Map
!= NULL
);
509 return (BOOLEAN
) (Map
->Count
== 0);
514 Return the number of the <Key, Value> pairs in the netmap.
516 @param[in] Map The netmap to get the entry number.
518 @return The entry number in the netmap.
532 Return one allocated item.
534 If the Recycled doubly linked list of the netmap is empty, it will try to allocate
535 a batch of items if there are enough resources and add corresponding nodes to the begining
536 of the Recycled doubly linked list of the netmap. Otherwise, it will directly remove
537 the fist node entry of the Recycled doubly linked list and return the corresponding item.
539 If Map is NULL, then ASSERT().
541 @param[in, out] Map The netmap to allocate item for.
543 @return The allocated item. If NULL, the
544 allocation failed due to resource limit.
556 ASSERT (Map
!= NULL
);
558 Head
= &Map
->Recycled
;
560 if (IsListEmpty (Head
)) {
561 for (Index
= 0; Index
< NET_MAP_INCREAMENT
; Index
++) {
562 Item
= AllocatePool (sizeof (NET_MAP_ITEM
));
572 InsertHeadList (Head
, &Item
->Link
);
576 Item
= NET_LIST_HEAD (Head
, NET_MAP_ITEM
, Link
);
577 NetListRemoveHead (Head
);
584 Allocate an item to save the <Key, Value> pair to the head of the netmap.
586 Allocate an item to save the <Key, Value> pair and add corresponding node entry
587 to the beginning of the Used doubly linked list. The number of the <Key, Value>
588 pairs in the netmap increase by 1.
590 If Map is NULL, then ASSERT().
592 @param[in, out] Map The netmap to insert into.
593 @param[in] Key The user's key.
594 @param[in] Value The user's value for the key.
596 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item.
597 @retval EFI_SUCCESS The item is inserted to the head.
605 IN VOID
*Value OPTIONAL
610 ASSERT (Map
!= NULL
);
612 Item
= NetMapAllocItem (Map
);
615 return EFI_OUT_OF_RESOURCES
;
620 InsertHeadList (&Map
->Used
, &Item
->Link
);
628 Allocate an item to save the <Key, Value> pair to the tail of the netmap.
630 Allocate an item to save the <Key, Value> pair and add corresponding node entry
631 to the tail of the Used doubly linked list. The number of the <Key, Value>
632 pairs in the netmap increase by 1.
634 If Map is NULL, then ASSERT().
636 @param[in, out] Map The netmap to insert into.
637 @param[in] Key The user's key.
638 @param[in] Value The user's value for the key.
640 @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the item.
641 @retval EFI_SUCCESS The item is inserted to the tail.
649 IN VOID
*Value OPTIONAL
654 ASSERT (Map
!= NULL
);
656 Item
= NetMapAllocItem (Map
);
659 return EFI_OUT_OF_RESOURCES
;
664 InsertTailList (&Map
->Used
, &Item
->Link
);
673 Check whether the item is in the Map and return TRUE if it is.
675 @param[in] Map The netmap to search within.
676 @param[in] Item The item to search.
678 @return TRUE if the item is in the netmap, otherwise FALSE.
684 IN NET_MAP_ITEM
*Item
687 LIST_ENTRY
*ListEntry
;
689 NET_LIST_FOR_EACH (ListEntry
, &Map
->Used
) {
690 if (ListEntry
== &Item
->Link
) {
700 Find the key in the netmap and returns the point to the item contains the Key.
702 Iterate the Used doubly linked list of the netmap to get every item. Compare the key of every
703 item with the key to search. It returns the point to the item contains the Key if found.
705 If Map is NULL, then ASSERT().
707 @param[in] Map The netmap to search within.
708 @param[in] Key The key to search.
710 @return The point to the item contains the Key, or NULL if Key isn't in the map.
723 ASSERT (Map
!= NULL
);
725 NET_LIST_FOR_EACH (Entry
, &Map
->Used
) {
726 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
728 if (Item
->Key
== Key
) {
738 Remove the node entry of the item from the netmap and return the key of the removed item.
740 Remove the node entry of the item from the Used doubly linked list of the netmap.
741 The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
742 entry of the item to the Recycled doubly linked list of the netmap. If Value is not NULL,
743 Value will point to the value of the item. It returns the key of the removed item.
745 If Map is NULL, then ASSERT().
746 If Item is NULL, then ASSERT().
747 if item in not in the netmap, then ASSERT().
749 @param[in, out] Map The netmap to remove the item from.
750 @param[in, out] Item The item to remove.
751 @param[out] Value The variable to receive the value if not NULL.
753 @return The key of the removed item.
760 IN OUT NET_MAP_ITEM
*Item
,
761 OUT VOID
**Value OPTIONAL
764 ASSERT ((Map
!= NULL
) && (Item
!= NULL
));
765 ASSERT (NetItemInMap (Map
, Item
));
767 RemoveEntryList (&Item
->Link
);
769 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
772 *Value
= Item
->Value
;
780 Remove the first node entry on the netmap and return the key of the removed item.
782 Remove the first node entry from the Used doubly linked list of the netmap.
783 The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
784 entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,
785 parameter Value will point to the value of the item. It returns the key of the removed item.
787 If Map is NULL, then ASSERT().
788 If the Used doubly linked list is empty, then ASSERT().
790 @param[in, out] Map The netmap to remove the head from.
791 @param[out] Value The variable to receive the value if not NULL.
793 @return The key of the item removed.
800 OUT VOID
**Value OPTIONAL
806 // Often, it indicates a programming error to remove
807 // the first entry in an empty list
809 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
811 Item
= NET_LIST_HEAD (&Map
->Used
, NET_MAP_ITEM
, Link
);
812 RemoveEntryList (&Item
->Link
);
814 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
817 *Value
= Item
->Value
;
825 Remove the last node entry on the netmap and return the key of the removed item.
827 Remove the last node entry from the Used doubly linked list of the netmap.
828 The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node
829 entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,
830 parameter Value will point to the value of the item. It returns the key of the removed item.
832 If Map is NULL, then ASSERT().
833 If the Used doubly linked list is empty, then ASSERT().
835 @param[in, out] Map The netmap to remove the tail from.
836 @param[out] Value The variable to receive the value if not NULL.
838 @return The key of the item removed.
845 OUT VOID
**Value OPTIONAL
851 // Often, it indicates a programming error to remove
852 // the last entry in an empty list
854 ASSERT (Map
&& !IsListEmpty (&Map
->Used
));
856 Item
= NET_LIST_TAIL (&Map
->Used
, NET_MAP_ITEM
, Link
);
857 RemoveEntryList (&Item
->Link
);
859 InsertHeadList (&Map
->Recycled
, &Item
->Link
);
862 *Value
= Item
->Value
;
870 Iterate through the netmap and call CallBack for each item.
872 It will contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
873 from the loop. It returns the CallBack's last return value. This function is
874 delete safe for the current item.
876 If Map is NULL, then ASSERT().
877 If CallBack is NULL, then ASSERT().
879 @param[in] Map The Map to iterate through.
880 @param[in] CallBack The callback function to call for each item.
881 @param[in] Arg The opaque parameter to the callback.
883 @retval EFI_SUCCESS There is no item in the netmap or CallBack for each item
885 @retval Others It returns the CallBack's last return value.
892 IN NET_MAP_CALLBACK CallBack
,
903 ASSERT ((Map
!= NULL
) && (CallBack
!= NULL
));
907 if (IsListEmpty (Head
)) {
911 NET_LIST_FOR_EACH_SAFE (Entry
, Next
, Head
) {
912 Item
= NET_LIST_USER_STRUCT (Entry
, NET_MAP_ITEM
, Link
);
913 Result
= CallBack (Map
, Item
, Arg
);
915 if (EFI_ERROR (Result
)) {
925 This is the default unload handle for all the network drivers.
927 Disconnect the driver specified by ImageHandle from all the devices in the handle database.
928 Uninstall all the protocols installed in the driver entry point.
930 @param[in] ImageHandle The drivers' driver image.
932 @retval EFI_SUCCESS The image is unloaded.
933 @retval Others Failed to unload the image.
938 NetLibDefaultUnload (
939 IN EFI_HANDLE ImageHandle
943 EFI_HANDLE
*DeviceHandleBuffer
;
944 UINTN DeviceHandleCount
;
946 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
947 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
948 EFI_COMPONENT_NAME2_PROTOCOL
*ComponentName2
;
951 // Get the list of all the handles in the handle database.
952 // If there is an error getting the list, then the unload
955 Status
= gBS
->LocateHandleBuffer (
963 if (EFI_ERROR (Status
)) {
968 // Disconnect the driver specified by ImageHandle from all
969 // the devices in the handle database.
971 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
972 Status
= gBS
->DisconnectController (
973 DeviceHandleBuffer
[Index
],
980 // Uninstall all the protocols installed in the driver entry point
982 for (Index
= 0; Index
< DeviceHandleCount
; Index
++) {
983 Status
= gBS
->HandleProtocol (
984 DeviceHandleBuffer
[Index
],
985 &gEfiDriverBindingProtocolGuid
,
986 (VOID
**) &DriverBinding
989 if (EFI_ERROR (Status
)) {
993 if (DriverBinding
->ImageHandle
!= ImageHandle
) {
997 gBS
->UninstallProtocolInterface (
999 &gEfiDriverBindingProtocolGuid
,
1002 Status
= gBS
->HandleProtocol (
1003 DeviceHandleBuffer
[Index
],
1004 &gEfiComponentNameProtocolGuid
,
1005 (VOID
**) &ComponentName
1007 if (!EFI_ERROR (Status
)) {
1008 gBS
->UninstallProtocolInterface (
1010 &gEfiComponentNameProtocolGuid
,
1015 Status
= gBS
->HandleProtocol (
1016 DeviceHandleBuffer
[Index
],
1017 &gEfiComponentName2ProtocolGuid
,
1018 (VOID
**) &ComponentName2
1020 if (!EFI_ERROR (Status
)) {
1021 gBS
->UninstallProtocolInterface (
1023 &gEfiComponentName2ProtocolGuid
,
1030 // Free the buffer containing the list of handles from the handle database
1032 if (DeviceHandleBuffer
!= NULL
) {
1033 gBS
->FreePool (DeviceHandleBuffer
);
1042 Create a child of the service that is identified by ServiceBindingGuid.
1044 Get the ServiceBinding Protocol first, then use it to create a child.
1046 If ServiceBindingGuid is NULL, then ASSERT().
1047 If ChildHandle is NULL, then ASSERT().
1049 @param[in] Controller The controller which has the service installed.
1050 @param[in] Image The image handle used to open service.
1051 @param[in] ServiceBindingGuid The service's Guid.
1052 @param[in, out] ChildHandle The handle to receive the create child.
1054 @retval EFI_SUCCESS The child is successfully created.
1055 @retval Others Failed to create the child.
1060 NetLibCreateServiceChild (
1061 IN EFI_HANDLE Controller
,
1062 IN EFI_HANDLE Image
,
1063 IN EFI_GUID
*ServiceBindingGuid
,
1064 IN OUT EFI_HANDLE
*ChildHandle
1068 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1071 ASSERT ((ServiceBindingGuid
!= NULL
) && (ChildHandle
!= NULL
));
1074 // Get the ServiceBinding Protocol
1076 Status
= gBS
->OpenProtocol (
1082 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1085 if (EFI_ERROR (Status
)) {
1092 Status
= Service
->CreateChild (Service
, ChildHandle
);
1098 Destory a child of the service that is identified by ServiceBindingGuid.
1100 Get the ServiceBinding Protocol first, then use it to destroy a child.
1102 If ServiceBindingGuid is NULL, then ASSERT().
1104 @param[in] Controller The controller which has the service installed.
1105 @param[in] Image The image handle used to open service.
1106 @param[in] ServiceBindingGuid The service's Guid.
1107 @param[in] ChildHandle The child to destory.
1109 @retval EFI_SUCCESS The child is successfully destoried.
1110 @retval Others Failed to destory the child.
1115 NetLibDestroyServiceChild (
1116 IN EFI_HANDLE Controller
,
1117 IN EFI_HANDLE Image
,
1118 IN EFI_GUID
*ServiceBindingGuid
,
1119 IN EFI_HANDLE ChildHandle
1123 EFI_SERVICE_BINDING_PROTOCOL
*Service
;
1125 ASSERT (ServiceBindingGuid
!= NULL
);
1128 // Get the ServiceBinding Protocol
1130 Status
= gBS
->OpenProtocol (
1136 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1139 if (EFI_ERROR (Status
)) {
1144 // destory the child
1146 Status
= Service
->DestroyChild (Service
, ChildHandle
);
1152 Convert the mac address of the simple network protocol installed on
1153 SnpHandle to a unicode string. Callers are responsible for freeing the
1156 Get the mac address of the Simple Network protocol from the SnpHandle. Then convert
1157 the mac address into a unicode string. It takes 2 unicode characters to represent
1158 a 1 byte binary buffer. Plus one unicode character for the null-terminator.
1161 @param[in] SnpHandle The handle where the simple network protocol is
1163 @param[in] ImageHandle The image handle used to act as the agent handle to
1164 get the simple network protocol.
1165 @param[out] MacString The pointer to store the address of the string
1166 representation of the mac address.
1168 @retval EFI_SUCCESS Convert the mac address a unicode string successfully.
1169 @retval EFI_OUT_OF_RESOURCES There are not enough memory resource.
1170 @retval Others Failed to open the simple network protocol.
1175 NetLibGetMacString (
1176 IN EFI_HANDLE SnpHandle
,
1177 IN EFI_HANDLE ImageHandle
,
1178 OUT CHAR16
**MacString
1182 EFI_SIMPLE_NETWORK_PROTOCOL
*Snp
;
1183 EFI_SIMPLE_NETWORK_MODE
*Mode
;
1190 // Get the Simple Network protocol from the SnpHandle.
1192 Status
= gBS
->OpenProtocol (
1194 &gEfiSimpleNetworkProtocolGuid
,
1198 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1200 if (EFI_ERROR (Status
)) {
1207 // It takes 2 unicode characters to represent a 1 byte binary buffer.
1208 // Plus one unicode character for the null-terminator.
1210 MacAddress
= AllocatePool ((2 * Mode
->HwAddressSize
+ 1) * sizeof (CHAR16
));
1211 if (MacAddress
== NULL
) {
1212 return EFI_OUT_OF_RESOURCES
;
1216 // Convert the mac address into a unicode string.
1218 for (Index
= 0; Index
< Mode
->HwAddressSize
; Index
++) {
1219 MacAddress
[Index
* 2] = (CHAR16
) mNetLibHexStr
[(Mode
->CurrentAddress
.Addr
[Index
] >> 4) & 0x0F];
1220 MacAddress
[Index
* 2 + 1] = (CHAR16
) mNetLibHexStr
[Mode
->CurrentAddress
.Addr
[Index
] & 0x0F];
1223 MacAddress
[Mode
->HwAddressSize
* 2] = L
'\0';
1225 *MacString
= MacAddress
;
1231 Check the default address used by the IPv4 driver is static or dynamic (acquired
1234 If the controller handle does not have the NIC Ip4 Config Protocol installed, the
1235 default address is static. If the EFI variable to save the configuration is not found,
1236 the default address is static. Otherwise, get the result from the EFI variable which
1237 saving the configuration.
1239 @param[in] Controller The controller handle which has the NIC Ip4 Config Protocol
1240 relative with the default address to judge.
1242 @retval TRUE If the default address is static.
1243 @retval FALSE If the default address is acquired from DHCP.
1247 NetLibDefaultAddressIsStatic (
1248 IN EFI_HANDLE Controller
1252 EFI_NIC_IP4_CONFIG_PROTOCOL
*NicIp4
;
1254 NIC_IP4_CONFIG_INFO
*ConfigInfo
;
1257 Status
= gBS
->HandleProtocol (
1259 &gEfiNicIp4ConfigProtocolGuid
,
1262 if (EFI_ERROR (Status
)) {
1267 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, NULL
);
1268 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1272 ConfigInfo
= AllocatePool (Len
);
1273 if (ConfigInfo
== NULL
) {
1278 Status
= NicIp4
->GetInfo (NicIp4
, &Len
, ConfigInfo
);
1279 if (EFI_ERROR (Status
)) {
1283 IsStatic
= (BOOLEAN
) (ConfigInfo
->Source
== IP4_CONFIG_SOURCE_STATIC
);
1287 gBS
->FreePool (ConfigInfo
);
1293 Create an IPv4 device path node.
1295 The header type of IPv4 device path node is MESSAGING_DEVICE_PATH.
1296 The header subtype of IPv4 device path node is MSG_IPv4_DP.
1297 The length of the IPv4 device path node in bytes is 19.
1298 Get other info from parameters to make up the whole IPv4 device path node.
1300 @param[in, out] Node Pointer to the IPv4 device path node.
1301 @param[in] Controller The handle where the NIC IP4 config protocol resides.
1302 @param[in] LocalIp The local IPv4 address.
1303 @param[in] LocalPort The local port.
1304 @param[in] RemoteIp The remote IPv4 address.
1305 @param[in] RemotePort The remote port.
1306 @param[in] Protocol The protocol type in the IP header.
1307 @param[in] UseDefaultAddress Whether this instance is using default address or not.
1312 NetLibCreateIPv4DPathNode (
1313 IN OUT IPv4_DEVICE_PATH
*Node
,
1314 IN EFI_HANDLE Controller
,
1315 IN IP4_ADDR LocalIp
,
1316 IN UINT16 LocalPort
,
1317 IN IP4_ADDR RemoteIp
,
1318 IN UINT16 RemotePort
,
1320 IN BOOLEAN UseDefaultAddress
1323 Node
->Header
.Type
= MESSAGING_DEVICE_PATH
;
1324 Node
->Header
.SubType
= MSG_IPv4_DP
;
1325 SetDevicePathNodeLength (&Node
->Header
, 19);
1327 CopyMem (&Node
->LocalIpAddress
, &LocalIp
, sizeof (EFI_IPv4_ADDRESS
));
1328 CopyMem (&Node
->RemoteIpAddress
, &RemoteIp
, sizeof (EFI_IPv4_ADDRESS
));
1330 Node
->LocalPort
= LocalPort
;
1331 Node
->RemotePort
= RemotePort
;
1333 Node
->Protocol
= Protocol
;
1335 if (!UseDefaultAddress
) {
1336 Node
->StaticIpAddress
= TRUE
;
1338 Node
->StaticIpAddress
= NetLibDefaultAddressIsStatic (Controller
);
1344 Find the UNDI/SNP handle from controller and protocol GUID.
1346 For example, IP will open a MNP child to transmit/receive
1347 packets, when MNP is stopped, IP should also be stopped. IP
1348 needs to find its own private data which is related the IP's
1349 service binding instance that is install on UNDI/SNP handle.
1350 Now, the controller is either a MNP or ARP child handle. But
1351 IP opens these handle BY_DRIVER, use that info, we can get the
1354 @param[in] Controller Then protocol handle to check.
1355 @param[in] ProtocolGuid The protocol that is related with the handle.
1357 @return The UNDI/SNP handle or NULL for errors.
1362 NetLibGetNicHandle (
1363 IN EFI_HANDLE Controller
,
1364 IN EFI_GUID
*ProtocolGuid
1367 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenBuffer
;
1373 Status
= gBS
->OpenProtocolInformation (
1380 if (EFI_ERROR (Status
)) {
1386 for (Index
= 0; Index
< OpenCount
; Index
++) {
1387 if (OpenBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_DRIVER
) {
1388 Handle
= OpenBuffer
[Index
].ControllerHandle
;
1393 gBS
->FreePool (OpenBuffer
);
1398 Add a Deferred Procedure Call to the end of the DPC queue.
1400 @param[in] DpcTpl The EFI_TPL that the DPC should be invoked.
1401 @param[in] DpcProcedure Pointer to the DPC's function.
1402 @param[in] DpcContext Pointer to the DPC's context. Passed to DpcProcedure
1403 when DpcProcedure is invoked.
1405 @retval EFI_SUCCESS The DPC was queued.
1406 @retval EFI_INVALID_PARAMETER DpcTpl is not a valid EFI_TPL, or DpcProcedure
1408 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
1409 add the DPC to the queue.
1416 IN EFI_DPC_PROCEDURE DpcProcedure
,
1417 IN VOID
*DpcContext OPTIONAL
1420 return mDpc
->QueueDpc (mDpc
, DpcTpl
, DpcProcedure
, DpcContext
);
1424 Dispatch the queue of DPCs. ALL DPCs that have been queued with a DpcTpl
1425 value greater than or equal to the current TPL are invoked in the order that
1426 they were queued. DPCs with higher DpcTpl values are invoked before DPCs with
1427 lower DpcTpl values.
1429 @retval EFI_SUCCESS One or more DPCs were invoked.
1430 @retval EFI_NOT_FOUND No DPCs were invoked.
1439 return mDpc
->DispatchDpc(mDpc
);
1443 The constructor function caches the pointer to DPC protocol.
1445 The constructor function locates DPC protocol from protocol database.
1446 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.
1448 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1449 @param[in] SystemTable A pointer to the EFI System Table.
1451 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
1457 IN EFI_HANDLE ImageHandle
,
1458 IN EFI_SYSTEM_TABLE
*SystemTable
1463 Status
= gBS
->LocateProtocol (&gEfiDpcProtocolGuid
, NULL
, (VOID
**) &mDpc
);
1464 ASSERT_EFI_ERROR (Status
);
1465 ASSERT (mDpc
!= NULL
);