2 Helper functions for configuring or obtaining the parameters relating to IP6.
4 Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
12 CHAR16 mIp6ConfigStorageName
[] = L
"IP6_CONFIG_IFR_NVDATA";
15 The notify function of create event when performing a manual configuration.
17 @param[in] Event The pointer of Event.
18 @param[in] Context The pointer of Context.
23 Ip6ConfigManualAddressNotify (
28 *((BOOLEAN
*)Context
) = TRUE
;
32 Get the configuration data for the EFI IPv6 network stack running on the
33 communication. It is a help function to the call EfiIp6ConfigGetData().
35 @param[in] Ip6Config The pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
36 @param[in] DataType The type of data to get.
37 @param[out] DataSize The size of buffer required in bytes.
38 @param[out] Data The data buffer in which the configuration data is returned. The
39 type of the data buffer associated with the DataType.
40 It is the caller's responsibility to free the resource.
42 @retval EFI_SUCCESS The specified configuration data was obtained successfully.
43 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
44 - Ip6Config is NULL or invalid.
47 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resources.
48 @retval EFI_NOT_READY The specified configuration data is not ready due to an
49 asynchronous configuration process already in progress.
50 @retval EFI_NOT_FOUND The specified configuration data was not found.
55 IN EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
,
56 IN EFI_IP6_CONFIG_DATA_TYPE DataType
,
65 if ((Ip6Config
== NULL
) || (Data
== NULL
) || (DataSize
== NULL
)) {
66 return EFI_INVALID_PARAMETER
;
70 Status
= Ip6Config
->GetData (
76 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
80 Buffer
= AllocateZeroPool (BufferSize
);
82 return EFI_OUT_OF_RESOURCES
;
85 Status
= Ip6Config
->GetData (
91 if (EFI_ERROR (Status
)) {
96 *DataSize
= BufferSize
;
103 Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified
106 @param[in] ListHead The head of the list array in IP6_ADDRESS_INFO_ENTRY.
110 Ip6FreeAddressInfoList (
111 IN LIST_ENTRY
*ListHead
114 IP6_ADDRESS_INFO_ENTRY
*Node
;
116 LIST_ENTRY
*NextEntry
;
118 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, ListHead
) {
119 Node
= NET_LIST_USER_STRUCT (Entry
, IP6_ADDRESS_INFO_ENTRY
, Link
);
120 RemoveEntryList (&Node
->Link
);
126 Convert the IPv6 address into a formatted string.
128 @param[in] Ip6 The IPv6 address.
129 @param[out] Str The formatted IP string.
134 IN EFI_IPv6_ADDRESS
*Ip6
,
141 CHAR16 FormatString
[8];
145 for (Index
= 0; Index
< 15; Index
= Index
+ 2) {
148 (Ip6
->Addr
[Index
] == 0) &&
149 (Ip6
->Addr
[Index
+ 1] == 0)
153 // Deal with the case of ::.
164 while ((Index
< 15) && (Ip6
->Addr
[Index
] == 0) && (Ip6
->Addr
[Index
+ 1] == 0)) {
172 // :: is at the end of the address.
181 if (Ip6
->Addr
[Index
] == 0) {
182 Number
= UnicodeSPrint (Str
, 2 * IP6_STR_MAX_SIZE
, L
"%x:", (UINTN
)Ip6
->Addr
[Index
+ 1]);
184 if (Ip6
->Addr
[Index
+ 1] < 0x10) {
185 CopyMem (FormatString
, L
"%x0%x:", StrSize (L
"%x0%x:"));
187 CopyMem (FormatString
, L
"%x%x:", StrSize (L
"%x%x:"));
190 Number
= UnicodeSPrint (
192 2 * IP6_STR_MAX_SIZE
,
193 (CONST CHAR16
*)FormatString
,
194 (UINTN
)Ip6
->Addr
[Index
],
195 (UINTN
)Ip6
->Addr
[Index
+ 1]
201 if (Index
+ 2 == 16) {
203 if (*(Str
- 1) == L
':') {
211 Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.
213 @param[out] String The buffer to store the converted string.
214 @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
216 @retval EFI_SUCCESS The string converted successfully.
217 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
221 Ip6ConvertInterfaceIdToString (
223 IN EFI_IP6_CONFIG_INTERFACE_ID
*IfId
229 if ((String
== NULL
) || (IfId
== NULL
)) {
230 return EFI_INVALID_PARAMETER
;
233 for (Index
= 0; Index
< 8; Index
++) {
234 Number
= UnicodeSPrint (
236 2 * INTERFACE_ID_STR_STORAGE
,
238 (UINTN
)IfId
->Id
[Index
]
240 String
= String
+ Number
;
243 *(String
- 1) = '\0';
249 Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.
251 @param[in] String The buffer of the string to be parsed.
252 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
254 @retval EFI_SUCCESS The operation finished successfully.
255 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
259 Ip6ParseInterfaceIdFromString (
260 IN CONST CHAR16
*String
,
261 OUT EFI_IP6_CONFIG_INTERFACE_ID
*IfId
269 if ((String
== NULL
) || (IfId
== NULL
)) {
270 return EFI_INVALID_PARAMETER
;
273 IfIdStr
= (CHAR16
*)String
;
275 ZeroMem (IfId
, sizeof (EFI_IP6_CONFIG_INTERFACE_ID
));
277 for (Index
= 0; Index
< 8; Index
++) {
280 while ((*IfIdStr
!= L
'\0') && (*IfIdStr
!= L
':')) {
285 // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.
286 // If the number of X is less than 8, zero is appended to the InterfaceId.
288 if ((*IfIdStr
== ':') && (Index
== 7)) {
289 return EFI_INVALID_PARAMETER
;
293 // Convert the string to interface id. AsciiStrHexToUintn stops at the
294 // first character that is not a valid hex character, ':' or '\0' here.
296 NodeVal
= StrHexToUintn (TempStr
);
297 if (NodeVal
> 0xFF) {
298 return EFI_INVALID_PARAMETER
;
301 IfId
->Id
[Index
] = (UINT8
)NodeVal
;
310 Create Hii Extend Label OpCode as the start opcode and end opcode. It is
313 @param[in] StartLabelNumber The number of start label.
314 @param[out] StartOpCodeHandle Points to the start opcode handle.
315 @param[out] StartLabel Points to the created start opcode.
316 @param[out] EndOpCodeHandle Points to the end opcode handle.
317 @param[out] EndLabel Points to the created end opcode.
319 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
321 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
322 @retval EFI_SUCCESS The operation completed successfully.
327 IN UINT16 StartLabelNumber
,
328 OUT VOID
**StartOpCodeHandle
,
329 OUT EFI_IFR_GUID_LABEL
**StartLabel
,
330 OUT VOID
**EndOpCodeHandle
,
331 OUT EFI_IFR_GUID_LABEL
**EndLabel
335 EFI_IFR_GUID_LABEL
*InternalStartLabel
;
336 EFI_IFR_GUID_LABEL
*InternalEndLabel
;
338 if ((StartOpCodeHandle
== NULL
) || (StartLabel
== NULL
) || (EndOpCodeHandle
== NULL
) || (EndLabel
== NULL
)) {
339 return EFI_INVALID_PARAMETER
;
342 *StartOpCodeHandle
= NULL
;
343 *EndOpCodeHandle
= NULL
;
344 Status
= EFI_OUT_OF_RESOURCES
;
347 // Initialize the container for dynamic opcodes.
349 *StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
350 if (*StartOpCodeHandle
== NULL
) {
354 *EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
355 if (*EndOpCodeHandle
== NULL
) {
360 // Create Hii Extend Label OpCode as the start opcode.
362 InternalStartLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
366 sizeof (EFI_IFR_GUID_LABEL
)
368 if (InternalStartLabel
== NULL
) {
372 InternalStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
373 InternalStartLabel
->Number
= StartLabelNumber
;
376 // Create Hii Extend Label OpCode as the end opcode.
378 InternalEndLabel
= (EFI_IFR_GUID_LABEL
*)HiiCreateGuidOpCode (
382 sizeof (EFI_IFR_GUID_LABEL
)
384 if (InternalEndLabel
== NULL
) {
388 InternalEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
389 InternalEndLabel
->Number
= LABEL_END
;
391 *StartLabel
= InternalStartLabel
;
392 *EndLabel
= InternalEndLabel
;
398 if (*StartOpCodeHandle
!= NULL
) {
399 HiiFreeOpCodeHandle (*StartOpCodeHandle
);
402 if (*EndOpCodeHandle
!= NULL
) {
403 HiiFreeOpCodeHandle (*EndOpCodeHandle
);
410 This function converts the different format of address list to string format and
411 then generates the corresponding text opcode to illustrate the address info in
412 IP6 configuration page. Currently, the following formats are supported:
413 EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;
414 EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;
415 EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable.
417 @param[in, out] String The pointer to the buffer to store the converted
419 @param[in] HiiHandle A handle that was previously registered in the
421 @param[in] AddressType The address type.
422 @param[in] AddressInfo Pointer to the address list.
423 @param[in] AddressCount The address count of the address list.
425 @retval EFI_SUCCESS The operation finished successfully.
426 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
427 @retval EFI_UNSUPPORTED The AddressType is not supported.
432 Ip6ConvertAddressListToString (
433 IN OUT CHAR16
*String
,
434 IN EFI_HII_HANDLE HiiHandle
,
435 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
436 IN VOID
*AddressInfo
,
437 IN UINTN AddressCount
444 VOID
*StartOpCodeHandle
;
445 EFI_IFR_GUID_LABEL
*StartLabel
;
446 VOID
*EndOpCodeHandle
;
447 EFI_IFR_GUID_LABEL
*EndLabel
;
448 UINT16 StartLabelNumber
;
449 EFI_STRING_ID TextTwo
;
452 EFI_IPv6_ADDRESS
*Address
;
454 if ((String
== NULL
) || (HiiHandle
== NULL
) || (AddressInfo
== NULL
)) {
455 return EFI_INVALID_PARAMETER
;
458 if (AddressType
== Ip6ConfigNvHostAddress
) {
459 StartLabelNumber
= HOST_ADDRESS_LABEL
;
460 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
461 StartLabelNumber
= GATEWAY_ADDRESS_LABEL
;
462 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
463 StartLabelNumber
= DNS_ADDRESS_LABEL
;
464 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
465 StartLabelNumber
= ROUTE_TABLE_LABEL
;
468 return EFI_UNSUPPORTED
;
471 Status
= Ip6CreateOpCode (
478 if (EFI_ERROR (Status
)) {
482 AddressHead
= (UINT8
*)AddressInfo
;
484 for (Index
= 0; Index
< AddressCount
; Index
++) {
485 if (AddressType
== Ip6ConfigNvHostAddress
) {
486 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ADDRESS_INFO
) * Index
;
487 Address
= &((EFI_IP6_ADDRESS_INFO
*)AddressInfo
)->Address
;
488 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
489 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ROUTE_TABLE
) * Index
;
490 Address
= &((EFI_IP6_ROUTE_TABLE
*)AddressInfo
)->Destination
;
492 AddressInfo
= AddressHead
+ sizeof (EFI_IPv6_ADDRESS
) * Index
;
493 Address
= AddressInfo
;
497 // Convert the IP address info to string.
499 Ip6ToStr (Address
, String
);
500 TempStr
= String
+ StrLen (String
);
502 if ((AddressType
== Ip6ConfigNvHostAddress
) || (AddressType
== Ip6ConfigNvRouteTable
)) {
503 if (AddressType
== Ip6ConfigNvHostAddress
) {
504 PrefixLength
= ((EFI_IP6_ADDRESS_INFO
*)AddressInfo
)->PrefixLength
;
506 PrefixLength
= ((EFI_IP6_ROUTE_TABLE
*)AddressInfo
)->PrefixLength
;
510 // Append the prefix length to the string.
514 Number
= UnicodeSPrint (TempStr
, 6, L
"%d", PrefixLength
);
515 TempStr
= TempStr
+ Number
;
518 if (AddressType
== Ip6ConfigNvRouteTable
) {
520 // Append " >> " to the string.
522 Number
= UnicodeSPrint (TempStr
, 8, L
" >> ");
523 TempStr
= TempStr
+ Number
;
526 // Append the gateway address to the string.
528 Ip6ToStr (&((EFI_IP6_ROUTE_TABLE
*)AddressInfo
)->Gateway
, TempStr
);
529 TempStr
= TempStr
+ StrLen (TempStr
);
533 // Generate a text opcode and update the UI.
535 TextTwo
= HiiSetString (HiiHandle
, 0, String
, NULL
);
537 Status
= EFI_INVALID_PARAMETER
;
541 HiiCreateTextOpCode (StartOpCodeHandle
, STR_NULL
, STR_NULL
, TextTwo
);
544 *String
= IP6_ADDRESS_DELIMITER
;
548 *(String
- 1) = '\0';
550 Status
= HiiUpdateForm (
551 HiiHandle
, // HII handle
552 &gIp6ConfigNvDataGuid
, // Formset GUID
553 FORMID_MAIN_FORM
, // Form ID
554 StartOpCodeHandle
, // Label for where to insert opcodes
555 EndOpCodeHandle
// Replace data
559 HiiFreeOpCodeHandle (StartOpCodeHandle
);
560 HiiFreeOpCodeHandle (EndOpCodeHandle
);
566 Parse address list in string format and convert it to a list array of node in
567 IP6_ADDRESS_INFO_ENTRY.
569 @param[in] String The buffer to string to be parsed.
570 @param[out] ListHead The list head of array.
571 @param[out] AddressCount The number of list nodes in the array.
573 @retval EFI_SUCCESS The operation finished successfully.
574 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
575 @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource.
579 Ip6ParseAddressListFromString (
580 IN CONST CHAR16
*String
,
581 OUT LIST_ENTRY
*ListHead
,
582 OUT UINT32
*AddressCount
589 EFI_IP6_ADDRESS_INFO AddressInfo
;
590 IP6_ADDRESS_INFO_ENTRY
*Node
;
594 if ((String
== NULL
) || (ListHead
== NULL
) || (AddressCount
== NULL
)) {
595 return EFI_INVALID_PARAMETER
;
598 ZeroMem (&AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
599 LocalString
= (CHAR16
*)AllocateCopyPool (StrSize (String
), String
);
600 if (LocalString
== NULL
) {
601 return EFI_OUT_OF_RESOURCES
;
605 // Clean the original address list.
607 Ip6FreeAddressInfoList (ListHead
);
613 while (*LocalString
!= L
'\0') {
614 TempStr
= LocalString
;
615 while ((*LocalString
!= L
'\0') && (*LocalString
!= IP6_ADDRESS_DELIMITER
)) {
619 if (*LocalString
== L
'\0') {
623 *LocalString
= L
'\0';
625 Status
= NetLibStrToIp6andPrefix (TempStr
, &AddressInfo
.Address
, &AddressInfo
.PrefixLength
);
626 if (EFI_ERROR (Status
)) {
630 if (AddressInfo
.PrefixLength
== 0xFF) {
631 AddressInfo
.PrefixLength
= 0;
634 if (!NetIp6IsValidUnicast (&AddressInfo
.Address
)) {
635 Status
= EFI_INVALID_PARAMETER
;
639 Node
= AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY
));
641 Status
= EFI_OUT_OF_RESOURCES
;
645 CopyMem (&Node
->AddrInfo
, &AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
646 InsertTailList (ListHead
, &Node
->Link
);
657 *AddressCount
= Count
;
661 Ip6FreeAddressInfoList (ListHead
);
667 This function converts the interface info to string and draws it to the IP6 UI.
668 The interface information includes interface name, interface type, hardware
669 address and route table information.
671 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
672 @param[in] HiiHandle The handle that was previously registered in the
674 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.
676 @retval EFI_SUCCESS The operation finished successfully.
677 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
678 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
682 Ip6ConvertInterfaceInfoToString (
683 IN EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
,
684 IN EFI_HII_HANDLE HiiHandle
,
685 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
691 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
692 CHAR16 FormatString
[8];
693 EFI_STRING_ID StringId
;
695 if ((IfInfo
== NULL
) || (HiiHandle
== NULL
) || (IfrNvData
== NULL
)) {
696 return EFI_INVALID_PARAMETER
;
700 // Print the interface name.
702 StringId
= HiiSetString (
704 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT
),
709 return EFI_OUT_OF_RESOURCES
;
713 // Print the interface type.
715 if (IfInfo
->IfType
== Ip6InterfaceTypeEthernet
) {
716 CopyMem (PortString
, IP6_ETHERNET
, sizeof (IP6_ETHERNET
));
717 } else if (IfInfo
->IfType
== Ip6InterfaceTypeExperimentalEthernet
) {
718 CopyMem (PortString
, IP6_EXPERIMENTAL_ETHERNET
, sizeof (IP6_EXPERIMENTAL_ETHERNET
));
721 // Refer to RFC1700, chapter Number Hardware Type.
723 UnicodeSPrint (PortString
, 6, L
"%d", IfInfo
->IfType
);
726 StringId
= HiiSetString (
728 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT
),
733 return EFI_OUT_OF_RESOURCES
;
737 // Convert the hardware address.
740 ASSERT (IfInfo
->HwAddressSize
<= 32);
742 for (Index
= 0; Index
< IfInfo
->HwAddressSize
; Index
++) {
743 if (IfInfo
->HwAddress
.Addr
[Index
] < 0x10) {
744 CopyMem (FormatString
, L
"0%x-", sizeof (L
"0%x-"));
746 CopyMem (FormatString
, L
"%x-", sizeof (L
"%x-"));
749 Number
= UnicodeSPrint (
752 (CONST CHAR16
*)FormatString
,
753 (UINTN
)IfInfo
->HwAddress
.Addr
[Index
]
755 String
= String
+ Number
;
759 ASSERT (String
> PortString
);
765 // Print the hardware address.
767 StringId
= HiiSetString (
769 STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT
),
774 return EFI_OUT_OF_RESOURCES
;
781 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.
783 @param[in] Instance Points to IP6 config instance data.
784 @param[in] AddressType The address type.
785 @param[out] AddressInfo The pointer to the buffer to store the address list.
786 @param[out] AddressSize The address size of the address list.
788 @retval EFI_SUCCESS The operation finished successfully.
789 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
790 @retval EFI_UNSUPPORTED The AddressType is not supported.
794 Ip6BuildNvAddressInfo (
795 IN IP6_CONFIG_INSTANCE
*Instance
,
796 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
797 OUT VOID
**AddressInfo
,
798 OUT UINTN
*AddressSize
801 IP6_CONFIG_NVDATA
*Ip6NvData
;
803 LIST_ENTRY
*ListHead
;
804 IP6_ADDRESS_INFO_ENTRY
*Node
;
808 EFI_IPv6_ADDRESS
*Ip6Address
;
809 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
811 if ((Instance
== NULL
) || (AddressInfo
== NULL
) || (AddressSize
== NULL
)) {
812 return EFI_INVALID_PARAMETER
;
815 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
817 Ip6NvData
= &Instance
->Ip6NvData
;
819 if (AddressType
== Ip6ConfigNvHostAddress
) {
820 ListHead
= &Ip6NvData
->ManualAddress
;
821 DataSize
= sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
) * Ip6NvData
->ManualAddressCount
;
822 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
823 ListHead
= &Ip6NvData
->GatewayAddress
;
824 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->GatewayAddressCount
;
825 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
826 ListHead
= &Ip6NvData
->DnsAddress
;
827 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->DnsAddressCount
;
829 return EFI_UNSUPPORTED
;
832 AddressList
= AllocateZeroPool (DataSize
);
833 if (AddressList
== NULL
) {
834 return EFI_OUT_OF_RESOURCES
;
837 TmpStr
= AddressList
;
839 NET_LIST_FOR_EACH (Entry
, ListHead
) {
840 Node
= NET_LIST_USER_STRUCT (Entry
, IP6_ADDRESS_INFO_ENTRY
, Link
);
841 if (AddressType
== Ip6ConfigNvHostAddress
) {
842 ManualAddress
= (EFI_IP6_CONFIG_MANUAL_ADDRESS
*)AddressList
;
843 IP6_COPY_ADDRESS (&ManualAddress
->Address
, &Node
->AddrInfo
.Address
);
844 ManualAddress
->PrefixLength
= Node
->AddrInfo
.PrefixLength
;
845 AddressList
= (UINT8
*)AddressList
+ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
);
847 Ip6Address
= (EFI_IPv6_ADDRESS
*)AddressList
;
848 IP6_COPY_ADDRESS (Ip6Address
, &Node
->AddrInfo
.Address
);
849 AddressList
= (UINT8
*)AddressList
+ sizeof (EFI_IPv6_ADDRESS
);
853 *AddressInfo
= TmpStr
;
854 *AddressSize
= DataSize
;
859 Convert the IP6 configuration data into the IFR data.
861 @param[in, out] IfrNvData The IFR NV data.
862 @param[in] Instance The IP6 config instance data.
864 @retval EFI_SUCCESS The operation finished successfully.
865 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
866 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.
867 @retval Others Other errors as indicated.
871 Ip6ConvertConfigNvDataToIfrNvData (
872 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
873 IN IP6_CONFIG_INSTANCE
*Instance
876 IP6_CONFIG_NVDATA
*Ip6NvData
;
877 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
881 EFI_IP6_CONFIG_POLICY Policy
;
882 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits
;
883 EFI_HII_HANDLE HiiHandle
;
885 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
886 return EFI_INVALID_PARAMETER
;
889 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
891 Ip6Config
= &Instance
->Ip6Config
;
892 Ip6NvData
= &Instance
->Ip6NvData
;
895 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
898 // Get the current interface info.
900 Status
= Ip6ConfigNvGetData (
902 Ip6ConfigDataTypeInterfaceInfo
,
906 if (EFI_ERROR (Status
)) {
911 // Convert the interface info to string and print.
913 Status
= Ip6ConvertInterfaceInfoToString (
914 (EFI_IP6_CONFIG_INTERFACE_INFO
*)Data
,
918 if (EFI_ERROR (Status
)) {
923 // Get the interface id.
925 DataSize
= sizeof (EFI_IP6_CONFIG_INTERFACE_ID
);
926 ZeroMem (&Ip6NvData
->InterfaceId
, DataSize
);
927 Status
= Ip6Config
->GetData (
929 Ip6ConfigDataTypeAltInterfaceId
,
931 &Ip6NvData
->InterfaceId
933 if (EFI_ERROR (Status
)) {
937 Ip6ConvertInterfaceIdToString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
940 // Get current policy.
942 DataSize
= sizeof (EFI_IP6_CONFIG_POLICY
);
943 Status
= Ip6Config
->GetData (
945 Ip6ConfigDataTypePolicy
,
950 if (EFI_ERROR (Status
)) {
954 if (Policy
== Ip6ConfigPolicyManual
) {
955 IfrNvData
->Policy
= IP6_POLICY_MANUAL
;
956 } else if (Policy
== Ip6ConfigPolicyAutomatic
) {
957 IfrNvData
->Policy
= IP6_POLICY_AUTO
;
960 Status
= EFI_UNSUPPORTED
;
965 // Get Duplicate Address Detection Transmits count.
967 DataSize
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
968 Status
= Ip6Config
->GetData (
970 Ip6ConfigDataTypeDupAddrDetectTransmits
,
975 if (EFI_ERROR (Status
)) {
979 IfrNvData
->DadTransmitCount
= DadXmits
.DupAddrDetectTransmits
;
990 Convert IFR data into IP6 configuration data. The policy, alternative interface
991 ID, and DAD transmit counts, and will be saved.
993 @param[in] IfrNvData The IFR NV data.
994 @param[in, out] Instance The IP6 config instance data.
996 @retval EFI_SUCCESS The operation finished successfully.
997 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
998 @retval Others Other errors as indicated.
1002 Ip6ConvertIfrNvDataToConfigNvDataGeneral (
1003 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1004 IN OUT IP6_CONFIG_INSTANCE
*Instance
1007 IP6_CONFIG_NVDATA
*Ip6NvData
;
1008 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1011 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1012 return EFI_INVALID_PARAMETER
;
1015 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1016 Ip6NvData
= &Instance
->Ip6NvData
;
1017 Ip6Config
= &Instance
->Ip6Config
;
1020 // Update those fields which don't have INTERACTIVE attribute.
1022 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1023 Ip6NvData
->Policy
= Ip6ConfigPolicyAutomatic
;
1024 } else if (IfrNvData
->Policy
== IP6_POLICY_MANUAL
) {
1025 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1028 Ip6NvData
->DadTransmitCount
.DupAddrDetectTransmits
= IfrNvData
->DadTransmitCount
;
1031 // Set the configured policy.
1033 Status
= Ip6Config
->SetData (
1035 Ip6ConfigDataTypePolicy
,
1036 sizeof (EFI_IP6_CONFIG_POLICY
),
1039 if (EFI_ERROR (Status
)) {
1044 // Set the duplicate address detection transmits count.
1046 Status
= Ip6Config
->SetData (
1048 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1049 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
),
1050 &Ip6NvData
->DadTransmitCount
1052 if (EFI_ERROR (Status
)) {
1057 // Set the alternative interface ID
1059 Status
= Ip6Config
->SetData (
1061 Ip6ConfigDataTypeAltInterfaceId
,
1062 sizeof (EFI_IP6_CONFIG_INTERFACE_ID
),
1063 &Ip6NvData
->InterfaceId
1065 if (EFI_ERROR (Status
)) {
1073 Convert IFR data into IP6 configuration data. The policy, configured
1074 manual address, gateway address, and DNS server address will be saved.
1076 @param[in] IfrNvData The IFR NV data.
1077 @param[in, out] Instance The IP6 config instance data.
1079 @retval EFI_SUCCESS The operation finished successfully.
1080 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1081 @retval Others Other errors as indicated.
1085 Ip6ConvertIfrNvDataToConfigNvDataAdvanced (
1086 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1087 IN OUT IP6_CONFIG_INSTANCE
*Instance
1090 IP6_CONFIG_NVDATA
*Ip6NvData
;
1091 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1093 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
1094 EFI_IPv6_ADDRESS
*Address
;
1095 BOOLEAN IsAddressOk
;
1096 EFI_EVENT SetAddressEvent
;
1097 EFI_EVENT TimeoutEvent
;
1100 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1101 return EFI_INVALID_PARAMETER
;
1104 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1108 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1109 Ip6NvData
= &Instance
->Ip6NvData
;
1110 Ip6Config
= &Instance
->Ip6Config
;
1113 // Update those fields which don't have INTERACTIVE attribute.
1115 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1118 // Set the configured policy.
1120 Status
= Ip6Config
->SetData (
1122 Ip6ConfigDataTypePolicy
,
1123 sizeof (EFI_IP6_CONFIG_POLICY
),
1126 if (EFI_ERROR (Status
)) {
1131 // Create events & timers for asynchronous settings.
1133 SetAddressEvent
= NULL
;
1134 TimeoutEvent
= NULL
;
1135 ManualAddress
= NULL
;
1138 Status
= gBS
->CreateEvent (
1141 Ip6ConfigManualAddressNotify
,
1145 if (EFI_ERROR (Status
)) {
1149 Status
= gBS
->CreateEvent (
1156 if (EFI_ERROR (Status
)) {
1161 // Set the manual address list. This is an asynchronous process.
1163 if (!IsListEmpty (&Ip6NvData
->ManualAddress
) && (Ip6NvData
->ManualAddressCount
!= 0)) {
1164 Status
= Ip6BuildNvAddressInfo (
1166 Ip6ConfigNvHostAddress
,
1167 (VOID
**)&ManualAddress
,
1170 if (EFI_ERROR (Status
)) {
1174 IsAddressOk
= FALSE
;
1176 Status
= Ip6Config
->RegisterDataNotify (
1178 Ip6ConfigDataTypeManualAddress
,
1181 if (EFI_ERROR (Status
)) {
1185 Status
= Ip6Config
->SetData (
1187 Ip6ConfigDataTypeManualAddress
,
1189 (VOID
*)ManualAddress
1191 if (Status
== EFI_NOT_READY
) {
1192 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
1193 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
1195 Status
= EFI_SUCCESS
;
1202 Status
= Ip6Config
->UnregisterDataNotify (
1204 Ip6ConfigDataTypeManualAddress
,
1207 if (EFI_ERROR (Status
)) {
1213 // Set gateway address list.
1215 if (!IsListEmpty (&Ip6NvData
->GatewayAddress
) && (Ip6NvData
->GatewayAddressCount
!= 0)) {
1216 Status
= Ip6BuildNvAddressInfo (
1218 Ip6ConfigNvGatewayAddress
,
1222 if (EFI_ERROR (Status
)) {
1226 Status
= Ip6Config
->SetData (
1228 Ip6ConfigDataTypeGateway
,
1232 if (EFI_ERROR (Status
)) {
1241 // Set DNS server address list.
1243 if (!IsListEmpty (&Ip6NvData
->DnsAddress
) && (Ip6NvData
->DnsAddressCount
!= 0)) {
1244 Status
= Ip6BuildNvAddressInfo (
1246 Ip6ConfigNvDnsAddress
,
1250 if (EFI_ERROR (Status
)) {
1254 Status
= Ip6Config
->SetData (
1256 Ip6ConfigDataTypeDnsServer
,
1260 if (EFI_ERROR (Status
)) {
1265 Status
= EFI_SUCCESS
;
1268 if (SetAddressEvent
!= NULL
) {
1269 gBS
->CloseEvent (SetAddressEvent
);
1272 if (TimeoutEvent
!= NULL
) {
1273 gBS
->CloseEvent (TimeoutEvent
);
1276 if (ManualAddress
!= NULL
) {
1277 FreePool (ManualAddress
);
1280 if (Address
!= NULL
) {
1288 This function allows the caller to request the current
1289 configuration for one or more named elements. The resulting
1290 string is in <ConfigAltResp> format. Any and all alternative
1291 configuration strings shall also be appended to the end of the
1292 current configuration string. If they are, they must appear
1293 after the current configuration. They must contain the same
1294 routing (GUID, NAME, PATH) as the current configuration string.
1295 They must have an additional description indicating the type of
1296 alternative configuration the string represents,
1297 "ALTCFG=<StringToken>". That <StringToken> (when
1298 converted from Hex UNICODE to binary) is a reference to a
1299 string in the associated string pack.
1301 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1302 @param[in] Request A null-terminated Unicode string in
1303 <ConfigRequest> format. Note that this
1304 includes the routing information as well as
1305 the configurable name / value pairs. It is
1306 invalid for this string to be in
1307 <MultiConfigRequest> format.
1308 @param[out] Progress On return, points to a character in the
1309 Request string. Points to the string's null
1310 terminator if request was successful. Points
1311 to the most recent "&" before the first
1312 failing name / value pair (or the beginning
1313 of the string if the failure is in the first
1314 name / value pair) if the request was not
1316 @param[out] Results A null-terminated Unicode string in
1317 <ConfigAltResp> format which has all values
1318 filled in for the names in the Request string.
1319 String to be allocated by the called function.
1321 @retval EFI_SUCCESS The Results string is filled with the
1322 values corresponding to all requested
1324 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1325 parts of the results that must be
1326 stored awaiting possible future
1328 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
1329 for the Request parameter
1330 would result in this type of
1331 error. In this case, the
1332 Progress parameter would be
1334 @retval EFI_NOT_FOUND Routing data doesn't match any
1335 known driver. Progress set to the
1336 first character in the routing header.
1337 Note: There is no requirement that the
1338 driver validate the routing data. It
1339 must skip the <ConfigHdr> in order to
1341 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1342 to most recent & before the
1343 error or the beginning of the
1345 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1346 to the & before the name in
1347 question. Currently not implemented.
1351 Ip6FormExtractConfig (
1352 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1353 IN CONST EFI_STRING Request
,
1354 OUT EFI_STRING
*Progress
,
1355 OUT EFI_STRING
*Results
1359 IP6_FORM_CALLBACK_INFO
*Private
;
1360 IP6_CONFIG_INSTANCE
*Ip6ConfigInstance
;
1361 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1362 EFI_STRING ConfigRequestHdr
;
1363 EFI_STRING ConfigRequest
;
1364 BOOLEAN AllocatedRequest
;
1368 if ((This
== NULL
) || (Progress
== NULL
) || (Results
== NULL
)) {
1369 return EFI_INVALID_PARAMETER
;
1372 *Progress
= Request
;
1373 if ((Request
!= NULL
) &&
1374 !HiiIsConfigHdrMatch (Request
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
))
1376 return EFI_NOT_FOUND
;
1379 ConfigRequestHdr
= NULL
;
1380 ConfigRequest
= NULL
;
1381 AllocatedRequest
= FALSE
;
1384 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1385 Ip6ConfigInstance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1386 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1388 IfrNvData
= (IP6_CONFIG_IFR_NVDATA
*)AllocateZeroPool (BufferSize
);
1389 if (IfrNvData
== NULL
) {
1390 return EFI_OUT_OF_RESOURCES
;
1393 Status
= Ip6ConvertConfigNvDataToIfrNvData (IfrNvData
, Ip6ConfigInstance
);
1394 if (EFI_ERROR (Status
)) {
1398 ConfigRequest
= Request
;
1399 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1401 // Request has no request element, construct full request string.
1402 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1403 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
1405 ConfigRequestHdr
= HiiConstructConfigHdr (
1406 &gIp6ConfigNvDataGuid
,
1407 mIp6ConfigStorageName
,
1408 Private
->ChildHandle
1410 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
1411 ConfigRequest
= AllocateZeroPool (Size
);
1412 ASSERT (ConfigRequest
!= NULL
);
1413 AllocatedRequest
= TRUE
;
1417 L
"%s&OFFSET=0&WIDTH=%016LX",
1421 FreePool (ConfigRequestHdr
);
1425 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1427 Status
= gHiiConfigRouting
->BlockToConfig (
1437 FreePool (IfrNvData
);
1439 // Free the allocated config request string.
1441 if (AllocatedRequest
) {
1442 FreePool (ConfigRequest
);
1443 ConfigRequest
= NULL
;
1447 // Set Progress string to the original request string.
1449 if (Request
== NULL
) {
1451 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1452 *Progress
= Request
+ StrLen (Request
);
1459 This function applies changes in a driver's configuration.
1460 Input is a Configuration, which has the routing data for this
1461 driver followed by name / value configuration pairs. The driver
1462 must apply those pairs to its configurable storage. If the
1463 driver's configuration is stored in a linear block of data
1464 and the driver's name / value pairs are in <BlockConfig>
1465 format, it may use the ConfigToBlock helper function (above) to
1466 simplify the job. Currently not implemented.
1468 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1469 @param[in] Configuration A null-terminated Unicode string in
1470 <ConfigString> format.
1471 @param[out] Progress A pointer to a string filled in with the
1472 offset of the most recent '&' before the
1473 first failing name / value pair (or the
1474 beginning of the string if the failure
1475 is in the first name / value pair) or
1476 the terminating NULL if all was
1479 @retval EFI_SUCCESS The results have been distributed or are
1480 awaiting distribution.
1481 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1482 parts of the results that must be
1483 stored awaiting possible future
1485 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1486 Results parameter would result
1487 in this type of error.
1488 @retval EFI_NOT_FOUND Target for the specified routing data
1493 Ip6FormRouteConfig (
1494 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1495 IN CONST EFI_STRING Configuration
,
1496 OUT EFI_STRING
*Progress
1499 if ((This
== NULL
) || (Configuration
== NULL
) || (Progress
== NULL
)) {
1500 return EFI_INVALID_PARAMETER
;
1504 // Check routing data in <ConfigHdr>.
1505 // Note: if only one Storage is used, then this checking could be skipped.
1507 if (!HiiIsConfigHdrMatch (Configuration
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1508 *Progress
= Configuration
;
1509 return EFI_NOT_FOUND
;
1512 *Progress
= Configuration
+ StrLen (Configuration
);
1518 Display host addresses, route table, DNS addresses and gateway addresses in
1519 "IPv6 Current Setting" page.
1521 @param[in] Instance The IP6 config instance data.
1523 @retval EFI_SUCCESS The operation finished successfully.
1524 @retval Others Other errors as indicated.
1528 Ip6GetCurrentSetting (
1529 IN IP6_CONFIG_INSTANCE
*Instance
1532 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1533 EFI_HII_HANDLE HiiHandle
;
1534 EFI_IP6_CONFIG_INTERFACE_INFO
*Data
;
1537 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
1538 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
1540 Ip6Config
= &Instance
->Ip6Config
;
1541 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
1545 // Get current interface info.
1547 Status
= Ip6ConfigNvGetData (
1549 Ip6ConfigDataTypeInterfaceInfo
,
1553 if (EFI_ERROR (Status
)) {
1558 // Generate dynamic text opcode for host address and draw it.
1560 IfInfo
= (EFI_IP6_CONFIG_INTERFACE_INFO
*)Data
;
1561 Status
= Ip6ConvertAddressListToString (
1564 Ip6ConfigNvHostAddress
,
1565 IfInfo
->AddressInfo
,
1566 IfInfo
->AddressInfoCount
1568 if (EFI_ERROR (Status
)) {
1574 // Generate the dynamic text opcode for route table and draw it.
1576 Status
= Ip6ConvertAddressListToString (
1579 Ip6ConfigNvRouteTable
,
1583 if (EFI_ERROR (Status
)) {
1589 // Get DNS server list.
1594 Status
= Ip6ConfigNvGetData (
1596 Ip6ConfigDataTypeDnsServer
,
1600 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1610 // Generate the dynamic text opcode for DNS server and draw it.
1612 Status
= Ip6ConvertAddressListToString (
1615 Ip6ConfigNvDnsAddress
,
1617 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1619 if (EFI_ERROR (Status
)) {
1626 // Get gateway address list.
1634 Status
= Ip6ConfigNvGetData (
1636 Ip6ConfigDataTypeGateway
,
1640 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1650 // Generate the dynamic text opcode for gateway and draw it.
1652 Status
= Ip6ConvertAddressListToString (
1655 Ip6ConfigNvGatewayAddress
,
1657 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1659 if (EFI_ERROR (Status
)) {
1673 This function is called to provide results data to the driver.
1674 This data consists of a unique key that is used to identify
1675 which data is either being passed back or being asked for.
1677 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1678 @param[in] Action Specifies the type of action taken by the browser.
1679 @param[in] QuestionId A unique value which is sent to the original
1680 exporting driver so that it can identify the type
1681 of data to expect. The format of the data tends to
1682 vary based on the opcode that generated the callback.
1683 @param[in] Type The type of value for the question.
1684 @param[in] Value A pointer to the data being sent to the original
1686 @param[out] ActionRequest On return, points to the action requested by the
1689 @retval EFI_SUCCESS The callback successfully handled the action.
1690 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1691 variable and its data.
1692 @retval EFI_DEVICE_ERROR The variable could not be saved.
1693 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1694 callback. Currently not implemented.
1695 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.
1696 @retval Others Other errors as indicated.
1702 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1703 IN EFI_BROWSER_ACTION Action
,
1704 IN EFI_QUESTION_ID QuestionId
,
1706 IN EFI_IFR_TYPE_VALUE
*Value
,
1707 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1710 IP6_FORM_CALLBACK_INFO
*Private
;
1712 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1715 IP6_CONFIG_INSTANCE
*Instance
;
1716 IP6_CONFIG_NVDATA
*Ip6NvData
;
1719 return EFI_INVALID_PARAMETER
;
1722 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1723 Instance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1724 Ip6NvData
= &Instance
->Ip6NvData
;
1726 if ((Action
== EFI_BROWSER_ACTION_FORM_OPEN
) || (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
)) {
1730 if ((Action
!= EFI_BROWSER_ACTION_CHANGING
) && (Action
!= EFI_BROWSER_ACTION_CHANGED
)) {
1731 return EFI_UNSUPPORTED
;
1734 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1735 return EFI_INVALID_PARAMETER
;
1739 // Retrieve uncommitted data from Browser
1742 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1743 IfrNvData
= AllocateZeroPool (BufferSize
);
1744 if (IfrNvData
== NULL
) {
1745 return EFI_OUT_OF_RESOURCES
;
1748 Status
= EFI_SUCCESS
;
1750 HiiGetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*)IfrNvData
);
1752 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1753 switch (QuestionId
) {
1754 case KEY_GET_CURRENT_SETTING
:
1755 Status
= Ip6GetCurrentSetting (Instance
);
1761 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1762 switch (QuestionId
) {
1763 case KEY_SAVE_CONFIG_CHANGES
:
1764 Status
= Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData
, Instance
);
1765 if (EFI_ERROR (Status
)) {
1769 Status
= Ip6GetCurrentSetting (Instance
);
1771 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1774 case KEY_IGNORE_CONFIG_CHANGES
:
1775 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
1776 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
1777 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
1779 Ip6NvData
->ManualAddressCount
= 0;
1780 Ip6NvData
->GatewayAddressCount
= 0;
1781 Ip6NvData
->DnsAddressCount
= 0;
1783 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1786 case KEY_SAVE_CHANGES
:
1787 Status
= Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData
, Instance
);
1788 if (EFI_ERROR (Status
)) {
1792 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1795 case KEY_INTERFACE_ID
:
1796 Status
= Ip6ParseInterfaceIdFromString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
1797 if (EFI_ERROR (Status
)) {
1799 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1801 L
"Invalid Interface ID!",
1808 case KEY_MANUAL_ADDRESS
:
1809 Status
= Ip6ParseAddressListFromString (
1810 IfrNvData
->ManualAddress
,
1811 &Ip6NvData
->ManualAddress
,
1812 &Ip6NvData
->ManualAddressCount
1814 if (EFI_ERROR (Status
)) {
1816 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1818 L
"Invalid Host Addresses!",
1825 case KEY_GATEWAY_ADDRESS
:
1826 Status
= Ip6ParseAddressListFromString (
1827 IfrNvData
->GatewayAddress
,
1828 &Ip6NvData
->GatewayAddress
,
1829 &Ip6NvData
->GatewayAddressCount
1831 if (EFI_ERROR (Status
)) {
1833 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1835 L
"Invalid Gateway Addresses!",
1842 case KEY_DNS_ADDRESS
:
1843 Status
= Ip6ParseAddressListFromString (
1844 IfrNvData
->DnsAddress
,
1845 &Ip6NvData
->DnsAddress
,
1846 &Ip6NvData
->DnsAddressCount
1848 if (EFI_ERROR (Status
)) {
1850 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1852 L
"Invalid DNS Addresses!",
1864 if (!EFI_ERROR (Status
)) {
1866 // Pass changed uncommitted data back to Form Browser.
1868 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1869 HiiSetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*)IfrNvData
, NULL
);
1872 FreePool (IfrNvData
);
1877 Install HII Config Access protocol for network device and allocate resources.
1879 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.
1881 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1882 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1883 @retval Others Other errors as indicated.
1888 IN OUT IP6_CONFIG_INSTANCE
*Instance
1893 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
1894 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1895 VENDOR_DEVICE_PATH VendorDeviceNode
;
1896 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1898 CHAR16 MenuString
[128];
1899 CHAR16 PortString
[128];
1900 CHAR16
*OldMenuString
;
1901 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1903 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
1904 ASSERT (IpSb
!= NULL
);
1906 Status
= gBS
->HandleProtocol (
1908 &gEfiDevicePathProtocolGuid
,
1909 (VOID
**)&ParentDevicePath
1911 if (EFI_ERROR (Status
)) {
1915 CallbackInfo
= &Instance
->CallbackInfo
;
1916 CallbackInfo
->Signature
= IP6_FORM_CALLBACK_INFO_SIGNATURE
;
1919 // Construct device path node for EFI HII Config Access protocol,
1920 // which consists of controller physical device path and one hardware
1921 // vendor guid node.
1923 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1924 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1925 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1927 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1929 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1930 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1932 (EFI_DEVICE_PATH_PROTOCOL
*)&VendorDeviceNode
1934 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1935 Status
= EFI_OUT_OF_RESOURCES
;
1939 ConfigAccess
= &CallbackInfo
->HiiConfigAccess
;
1940 ConfigAccess
->ExtractConfig
= Ip6FormExtractConfig
;
1941 ConfigAccess
->RouteConfig
= Ip6FormRouteConfig
;
1942 ConfigAccess
->Callback
= Ip6FormCallback
;
1945 // Install Device Path Protocol and Config Access protocol on new handle
1947 Status
= gBS
->InstallMultipleProtocolInterfaces (
1948 &CallbackInfo
->ChildHandle
,
1949 &gEfiDevicePathProtocolGuid
,
1950 CallbackInfo
->HiiVendorDevicePath
,
1951 &gEfiHiiConfigAccessProtocolGuid
,
1955 if (!EFI_ERROR (Status
)) {
1957 // Open the Parent Handle for the child
1959 Status
= gBS
->OpenProtocol (
1961 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1964 CallbackInfo
->ChildHandle
,
1965 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1969 if (EFI_ERROR (Status
)) {
1974 // Publish our HII data
1976 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1977 &gIp6ConfigNvDataGuid
,
1978 CallbackInfo
->ChildHandle
,
1983 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1984 Status
= EFI_OUT_OF_RESOURCES
;
1989 // Append MAC string in the menu help string and tile help string
1991 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1992 if (!EFI_ERROR (Status
)) {
1993 OldMenuString
= HiiGetString (
1994 CallbackInfo
->RegisteredHandle
,
1995 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
1999 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
2001 CallbackInfo
->RegisteredHandle
,
2002 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2006 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
2008 CallbackInfo
->RegisteredHandle
,
2009 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP
),
2014 FreePool (MacString
);
2015 FreePool (OldMenuString
);
2017 InitializeListHead (&Instance
->Ip6NvData
.ManualAddress
);
2018 InitializeListHead (&Instance
->Ip6NvData
.GatewayAddress
);
2019 InitializeListHead (&Instance
->Ip6NvData
.DnsAddress
);
2025 Ip6ConfigFormUnload (Instance
);
2030 Uninstall the HII Config Access protocol for network devices and free up the resources.
2032 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.
2036 Ip6ConfigFormUnload (
2037 IN OUT IP6_CONFIG_INSTANCE
*Instance
2041 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
2042 IP6_CONFIG_NVDATA
*Ip6NvData
;
2044 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
2045 ASSERT (IpSb
!= NULL
);
2047 CallbackInfo
= &Instance
->CallbackInfo
;
2049 if (CallbackInfo
->ChildHandle
!= NULL
) {
2051 // Close the child handle
2053 gBS
->CloseProtocol (
2055 &gEfiManagedNetworkServiceBindingProtocolGuid
,
2057 CallbackInfo
->ChildHandle
2060 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
2062 gBS
->UninstallMultipleProtocolInterfaces (
2063 CallbackInfo
->ChildHandle
,
2064 &gEfiDevicePathProtocolGuid
,
2065 CallbackInfo
->HiiVendorDevicePath
,
2066 &gEfiHiiConfigAccessProtocolGuid
,
2067 &CallbackInfo
->HiiConfigAccess
,
2072 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
2073 FreePool (CallbackInfo
->HiiVendorDevicePath
);
2076 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
2078 // Remove HII package list
2080 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
2083 Ip6NvData
= &Instance
->Ip6NvData
;
2085 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
2086 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
2087 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
2089 Ip6NvData
->ManualAddressCount
= 0;
2090 Ip6NvData
->GatewayAddressCount
= 0;
2091 Ip6NvData
->DnsAddressCount
= 0;