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
152 // Deal with the case of ::.
163 while ((Index
< 15) && (Ip6
->Addr
[Index
] == 0) && (Ip6
->Addr
[Index
+ 1] == 0)) {
171 // :: is at the end of the address.
180 if (Ip6
->Addr
[Index
] == 0) {
181 Number
= UnicodeSPrint (Str
, 2 * IP6_STR_MAX_SIZE
, L
"%x:", (UINTN
) Ip6
->Addr
[Index
+ 1]);
183 if (Ip6
->Addr
[Index
+ 1] < 0x10) {
184 CopyMem (FormatString
, L
"%x0%x:", StrSize (L
"%x0%x:"));
186 CopyMem (FormatString
, L
"%x%x:", StrSize (L
"%x%x:"));
189 Number
= UnicodeSPrint (
191 2 * IP6_STR_MAX_SIZE
,
192 (CONST CHAR16
*) FormatString
,
193 (UINTN
) Ip6
->Addr
[Index
],
194 (UINTN
) Ip6
->Addr
[Index
+ 1]
200 if (Index
+ 2 == 16) {
202 if (*(Str
- 1) == L
':') {
210 Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.
212 @param[out] String The buffer to store the converted string.
213 @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
215 @retval EFI_SUCCESS The string converted successfully.
216 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
220 Ip6ConvertInterfaceIdToString (
222 IN EFI_IP6_CONFIG_INTERFACE_ID
*IfId
228 if ((String
== NULL
) || (IfId
== NULL
)) {
229 return EFI_INVALID_PARAMETER
;
232 for (Index
= 0; Index
< 8; Index
++) {
233 Number
= UnicodeSPrint (
235 2 * INTERFACE_ID_STR_STORAGE
,
237 (UINTN
) IfId
->Id
[Index
]
239 String
= String
+ Number
;
242 *(String
- 1) = '\0';
248 Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.
250 @param[in] String The buffer of the string to be parsed.
251 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
253 @retval EFI_SUCCESS The operation finished successfully.
254 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
258 Ip6ParseInterfaceIdFromString (
259 IN CONST CHAR16
*String
,
260 OUT EFI_IP6_CONFIG_INTERFACE_ID
*IfId
268 if ((String
== NULL
) || (IfId
== NULL
)) {
269 return EFI_INVALID_PARAMETER
;
272 IfIdStr
= (CHAR16
*) String
;
274 ZeroMem (IfId
, sizeof (EFI_IP6_CONFIG_INTERFACE_ID
));
276 for (Index
= 0; Index
< 8; Index
++) {
279 while ((*IfIdStr
!= L
'\0') && (*IfIdStr
!= L
':')) {
284 // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.
285 // If the number of X is less than 8, zero is appended to the InterfaceId.
287 if ((*IfIdStr
== ':') && (Index
== 7)) {
288 return EFI_INVALID_PARAMETER
;
292 // Convert the string to interface id. AsciiStrHexToUintn stops at the
293 // first character that is not a valid hex character, ':' or '\0' here.
295 NodeVal
= StrHexToUintn (TempStr
);
296 if (NodeVal
> 0xFF) {
297 return EFI_INVALID_PARAMETER
;
300 IfId
->Id
[Index
] = (UINT8
) NodeVal
;
309 Create Hii Extend Label OpCode as the start opcode and end opcode. It is
312 @param[in] StartLabelNumber The number of start label.
313 @param[out] StartOpCodeHandle Points to the start opcode handle.
314 @param[out] StartLabel Points to the created start opcode.
315 @param[out] EndOpCodeHandle Points to the end opcode handle.
316 @param[out] EndLabel Points to the created end opcode.
318 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
320 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
321 @retval EFI_SUCCESS The operation completed successfully.
326 IN UINT16 StartLabelNumber
,
327 OUT VOID
**StartOpCodeHandle
,
328 OUT EFI_IFR_GUID_LABEL
**StartLabel
,
329 OUT VOID
**EndOpCodeHandle
,
330 OUT EFI_IFR_GUID_LABEL
**EndLabel
334 EFI_IFR_GUID_LABEL
*InternalStartLabel
;
335 EFI_IFR_GUID_LABEL
*InternalEndLabel
;
337 if (StartOpCodeHandle
== NULL
|| StartLabel
== NULL
|| EndOpCodeHandle
== NULL
|| EndLabel
== NULL
) {
338 return EFI_INVALID_PARAMETER
;
341 *StartOpCodeHandle
= NULL
;
342 *EndOpCodeHandle
= NULL
;
343 Status
= EFI_OUT_OF_RESOURCES
;
346 // Initialize the container for dynamic opcodes.
348 *StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
349 if (*StartOpCodeHandle
== NULL
) {
353 *EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
354 if (*EndOpCodeHandle
== NULL
) {
359 // Create Hii Extend Label OpCode as the start opcode.
361 InternalStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
365 sizeof (EFI_IFR_GUID_LABEL
)
367 if (InternalStartLabel
== NULL
) {
371 InternalStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
372 InternalStartLabel
->Number
= StartLabelNumber
;
375 // Create Hii Extend Label OpCode as the end opcode.
377 InternalEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
381 sizeof (EFI_IFR_GUID_LABEL
)
383 if (InternalEndLabel
== NULL
) {
387 InternalEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
388 InternalEndLabel
->Number
= LABEL_END
;
390 *StartLabel
= InternalStartLabel
;
391 *EndLabel
= InternalEndLabel
;
397 if (*StartOpCodeHandle
!= NULL
) {
398 HiiFreeOpCodeHandle (*StartOpCodeHandle
);
401 if (*EndOpCodeHandle
!= NULL
) {
402 HiiFreeOpCodeHandle (*EndOpCodeHandle
);
409 This function converts the different format of address list to string format and
410 then generates the corresponding text opcode to illustarate the address info in
411 IP6 configuration page. Currently, the following formats are supported:
412 EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;
413 EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;
414 EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable.
416 @param[in, out] String The pointer to the buffer to store the converted
418 @param[in] HiiHandle A handle that was previously registered in the
420 @param[in] AddressType The address type.
421 @param[in] AddressInfo Pointer to the address list.
422 @param[in] AddressCount The address count of the address list.
424 @retval EFI_SUCCESS The operation finished successfully.
425 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
426 @retval EFI_UNSUPPORTED The AddressType is not supported.
431 Ip6ConvertAddressListToString (
432 IN OUT CHAR16
*String
,
433 IN EFI_HII_HANDLE HiiHandle
,
434 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
435 IN VOID
*AddressInfo
,
436 IN UINTN AddressCount
443 VOID
*StartOpCodeHandle
;
444 EFI_IFR_GUID_LABEL
*StartLabel
;
445 VOID
*EndOpCodeHandle
;
446 EFI_IFR_GUID_LABEL
*EndLabel
;
447 UINT16 StartLabelNumber
;
448 EFI_STRING_ID TextTwo
;
451 EFI_IPv6_ADDRESS
*Address
;
453 if ((String
== NULL
) || (HiiHandle
== NULL
) || (AddressInfo
== NULL
)) {
454 return EFI_INVALID_PARAMETER
;
457 if (AddressType
== Ip6ConfigNvHostAddress
) {
458 StartLabelNumber
= HOST_ADDRESS_LABEL
;
459 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
460 StartLabelNumber
= GATEWAY_ADDRESS_LABEL
;
461 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
462 StartLabelNumber
= DNS_ADDRESS_LABEL
;
463 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
464 StartLabelNumber
= ROUTE_TABLE_LABEL
;
467 return EFI_UNSUPPORTED
;
470 Status
= Ip6CreateOpCode (
477 if (EFI_ERROR (Status
)) {
481 AddressHead
= (UINT8
*) AddressInfo
;
483 for (Index
= 0; Index
< AddressCount
; Index
++) {
484 if (AddressType
== Ip6ConfigNvHostAddress
) {
485 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ADDRESS_INFO
) * Index
;
486 Address
= &((EFI_IP6_ADDRESS_INFO
*) AddressInfo
)->Address
;
487 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
488 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ROUTE_TABLE
) * Index
;
489 Address
= &((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->Destination
;
491 AddressInfo
= AddressHead
+ sizeof (EFI_IPv6_ADDRESS
) * Index
;
492 Address
= AddressInfo
;
496 // Convert the IP address info to string.
498 Ip6ToStr (Address
, String
);
499 TempStr
= String
+ StrLen (String
);
501 if ((AddressType
== Ip6ConfigNvHostAddress
) || (AddressType
== Ip6ConfigNvRouteTable
)) {
502 if (AddressType
== Ip6ConfigNvHostAddress
) {
503 PrefixLength
= ((EFI_IP6_ADDRESS_INFO
*) AddressInfo
)->PrefixLength
;
505 PrefixLength
= ((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->PrefixLength
;
509 // Append the prefix length to the string.
513 Number
= UnicodeSPrint (TempStr
, 6, L
"%d", PrefixLength
);
514 TempStr
= TempStr
+ Number
;
517 if (AddressType
== Ip6ConfigNvRouteTable
) {
519 // Append " >> " to the string.
521 Number
= UnicodeSPrint (TempStr
, 8, L
" >> ");
522 TempStr
= TempStr
+ Number
;
525 // Append the gateway address to the string.
527 Ip6ToStr (&((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->Gateway
, TempStr
);
528 TempStr
= TempStr
+ StrLen (TempStr
);
532 // Generate a text opcode and update the UI.
534 TextTwo
= HiiSetString (HiiHandle
, 0, String
, NULL
);
536 Status
= EFI_INVALID_PARAMETER
;
540 HiiCreateTextOpCode (StartOpCodeHandle
, STR_NULL
, STR_NULL
, TextTwo
);
543 *String
= IP6_ADDRESS_DELIMITER
;
547 *(String
- 1) = '\0';
549 Status
= HiiUpdateForm (
550 HiiHandle
, // HII handle
551 &gIp6ConfigNvDataGuid
, // Formset GUID
552 FORMID_MAIN_FORM
, // Form ID
553 StartOpCodeHandle
, // Label for where to insert opcodes
554 EndOpCodeHandle
// Replace data
558 HiiFreeOpCodeHandle (StartOpCodeHandle
);
559 HiiFreeOpCodeHandle (EndOpCodeHandle
);
565 Parse address list in string format and convert it to a list array of node in
566 IP6_ADDRESS_INFO_ENTRY.
568 @param[in] String The buffer to string to be parsed.
569 @param[out] ListHead The list head of array.
570 @param[out] AddressCount The number of list nodes in the array.
572 @retval EFI_SUCCESS The operation finished successfully.
573 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
574 @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource.
578 Ip6ParseAddressListFromString (
579 IN CONST CHAR16
*String
,
580 OUT LIST_ENTRY
*ListHead
,
581 OUT UINT32
*AddressCount
588 EFI_IP6_ADDRESS_INFO AddressInfo
;
589 IP6_ADDRESS_INFO_ENTRY
*Node
;
593 if ((String
== NULL
) || (ListHead
== NULL
) || (AddressCount
== NULL
)) {
594 return EFI_INVALID_PARAMETER
;
597 ZeroMem (&AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
598 LocalString
= (CHAR16
*) AllocateCopyPool (StrSize (String
), String
);
599 if (LocalString
== NULL
) {
600 return EFI_OUT_OF_RESOURCES
;
604 // Clean the original address list.
606 Ip6FreeAddressInfoList (ListHead
);
612 while (*LocalString
!= L
'\0') {
613 TempStr
= LocalString
;
614 while ((*LocalString
!= L
'\0') && (*LocalString
!= IP6_ADDRESS_DELIMITER
)) {
618 if (*LocalString
== L
'\0') {
622 *LocalString
= L
'\0';
624 Status
= NetLibStrToIp6andPrefix (TempStr
, &AddressInfo
.Address
, &AddressInfo
.PrefixLength
);
625 if (EFI_ERROR (Status
)) {
629 if (AddressInfo
.PrefixLength
== 0xFF) {
630 AddressInfo
.PrefixLength
= 0;
633 if (!NetIp6IsValidUnicast (&AddressInfo
.Address
)) {
634 Status
= EFI_INVALID_PARAMETER
;
638 Node
= AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY
));
640 Status
= EFI_OUT_OF_RESOURCES
;
644 CopyMem (&Node
->AddrInfo
, &AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
645 InsertTailList (ListHead
, &Node
->Link
);
656 *AddressCount
= Count
;
660 Ip6FreeAddressInfoList (ListHead
);
666 This function converts the interface info to string and draws it to the IP6 UI.
667 The interface information includes interface name, interface type, hardware
668 address and route table information.
670 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
671 @param[in] HiiHandle The handle that was previously registered in the
673 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.
675 @retval EFI_SUCCESS The operation finished successfully.
676 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
677 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
681 Ip6ConvertInterfaceInfoToString (
682 IN EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
,
683 IN EFI_HII_HANDLE HiiHandle
,
684 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
690 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
691 CHAR16 FormatString
[8];
692 EFI_STRING_ID StringId
;
694 if ((IfInfo
== NULL
) || (HiiHandle
== NULL
) || (IfrNvData
== NULL
)) {
695 return EFI_INVALID_PARAMETER
;
699 // Print the interface name.
701 StringId
= HiiSetString (
703 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT
),
708 return EFI_OUT_OF_RESOURCES
;
712 // Print the interface type.
714 if (IfInfo
->IfType
== Ip6InterfaceTypeEthernet
) {
715 CopyMem (PortString
, IP6_ETHERNET
, sizeof (IP6_ETHERNET
));
716 } else if (IfInfo
->IfType
== Ip6InterfaceTypeExperimentalEthernet
) {
717 CopyMem (PortString
, IP6_EXPERIMENTAL_ETHERNET
, sizeof (IP6_EXPERIMENTAL_ETHERNET
));
720 // Refer to RFC1700, chapter Number Hardware Type.
722 UnicodeSPrint (PortString
, 6, L
"%d", IfInfo
->IfType
);
725 StringId
= HiiSetString (
727 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT
),
732 return EFI_OUT_OF_RESOURCES
;
736 // Convert the hardware address.
739 ASSERT (IfInfo
->HwAddressSize
<= 32);
741 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
;
1201 Status
= Ip6Config
->UnregisterDataNotify (
1203 Ip6ConfigDataTypeManualAddress
,
1206 if (EFI_ERROR (Status
)) {
1212 // Set gateway address list.
1214 if (!IsListEmpty (&Ip6NvData
->GatewayAddress
) && (Ip6NvData
->GatewayAddressCount
!= 0)) {
1215 Status
= Ip6BuildNvAddressInfo (
1217 Ip6ConfigNvGatewayAddress
,
1221 if (EFI_ERROR (Status
)) {
1225 Status
= Ip6Config
->SetData (
1227 Ip6ConfigDataTypeGateway
,
1231 if (EFI_ERROR (Status
)) {
1240 // Set DNS server address list.
1242 if (!IsListEmpty (&Ip6NvData
->DnsAddress
) && (Ip6NvData
->DnsAddressCount
!= 0)) {
1243 Status
= Ip6BuildNvAddressInfo (
1245 Ip6ConfigNvDnsAddress
,
1249 if (EFI_ERROR (Status
)) {
1253 Status
= Ip6Config
->SetData (
1255 Ip6ConfigDataTypeDnsServer
,
1259 if (EFI_ERROR (Status
)) {
1264 Status
= EFI_SUCCESS
;
1267 if (SetAddressEvent
!= NULL
) {
1268 gBS
->CloseEvent (SetAddressEvent
);
1271 if (TimeoutEvent
!= NULL
) {
1272 gBS
->CloseEvent (TimeoutEvent
);
1275 if (ManualAddress
!= NULL
) {
1276 FreePool (ManualAddress
);
1279 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
1360 IP6_FORM_CALLBACK_INFO
*Private
;
1361 IP6_CONFIG_INSTANCE
*Ip6ConfigInstance
;
1362 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1363 EFI_STRING ConfigRequestHdr
;
1364 EFI_STRING ConfigRequest
;
1365 BOOLEAN AllocatedRequest
;
1369 if (This
== NULL
|| Progress
== NULL
|| Results
== NULL
) {
1370 return EFI_INVALID_PARAMETER
;
1373 *Progress
= Request
;
1374 if ((Request
!= NULL
) &&
1375 !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 (
1430 (UINT8
*) IfrNvData
,
1437 FreePool (IfrNvData
);
1439 // Free the allocated config request string.
1441 if (AllocatedRequest
) {
1442 FreePool (ConfigRequest
);
1443 ConfigRequest
= NULL
;
1446 // Set Progress string to the original request string.
1448 if (Request
== NULL
) {
1450 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1451 *Progress
= Request
+ StrLen (Request
);
1458 This function applies changes in a driver's configuration.
1459 Input is a Configuration, which has the routing data for this
1460 driver followed by name / value configuration pairs. The driver
1461 must apply those pairs to its configurable storage. If the
1462 driver's configuration is stored in a linear block of data
1463 and the driver's name / value pairs are in <BlockConfig>
1464 format, it may use the ConfigToBlock helper function (above) to
1465 simplify the job. Currently not implemented.
1467 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1468 @param[in] Configuration A null-terminated Unicode string in
1469 <ConfigString> format.
1470 @param[out] Progress A pointer to a string filled in with the
1471 offset of the most recent '&' before the
1472 first failing name / value pair (or the
1473 beginn ing of the string if the failure
1474 is in the first name / value pair) or
1475 the terminating NULL if all was
1478 @retval EFI_SUCCESS The results have been distributed or are
1479 awaiting distribution.
1480 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1481 parts of the results that must be
1482 stored awaiting possible future
1484 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1485 Results parameter would result
1486 in this type of error.
1487 @retval EFI_NOT_FOUND Target for the specified routing data
1492 Ip6FormRouteConfig (
1493 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1494 IN CONST EFI_STRING Configuration
,
1495 OUT EFI_STRING
*Progress
1498 if (This
== NULL
|| Configuration
== NULL
|| Progress
== NULL
) {
1499 return EFI_INVALID_PARAMETER
;
1503 // Check routing data in <ConfigHdr>.
1504 // Note: if only one Storage is used, then this checking could be skipped.
1506 if (!HiiIsConfigHdrMatch (Configuration
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1507 *Progress
= Configuration
;
1508 return EFI_NOT_FOUND
;
1511 *Progress
= Configuration
+ StrLen (Configuration
);
1517 Display host addresses, route table, DNS addresses and gateway addresses in
1518 "IPv6 Current Setting" page.
1520 @param[in] Instance The IP6 config instance data.
1522 @retval EFI_SUCCESS The operation finished successfully.
1523 @retval Others Other errors as indicated.
1527 Ip6GetCurrentSetting (
1528 IN IP6_CONFIG_INSTANCE
*Instance
1531 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1532 EFI_HII_HANDLE HiiHandle
;
1533 EFI_IP6_CONFIG_INTERFACE_INFO
*Data
;
1536 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
1537 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
)) {
1609 // Generate the dynamic text opcode for DNS server and draw it.
1611 Status
= Ip6ConvertAddressListToString (
1614 Ip6ConfigNvDnsAddress
,
1616 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1618 if (EFI_ERROR (Status
)) {
1625 // Get gateway adderss list.
1633 Status
= Ip6ConfigNvGetData (
1635 Ip6ConfigDataTypeGateway
,
1639 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1648 // Generate the dynamic text opcode for gateway and draw it.
1650 Status
= Ip6ConvertAddressListToString (
1653 Ip6ConfigNvGatewayAddress
,
1655 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1657 if (EFI_ERROR (Status
)) {
1671 This function is called to provide results data to the driver.
1672 This data consists of a unique key that is used to identify
1673 which data is either being passed back or being asked for.
1675 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1676 @param[in] Action Specifies the type of action taken by the browser.
1677 @param[in] QuestionId A unique value which is sent to the original
1678 exporting driver so that it can identify the type
1679 of data to expect. The format of the data tends to
1680 vary based on the opcode that generated the callback.
1681 @param[in] Type The type of value for the question.
1682 @param[in] Value A pointer to the data being sent to the original
1684 @param[out] ActionRequest On return, points to the action requested by the
1687 @retval EFI_SUCCESS The callback successfully handled the action.
1688 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1689 variable and its data.
1690 @retval EFI_DEVICE_ERROR The variable could not be saved.
1691 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1692 callback. Currently not implemented.
1693 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.
1694 @retval Others Other errors as indicated.
1700 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1701 IN EFI_BROWSER_ACTION Action
,
1702 IN EFI_QUESTION_ID QuestionId
,
1704 IN EFI_IFR_TYPE_VALUE
*Value
,
1705 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1708 IP6_FORM_CALLBACK_INFO
*Private
;
1710 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1713 IP6_CONFIG_INSTANCE
*Instance
;
1714 IP6_CONFIG_NVDATA
*Ip6NvData
;
1717 return EFI_INVALID_PARAMETER
;
1720 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1721 Instance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1722 Ip6NvData
= &Instance
->Ip6NvData
;
1724 if ((Action
== EFI_BROWSER_ACTION_FORM_OPEN
) || (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
)){
1728 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
1729 return EFI_UNSUPPORTED
;
1732 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1733 return EFI_INVALID_PARAMETER
;
1737 // Retrieve uncommitted data from Browser
1740 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1741 IfrNvData
= AllocateZeroPool (BufferSize
);
1742 if (IfrNvData
== NULL
) {
1743 return EFI_OUT_OF_RESOURCES
;
1746 Status
= EFI_SUCCESS
;
1748 HiiGetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
);
1750 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1751 switch (QuestionId
) {
1752 case KEY_GET_CURRENT_SETTING
:
1753 Status
= Ip6GetCurrentSetting (Instance
);
1759 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1760 switch (QuestionId
) {
1761 case KEY_SAVE_CONFIG_CHANGES
:
1762 Status
= Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData
, Instance
);
1763 if (EFI_ERROR (Status
)) {
1767 Status
= Ip6GetCurrentSetting (Instance
);
1769 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1772 case KEY_IGNORE_CONFIG_CHANGES
:
1773 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
1774 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
1775 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
1777 Ip6NvData
->ManualAddressCount
= 0;
1778 Ip6NvData
->GatewayAddressCount
= 0;
1779 Ip6NvData
->DnsAddressCount
= 0;
1781 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1784 case KEY_SAVE_CHANGES
:
1785 Status
= Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData
, Instance
);
1786 if (EFI_ERROR (Status
)) {
1789 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1792 case KEY_INTERFACE_ID
:
1793 Status
= Ip6ParseInterfaceIdFromString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
1794 if (EFI_ERROR (Status
)) {
1796 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1798 L
"Invalid Interface ID!",
1805 case KEY_MANUAL_ADDRESS
:
1806 Status
= Ip6ParseAddressListFromString (
1807 IfrNvData
->ManualAddress
,
1808 &Ip6NvData
->ManualAddress
,
1809 &Ip6NvData
->ManualAddressCount
1811 if (EFI_ERROR (Status
)) {
1813 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1815 L
"Invalid Host Addresses!",
1822 case KEY_GATEWAY_ADDRESS
:
1823 Status
= Ip6ParseAddressListFromString (
1824 IfrNvData
->GatewayAddress
,
1825 &Ip6NvData
->GatewayAddress
,
1826 &Ip6NvData
->GatewayAddressCount
1828 if (EFI_ERROR (Status
)) {
1830 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1832 L
"Invalid Gateway Addresses!",
1839 case KEY_DNS_ADDRESS
:
1840 Status
= Ip6ParseAddressListFromString (
1841 IfrNvData
->DnsAddress
,
1842 &Ip6NvData
->DnsAddress
,
1843 &Ip6NvData
->DnsAddressCount
1845 if (EFI_ERROR (Status
)) {
1847 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1849 L
"Invalid DNS Addresses!",
1861 if (!EFI_ERROR (Status
)) {
1863 // Pass changed uncommitted data back to Form Browser.
1865 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1866 HiiSetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
1869 FreePool (IfrNvData
);
1874 Install HII Config Access protocol for network device and allocate resources.
1876 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.
1878 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1879 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1880 @retval Others Other errors as indicated.
1885 IN OUT IP6_CONFIG_INSTANCE
*Instance
1890 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
1891 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1892 VENDOR_DEVICE_PATH VendorDeviceNode
;
1893 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1895 CHAR16 MenuString
[128];
1896 CHAR16 PortString
[128];
1897 CHAR16
*OldMenuString
;
1898 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1900 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
1901 ASSERT (IpSb
!= NULL
);
1903 Status
= gBS
->HandleProtocol (
1905 &gEfiDevicePathProtocolGuid
,
1906 (VOID
**) &ParentDevicePath
1908 if (EFI_ERROR (Status
)) {
1912 CallbackInfo
= &Instance
->CallbackInfo
;
1913 CallbackInfo
->Signature
= IP6_FORM_CALLBACK_INFO_SIGNATURE
;
1916 // Construct device path node for EFI HII Config Access protocol,
1917 // which consists of controller physical device path and one hardware
1918 // vendor guid node.
1920 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1921 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1922 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1924 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1926 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1927 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1929 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
1931 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1932 Status
= EFI_OUT_OF_RESOURCES
;
1936 ConfigAccess
= &CallbackInfo
->HiiConfigAccess
;
1937 ConfigAccess
->ExtractConfig
= Ip6FormExtractConfig
;
1938 ConfigAccess
->RouteConfig
= Ip6FormRouteConfig
;
1939 ConfigAccess
->Callback
= Ip6FormCallback
;
1942 // Install Device Path Protocol and Config Access protocol on new handle
1944 Status
= gBS
->InstallMultipleProtocolInterfaces (
1945 &CallbackInfo
->ChildHandle
,
1946 &gEfiDevicePathProtocolGuid
,
1947 CallbackInfo
->HiiVendorDevicePath
,
1948 &gEfiHiiConfigAccessProtocolGuid
,
1952 if (!EFI_ERROR (Status
)) {
1954 // Open the Parent Handle for the child
1956 Status
= gBS
->OpenProtocol (
1958 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1961 CallbackInfo
->ChildHandle
,
1962 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1966 if (EFI_ERROR (Status
)) {
1971 // Publish our HII data
1973 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1974 &gIp6ConfigNvDataGuid
,
1975 CallbackInfo
->ChildHandle
,
1980 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1981 Status
= EFI_OUT_OF_RESOURCES
;
1986 // Append MAC string in the menu help string and tile help string
1988 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1989 if (!EFI_ERROR (Status
)) {
1990 OldMenuString
= HiiGetString (
1991 CallbackInfo
->RegisteredHandle
,
1992 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
1995 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
1997 CallbackInfo
->RegisteredHandle
,
1998 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2002 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
2004 CallbackInfo
->RegisteredHandle
,
2005 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP
),
2010 FreePool (MacString
);
2011 FreePool (OldMenuString
);
2013 InitializeListHead (&Instance
->Ip6NvData
.ManualAddress
);
2014 InitializeListHead (&Instance
->Ip6NvData
.GatewayAddress
);
2015 InitializeListHead (&Instance
->Ip6NvData
.DnsAddress
);
2021 Ip6ConfigFormUnload (Instance
);
2026 Uninstall the HII Config Access protocol for network devices and free up the resources.
2028 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.
2032 Ip6ConfigFormUnload (
2033 IN OUT IP6_CONFIG_INSTANCE
*Instance
2037 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
2038 IP6_CONFIG_NVDATA
*Ip6NvData
;
2040 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
2041 ASSERT (IpSb
!= NULL
);
2043 CallbackInfo
= &Instance
->CallbackInfo
;
2045 if (CallbackInfo
->ChildHandle
!= NULL
) {
2048 // Close the child handle
2050 gBS
->CloseProtocol (
2052 &gEfiManagedNetworkServiceBindingProtocolGuid
,
2054 CallbackInfo
->ChildHandle
2057 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
2059 gBS
->UninstallMultipleProtocolInterfaces (
2060 CallbackInfo
->ChildHandle
,
2061 &gEfiDevicePathProtocolGuid
,
2062 CallbackInfo
->HiiVendorDevicePath
,
2063 &gEfiHiiConfigAccessProtocolGuid
,
2064 &CallbackInfo
->HiiConfigAccess
,
2069 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
2070 FreePool (CallbackInfo
->HiiVendorDevicePath
);
2073 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
2075 // Remove HII package list
2077 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
2080 Ip6NvData
= &Instance
->Ip6NvData
;
2082 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
2083 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
2084 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
2086 Ip6NvData
->ManualAddressCount
= 0;
2087 Ip6NvData
->GatewayAddressCount
= 0;
2088 Ip6NvData
->DnsAddressCount
= 0;