2 Helper functions for configuring or obtaining the parameters relating to IP6.
4 Copyright (c) 2010 - 2018, 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 ZeroMem (&AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
604 LocalString
= (CHAR16
*) AllocateCopyPool (StrSize (String
), String
);
605 if (LocalString
== NULL
) {
606 return EFI_OUT_OF_RESOURCES
;
610 // Clean the original address list.
612 Ip6FreeAddressInfoList (ListHead
);
618 while (*LocalString
!= L
'\0') {
619 TempStr
= LocalString
;
620 while ((*LocalString
!= L
'\0') && (*LocalString
!= IP6_ADDRESS_DELIMITER
)) {
624 if (*LocalString
== L
'\0') {
628 *LocalString
= L
'\0';
630 Status
= NetLibStrToIp6andPrefix (TempStr
, &AddressInfo
.Address
, &AddressInfo
.PrefixLength
);
631 if (EFI_ERROR (Status
)) {
635 if (AddressInfo
.PrefixLength
== 0xFF) {
636 AddressInfo
.PrefixLength
= 0;
639 if (!NetIp6IsValidUnicast (&AddressInfo
.Address
)) {
640 Status
= EFI_INVALID_PARAMETER
;
644 Node
= AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY
));
646 Status
= EFI_OUT_OF_RESOURCES
;
650 CopyMem (&Node
->AddrInfo
, &AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
651 InsertTailList (ListHead
, &Node
->Link
);
662 *AddressCount
= Count
;
666 Ip6FreeAddressInfoList (ListHead
);
672 This function converts the interface info to string and draws it to the IP6 UI.
673 The interface information includes interface name, interface type, hardware
674 address and route table information.
676 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
677 @param[in] HiiHandle The handle that was previously registered in the
679 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.
681 @retval EFI_SUCCESS The operation finished successfully.
682 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
683 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
687 Ip6ConvertInterfaceInfoToString (
688 IN EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
,
689 IN EFI_HII_HANDLE HiiHandle
,
690 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
696 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
697 CHAR16 FormatString
[8];
698 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 CopyMem (PortString
, IP6_ETHERNET
, sizeof (IP6_ETHERNET
));
722 } else if (IfInfo
->IfType
== Ip6InterfaceTypeExperimentalEthernet
) {
723 CopyMem (PortString
, IP6_EXPERIMENTAL_ETHERNET
, sizeof (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 CopyMem (FormatString
, L
"0%x-", sizeof (L
"0%x-"));
752 CopyMem (FormatString
, L
"%x-", sizeof (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
;
787 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.
789 @param[in] Instance Points to IP6 config instance data.
790 @param[in] AddressType The address type.
791 @param[out] AddressInfo The pointer to the buffer to store the address list.
792 @param[out] AddressSize The address size of the address list.
794 @retval EFI_SUCCESS The operation finished successfully.
795 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
796 @retval EFI_UNSUPPORTED The AddressType is not supported.
800 Ip6BuildNvAddressInfo (
801 IN IP6_CONFIG_INSTANCE
*Instance
,
802 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
803 OUT VOID
**AddressInfo
,
804 OUT UINTN
*AddressSize
807 IP6_CONFIG_NVDATA
*Ip6NvData
;
809 LIST_ENTRY
*ListHead
;
810 IP6_ADDRESS_INFO_ENTRY
*Node
;
814 EFI_IPv6_ADDRESS
*Ip6Address
;
815 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
817 if ((Instance
== NULL
) || (AddressInfo
== NULL
) || (AddressSize
== NULL
)) {
818 return EFI_INVALID_PARAMETER
;
821 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
823 Ip6NvData
= &Instance
->Ip6NvData
;
825 if (AddressType
== Ip6ConfigNvHostAddress
) {
826 ListHead
= &Ip6NvData
->ManualAddress
;
827 DataSize
= sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
) * Ip6NvData
->ManualAddressCount
;
828 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
829 ListHead
= &Ip6NvData
->GatewayAddress
;
830 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->GatewayAddressCount
;
831 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
832 ListHead
= &Ip6NvData
->DnsAddress
;
833 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->DnsAddressCount
;
835 return EFI_UNSUPPORTED
;
838 AddressList
= AllocateZeroPool (DataSize
);
839 if (AddressList
== NULL
) {
840 return EFI_OUT_OF_RESOURCES
;
843 TmpStr
= AddressList
;
845 NET_LIST_FOR_EACH (Entry
, ListHead
) {
846 Node
= NET_LIST_USER_STRUCT (Entry
, IP6_ADDRESS_INFO_ENTRY
, Link
);
847 if (AddressType
== Ip6ConfigNvHostAddress
) {
848 ManualAddress
= (EFI_IP6_CONFIG_MANUAL_ADDRESS
*) AddressList
;
849 IP6_COPY_ADDRESS (&ManualAddress
->Address
, &Node
->AddrInfo
.Address
);
850 ManualAddress
->PrefixLength
= Node
->AddrInfo
.PrefixLength
;
851 AddressList
= (UINT8
*) AddressList
+ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
);
853 Ip6Address
= (EFI_IPv6_ADDRESS
*) AddressList
;
854 IP6_COPY_ADDRESS (Ip6Address
, &Node
->AddrInfo
.Address
);
855 AddressList
= (UINT8
*) AddressList
+ sizeof (EFI_IPv6_ADDRESS
);
859 *AddressInfo
= TmpStr
;
860 *AddressSize
= DataSize
;
865 Convert the IP6 configuration data into the IFR data.
867 @param[in, out] IfrNvData The IFR NV data.
868 @param[in] Instance The IP6 config instance data.
870 @retval EFI_SUCCESS The operation finished successfully.
871 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
872 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.
873 @retval Others Other errors as indicated.
877 Ip6ConvertConfigNvDataToIfrNvData (
878 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
879 IN IP6_CONFIG_INSTANCE
*Instance
882 IP6_CONFIG_NVDATA
*Ip6NvData
;
883 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
887 EFI_IP6_CONFIG_POLICY Policy
;
888 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits
;
889 EFI_HII_HANDLE HiiHandle
;
891 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
892 return EFI_INVALID_PARAMETER
;
895 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
897 Ip6Config
= &Instance
->Ip6Config
;
898 Ip6NvData
= &Instance
->Ip6NvData
;
901 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
904 // Get the current interface info.
906 Status
= Ip6ConfigNvGetData (
908 Ip6ConfigDataTypeInterfaceInfo
,
912 if (EFI_ERROR (Status
)) {
917 // Convert the interface info to string and print.
919 Status
= Ip6ConvertInterfaceInfoToString (
920 (EFI_IP6_CONFIG_INTERFACE_INFO
*) Data
,
924 if (EFI_ERROR (Status
)) {
929 // Get the interface id.
931 DataSize
= sizeof (EFI_IP6_CONFIG_INTERFACE_ID
);
932 ZeroMem (&Ip6NvData
->InterfaceId
, DataSize
);
933 Status
= Ip6Config
->GetData (
935 Ip6ConfigDataTypeAltInterfaceId
,
937 &Ip6NvData
->InterfaceId
939 if (EFI_ERROR (Status
)) {
943 Ip6ConvertInterfaceIdToString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
946 // Get current policy.
948 DataSize
= sizeof (EFI_IP6_CONFIG_POLICY
);
949 Status
= Ip6Config
->GetData (
951 Ip6ConfigDataTypePolicy
,
956 if (EFI_ERROR (Status
)) {
960 if (Policy
== Ip6ConfigPolicyManual
) {
961 IfrNvData
->Policy
= IP6_POLICY_MANUAL
;
962 } else if (Policy
== Ip6ConfigPolicyAutomatic
) {
963 IfrNvData
->Policy
= IP6_POLICY_AUTO
;
966 Status
= EFI_UNSUPPORTED
;
971 // Get Duplicate Address Detection Transmits count.
973 DataSize
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
974 Status
= Ip6Config
->GetData (
976 Ip6ConfigDataTypeDupAddrDetectTransmits
,
981 if (EFI_ERROR (Status
)) {
985 IfrNvData
->DadTransmitCount
= DadXmits
.DupAddrDetectTransmits
;
996 Convert IFR data into IP6 configuration data. The policy, alternative interface
997 ID, and DAD transmit counts, and will be saved.
999 @param[in] IfrNvData The IFR NV data.
1000 @param[in, out] Instance The IP6 config instance data.
1002 @retval EFI_SUCCESS The operation finished successfully.
1003 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1004 @retval Others Other errors as indicated.
1008 Ip6ConvertIfrNvDataToConfigNvDataGeneral (
1009 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1010 IN OUT IP6_CONFIG_INSTANCE
*Instance
1013 IP6_CONFIG_NVDATA
*Ip6NvData
;
1014 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1017 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1018 return EFI_INVALID_PARAMETER
;
1021 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1022 Ip6NvData
= &Instance
->Ip6NvData
;
1023 Ip6Config
= &Instance
->Ip6Config
;
1026 // Update those fields which don't have INTERACTIVE attribute.
1028 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1029 Ip6NvData
->Policy
= Ip6ConfigPolicyAutomatic
;
1030 } else if (IfrNvData
->Policy
== IP6_POLICY_MANUAL
) {
1031 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1034 Ip6NvData
->DadTransmitCount
.DupAddrDetectTransmits
= IfrNvData
->DadTransmitCount
;
1037 // Set the configured policy.
1039 Status
= Ip6Config
->SetData (
1041 Ip6ConfigDataTypePolicy
,
1042 sizeof (EFI_IP6_CONFIG_POLICY
),
1045 if (EFI_ERROR (Status
)) {
1050 // Set the duplicate address detection transmits count.
1052 Status
= Ip6Config
->SetData (
1054 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1055 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
),
1056 &Ip6NvData
->DadTransmitCount
1058 if (EFI_ERROR (Status
)) {
1063 // Set the alternative interface ID
1065 Status
= Ip6Config
->SetData (
1067 Ip6ConfigDataTypeAltInterfaceId
,
1068 sizeof (EFI_IP6_CONFIG_INTERFACE_ID
),
1069 &Ip6NvData
->InterfaceId
1071 if (EFI_ERROR (Status
)) {
1079 Convert IFR data into IP6 configuration data. The policy, configured
1080 manual address, gateway address, and DNS server address will be saved.
1082 @param[in] IfrNvData The IFR NV data.
1083 @param[in, out] Instance The IP6 config instance data.
1085 @retval EFI_SUCCESS The operation finished successfully.
1086 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1087 @retval Others Other errors as indicated.
1091 Ip6ConvertIfrNvDataToConfigNvDataAdvanced (
1092 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1093 IN OUT IP6_CONFIG_INSTANCE
*Instance
1096 IP6_CONFIG_NVDATA
*Ip6NvData
;
1097 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1099 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
1100 EFI_IPv6_ADDRESS
*Address
;
1101 BOOLEAN IsAddressOk
;
1102 EFI_EVENT SetAddressEvent
;
1103 EFI_EVENT TimeoutEvent
;
1106 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1107 return EFI_INVALID_PARAMETER
;
1110 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1114 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1115 Ip6NvData
= &Instance
->Ip6NvData
;
1116 Ip6Config
= &Instance
->Ip6Config
;
1119 // Update those fields which don't have INTERACTIVE attribute.
1121 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1124 // Set the configured policy.
1126 Status
= Ip6Config
->SetData (
1128 Ip6ConfigDataTypePolicy
,
1129 sizeof (EFI_IP6_CONFIG_POLICY
),
1132 if (EFI_ERROR (Status
)) {
1137 // Create events & timers for asynchronous settings.
1139 SetAddressEvent
= NULL
;
1140 TimeoutEvent
= NULL
;
1141 ManualAddress
= NULL
;
1144 Status
= gBS
->CreateEvent (
1147 Ip6ConfigManualAddressNotify
,
1151 if (EFI_ERROR (Status
)) {
1155 Status
= gBS
->CreateEvent (
1162 if (EFI_ERROR (Status
)) {
1167 // Set the manual address list. This is an asynchronous process.
1169 if (!IsListEmpty (&Ip6NvData
->ManualAddress
) && (Ip6NvData
->ManualAddressCount
!= 0)) {
1170 Status
= Ip6BuildNvAddressInfo (
1172 Ip6ConfigNvHostAddress
,
1173 (VOID
**) &ManualAddress
,
1176 if (EFI_ERROR (Status
)) {
1180 IsAddressOk
= FALSE
;
1182 Status
= Ip6Config
->RegisterDataNotify (
1184 Ip6ConfigDataTypeManualAddress
,
1187 if (EFI_ERROR (Status
)) {
1191 Status
= Ip6Config
->SetData (
1193 Ip6ConfigDataTypeManualAddress
,
1195 (VOID
*) ManualAddress
1197 if (Status
== EFI_NOT_READY
) {
1198 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
1199 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
1201 Status
= EFI_SUCCESS
;
1207 Status
= Ip6Config
->UnregisterDataNotify (
1209 Ip6ConfigDataTypeManualAddress
,
1212 if (EFI_ERROR (Status
)) {
1218 // Set gateway address list.
1220 if (!IsListEmpty (&Ip6NvData
->GatewayAddress
) && (Ip6NvData
->GatewayAddressCount
!= 0)) {
1221 Status
= Ip6BuildNvAddressInfo (
1223 Ip6ConfigNvGatewayAddress
,
1227 if (EFI_ERROR (Status
)) {
1231 Status
= Ip6Config
->SetData (
1233 Ip6ConfigDataTypeGateway
,
1237 if (EFI_ERROR (Status
)) {
1246 // Set DNS server address list.
1248 if (!IsListEmpty (&Ip6NvData
->DnsAddress
) && (Ip6NvData
->DnsAddressCount
!= 0)) {
1249 Status
= Ip6BuildNvAddressInfo (
1251 Ip6ConfigNvDnsAddress
,
1255 if (EFI_ERROR (Status
)) {
1259 Status
= Ip6Config
->SetData (
1261 Ip6ConfigDataTypeDnsServer
,
1265 if (EFI_ERROR (Status
)) {
1270 Status
= EFI_SUCCESS
;
1273 if (SetAddressEvent
!= NULL
) {
1274 gBS
->CloseEvent (SetAddressEvent
);
1277 if (TimeoutEvent
!= NULL
) {
1278 gBS
->CloseEvent (TimeoutEvent
);
1281 if (ManualAddress
!= NULL
) {
1282 FreePool (ManualAddress
);
1285 if (Address
!= NULL
) {
1294 This function allows the caller to request the current
1295 configuration for one or more named elements. The resulting
1296 string is in <ConfigAltResp> format. Any and all alternative
1297 configuration strings shall also be appended to the end of the
1298 current configuration string. If they are, they must appear
1299 after the current configuration. They must contain the same
1300 routing (GUID, NAME, PATH) as the current configuration string.
1301 They must have an additional description indicating the type of
1302 alternative configuration the string represents,
1303 "ALTCFG=<StringToken>". That <StringToken> (when
1304 converted from Hex UNICODE to binary) is a reference to a
1305 string in the associated string pack.
1307 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1308 @param[in] Request A null-terminated Unicode string in
1309 <ConfigRequest> format. Note that this
1310 includes the routing information as well as
1311 the configurable name / value pairs. It is
1312 invalid for this string to be in
1313 <MultiConfigRequest> format.
1314 @param[out] Progress On return, points to a character in the
1315 Request string. Points to the string's null
1316 terminator if request was successful. Points
1317 to the most recent "&" before the first
1318 failing name / value pair (or the beginning
1319 of the string if the failure is in the first
1320 name / value pair) if the request was not
1322 @param[out] Results A null-terminated Unicode string in
1323 <ConfigAltResp> format which has all values
1324 filled in for the names in the Request string.
1325 String to be allocated by the called function.
1327 @retval EFI_SUCCESS The Results string is filled with the
1328 values corresponding to all requested
1330 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1331 parts of the results that must be
1332 stored awaiting possible future
1334 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
1335 for the Request parameter
1336 would result in this type of
1337 error. In this case, the
1338 Progress parameter would be
1340 @retval EFI_NOT_FOUND Routing data doesn't match any
1341 known driver. Progress set to the
1342 first character in the routing header.
1343 Note: There is no requirement that the
1344 driver validate the routing data. It
1345 must skip the <ConfigHdr> in order to
1347 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1348 to most recent & before the
1349 error or the beginning of the
1351 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1352 to the & before the name in
1353 question. Currently not implemented.
1357 Ip6FormExtractConfig (
1358 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1359 IN CONST EFI_STRING Request
,
1360 OUT EFI_STRING
*Progress
,
1361 OUT EFI_STRING
*Results
1366 IP6_FORM_CALLBACK_INFO
*Private
;
1367 IP6_CONFIG_INSTANCE
*Ip6ConfigInstance
;
1368 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1369 EFI_STRING ConfigRequestHdr
;
1370 EFI_STRING ConfigRequest
;
1371 BOOLEAN AllocatedRequest
;
1375 if (This
== NULL
|| Progress
== NULL
|| Results
== NULL
) {
1376 return EFI_INVALID_PARAMETER
;
1379 *Progress
= Request
;
1380 if ((Request
!= NULL
) &&
1381 !HiiIsConfigHdrMatch (Request
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1382 return EFI_NOT_FOUND
;
1385 ConfigRequestHdr
= NULL
;
1386 ConfigRequest
= NULL
;
1387 AllocatedRequest
= FALSE
;
1390 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1391 Ip6ConfigInstance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1392 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1394 IfrNvData
= (IP6_CONFIG_IFR_NVDATA
*) AllocateZeroPool (BufferSize
);
1395 if (IfrNvData
== NULL
) {
1396 return EFI_OUT_OF_RESOURCES
;
1399 Status
= Ip6ConvertConfigNvDataToIfrNvData (IfrNvData
, Ip6ConfigInstance
);
1400 if (EFI_ERROR (Status
)) {
1404 ConfigRequest
= Request
;
1405 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1407 // Request has no request element, construct full request string.
1408 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1409 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
1411 ConfigRequestHdr
= HiiConstructConfigHdr (
1412 &gIp6ConfigNvDataGuid
,
1413 mIp6ConfigStorageName
,
1414 Private
->ChildHandle
1416 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
1417 ConfigRequest
= AllocateZeroPool (Size
);
1418 ASSERT (ConfigRequest
!= NULL
);
1419 AllocatedRequest
= TRUE
;
1423 L
"%s&OFFSET=0&WIDTH=%016LX",
1427 FreePool (ConfigRequestHdr
);
1431 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1433 Status
= gHiiConfigRouting
->BlockToConfig (
1436 (UINT8
*) IfrNvData
,
1443 FreePool (IfrNvData
);
1445 // Free the allocated config request string.
1447 if (AllocatedRequest
) {
1448 FreePool (ConfigRequest
);
1449 ConfigRequest
= NULL
;
1452 // Set Progress string to the original request string.
1454 if (Request
== NULL
) {
1456 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1457 *Progress
= Request
+ StrLen (Request
);
1464 This function applies changes in a driver's configuration.
1465 Input is a Configuration, which has the routing data for this
1466 driver followed by name / value configuration pairs. The driver
1467 must apply those pairs to its configurable storage. If the
1468 driver's configuration is stored in a linear block of data
1469 and the driver's name / value pairs are in <BlockConfig>
1470 format, it may use the ConfigToBlock helper function (above) to
1471 simplify the job. Currently not implemented.
1473 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1474 @param[in] Configuration A null-terminated Unicode string in
1475 <ConfigString> format.
1476 @param[out] Progress A pointer to a string filled in with the
1477 offset of the most recent '&' before the
1478 first failing name / value pair (or the
1479 beginn ing of the string if the failure
1480 is in the first name / value pair) or
1481 the terminating NULL if all was
1484 @retval EFI_SUCCESS The results have been distributed or are
1485 awaiting distribution.
1486 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1487 parts of the results that must be
1488 stored awaiting possible future
1490 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1491 Results parameter would result
1492 in this type of error.
1493 @retval EFI_NOT_FOUND Target for the specified routing data
1498 Ip6FormRouteConfig (
1499 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1500 IN CONST EFI_STRING Configuration
,
1501 OUT EFI_STRING
*Progress
1504 if (This
== NULL
|| Configuration
== NULL
|| Progress
== NULL
) {
1505 return EFI_INVALID_PARAMETER
;
1509 // Check routing data in <ConfigHdr>.
1510 // Note: if only one Storage is used, then this checking could be skipped.
1512 if (!HiiIsConfigHdrMatch (Configuration
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1513 *Progress
= Configuration
;
1514 return EFI_NOT_FOUND
;
1517 *Progress
= Configuration
+ StrLen (Configuration
);
1523 Display host addresses, route table, DNS addresses and gateway addresses in
1524 "IPv6 Current Setting" page.
1526 @param[in] Instance The IP6 config instance data.
1528 @retval EFI_SUCCESS The operation finished successfully.
1529 @retval Others Other errors as indicated.
1533 Ip6GetCurrentSetting (
1534 IN IP6_CONFIG_INSTANCE
*Instance
1537 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1538 EFI_HII_HANDLE HiiHandle
;
1539 EFI_IP6_CONFIG_INTERFACE_INFO
*Data
;
1542 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
1543 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
1546 Ip6Config
= &Instance
->Ip6Config
;
1547 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
1551 // Get current interface info.
1553 Status
= Ip6ConfigNvGetData (
1555 Ip6ConfigDataTypeInterfaceInfo
,
1559 if (EFI_ERROR (Status
)) {
1564 // Generate dynamic text opcode for host address and draw it.
1566 IfInfo
= (EFI_IP6_CONFIG_INTERFACE_INFO
*) Data
;
1567 Status
= Ip6ConvertAddressListToString (
1570 Ip6ConfigNvHostAddress
,
1571 IfInfo
->AddressInfo
,
1572 IfInfo
->AddressInfoCount
1574 if (EFI_ERROR (Status
)) {
1580 // Generate the dynamic text opcode for route table and draw it.
1582 Status
= Ip6ConvertAddressListToString (
1585 Ip6ConfigNvRouteTable
,
1589 if (EFI_ERROR (Status
)) {
1595 // Get DNS server list.
1600 Status
= Ip6ConfigNvGetData (
1602 Ip6ConfigDataTypeDnsServer
,
1606 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1615 // Generate the dynamic text opcode for DNS server and draw it.
1617 Status
= Ip6ConvertAddressListToString (
1620 Ip6ConfigNvDnsAddress
,
1622 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1624 if (EFI_ERROR (Status
)) {
1631 // Get gateway adderss list.
1639 Status
= Ip6ConfigNvGetData (
1641 Ip6ConfigDataTypeGateway
,
1645 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1654 // Generate the dynamic text opcode for gateway and draw it.
1656 Status
= Ip6ConvertAddressListToString (
1659 Ip6ConfigNvGatewayAddress
,
1661 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1663 if (EFI_ERROR (Status
)) {
1677 This function is called to provide results data to the driver.
1678 This data consists of a unique key that is used to identify
1679 which data is either being passed back or being asked for.
1681 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1682 @param[in] Action Specifies the type of action taken by the browser.
1683 @param[in] QuestionId A unique value which is sent to the original
1684 exporting driver so that it can identify the type
1685 of data to expect. The format of the data tends to
1686 vary based on the opcode that generated the callback.
1687 @param[in] Type The type of value for the question.
1688 @param[in] Value A pointer to the data being sent to the original
1690 @param[out] ActionRequest On return, points to the action requested by the
1693 @retval EFI_SUCCESS The callback successfully handled the action.
1694 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1695 variable and its data.
1696 @retval EFI_DEVICE_ERROR The variable could not be saved.
1697 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1698 callback. Currently not implemented.
1699 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.
1700 @retval Others Other errors as indicated.
1706 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1707 IN EFI_BROWSER_ACTION Action
,
1708 IN EFI_QUESTION_ID QuestionId
,
1710 IN EFI_IFR_TYPE_VALUE
*Value
,
1711 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1714 IP6_FORM_CALLBACK_INFO
*Private
;
1716 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1719 IP6_CONFIG_INSTANCE
*Instance
;
1720 IP6_CONFIG_NVDATA
*Ip6NvData
;
1723 return EFI_INVALID_PARAMETER
;
1726 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1727 Instance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1728 Ip6NvData
= &Instance
->Ip6NvData
;
1730 if ((Action
== EFI_BROWSER_ACTION_FORM_OPEN
) || (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
)){
1734 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
1735 return EFI_UNSUPPORTED
;
1738 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1739 return EFI_INVALID_PARAMETER
;
1743 // Retrieve uncommitted data from Browser
1746 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1747 IfrNvData
= AllocateZeroPool (BufferSize
);
1748 if (IfrNvData
== NULL
) {
1749 return EFI_OUT_OF_RESOURCES
;
1752 Status
= EFI_SUCCESS
;
1754 HiiGetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
);
1756 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1757 switch (QuestionId
) {
1758 case KEY_GET_CURRENT_SETTING
:
1759 Status
= Ip6GetCurrentSetting (Instance
);
1765 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1766 switch (QuestionId
) {
1767 case KEY_SAVE_CONFIG_CHANGES
:
1768 Status
= Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData
, Instance
);
1769 if (EFI_ERROR (Status
)) {
1773 Status
= Ip6GetCurrentSetting (Instance
);
1775 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1778 case KEY_IGNORE_CONFIG_CHANGES
:
1779 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
1780 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
1781 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
1783 Ip6NvData
->ManualAddressCount
= 0;
1784 Ip6NvData
->GatewayAddressCount
= 0;
1785 Ip6NvData
->DnsAddressCount
= 0;
1787 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1790 case KEY_SAVE_CHANGES
:
1791 Status
= Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData
, Instance
);
1792 if (EFI_ERROR (Status
)) {
1795 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1798 case KEY_INTERFACE_ID
:
1799 Status
= Ip6ParseInterfaceIdFromString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
1800 if (EFI_ERROR (Status
)) {
1802 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1804 L
"Invalid Interface ID!",
1811 case KEY_MANUAL_ADDRESS
:
1812 Status
= Ip6ParseAddressListFromString (
1813 IfrNvData
->ManualAddress
,
1814 &Ip6NvData
->ManualAddress
,
1815 &Ip6NvData
->ManualAddressCount
1817 if (EFI_ERROR (Status
)) {
1819 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1821 L
"Invalid Host Addresses!",
1828 case KEY_GATEWAY_ADDRESS
:
1829 Status
= Ip6ParseAddressListFromString (
1830 IfrNvData
->GatewayAddress
,
1831 &Ip6NvData
->GatewayAddress
,
1832 &Ip6NvData
->GatewayAddressCount
1834 if (EFI_ERROR (Status
)) {
1836 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1838 L
"Invalid Gateway Addresses!",
1845 case KEY_DNS_ADDRESS
:
1846 Status
= Ip6ParseAddressListFromString (
1847 IfrNvData
->DnsAddress
,
1848 &Ip6NvData
->DnsAddress
,
1849 &Ip6NvData
->DnsAddressCount
1851 if (EFI_ERROR (Status
)) {
1853 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1855 L
"Invalid DNS Addresses!",
1867 if (!EFI_ERROR (Status
)) {
1869 // Pass changed uncommitted data back to Form Browser.
1871 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1872 HiiSetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
1875 FreePool (IfrNvData
);
1880 Install HII Config Access protocol for network device and allocate resources.
1882 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.
1884 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1885 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1886 @retval Others Other errors as indicated.
1891 IN OUT IP6_CONFIG_INSTANCE
*Instance
1896 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
1897 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1898 VENDOR_DEVICE_PATH VendorDeviceNode
;
1899 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1901 CHAR16 MenuString
[128];
1902 CHAR16 PortString
[128];
1903 CHAR16
*OldMenuString
;
1904 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1906 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
1907 ASSERT (IpSb
!= NULL
);
1909 Status
= gBS
->HandleProtocol (
1911 &gEfiDevicePathProtocolGuid
,
1912 (VOID
**) &ParentDevicePath
1914 if (EFI_ERROR (Status
)) {
1918 CallbackInfo
= &Instance
->CallbackInfo
;
1919 CallbackInfo
->Signature
= IP6_FORM_CALLBACK_INFO_SIGNATURE
;
1922 // Construct device path node for EFI HII Config Access protocol,
1923 // which consists of controller physical device path and one hardware
1924 // vendor guid node.
1926 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1927 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1928 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1930 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1932 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1933 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1935 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
1937 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1938 Status
= EFI_OUT_OF_RESOURCES
;
1942 ConfigAccess
= &CallbackInfo
->HiiConfigAccess
;
1943 ConfigAccess
->ExtractConfig
= Ip6FormExtractConfig
;
1944 ConfigAccess
->RouteConfig
= Ip6FormRouteConfig
;
1945 ConfigAccess
->Callback
= Ip6FormCallback
;
1948 // Install Device Path Protocol and Config Access protocol on new handle
1950 Status
= gBS
->InstallMultipleProtocolInterfaces (
1951 &CallbackInfo
->ChildHandle
,
1952 &gEfiDevicePathProtocolGuid
,
1953 CallbackInfo
->HiiVendorDevicePath
,
1954 &gEfiHiiConfigAccessProtocolGuid
,
1958 if (!EFI_ERROR (Status
)) {
1960 // Open the Parent Handle for the child
1962 Status
= gBS
->OpenProtocol (
1964 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1967 CallbackInfo
->ChildHandle
,
1968 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1972 if (EFI_ERROR (Status
)) {
1977 // Publish our HII data
1979 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1980 &gIp6ConfigNvDataGuid
,
1981 CallbackInfo
->ChildHandle
,
1986 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1987 Status
= EFI_OUT_OF_RESOURCES
;
1992 // Append MAC string in the menu help string and tile help string
1994 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1995 if (!EFI_ERROR (Status
)) {
1996 OldMenuString
= HiiGetString (
1997 CallbackInfo
->RegisteredHandle
,
1998 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2001 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
2003 CallbackInfo
->RegisteredHandle
,
2004 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2008 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
2010 CallbackInfo
->RegisteredHandle
,
2011 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP
),
2016 FreePool (MacString
);
2017 FreePool (OldMenuString
);
2019 InitializeListHead (&Instance
->Ip6NvData
.ManualAddress
);
2020 InitializeListHead (&Instance
->Ip6NvData
.GatewayAddress
);
2021 InitializeListHead (&Instance
->Ip6NvData
.DnsAddress
);
2027 Ip6ConfigFormUnload (Instance
);
2032 Uninstall the HII Config Access protocol for network devices and free up the resources.
2034 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.
2038 Ip6ConfigFormUnload (
2039 IN OUT IP6_CONFIG_INSTANCE
*Instance
2043 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
2044 IP6_CONFIG_NVDATA
*Ip6NvData
;
2046 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
2047 ASSERT (IpSb
!= NULL
);
2049 CallbackInfo
= &Instance
->CallbackInfo
;
2051 if (CallbackInfo
->ChildHandle
!= NULL
) {
2054 // Close the child handle
2056 gBS
->CloseProtocol (
2058 &gEfiManagedNetworkServiceBindingProtocolGuid
,
2060 CallbackInfo
->ChildHandle
2063 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
2065 gBS
->UninstallMultipleProtocolInterfaces (
2066 CallbackInfo
->ChildHandle
,
2067 &gEfiDevicePathProtocolGuid
,
2068 CallbackInfo
->HiiVendorDevicePath
,
2069 &gEfiHiiConfigAccessProtocolGuid
,
2070 &CallbackInfo
->HiiConfigAccess
,
2075 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
2076 FreePool (CallbackInfo
->HiiVendorDevicePath
);
2079 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
2081 // Remove HII package list
2083 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
2086 Ip6NvData
= &Instance
->Ip6NvData
;
2088 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
2089 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
2090 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
2092 Ip6NvData
->ManualAddressCount
= 0;
2093 Ip6NvData
->GatewayAddressCount
= 0;
2094 Ip6NvData
->DnsAddressCount
= 0;