2 Helper functions for configuring or obtaining the parameters relating to IP6.
4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 CHAR16 mIp6ConfigStorageName
[] = L
"IP6_CONFIG_IFR_NVDATA";
21 The notify function of create event when performing a manual configuration.
23 @param[in] Event The pointer of Event.
24 @param[in] Context The pointer of Context.
29 Ip6ConfigManualAddressNotify (
34 *((BOOLEAN
*) Context
) = TRUE
;
38 Get the configuration data for the EFI IPv6 network stack running on the
39 communication. It is a help function to the call EfiIp6ConfigGetData().
41 @param[in] Ip6Config The pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
42 @param[in] DataType The type of data to get.
43 @param[out] DataSize The size of buffer required in bytes.
44 @param[out] Data The data buffer in which the configuration data is returned. The
45 type of the data buffer associated with the DataType.
46 It is the caller's responsibility to free the resource.
48 @retval EFI_SUCCESS The specified configuration data was obtained successfully.
49 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
50 - Ip6Config is NULL or invalid.
53 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resources.
54 @retval EFI_NOT_READY The specified configuration data is not ready due to an
55 asynchronous configuration process already in progress.
56 @retval EFI_NOT_FOUND The specified configuration data was not found.
61 IN EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
,
62 IN EFI_IP6_CONFIG_DATA_TYPE DataType
,
71 if ((Ip6Config
== NULL
) || (Data
== NULL
) || (DataSize
== NULL
)) {
72 return EFI_INVALID_PARAMETER
;
76 Status
= Ip6Config
->GetData (
82 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
86 Buffer
= AllocateZeroPool (BufferSize
);
88 return EFI_OUT_OF_RESOURCES
;
91 Status
= Ip6Config
->GetData (
97 if (EFI_ERROR (Status
)) {
102 *DataSize
= BufferSize
;
109 Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified
112 @param[in] ListHead The head of the list array in IP6_ADDRESS_INFO_ENTRY.
116 Ip6FreeAddressInfoList (
117 IN LIST_ENTRY
*ListHead
120 IP6_ADDRESS_INFO_ENTRY
*Node
;
122 LIST_ENTRY
*NextEntry
;
124 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, ListHead
) {
125 Node
= NET_LIST_USER_STRUCT (Entry
, IP6_ADDRESS_INFO_ENTRY
, Link
);
126 RemoveEntryList (&Node
->Link
);
132 Convert the IPv6 address into a formatted string.
134 @param[in] Ip6 The IPv6 address.
135 @param[out] Str The formatted IP string.
140 IN EFI_IPv6_ADDRESS
*Ip6
,
147 CHAR16 FormatString
[8];
151 for (Index
= 0; Index
< 15; Index
= Index
+ 2) {
154 Ip6
->Addr
[Index
] == 0 &&
155 Ip6
->Addr
[Index
+ 1] == 0
158 // Deal with the case of ::.
169 while ((Index
< 15) && (Ip6
->Addr
[Index
] == 0) && (Ip6
->Addr
[Index
+ 1] == 0)) {
177 // :: is at the end of the address.
186 if (Ip6
->Addr
[Index
] == 0) {
187 Number
= UnicodeSPrint (Str
, 2 * IP6_STR_MAX_SIZE
, L
"%x:", (UINTN
) Ip6
->Addr
[Index
+ 1]);
189 if (Ip6
->Addr
[Index
+ 1] < 0x10) {
190 CopyMem (FormatString
, L
"%x0%x:", StrSize (L
"%x0%x:"));
192 CopyMem (FormatString
, L
"%x%x:", StrSize (L
"%x%x:"));
195 Number
= UnicodeSPrint (
197 2 * IP6_STR_MAX_SIZE
,
198 (CONST CHAR16
*) FormatString
,
199 (UINTN
) Ip6
->Addr
[Index
],
200 (UINTN
) Ip6
->Addr
[Index
+ 1]
206 if (Index
+ 2 == 16) {
208 if (*(Str
- 1) == L
':') {
216 Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.
218 @param[out] String The buffer to store the converted string.
219 @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
221 @retval EFI_SUCCESS The string converted successfully.
222 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
226 Ip6ConvertInterfaceIdToString (
228 IN EFI_IP6_CONFIG_INTERFACE_ID
*IfId
234 if ((String
== NULL
) || (IfId
== NULL
)) {
235 return EFI_INVALID_PARAMETER
;
238 for (Index
= 0; Index
< 8; Index
++) {
239 Number
= UnicodeSPrint (
241 2 * INTERFACE_ID_STR_STORAGE
,
243 (UINTN
) IfId
->Id
[Index
]
245 String
= String
+ Number
;
248 *(String
- 1) = '\0';
254 Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.
256 @param[in] String The buffer of the string to be parsed.
257 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
259 @retval EFI_SUCCESS The operation finished successfully.
260 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
264 Ip6ParseInterfaceIdFromString (
265 IN CONST CHAR16
*String
,
266 OUT EFI_IP6_CONFIG_INTERFACE_ID
*IfId
274 if ((String
== NULL
) || (IfId
== NULL
)) {
275 return EFI_INVALID_PARAMETER
;
278 IfIdStr
= (CHAR16
*) String
;
280 ZeroMem (IfId
, sizeof (EFI_IP6_CONFIG_INTERFACE_ID
));
282 for (Index
= 0; Index
< 8; Index
++) {
285 while ((*IfIdStr
!= L
'\0') && (*IfIdStr
!= L
':')) {
290 // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.
291 // If the number of X is less than 8, zero is appended to the InterfaceId.
293 if ((*IfIdStr
== ':') && (Index
== 7)) {
294 return EFI_INVALID_PARAMETER
;
298 // Convert the string to interface id. AsciiStrHexToUintn stops at the
299 // first character that is not a valid hex character, ':' or '\0' here.
301 NodeVal
= StrHexToUintn (TempStr
);
302 if (NodeVal
> 0xFF) {
303 return EFI_INVALID_PARAMETER
;
306 IfId
->Id
[Index
] = (UINT8
) NodeVal
;
315 Create Hii Extend Label OpCode as the start opcode and end opcode. It is
318 @param[in] StartLabelNumber The number of start label.
319 @param[out] StartOpCodeHandle Points to the start opcode handle.
320 @param[out] StartLabel Points to the created start opcode.
321 @param[out] EndOpCodeHandle Points to the end opcode handle.
322 @param[out] EndLabel Points to the created end opcode.
324 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
326 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
327 @retval EFI_SUCCESS The operation completed successfully.
332 IN UINT16 StartLabelNumber
,
333 OUT VOID
**StartOpCodeHandle
,
334 OUT EFI_IFR_GUID_LABEL
**StartLabel
,
335 OUT VOID
**EndOpCodeHandle
,
336 OUT EFI_IFR_GUID_LABEL
**EndLabel
340 EFI_IFR_GUID_LABEL
*InternalStartLabel
;
341 EFI_IFR_GUID_LABEL
*InternalEndLabel
;
343 if (StartOpCodeHandle
== NULL
|| StartLabel
== NULL
|| EndOpCodeHandle
== NULL
|| EndLabel
== NULL
) {
344 return EFI_INVALID_PARAMETER
;
347 *StartOpCodeHandle
= NULL
;
348 *EndOpCodeHandle
= NULL
;
349 Status
= EFI_OUT_OF_RESOURCES
;
352 // Initialize the container for dynamic opcodes.
354 *StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
355 if (*StartOpCodeHandle
== NULL
) {
359 *EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
360 if (*EndOpCodeHandle
== NULL
) {
365 // Create Hii Extend Label OpCode as the start opcode.
367 InternalStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
371 sizeof (EFI_IFR_GUID_LABEL
)
373 if (InternalStartLabel
== NULL
) {
377 InternalStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
378 InternalStartLabel
->Number
= StartLabelNumber
;
381 // Create Hii Extend Label OpCode as the end opcode.
383 InternalEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
387 sizeof (EFI_IFR_GUID_LABEL
)
389 if (InternalEndLabel
== NULL
) {
393 InternalEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
394 InternalEndLabel
->Number
= LABEL_END
;
396 *StartLabel
= InternalStartLabel
;
397 *EndLabel
= InternalEndLabel
;
403 if (*StartOpCodeHandle
!= NULL
) {
404 HiiFreeOpCodeHandle (*StartOpCodeHandle
);
407 if (*EndOpCodeHandle
!= NULL
) {
408 HiiFreeOpCodeHandle (*EndOpCodeHandle
);
415 This function converts the different format of address list to string format and
416 then generates the corresponding text opcode to illustarate the address info in
417 IP6 configuration page. Currently, the following formats are supported:
418 EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;
419 EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;
420 EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable.
422 @param[in, out] String The pointer to the buffer to store the converted
424 @param[in] HiiHandle A handle that was previously registered in the
426 @param[in] AddressType The address type.
427 @param[in] AddressInfo Pointer to the address list.
428 @param[in] AddressCount The address count of the address list.
430 @retval EFI_SUCCESS The operation finished successfully.
431 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
432 @retval EFI_UNSUPPORTED The AddressType is not supported.
437 Ip6ConvertAddressListToString (
438 IN OUT CHAR16
*String
,
439 IN EFI_HII_HANDLE HiiHandle
,
440 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
441 IN VOID
*AddressInfo
,
442 IN UINTN AddressCount
449 VOID
*StartOpCodeHandle
;
450 EFI_IFR_GUID_LABEL
*StartLabel
;
451 VOID
*EndOpCodeHandle
;
452 EFI_IFR_GUID_LABEL
*EndLabel
;
453 UINT16 StartLabelNumber
;
454 EFI_STRING_ID TextTwo
;
457 EFI_IPv6_ADDRESS
*Address
;
459 if ((String
== NULL
) || (HiiHandle
== NULL
) || (AddressInfo
== NULL
)) {
460 return EFI_INVALID_PARAMETER
;
463 if (AddressType
== Ip6ConfigNvHostAddress
) {
464 StartLabelNumber
= HOST_ADDRESS_LABEL
;
465 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
466 StartLabelNumber
= GATEWAY_ADDRESS_LABEL
;
467 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
468 StartLabelNumber
= DNS_ADDRESS_LABEL
;
469 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
470 StartLabelNumber
= ROUTE_TABLE_LABEL
;
473 return EFI_UNSUPPORTED
;
476 Status
= Ip6CreateOpCode (
483 if (EFI_ERROR (Status
)) {
487 AddressHead
= (UINT8
*) AddressInfo
;
489 for (Index
= 0; Index
< AddressCount
; Index
++) {
490 if (AddressType
== Ip6ConfigNvHostAddress
) {
491 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ADDRESS_INFO
) * Index
;
492 Address
= &((EFI_IP6_ADDRESS_INFO
*) AddressInfo
)->Address
;
493 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
494 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ROUTE_TABLE
) * Index
;
495 Address
= &((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->Destination
;
497 AddressInfo
= AddressHead
+ sizeof (EFI_IPv6_ADDRESS
) * Index
;
498 Address
= AddressInfo
;
502 // Convert the IP address info to string.
504 Ip6ToStr (Address
, String
);
505 TempStr
= String
+ StrLen (String
);
507 if ((AddressType
== Ip6ConfigNvHostAddress
) || (AddressType
== Ip6ConfigNvRouteTable
)) {
508 if (AddressType
== Ip6ConfigNvHostAddress
) {
509 PrefixLength
= ((EFI_IP6_ADDRESS_INFO
*) AddressInfo
)->PrefixLength
;
511 PrefixLength
= ((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->PrefixLength
;
515 // Append the prefix length to the string.
519 Number
= UnicodeSPrint (TempStr
, 6, L
"%d", PrefixLength
);
520 TempStr
= TempStr
+ Number
;
523 if (AddressType
== Ip6ConfigNvRouteTable
) {
525 // Append " >> " to the string.
527 Number
= UnicodeSPrint (TempStr
, 8, L
" >> ");
528 TempStr
= TempStr
+ Number
;
531 // Append the gateway address to the string.
533 Ip6ToStr (&((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->Gateway
, TempStr
);
534 TempStr
= TempStr
+ StrLen (TempStr
);
538 // Generate a text opcode and update the UI.
540 TextTwo
= HiiSetString (HiiHandle
, 0, String
, NULL
);
542 Status
= EFI_INVALID_PARAMETER
;
546 HiiCreateTextOpCode (StartOpCodeHandle
, STR_NULL
, STR_NULL
, TextTwo
);
549 *String
= IP6_ADDRESS_DELIMITER
;
553 *(String
- 1) = '\0';
555 Status
= HiiUpdateForm (
556 HiiHandle
, // HII handle
557 &gIp6ConfigNvDataGuid
, // Formset GUID
558 FORMID_MAIN_FORM
, // Form ID
559 StartOpCodeHandle
, // Label for where to insert opcodes
560 EndOpCodeHandle
// Replace data
564 HiiFreeOpCodeHandle (StartOpCodeHandle
);
565 HiiFreeOpCodeHandle (EndOpCodeHandle
);
571 Parse address list in string format and convert it to a list array of node in
572 IP6_ADDRESS_INFO_ENTRY.
574 @param[in] String The buffer to string to be parsed.
575 @param[out] ListHead The list head of array.
576 @param[out] AddressCount The number of list nodes in the array.
578 @retval EFI_SUCCESS The operation finished successfully.
579 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
580 @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource.
584 Ip6ParseAddressListFromString (
585 IN CONST CHAR16
*String
,
586 OUT LIST_ENTRY
*ListHead
,
587 OUT UINT32
*AddressCount
594 EFI_IP6_ADDRESS_INFO AddressInfo
;
595 IP6_ADDRESS_INFO_ENTRY
*Node
;
599 if ((String
== NULL
) || (ListHead
== NULL
) || (AddressCount
== NULL
)) {
600 return EFI_INVALID_PARAMETER
;
603 LocalString
= (CHAR16
*) AllocateCopyPool (StrSize (String
), String
);
604 if (LocalString
== NULL
) {
605 return EFI_OUT_OF_RESOURCES
;
609 // Clean the original address list.
611 Ip6FreeAddressInfoList (ListHead
);
617 while (*LocalString
!= L
'\0') {
618 TempStr
= LocalString
;
619 while ((*LocalString
!= L
'\0') && (*LocalString
!= IP6_ADDRESS_DELIMITER
)) {
623 if (*LocalString
== L
'\0') {
627 *LocalString
= L
'\0';
629 Status
= NetLibStrToIp6andPrefix (TempStr
, &AddressInfo
.Address
, &AddressInfo
.PrefixLength
);
630 if (EFI_ERROR (Status
)) {
634 if (AddressInfo
.PrefixLength
== 0xFF) {
635 AddressInfo
.PrefixLength
= 0;
638 if (!NetIp6IsValidUnicast (&AddressInfo
.Address
)) {
639 Status
= EFI_INVALID_PARAMETER
;
643 Node
= AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY
));
645 Status
= EFI_OUT_OF_RESOURCES
;
649 CopyMem (&Node
->AddrInfo
, &AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
650 InsertTailList (ListHead
, &Node
->Link
);
661 *AddressCount
= Count
;
665 Ip6FreeAddressInfoList (ListHead
);
671 This function converts the interface info to string and draws it to the IP6 UI.
672 The interface information includes interface name, interface type, hardware
673 address and route table information.
675 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
676 @param[in] HiiHandle The handle that was previously registered in the
678 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.
680 @retval EFI_SUCCESS The operation finished successfully.
681 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
682 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
686 Ip6ConvertInterfaceInfoToString (
687 IN EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
,
688 IN EFI_HII_HANDLE HiiHandle
,
689 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
695 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
696 CHAR16 FormatString
[8];
697 EFI_STRING_ID StringId
;
700 if ((IfInfo
== NULL
) || (HiiHandle
== NULL
) || (IfrNvData
== NULL
)) {
701 return EFI_INVALID_PARAMETER
;
705 // Print the interface name.
707 StringId
= HiiSetString (
709 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT
),
714 return EFI_OUT_OF_RESOURCES
;
718 // Print the interface type.
720 if (IfInfo
->IfType
== Ip6InterfaceTypeEthernet
) {
721 StrCpy (PortString
, IP6_ETHERNET
);
722 } else if (IfInfo
->IfType
== Ip6InterfaceTypeExperimentalEthernet
) {
723 StrCpy (PortString
, IP6_EXPERIMENTAL_ETHERNET
);
726 // Refer to RFC1700, chapter Number Hardware Type.
728 UnicodeSPrint (PortString
, 6, L
"%d", IfInfo
->IfType
);
731 StringId
= HiiSetString (
733 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT
),
738 return EFI_OUT_OF_RESOURCES
;
742 // Convert the hardware address.
745 ASSERT (IfInfo
->HwAddressSize
<= 32);
747 for (Index
= 0; Index
< IfInfo
->HwAddressSize
; Index
++) {
749 if (IfInfo
->HwAddress
.Addr
[Index
] < 0x10) {
750 StrCpy (FormatString
, L
"0%x-");
752 StrCpy (FormatString
, L
"%x-");
755 Number
= UnicodeSPrint (
758 (CONST CHAR16
*) FormatString
,
759 (UINTN
) IfInfo
->HwAddress
.Addr
[Index
]
761 String
= String
+ Number
;
765 ASSERT (String
> PortString
);
771 // Print the hardware address.
773 StringId
= HiiSetString (
775 STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT
),
780 return EFI_OUT_OF_RESOURCES
;
784 // Print the route table information.
786 Status
= Ip6ConvertAddressListToString (
789 Ip6ConfigNvRouteTable
,
797 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.
799 @param[in] Instance Points to IP6 config instance data.
800 @param[in] AddressType The address type.
801 @param[out] AddressInfo The pointer to the buffer to store the address list.
802 @param[out] AddressSize The address size of the address list.
804 @retval EFI_SUCCESS The operation finished successfully.
805 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
806 @retval EFI_UNSUPPORTED The AddressType is not supported.
810 Ip6BuildNvAddressInfo (
811 IN IP6_CONFIG_INSTANCE
*Instance
,
812 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
813 OUT VOID
**AddressInfo
,
814 OUT UINTN
*AddressSize
817 IP6_CONFIG_NVDATA
*Ip6NvData
;
819 LIST_ENTRY
*ListHead
;
820 IP6_ADDRESS_INFO_ENTRY
*Node
;
824 EFI_IPv6_ADDRESS
*Ip6Address
;
825 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
827 if ((Instance
== NULL
) || (AddressInfo
== NULL
) || (AddressSize
== NULL
)) {
828 return EFI_INVALID_PARAMETER
;
831 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
833 Ip6NvData
= &Instance
->Ip6NvData
;
835 if (AddressType
== Ip6ConfigNvHostAddress
) {
836 ListHead
= &Ip6NvData
->ManualAddress
;
837 DataSize
= sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
) * Ip6NvData
->ManualAddressCount
;
838 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
839 ListHead
= &Ip6NvData
->GatewayAddress
;
840 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->GatewayAddressCount
;
841 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
842 ListHead
= &Ip6NvData
->DnsAddress
;
843 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->DnsAddressCount
;
845 return EFI_UNSUPPORTED
;
848 AddressList
= AllocateZeroPool (DataSize
);
849 if (AddressList
== NULL
) {
850 return EFI_OUT_OF_RESOURCES
;
853 TmpStr
= AddressList
;
855 NET_LIST_FOR_EACH (Entry
, ListHead
) {
856 Node
= NET_LIST_USER_STRUCT (Entry
, IP6_ADDRESS_INFO_ENTRY
, Link
);
857 if (AddressType
== Ip6ConfigNvHostAddress
) {
858 ManualAddress
= (EFI_IP6_CONFIG_MANUAL_ADDRESS
*) AddressList
;
859 IP6_COPY_ADDRESS (&ManualAddress
->Address
, &Node
->AddrInfo
.Address
);
860 ManualAddress
->PrefixLength
= Node
->AddrInfo
.PrefixLength
;
861 AddressList
= (UINT8
*) AddressList
+ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
);
863 Ip6Address
= (EFI_IPv6_ADDRESS
*) AddressList
;
864 IP6_COPY_ADDRESS (Ip6Address
, &Node
->AddrInfo
.Address
);
865 AddressList
= (UINT8
*) AddressList
+ sizeof (EFI_IPv6_ADDRESS
);
869 *AddressInfo
= TmpStr
;
870 *AddressSize
= DataSize
;
875 Convert the IP6 configuration data into the IFR data.
877 @param[in, out] IfrNvData The IFR NV data.
878 @param[in] Instance The IP6 config instance data.
880 @retval EFI_SUCCESS The operation finished successfully.
881 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
882 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.
883 @retval Others Other errors as indicated.
887 Ip6ConvertConfigNvDataToIfrNvData (
888 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
889 IN IP6_CONFIG_INSTANCE
*Instance
892 IP6_CONFIG_NVDATA
*Ip6NvData
;
893 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
897 EFI_IP6_CONFIG_POLICY Policy
;
898 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits
;
899 EFI_HII_HANDLE HiiHandle
;
901 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
902 return EFI_INVALID_PARAMETER
;
905 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
907 Ip6Config
= &Instance
->Ip6Config
;
908 Ip6NvData
= &Instance
->Ip6NvData
;
911 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
914 // Get the current interface info.
916 Status
= Ip6ConfigNvGetData (
918 Ip6ConfigDataTypeInterfaceInfo
,
922 if (EFI_ERROR (Status
)) {
927 // Convert the interface info to string and print.
929 Status
= Ip6ConvertInterfaceInfoToString (
930 (EFI_IP6_CONFIG_INTERFACE_INFO
*) Data
,
934 if (EFI_ERROR (Status
)) {
939 // Get the interface id.
941 DataSize
= sizeof (EFI_IP6_CONFIG_INTERFACE_ID
);
942 ZeroMem (&Ip6NvData
->InterfaceId
, DataSize
);
943 Status
= Ip6Config
->GetData (
945 Ip6ConfigDataTypeAltInterfaceId
,
947 &Ip6NvData
->InterfaceId
949 if (EFI_ERROR (Status
)) {
953 Ip6ConvertInterfaceIdToString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
956 // Get current policy.
958 DataSize
= sizeof (EFI_IP6_CONFIG_POLICY
);
959 Status
= Ip6Config
->GetData (
961 Ip6ConfigDataTypePolicy
,
966 if (EFI_ERROR (Status
)) {
970 if (Policy
== Ip6ConfigPolicyManual
) {
971 IfrNvData
->Policy
= IP6_POLICY_MANUAL
;
972 } else if (Policy
== Ip6ConfigPolicyAutomatic
) {
973 IfrNvData
->Policy
= IP6_POLICY_AUTO
;
976 Status
= EFI_UNSUPPORTED
;
981 // Get Duplicate Address Detection Transmits count.
983 DataSize
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
984 Status
= Ip6Config
->GetData (
986 Ip6ConfigDataTypeDupAddrDetectTransmits
,
991 if (EFI_ERROR (Status
)) {
995 IfrNvData
->DadTransmitCount
= DadXmits
.DupAddrDetectTransmits
;
1006 Convert IFR data into IP6 configuration data. The policy, alternative interface
1007 ID, and DAD transmit counts, and will be saved.
1009 @param[in] IfrNvData The IFR NV data.
1010 @param[in, out] Instance The IP6 config instance data.
1012 @retval EFI_SUCCESS The operation finished successfully.
1013 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1014 @retval Others Other errors as indicated.
1018 Ip6ConvertIfrNvDataToConfigNvDataGeneral (
1019 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1020 IN OUT IP6_CONFIG_INSTANCE
*Instance
1023 IP6_CONFIG_NVDATA
*Ip6NvData
;
1024 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1027 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1028 return EFI_INVALID_PARAMETER
;
1031 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1032 Ip6NvData
= &Instance
->Ip6NvData
;
1033 Ip6Config
= &Instance
->Ip6Config
;
1036 // Update those fields which don't have INTERACTIVE attribute.
1038 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1039 Ip6NvData
->Policy
= Ip6ConfigPolicyAutomatic
;
1040 } else if (IfrNvData
->Policy
== IP6_POLICY_MANUAL
) {
1041 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1044 Ip6NvData
->DadTransmitCount
.DupAddrDetectTransmits
= IfrNvData
->DadTransmitCount
;
1047 // Set the configured policy.
1049 Status
= Ip6Config
->SetData (
1051 Ip6ConfigDataTypePolicy
,
1052 sizeof (EFI_IP6_CONFIG_POLICY
),
1055 if (EFI_ERROR (Status
)) {
1060 // Set the duplicate address detection transmits count.
1062 Status
= Ip6Config
->SetData (
1064 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1065 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
),
1066 &Ip6NvData
->DadTransmitCount
1068 if (EFI_ERROR (Status
)) {
1073 // Set the alternative interface ID
1075 Status
= Ip6Config
->SetData (
1077 Ip6ConfigDataTypeAltInterfaceId
,
1078 sizeof (EFI_IP6_CONFIG_INTERFACE_ID
),
1079 &Ip6NvData
->InterfaceId
1081 if (EFI_ERROR (Status
)) {
1089 Convert IFR data into IP6 configuration data. The policy, configured
1090 manual address, gateway address, and DNS server address will be saved.
1092 @param[in] IfrNvData The IFR NV data.
1093 @param[in, out] Instance The IP6 config instance data.
1095 @retval EFI_SUCCESS The operation finished successfully.
1096 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1097 @retval Others Other errors as indicated.
1101 Ip6ConvertIfrNvDataToConfigNvDataAdvanced (
1102 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1103 IN OUT IP6_CONFIG_INSTANCE
*Instance
1106 IP6_CONFIG_NVDATA
*Ip6NvData
;
1107 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1109 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
1110 EFI_IPv6_ADDRESS
*Address
;
1111 BOOLEAN IsAddressOk
;
1112 EFI_EVENT SetAddressEvent
;
1113 EFI_EVENT TimeoutEvent
;
1116 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1117 return EFI_INVALID_PARAMETER
;
1120 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1124 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1125 Ip6NvData
= &Instance
->Ip6NvData
;
1126 Ip6Config
= &Instance
->Ip6Config
;
1129 // Update those fields which don't have INTERACTIVE attribute.
1131 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1134 // Set the configured policy.
1136 Status
= Ip6Config
->SetData (
1138 Ip6ConfigDataTypePolicy
,
1139 sizeof (EFI_IP6_CONFIG_POLICY
),
1142 if (EFI_ERROR (Status
)) {
1147 // Create events & timers for asynchronous settings.
1149 SetAddressEvent
= NULL
;
1150 TimeoutEvent
= NULL
;
1151 ManualAddress
= NULL
;
1154 Status
= gBS
->CreateEvent (
1157 Ip6ConfigManualAddressNotify
,
1161 if (EFI_ERROR (Status
)) {
1165 Status
= gBS
->CreateEvent (
1172 if (EFI_ERROR (Status
)) {
1177 // Set the manual address list. This is an asynchronous process.
1179 if (!IsListEmpty (&Ip6NvData
->ManualAddress
) && (Ip6NvData
->ManualAddressCount
!= 0)) {
1180 Status
= Ip6BuildNvAddressInfo (
1182 Ip6ConfigNvHostAddress
,
1183 (VOID
**) &ManualAddress
,
1186 if (EFI_ERROR (Status
)) {
1190 IsAddressOk
= FALSE
;
1192 Status
= Ip6Config
->RegisterDataNotify (
1194 Ip6ConfigDataTypeManualAddress
,
1197 if (EFI_ERROR (Status
)) {
1201 Status
= Ip6Config
->SetData (
1203 Ip6ConfigDataTypeManualAddress
,
1205 (VOID
*) ManualAddress
1207 if (Status
== EFI_NOT_READY
) {
1208 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
1209 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
1211 Status
= EFI_SUCCESS
;
1217 Status
= Ip6Config
->UnregisterDataNotify (
1219 Ip6ConfigDataTypeManualAddress
,
1222 if (EFI_ERROR (Status
)) {
1228 // Set gateway address list.
1230 if (!IsListEmpty (&Ip6NvData
->GatewayAddress
) && (Ip6NvData
->GatewayAddressCount
!= 0)) {
1231 Status
= Ip6BuildNvAddressInfo (
1233 Ip6ConfigNvGatewayAddress
,
1237 if (EFI_ERROR (Status
)) {
1241 Status
= Ip6Config
->SetData (
1243 Ip6ConfigDataTypeGateway
,
1247 if (EFI_ERROR (Status
)) {
1256 // Set DNS server address list.
1258 if (!IsListEmpty (&Ip6NvData
->DnsAddress
) && (Ip6NvData
->DnsAddressCount
!= 0)) {
1259 Status
= Ip6BuildNvAddressInfo (
1261 Ip6ConfigNvDnsAddress
,
1265 if (EFI_ERROR (Status
)) {
1269 Status
= Ip6Config
->SetData (
1271 Ip6ConfigDataTypeDnsServer
,
1275 if (EFI_ERROR (Status
)) {
1280 Status
= EFI_SUCCESS
;
1283 if (SetAddressEvent
!= NULL
) {
1284 gBS
->CloseEvent (SetAddressEvent
);
1287 if (TimeoutEvent
!= NULL
) {
1288 gBS
->CloseEvent (TimeoutEvent
);
1291 if (ManualAddress
!= NULL
) {
1292 FreePool (ManualAddress
);
1295 if (Address
!= NULL
) {
1304 This function allows the caller to request the current
1305 configuration for one or more named elements. The resulting
1306 string is in <ConfigAltResp> format. Any and all alternative
1307 configuration strings shall also be appended to the end of the
1308 current configuration string. If they are, they must appear
1309 after the current configuration. They must contain the same
1310 routing (GUID, NAME, PATH) as the current configuration string.
1311 They must have an additional description indicating the type of
1312 alternative configuration the string represents,
1313 "ALTCFG=<StringToken>". That <StringToken> (when
1314 converted from Hex UNICODE to binary) is a reference to a
1315 string in the associated string pack.
1317 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1318 @param[in] Request A null-terminated Unicode string in
1319 <ConfigRequest> format. Note that this
1320 includes the routing information as well as
1321 the configurable name / value pairs. It is
1322 invalid for this string to be in
1323 <MultiConfigRequest> format.
1324 @param[out] Progress On return, points to a character in the
1325 Request string. Points to the string's null
1326 terminator if request was successful. Points
1327 to the most recent "&" before the first
1328 failing name / value pair (or the beginning
1329 of the string if the failure is in the first
1330 name / value pair) if the request was not
1332 @param[out] Results A null-terminated Unicode string in
1333 <ConfigAltResp> format which has all values
1334 filled in for the names in the Request string.
1335 String to be allocated by the called function.
1337 @retval EFI_SUCCESS The Results string is filled with the
1338 values corresponding to all requested
1340 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1341 parts of the results that must be
1342 stored awaiting possible future
1344 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
1345 for the Request parameter
1346 would result in this type of
1347 error. In this case, the
1348 Progress parameter would be
1350 @retval EFI_NOT_FOUND Routing data doesn't match any
1351 known driver. Progress set to the
1352 first character in the routing header.
1353 Note: There is no requirement that the
1354 driver validate the routing data. It
1355 must skip the <ConfigHdr> in order to
1357 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1358 to most recent & before the
1359 error or the beginning of the
1361 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1362 to the & before the name in
1363 question. Currently not implemented.
1367 Ip6FormExtractConfig (
1368 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1369 IN CONST EFI_STRING Request
,
1370 OUT EFI_STRING
*Progress
,
1371 OUT EFI_STRING
*Results
1376 IP6_FORM_CALLBACK_INFO
*Private
;
1377 IP6_CONFIG_INSTANCE
*Ip6ConfigInstance
;
1378 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1379 EFI_STRING ConfigRequestHdr
;
1380 EFI_STRING ConfigRequest
;
1381 BOOLEAN AllocatedRequest
;
1385 if (This
== NULL
|| Progress
== NULL
|| Results
== NULL
) {
1386 return EFI_INVALID_PARAMETER
;
1389 *Progress
= Request
;
1390 if ((Request
!= NULL
) &&
1391 !HiiIsConfigHdrMatch (Request
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1392 return EFI_NOT_FOUND
;
1395 ConfigRequestHdr
= NULL
;
1396 ConfigRequest
= NULL
;
1397 AllocatedRequest
= FALSE
;
1400 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1401 Ip6ConfigInstance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1402 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1404 IfrNvData
= (IP6_CONFIG_IFR_NVDATA
*) AllocateZeroPool (BufferSize
);
1405 if (IfrNvData
== NULL
) {
1406 return EFI_OUT_OF_RESOURCES
;
1409 Status
= Ip6ConvertConfigNvDataToIfrNvData (IfrNvData
, Ip6ConfigInstance
);
1410 if (EFI_ERROR (Status
)) {
1414 ConfigRequest
= Request
;
1415 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1417 // Request has no request element, construct full request string.
1418 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1419 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
1421 ConfigRequestHdr
= HiiConstructConfigHdr (
1422 &gIp6ConfigNvDataGuid
,
1423 mIp6ConfigStorageName
,
1424 Private
->ChildHandle
1426 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
1427 ConfigRequest
= AllocateZeroPool (Size
);
1428 ASSERT (ConfigRequest
!= NULL
);
1429 AllocatedRequest
= TRUE
;
1433 L
"%s&OFFSET=0&WIDTH=%016LX",
1437 FreePool (ConfigRequestHdr
);
1441 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1443 Status
= gHiiConfigRouting
->BlockToConfig (
1446 (UINT8
*) IfrNvData
,
1453 FreePool (IfrNvData
);
1455 // Free the allocated config request string.
1457 if (AllocatedRequest
) {
1458 FreePool (ConfigRequest
);
1459 ConfigRequest
= NULL
;
1462 // Set Progress string to the original request string.
1464 if (Request
== NULL
) {
1466 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1467 *Progress
= Request
+ StrLen (Request
);
1474 This function applies changes in a driver's configuration.
1475 Input is a Configuration, which has the routing data for this
1476 driver followed by name / value configuration pairs. The driver
1477 must apply those pairs to its configurable storage. If the
1478 driver's configuration is stored in a linear block of data
1479 and the driver's name / value pairs are in <BlockConfig>
1480 format, it may use the ConfigToBlock helper function (above) to
1481 simplify the job. Currently not implemented.
1483 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1484 @param[in] Configuration A null-terminated Unicode string in
1485 <ConfigString> format.
1486 @param[out] Progress A pointer to a string filled in with the
1487 offset of the most recent '&' before the
1488 first failing name / value pair (or the
1489 beginn ing of the string if the failure
1490 is in the first name / value pair) or
1491 the terminating NULL if all was
1494 @retval EFI_SUCCESS The results have been distributed or are
1495 awaiting distribution.
1496 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1497 parts of the results that must be
1498 stored awaiting possible future
1500 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1501 Results parameter would result
1502 in this type of error.
1503 @retval EFI_NOT_FOUND Target for the specified routing data
1508 Ip6FormRouteConfig (
1509 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1510 IN CONST EFI_STRING Configuration
,
1511 OUT EFI_STRING
*Progress
1514 if (This
== NULL
|| Configuration
== NULL
|| Progress
== NULL
) {
1515 return EFI_INVALID_PARAMETER
;
1519 // Check routing data in <ConfigHdr>.
1520 // Note: if only one Storage is used, then this checking could be skipped.
1522 if (!HiiIsConfigHdrMatch (Configuration
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1523 *Progress
= Configuration
;
1524 return EFI_NOT_FOUND
;
1527 *Progress
= Configuration
+ StrLen (Configuration
);
1533 Display host addresses, route table, DNS addresses and gateway addresses in
1534 "IPv6 Current Setting" page.
1536 @param[in] Instance The IP6 config instance data.
1538 @retval EFI_SUCCESS The operation finished successfully.
1539 @retval Others Other errors as indicated.
1543 Ip6GetCurrentSetting (
1544 IN IP6_CONFIG_INSTANCE
*Instance
1547 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1548 EFI_HII_HANDLE HiiHandle
;
1549 EFI_IP6_CONFIG_INTERFACE_INFO
*Data
;
1552 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
1553 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
1556 Ip6Config
= &Instance
->Ip6Config
;
1557 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
1561 // Get current interface info.
1563 Status
= Ip6ConfigNvGetData (
1565 Ip6ConfigDataTypeInterfaceInfo
,
1569 if (EFI_ERROR (Status
)) {
1574 // Generate dynamic text opcode for host address and draw it.
1576 IfInfo
= (EFI_IP6_CONFIG_INTERFACE_INFO
*) Data
;
1577 Status
= Ip6ConvertAddressListToString (
1580 Ip6ConfigNvHostAddress
,
1581 IfInfo
->AddressInfo
,
1582 IfInfo
->AddressInfoCount
1584 if (EFI_ERROR (Status
)) {
1590 // Generate the dynamic text opcode for route table and draw it.
1592 Status
= Ip6ConvertAddressListToString (
1595 Ip6ConfigNvRouteTable
,
1599 if (EFI_ERROR (Status
)) {
1605 // Get DNS server list.
1610 Status
= Ip6ConfigNvGetData (
1612 Ip6ConfigDataTypeDnsServer
,
1616 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1625 // Generate the dynamic text opcode for DNS server and draw it.
1627 Status
= Ip6ConvertAddressListToString (
1630 Ip6ConfigNvDnsAddress
,
1632 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1634 if (EFI_ERROR (Status
)) {
1641 // Get gateway adderss list.
1649 Status
= Ip6ConfigNvGetData (
1651 Ip6ConfigDataTypeGateway
,
1655 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1664 // Generate the dynamic text opcode for gateway and draw it.
1666 Status
= Ip6ConvertAddressListToString (
1669 Ip6ConfigNvGatewayAddress
,
1671 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1673 if (EFI_ERROR (Status
)) {
1687 This function is called to provide results data to the driver.
1688 This data consists of a unique key that is used to identify
1689 which data is either being passed back or being asked for.
1691 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1692 @param[in] Action Specifies the type of action taken by the browser.
1693 @param[in] QuestionId A unique value which is sent to the original
1694 exporting driver so that it can identify the type
1695 of data to expect. The format of the data tends to
1696 vary based on the opcode that generated the callback.
1697 @param[in] Type The type of value for the question.
1698 @param[in] Value A pointer to the data being sent to the original
1700 @param[out] ActionRequest On return, points to the action requested by the
1703 @retval EFI_SUCCESS The callback successfully handled the action.
1704 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1705 variable and its data.
1706 @retval EFI_DEVICE_ERROR The variable could not be saved.
1707 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1708 callback. Currently not implemented.
1709 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.
1710 @retval Others Other errors as indicated.
1716 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1717 IN EFI_BROWSER_ACTION Action
,
1718 IN EFI_QUESTION_ID QuestionId
,
1720 IN EFI_IFR_TYPE_VALUE
*Value
,
1721 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1724 IP6_FORM_CALLBACK_INFO
*Private
;
1726 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1729 IP6_CONFIG_INSTANCE
*Instance
;
1730 IP6_CONFIG_NVDATA
*Ip6NvData
;
1733 return EFI_INVALID_PARAMETER
;
1736 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1737 Instance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1738 Ip6NvData
= &Instance
->Ip6NvData
;
1740 if ((Action
== EFI_BROWSER_ACTION_FORM_OPEN
) || (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
)){
1744 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
1745 return EFI_UNSUPPORTED
;
1748 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1749 return EFI_INVALID_PARAMETER
;
1753 // Retrieve uncommitted data from Browser
1756 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1757 IfrNvData
= AllocateZeroPool (BufferSize
);
1758 if (IfrNvData
== NULL
) {
1759 return EFI_OUT_OF_RESOURCES
;
1762 Status
= EFI_SUCCESS
;
1764 HiiGetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
);
1766 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1767 switch (QuestionId
) {
1768 case KEY_GET_CURRENT_SETTING
:
1769 Status
= Ip6GetCurrentSetting (Instance
);
1775 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1776 switch (QuestionId
) {
1777 case KEY_SAVE_CONFIG_CHANGES
:
1778 Status
= Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData
, Instance
);
1779 if (EFI_ERROR (Status
)) {
1783 Status
= Ip6GetCurrentSetting (Instance
);
1785 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1788 case KEY_IGNORE_CONFIG_CHANGES
:
1789 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
1790 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
1791 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
1793 Ip6NvData
->ManualAddressCount
= 0;
1794 Ip6NvData
->GatewayAddressCount
= 0;
1795 Ip6NvData
->DnsAddressCount
= 0;
1797 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1800 case KEY_SAVE_CHANGES
:
1801 Status
= Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData
, Instance
);
1802 if (EFI_ERROR (Status
)) {
1805 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1808 case KEY_INTERFACE_ID
:
1809 Status
= Ip6ParseInterfaceIdFromString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
1810 if (EFI_ERROR (Status
)) {
1812 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1814 L
"Invalid Interface ID!",
1821 case KEY_MANUAL_ADDRESS
:
1822 Status
= Ip6ParseAddressListFromString (
1823 IfrNvData
->ManualAddress
,
1824 &Ip6NvData
->ManualAddress
,
1825 &Ip6NvData
->ManualAddressCount
1827 if (EFI_ERROR (Status
)) {
1829 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1831 L
"Invalid Host Addresses!",
1838 case KEY_GATEWAY_ADDRESS
:
1839 Status
= Ip6ParseAddressListFromString (
1840 IfrNvData
->GatewayAddress
,
1841 &Ip6NvData
->GatewayAddress
,
1842 &Ip6NvData
->GatewayAddressCount
1844 if (EFI_ERROR (Status
)) {
1846 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1848 L
"Invalid Gateway Addresses!",
1855 case KEY_DNS_ADDRESS
:
1856 Status
= Ip6ParseAddressListFromString (
1857 IfrNvData
->DnsAddress
,
1858 &Ip6NvData
->DnsAddress
,
1859 &Ip6NvData
->DnsAddressCount
1861 if (EFI_ERROR (Status
)) {
1863 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1865 L
"Invalid DNS Addresses!",
1877 if (!EFI_ERROR (Status
)) {
1879 // Pass changed uncommitted data back to Form Browser.
1881 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1882 HiiSetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
1885 FreePool (IfrNvData
);
1890 Install HII Config Access protocol for network device and allocate resources.
1892 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.
1894 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1895 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1896 @retval Others Other errors as indicated.
1901 IN OUT IP6_CONFIG_INSTANCE
*Instance
1906 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
1907 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1908 VENDOR_DEVICE_PATH VendorDeviceNode
;
1909 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1911 CHAR16 MenuString
[128];
1912 CHAR16 PortString
[128];
1913 CHAR16
*OldMenuString
;
1914 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1916 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
1917 ASSERT (IpSb
!= NULL
);
1919 Status
= gBS
->HandleProtocol (
1921 &gEfiDevicePathProtocolGuid
,
1922 (VOID
**) &ParentDevicePath
1924 if (EFI_ERROR (Status
)) {
1928 CallbackInfo
= &Instance
->CallbackInfo
;
1929 CallbackInfo
->Signature
= IP6_FORM_CALLBACK_INFO_SIGNATURE
;
1932 // Construct device path node for EFI HII Config Access protocol,
1933 // which consists of controller physical device path and one hardware
1934 // vendor guid node.
1936 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1937 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1938 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1940 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1942 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1943 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1945 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
1947 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1948 Status
= EFI_OUT_OF_RESOURCES
;
1952 ConfigAccess
= &CallbackInfo
->HiiConfigAccess
;
1953 ConfigAccess
->ExtractConfig
= Ip6FormExtractConfig
;
1954 ConfigAccess
->RouteConfig
= Ip6FormRouteConfig
;
1955 ConfigAccess
->Callback
= Ip6FormCallback
;
1958 // Install Device Path Protocol and Config Access protocol on new handle
1960 Status
= gBS
->InstallMultipleProtocolInterfaces (
1961 &CallbackInfo
->ChildHandle
,
1962 &gEfiDevicePathProtocolGuid
,
1963 CallbackInfo
->HiiVendorDevicePath
,
1964 &gEfiHiiConfigAccessProtocolGuid
,
1968 if (!EFI_ERROR (Status
)) {
1970 // Open the Parent Handle for the child
1972 Status
= gBS
->OpenProtocol (
1974 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1977 CallbackInfo
->ChildHandle
,
1978 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1982 if (EFI_ERROR (Status
)) {
1987 // Publish our HII data
1989 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1990 &gIp6ConfigNvDataGuid
,
1991 CallbackInfo
->ChildHandle
,
1996 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1997 Status
= EFI_OUT_OF_RESOURCES
;
2002 // Append MAC string in the menu help string and tile help string
2004 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
2005 if (!EFI_ERROR (Status
)) {
2006 OldMenuString
= HiiGetString (
2007 CallbackInfo
->RegisteredHandle
,
2008 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2011 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
2013 CallbackInfo
->RegisteredHandle
,
2014 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2018 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
2020 CallbackInfo
->RegisteredHandle
,
2021 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP
),
2026 FreePool (MacString
);
2027 FreePool (OldMenuString
);
2029 InitializeListHead (&Instance
->Ip6NvData
.ManualAddress
);
2030 InitializeListHead (&Instance
->Ip6NvData
.GatewayAddress
);
2031 InitializeListHead (&Instance
->Ip6NvData
.DnsAddress
);
2037 Ip6ConfigFormUnload (Instance
);
2042 Uninstall the HII Config Access protocol for network devices and free up the resources.
2044 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.
2048 Ip6ConfigFormUnload (
2049 IN OUT IP6_CONFIG_INSTANCE
*Instance
2053 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
2054 IP6_CONFIG_NVDATA
*Ip6NvData
;
2056 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
2057 ASSERT (IpSb
!= NULL
);
2059 CallbackInfo
= &Instance
->CallbackInfo
;
2061 if (CallbackInfo
->ChildHandle
!= NULL
) {
2064 // Close the child handle
2066 gBS
->CloseProtocol (
2068 &gEfiManagedNetworkServiceBindingProtocolGuid
,
2070 CallbackInfo
->ChildHandle
2073 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
2075 gBS
->UninstallMultipleProtocolInterfaces (
2076 CallbackInfo
->ChildHandle
,
2077 &gEfiDevicePathProtocolGuid
,
2078 CallbackInfo
->HiiVendorDevicePath
,
2079 &gEfiHiiConfigAccessProtocolGuid
,
2080 &CallbackInfo
->HiiConfigAccess
,
2085 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
2086 FreePool (CallbackInfo
->HiiVendorDevicePath
);
2089 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
2091 // Remove HII package list
2093 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
2096 Ip6NvData
= &Instance
->Ip6NvData
;
2098 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
2099 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
2100 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
2102 Ip6NvData
->ManualAddressCount
= 0;
2103 Ip6NvData
->GatewayAddressCount
= 0;
2104 Ip6NvData
->DnsAddressCount
= 0;