2 Helper functions for configuring or obtaining the parameters relating to IP6.
4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 CHAR16 mIp6ConfigStorageName
[] = L
"IP6_CONFIG_IFR_NVDATA";
21 The notify function of create event when performing a manual configuration.
23 @param[in] Event The pointer of Event.
24 @param[in] Context The pointer of Context.
29 Ip6ConfigManualAddressNotify (
34 *((BOOLEAN
*) Context
) = TRUE
;
38 Get the configuration data for the EFI IPv6 network stack running on the
39 communication. It is a help function to the call EfiIp6ConfigGetData().
41 @param[in] Ip6Config The pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
42 @param[in] DataType The type of data to get.
43 @param[out] DataSize The size of buffer required in bytes.
44 @param[out] Data The data buffer in which the configuration data is returned. The
45 type of the data buffer associated with the DataType.
46 It is the caller's responsibility to free the resource.
48 @retval EFI_SUCCESS The specified configuration data was obtained successfully.
49 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
50 - Ip6Config is NULL or invalid.
53 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resources.
54 @retval EFI_NOT_READY The specified configuration data is not ready due to an
55 asynchronous configuration process already in progress.
56 @retval EFI_NOT_FOUND The specified configuration data was not found.
61 IN EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
,
62 IN EFI_IP6_CONFIG_DATA_TYPE DataType
,
71 if ((Ip6Config
== NULL
) || (Data
== NULL
) || (DataSize
== NULL
)) {
72 return EFI_INVALID_PARAMETER
;
76 Status
= Ip6Config
->GetData (
82 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
86 Buffer
= AllocateZeroPool (BufferSize
);
88 return EFI_OUT_OF_RESOURCES
;
91 Status
= Ip6Config
->GetData (
97 if (EFI_ERROR (Status
)) {
102 *DataSize
= BufferSize
;
109 Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified
112 @param[in] ListHead The head of the list array in IP6_ADDRESS_INFO_ENTRY.
116 Ip6FreeAddressInfoList (
117 IN LIST_ENTRY
*ListHead
120 IP6_ADDRESS_INFO_ENTRY
*Node
;
122 LIST_ENTRY
*NextEntry
;
124 NET_LIST_FOR_EACH_SAFE (Entry
, NextEntry
, ListHead
) {
125 Node
= NET_LIST_USER_STRUCT (Entry
, IP6_ADDRESS_INFO_ENTRY
, Link
);
126 RemoveEntryList (&Node
->Link
);
132 Convert the IPv6 address into a formatted string.
134 @param[in] Ip6 The IPv6 address.
135 @param[out] Str The formatted IP string.
140 IN EFI_IPv6_ADDRESS
*Ip6
,
147 CHAR16 FormatString
[8];
151 for (Index
= 0; Index
< 15; Index
= Index
+ 2) {
154 Ip6
->Addr
[Index
] == 0 &&
155 Ip6
->Addr
[Index
+ 1] == 0
158 // Deal with the case of ::.
169 while ((Index
< 15) && (Ip6
->Addr
[Index
] == 0) && (Ip6
->Addr
[Index
+ 1] == 0)) {
177 // :: is at the end of the address.
186 if (Ip6
->Addr
[Index
] == 0) {
187 Number
= UnicodeSPrint (Str
, 2 * IP6_STR_MAX_SIZE
, L
"%x:", (UINTN
) Ip6
->Addr
[Index
+ 1]);
189 if (Ip6
->Addr
[Index
+ 1] < 0x10) {
190 CopyMem (FormatString
, L
"%x0%x:", StrSize (L
"%x0%x:"));
192 CopyMem (FormatString
, L
"%x%x:", StrSize (L
"%x%x:"));
195 Number
= UnicodeSPrint (
197 2 * IP6_STR_MAX_SIZE
,
198 (CONST CHAR16
*) FormatString
,
199 (UINTN
) Ip6
->Addr
[Index
],
200 (UINTN
) Ip6
->Addr
[Index
+ 1]
206 if (Index
+ 2 == 16) {
208 if (*(Str
- 1) == L
':') {
216 Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.
218 @param[out] String The buffer to store the converted string.
219 @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
221 @retval EFI_SUCCESS The string converted successfully.
222 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
226 Ip6ConvertInterfaceIdToString (
228 IN EFI_IP6_CONFIG_INTERFACE_ID
*IfId
234 if ((String
== NULL
) || (IfId
== NULL
)) {
235 return EFI_INVALID_PARAMETER
;
238 for (Index
= 0; Index
< 8; Index
++) {
239 Number
= UnicodeSPrint (
241 2 * INTERFACE_ID_STR_STORAGE
,
243 (UINTN
) IfId
->Id
[Index
]
245 String
= String
+ Number
;
248 *(String
- 1) = '\0';
254 Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.
256 @param[in] String The buffer of the string to be parsed.
257 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
259 @retval EFI_SUCCESS The operation finished successfully.
260 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
264 Ip6ParseInterfaceIdFromString (
265 IN CONST CHAR16
*String
,
266 OUT EFI_IP6_CONFIG_INTERFACE_ID
*IfId
274 if ((String
== NULL
) || (IfId
== NULL
)) {
275 return EFI_INVALID_PARAMETER
;
278 IfIdStr
= (CHAR16
*) String
;
280 ZeroMem (IfId
, sizeof (EFI_IP6_CONFIG_INTERFACE_ID
));
282 for (Index
= 0; Index
< 8; Index
++) {
285 while ((*IfIdStr
!= L
'\0') && (*IfIdStr
!= L
':')) {
290 // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.
291 // If the number of X is less than 8, zero is appended to the InterfaceId.
293 if ((*IfIdStr
== ':') && (Index
== 7)) {
294 return EFI_INVALID_PARAMETER
;
298 // Convert the string to interface id. AsciiStrHexToUintn stops at the
299 // first character that is not a valid hex character, ':' or '\0' here.
301 NodeVal
= StrHexToUintn (TempStr
);
302 if (NodeVal
> 0xFF) {
303 return EFI_INVALID_PARAMETER
;
306 IfId
->Id
[Index
] = (UINT8
) NodeVal
;
315 Create Hii Extend Label OpCode as the start opcode and end opcode. It is
318 @param[in] StartLabelNumber The number of start label.
319 @param[out] StartOpCodeHandle Points to the start opcode handle.
320 @param[out] StartLabel Points to the created start opcode.
321 @param[out] EndOpCodeHandle Points to the end opcode handle.
322 @param[out] EndLabel Points to the created end opcode.
324 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
326 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
327 @retval EFI_SUCCESS The operation completed successfully.
332 IN UINT16 StartLabelNumber
,
333 OUT VOID
**StartOpCodeHandle
,
334 OUT EFI_IFR_GUID_LABEL
**StartLabel
,
335 OUT VOID
**EndOpCodeHandle
,
336 OUT EFI_IFR_GUID_LABEL
**EndLabel
340 EFI_IFR_GUID_LABEL
*InternalStartLabel
;
341 EFI_IFR_GUID_LABEL
*InternalEndLabel
;
343 if (StartOpCodeHandle
== NULL
|| StartLabel
== NULL
|| EndOpCodeHandle
== NULL
|| EndLabel
== NULL
) {
344 return EFI_INVALID_PARAMETER
;
347 *StartOpCodeHandle
= NULL
;
348 *EndOpCodeHandle
= NULL
;
349 Status
= EFI_OUT_OF_RESOURCES
;
352 // Initialize the container for dynamic opcodes.
354 *StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
355 if (*StartOpCodeHandle
== NULL
) {
359 *EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
360 if (*EndOpCodeHandle
== NULL
) {
365 // Create Hii Extend Label OpCode as the start opcode.
367 InternalStartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
371 sizeof (EFI_IFR_GUID_LABEL
)
373 if (InternalStartLabel
== NULL
) {
377 InternalStartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
378 InternalStartLabel
->Number
= StartLabelNumber
;
381 // Create Hii Extend Label OpCode as the end opcode.
383 InternalEndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
387 sizeof (EFI_IFR_GUID_LABEL
)
389 if (InternalEndLabel
== NULL
) {
393 InternalEndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
394 InternalEndLabel
->Number
= LABEL_END
;
396 *StartLabel
= InternalStartLabel
;
397 *EndLabel
= InternalEndLabel
;
403 if (*StartOpCodeHandle
!= NULL
) {
404 HiiFreeOpCodeHandle (*StartOpCodeHandle
);
407 if (*EndOpCodeHandle
!= NULL
) {
408 HiiFreeOpCodeHandle (*EndOpCodeHandle
);
415 This function converts the different format of address list to string format and
416 then generates the corresponding text opcode to illustarate the address info in
417 IP6 configuration page. Currently, the following formats are supported:
418 EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;
419 EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;
420 EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable.
422 @param[in, out] String The pointer to the buffer to store the converted
424 @param[in] HiiHandle A handle that was previously registered in the
426 @param[in] AddressType The address type.
427 @param[in] AddressInfo Pointer to the address list.
428 @param[in] AddressCount The address count of the address list.
430 @retval EFI_SUCCESS The operation finished successfully.
431 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
432 @retval EFI_UNSUPPORTED The AddressType is not supported.
437 Ip6ConvertAddressListToString (
438 IN OUT CHAR16
*String
,
439 IN EFI_HII_HANDLE HiiHandle
,
440 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
441 IN VOID
*AddressInfo
,
442 IN UINTN AddressCount
449 VOID
*StartOpCodeHandle
;
450 EFI_IFR_GUID_LABEL
*StartLabel
;
451 VOID
*EndOpCodeHandle
;
452 EFI_IFR_GUID_LABEL
*EndLabel
;
453 UINT16 StartLabelNumber
;
454 EFI_STRING_ID TextTwo
;
457 EFI_IPv6_ADDRESS
*Address
;
459 if ((String
== NULL
) || (HiiHandle
== NULL
) || (AddressInfo
== NULL
)) {
460 return EFI_INVALID_PARAMETER
;
463 if (AddressType
== Ip6ConfigNvHostAddress
) {
464 StartLabelNumber
= HOST_ADDRESS_LABEL
;
465 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
466 StartLabelNumber
= GATEWAY_ADDRESS_LABEL
;
467 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
468 StartLabelNumber
= DNS_ADDRESS_LABEL
;
469 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
470 StartLabelNumber
= ROUTE_TABLE_LABEL
;
473 return EFI_UNSUPPORTED
;
476 Status
= Ip6CreateOpCode (
483 if (EFI_ERROR (Status
)) {
487 AddressHead
= (UINT8
*) AddressInfo
;
489 for (Index
= 0; Index
< AddressCount
; Index
++) {
490 if (AddressType
== Ip6ConfigNvHostAddress
) {
491 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ADDRESS_INFO
) * Index
;
492 Address
= &((EFI_IP6_ADDRESS_INFO
*) AddressInfo
)->Address
;
493 } else if (AddressType
== Ip6ConfigNvRouteTable
) {
494 AddressInfo
= AddressHead
+ sizeof (EFI_IP6_ROUTE_TABLE
) * Index
;
495 Address
= &((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->Destination
;
497 AddressInfo
= AddressHead
+ sizeof (EFI_IPv6_ADDRESS
) * Index
;
498 Address
= AddressInfo
;
502 // Convert the IP address info to string.
504 Ip6ToStr (Address
, String
);
505 TempStr
= String
+ StrLen (String
);
507 if ((AddressType
== Ip6ConfigNvHostAddress
) || (AddressType
== Ip6ConfigNvRouteTable
)) {
508 if (AddressType
== Ip6ConfigNvHostAddress
) {
509 PrefixLength
= ((EFI_IP6_ADDRESS_INFO
*) AddressInfo
)->PrefixLength
;
511 PrefixLength
= ((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->PrefixLength
;
515 // Append the prefix length to the string.
519 Number
= UnicodeSPrint (TempStr
, 6, L
"%d", PrefixLength
);
520 TempStr
= TempStr
+ Number
;
523 if (AddressType
== Ip6ConfigNvRouteTable
) {
525 // Append " >> " to the string.
527 Number
= UnicodeSPrint (TempStr
, 8, L
" >> ");
528 TempStr
= TempStr
+ Number
;
531 // Append the gateway address to the string.
533 Ip6ToStr (&((EFI_IP6_ROUTE_TABLE
*) AddressInfo
)->Gateway
, TempStr
);
534 TempStr
= TempStr
+ StrLen (TempStr
);
538 // Generate a text opcode and update the UI.
540 TextTwo
= HiiSetString (HiiHandle
, 0, String
, NULL
);
542 Status
= EFI_INVALID_PARAMETER
;
546 HiiCreateTextOpCode (StartOpCodeHandle
, STR_NULL
, STR_NULL
, TextTwo
);
549 *String
= IP6_ADDRESS_DELIMITER
;
553 *(String
- 1) = '\0';
555 Status
= HiiUpdateForm (
556 HiiHandle
, // HII handle
557 &gIp6ConfigNvDataGuid
, // Formset GUID
558 FORMID_MAIN_FORM
, // Form ID
559 StartOpCodeHandle
, // Label for where to insert opcodes
560 EndOpCodeHandle
// Replace data
564 HiiFreeOpCodeHandle (StartOpCodeHandle
);
565 HiiFreeOpCodeHandle (EndOpCodeHandle
);
571 Parse address list in string format and convert it to a list array of node in
572 IP6_ADDRESS_INFO_ENTRY.
574 @param[in] String The buffer to string to be parsed.
575 @param[out] ListHead The list head of array.
576 @param[out] AddressCount The number of list nodes in the array.
578 @retval EFI_SUCCESS The operation finished successfully.
579 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
580 @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource.
584 Ip6ParseAddressListFromString (
585 IN CONST CHAR16
*String
,
586 OUT LIST_ENTRY
*ListHead
,
587 OUT UINT32
*AddressCount
594 EFI_IP6_ADDRESS_INFO AddressInfo
;
595 IP6_ADDRESS_INFO_ENTRY
*Node
;
599 if ((String
== NULL
) || (ListHead
== NULL
) || (AddressCount
== NULL
)) {
600 return EFI_INVALID_PARAMETER
;
603 LocalString
= (CHAR16
*) AllocateCopyPool (StrSize (String
), String
);
604 if (LocalString
== NULL
) {
605 return EFI_OUT_OF_RESOURCES
;
609 // Clean the original address list.
611 Ip6FreeAddressInfoList (ListHead
);
617 while (*LocalString
!= L
'\0') {
618 TempStr
= LocalString
;
619 while ((*LocalString
!= L
'\0') && (*LocalString
!= IP6_ADDRESS_DELIMITER
)) {
623 if (*LocalString
== L
'\0') {
627 *LocalString
= L
'\0';
629 Status
= NetLibStrToIp6andPrefix (TempStr
, &AddressInfo
.Address
, &AddressInfo
.PrefixLength
);
630 if (EFI_ERROR (Status
)) {
634 if (AddressInfo
.PrefixLength
== 0xFF) {
635 AddressInfo
.PrefixLength
= 0;
638 if (!NetIp6IsValidUnicast (&AddressInfo
.Address
)) {
639 Status
= EFI_INVALID_PARAMETER
;
643 Node
= AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY
));
645 Status
= EFI_OUT_OF_RESOURCES
;
649 CopyMem (&Node
->AddrInfo
, &AddressInfo
, sizeof (EFI_IP6_ADDRESS_INFO
));
650 InsertTailList (ListHead
, &Node
->Link
);
661 *AddressCount
= Count
;
665 Ip6FreeAddressInfoList (ListHead
);
671 This function converts the interface info to string and draws it to the IP6 UI.
672 The interface information includes interface name, interface type, hardware
673 address and route table information.
675 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
676 @param[in] HiiHandle The handle that was previously registered in the
678 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.
680 @retval EFI_SUCCESS The operation finished successfully.
681 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
682 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
686 Ip6ConvertInterfaceInfoToString (
687 IN EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
,
688 IN EFI_HII_HANDLE HiiHandle
,
689 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
695 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
696 CHAR16 FormatString
[8];
697 EFI_STRING_ID StringId
;
699 if ((IfInfo
== NULL
) || (HiiHandle
== NULL
) || (IfrNvData
== NULL
)) {
700 return EFI_INVALID_PARAMETER
;
704 // Print the interface name.
706 StringId
= HiiSetString (
708 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT
),
713 return EFI_OUT_OF_RESOURCES
;
717 // Print the interface type.
719 if (IfInfo
->IfType
== Ip6InterfaceTypeEthernet
) {
720 StrCpy (PortString
, IP6_ETHERNET
);
721 } else if (IfInfo
->IfType
== Ip6InterfaceTypeExperimentalEthernet
) {
722 StrCpy (PortString
, IP6_EXPERIMENTAL_ETHERNET
);
725 // Refer to RFC1700, chapter Number Hardware Type.
727 UnicodeSPrint (PortString
, 6, L
"%d", IfInfo
->IfType
);
730 StringId
= HiiSetString (
732 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT
),
737 return EFI_OUT_OF_RESOURCES
;
741 // Convert the hardware address.
744 ASSERT (IfInfo
->HwAddressSize
<= 32);
746 for (Index
= 0; Index
< IfInfo
->HwAddressSize
; Index
++) {
748 if (IfInfo
->HwAddress
.Addr
[Index
] < 0x10) {
749 StrCpy (FormatString
, L
"0%x-");
751 StrCpy (FormatString
, L
"%x-");
754 Number
= UnicodeSPrint (
757 (CONST CHAR16
*) FormatString
,
758 (UINTN
) IfInfo
->HwAddress
.Addr
[Index
]
760 String
= String
+ Number
;
764 ASSERT (String
> PortString
);
770 // Print the hardware address.
772 StringId
= HiiSetString (
774 STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT
),
779 return EFI_OUT_OF_RESOURCES
;
786 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.
788 @param[in] Instance Points to IP6 config instance data.
789 @param[in] AddressType The address type.
790 @param[out] AddressInfo The pointer to the buffer to store the address list.
791 @param[out] AddressSize The address size of the address list.
793 @retval EFI_SUCCESS The operation finished successfully.
794 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
795 @retval EFI_UNSUPPORTED The AddressType is not supported.
799 Ip6BuildNvAddressInfo (
800 IN IP6_CONFIG_INSTANCE
*Instance
,
801 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType
,
802 OUT VOID
**AddressInfo
,
803 OUT UINTN
*AddressSize
806 IP6_CONFIG_NVDATA
*Ip6NvData
;
808 LIST_ENTRY
*ListHead
;
809 IP6_ADDRESS_INFO_ENTRY
*Node
;
813 EFI_IPv6_ADDRESS
*Ip6Address
;
814 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
816 if ((Instance
== NULL
) || (AddressInfo
== NULL
) || (AddressSize
== NULL
)) {
817 return EFI_INVALID_PARAMETER
;
820 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
822 Ip6NvData
= &Instance
->Ip6NvData
;
824 if (AddressType
== Ip6ConfigNvHostAddress
) {
825 ListHead
= &Ip6NvData
->ManualAddress
;
826 DataSize
= sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
) * Ip6NvData
->ManualAddressCount
;
827 } else if (AddressType
== Ip6ConfigNvGatewayAddress
) {
828 ListHead
= &Ip6NvData
->GatewayAddress
;
829 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->GatewayAddressCount
;
830 } else if (AddressType
== Ip6ConfigNvDnsAddress
) {
831 ListHead
= &Ip6NvData
->DnsAddress
;
832 DataSize
= sizeof (EFI_IPv6_ADDRESS
) * Ip6NvData
->DnsAddressCount
;
834 return EFI_UNSUPPORTED
;
837 AddressList
= AllocateZeroPool (DataSize
);
838 if (AddressList
== NULL
) {
839 return EFI_OUT_OF_RESOURCES
;
842 TmpStr
= AddressList
;
844 NET_LIST_FOR_EACH (Entry
, ListHead
) {
845 Node
= NET_LIST_USER_STRUCT (Entry
, IP6_ADDRESS_INFO_ENTRY
, Link
);
846 if (AddressType
== Ip6ConfigNvHostAddress
) {
847 ManualAddress
= (EFI_IP6_CONFIG_MANUAL_ADDRESS
*) AddressList
;
848 IP6_COPY_ADDRESS (&ManualAddress
->Address
, &Node
->AddrInfo
.Address
);
849 ManualAddress
->PrefixLength
= Node
->AddrInfo
.PrefixLength
;
850 AddressList
= (UINT8
*) AddressList
+ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
);
852 Ip6Address
= (EFI_IPv6_ADDRESS
*) AddressList
;
853 IP6_COPY_ADDRESS (Ip6Address
, &Node
->AddrInfo
.Address
);
854 AddressList
= (UINT8
*) AddressList
+ sizeof (EFI_IPv6_ADDRESS
);
858 *AddressInfo
= TmpStr
;
859 *AddressSize
= DataSize
;
864 Convert the IP6 configuration data into the IFR data.
866 @param[in, out] IfrNvData The IFR NV data.
867 @param[in] Instance The IP6 config instance data.
869 @retval EFI_SUCCESS The operation finished successfully.
870 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
871 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.
872 @retval Others Other errors as indicated.
876 Ip6ConvertConfigNvDataToIfrNvData (
877 IN OUT IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
878 IN IP6_CONFIG_INSTANCE
*Instance
881 IP6_CONFIG_NVDATA
*Ip6NvData
;
882 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
886 EFI_IP6_CONFIG_POLICY Policy
;
887 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits
;
888 EFI_HII_HANDLE HiiHandle
;
890 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
891 return EFI_INVALID_PARAMETER
;
894 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
896 Ip6Config
= &Instance
->Ip6Config
;
897 Ip6NvData
= &Instance
->Ip6NvData
;
900 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
903 // Get the current interface info.
905 Status
= Ip6ConfigNvGetData (
907 Ip6ConfigDataTypeInterfaceInfo
,
911 if (EFI_ERROR (Status
)) {
916 // Convert the interface info to string and print.
918 Status
= Ip6ConvertInterfaceInfoToString (
919 (EFI_IP6_CONFIG_INTERFACE_INFO
*) Data
,
923 if (EFI_ERROR (Status
)) {
928 // Get the interface id.
930 DataSize
= sizeof (EFI_IP6_CONFIG_INTERFACE_ID
);
931 ZeroMem (&Ip6NvData
->InterfaceId
, DataSize
);
932 Status
= Ip6Config
->GetData (
934 Ip6ConfigDataTypeAltInterfaceId
,
936 &Ip6NvData
->InterfaceId
938 if (EFI_ERROR (Status
)) {
942 Ip6ConvertInterfaceIdToString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
945 // Get current policy.
947 DataSize
= sizeof (EFI_IP6_CONFIG_POLICY
);
948 Status
= Ip6Config
->GetData (
950 Ip6ConfigDataTypePolicy
,
955 if (EFI_ERROR (Status
)) {
959 if (Policy
== Ip6ConfigPolicyManual
) {
960 IfrNvData
->Policy
= IP6_POLICY_MANUAL
;
961 } else if (Policy
== Ip6ConfigPolicyAutomatic
) {
962 IfrNvData
->Policy
= IP6_POLICY_AUTO
;
965 Status
= EFI_UNSUPPORTED
;
970 // Get Duplicate Address Detection Transmits count.
972 DataSize
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
973 Status
= Ip6Config
->GetData (
975 Ip6ConfigDataTypeDupAddrDetectTransmits
,
980 if (EFI_ERROR (Status
)) {
984 IfrNvData
->DadTransmitCount
= DadXmits
.DupAddrDetectTransmits
;
995 Convert IFR data into IP6 configuration data. The policy, alternative interface
996 ID, and DAD transmit counts, and will be saved.
998 @param[in] IfrNvData The IFR NV data.
999 @param[in, out] Instance The IP6 config instance data.
1001 @retval EFI_SUCCESS The operation finished successfully.
1002 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1003 @retval Others Other errors as indicated.
1007 Ip6ConvertIfrNvDataToConfigNvDataGeneral (
1008 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1009 IN OUT IP6_CONFIG_INSTANCE
*Instance
1012 IP6_CONFIG_NVDATA
*Ip6NvData
;
1013 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1016 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1017 return EFI_INVALID_PARAMETER
;
1020 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1021 Ip6NvData
= &Instance
->Ip6NvData
;
1022 Ip6Config
= &Instance
->Ip6Config
;
1025 // Update those fields which don't have INTERACTIVE attribute.
1027 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1028 Ip6NvData
->Policy
= Ip6ConfigPolicyAutomatic
;
1029 } else if (IfrNvData
->Policy
== IP6_POLICY_MANUAL
) {
1030 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1033 Ip6NvData
->DadTransmitCount
.DupAddrDetectTransmits
= IfrNvData
->DadTransmitCount
;
1036 // Set the configured policy.
1038 Status
= Ip6Config
->SetData (
1040 Ip6ConfigDataTypePolicy
,
1041 sizeof (EFI_IP6_CONFIG_POLICY
),
1044 if (EFI_ERROR (Status
)) {
1049 // Set the duplicate address detection transmits count.
1051 Status
= Ip6Config
->SetData (
1053 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1054 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
),
1055 &Ip6NvData
->DadTransmitCount
1057 if (EFI_ERROR (Status
)) {
1062 // Set the alternative interface ID
1064 Status
= Ip6Config
->SetData (
1066 Ip6ConfigDataTypeAltInterfaceId
,
1067 sizeof (EFI_IP6_CONFIG_INTERFACE_ID
),
1068 &Ip6NvData
->InterfaceId
1070 if (EFI_ERROR (Status
)) {
1078 Convert IFR data into IP6 configuration data. The policy, configured
1079 manual address, gateway address, and DNS server address will be saved.
1081 @param[in] IfrNvData The IFR NV data.
1082 @param[in, out] Instance The IP6 config instance data.
1084 @retval EFI_SUCCESS The operation finished successfully.
1085 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1086 @retval Others Other errors as indicated.
1090 Ip6ConvertIfrNvDataToConfigNvDataAdvanced (
1091 IN IP6_CONFIG_IFR_NVDATA
*IfrNvData
,
1092 IN OUT IP6_CONFIG_INSTANCE
*Instance
1095 IP6_CONFIG_NVDATA
*Ip6NvData
;
1096 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1098 EFI_IP6_CONFIG_MANUAL_ADDRESS
*ManualAddress
;
1099 EFI_IPv6_ADDRESS
*Address
;
1100 BOOLEAN IsAddressOk
;
1101 EFI_EVENT SetAddressEvent
;
1102 EFI_EVENT TimeoutEvent
;
1105 if ((IfrNvData
== NULL
) || (Instance
== NULL
)) {
1106 return EFI_INVALID_PARAMETER
;
1109 if (IfrNvData
->Policy
== IP6_POLICY_AUTO
) {
1113 NET_CHECK_SIGNATURE (Instance
, IP6_CONFIG_INSTANCE_SIGNATURE
);
1114 Ip6NvData
= &Instance
->Ip6NvData
;
1115 Ip6Config
= &Instance
->Ip6Config
;
1118 // Update those fields which don't have INTERACTIVE attribute.
1120 Ip6NvData
->Policy
= Ip6ConfigPolicyManual
;
1123 // Set the configured policy.
1125 Status
= Ip6Config
->SetData (
1127 Ip6ConfigDataTypePolicy
,
1128 sizeof (EFI_IP6_CONFIG_POLICY
),
1131 if (EFI_ERROR (Status
)) {
1136 // Create events & timers for asynchronous settings.
1138 SetAddressEvent
= NULL
;
1139 TimeoutEvent
= NULL
;
1140 ManualAddress
= NULL
;
1143 Status
= gBS
->CreateEvent (
1146 Ip6ConfigManualAddressNotify
,
1150 if (EFI_ERROR (Status
)) {
1154 Status
= gBS
->CreateEvent (
1161 if (EFI_ERROR (Status
)) {
1166 // Set the manual address list. This is an asynchronous process.
1168 if (!IsListEmpty (&Ip6NvData
->ManualAddress
) && (Ip6NvData
->ManualAddressCount
!= 0)) {
1169 Status
= Ip6BuildNvAddressInfo (
1171 Ip6ConfigNvHostAddress
,
1172 (VOID
**) &ManualAddress
,
1175 if (EFI_ERROR (Status
)) {
1179 IsAddressOk
= FALSE
;
1181 Status
= Ip6Config
->RegisterDataNotify (
1183 Ip6ConfigDataTypeManualAddress
,
1186 if (EFI_ERROR (Status
)) {
1190 Status
= Ip6Config
->SetData (
1192 Ip6ConfigDataTypeManualAddress
,
1194 (VOID
*) ManualAddress
1196 if (Status
== EFI_NOT_READY
) {
1197 gBS
->SetTimer (TimeoutEvent
, TimerRelative
, 50000000);
1198 while (EFI_ERROR (gBS
->CheckEvent (TimeoutEvent
))) {
1200 Status
= EFI_SUCCESS
;
1206 Status
= Ip6Config
->UnregisterDataNotify (
1208 Ip6ConfigDataTypeManualAddress
,
1211 if (EFI_ERROR (Status
)) {
1217 // Set gateway address list.
1219 if (!IsListEmpty (&Ip6NvData
->GatewayAddress
) && (Ip6NvData
->GatewayAddressCount
!= 0)) {
1220 Status
= Ip6BuildNvAddressInfo (
1222 Ip6ConfigNvGatewayAddress
,
1226 if (EFI_ERROR (Status
)) {
1230 Status
= Ip6Config
->SetData (
1232 Ip6ConfigDataTypeGateway
,
1236 if (EFI_ERROR (Status
)) {
1245 // Set DNS server address list.
1247 if (!IsListEmpty (&Ip6NvData
->DnsAddress
) && (Ip6NvData
->DnsAddressCount
!= 0)) {
1248 Status
= Ip6BuildNvAddressInfo (
1250 Ip6ConfigNvDnsAddress
,
1254 if (EFI_ERROR (Status
)) {
1258 Status
= Ip6Config
->SetData (
1260 Ip6ConfigDataTypeDnsServer
,
1264 if (EFI_ERROR (Status
)) {
1269 Status
= EFI_SUCCESS
;
1272 if (SetAddressEvent
!= NULL
) {
1273 gBS
->CloseEvent (SetAddressEvent
);
1276 if (TimeoutEvent
!= NULL
) {
1277 gBS
->CloseEvent (TimeoutEvent
);
1280 if (ManualAddress
!= NULL
) {
1281 FreePool (ManualAddress
);
1284 if (Address
!= NULL
) {
1293 This function allows the caller to request the current
1294 configuration for one or more named elements. The resulting
1295 string is in <ConfigAltResp> format. Any and all alternative
1296 configuration strings shall also be appended to the end of the
1297 current configuration string. If they are, they must appear
1298 after the current configuration. They must contain the same
1299 routing (GUID, NAME, PATH) as the current configuration string.
1300 They must have an additional description indicating the type of
1301 alternative configuration the string represents,
1302 "ALTCFG=<StringToken>". That <StringToken> (when
1303 converted from Hex UNICODE to binary) is a reference to a
1304 string in the associated string pack.
1306 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1307 @param[in] Request A null-terminated Unicode string in
1308 <ConfigRequest> format. Note that this
1309 includes the routing information as well as
1310 the configurable name / value pairs. It is
1311 invalid for this string to be in
1312 <MultiConfigRequest> format.
1313 @param[out] Progress On return, points to a character in the
1314 Request string. Points to the string's null
1315 terminator if request was successful. Points
1316 to the most recent "&" before the first
1317 failing name / value pair (or the beginning
1318 of the string if the failure is in the first
1319 name / value pair) if the request was not
1321 @param[out] Results A null-terminated Unicode string in
1322 <ConfigAltResp> format which has all values
1323 filled in for the names in the Request string.
1324 String to be allocated by the called function.
1326 @retval EFI_SUCCESS The Results string is filled with the
1327 values corresponding to all requested
1329 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1330 parts of the results that must be
1331 stored awaiting possible future
1333 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
1334 for the Request parameter
1335 would result in this type of
1336 error. In this case, the
1337 Progress parameter would be
1339 @retval EFI_NOT_FOUND Routing data doesn't match any
1340 known driver. Progress set to the
1341 first character in the routing header.
1342 Note: There is no requirement that the
1343 driver validate the routing data. It
1344 must skip the <ConfigHdr> in order to
1346 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1347 to most recent & before the
1348 error or the beginning of the
1350 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1351 to the & before the name in
1352 question. Currently not implemented.
1356 Ip6FormExtractConfig (
1357 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1358 IN CONST EFI_STRING Request
,
1359 OUT EFI_STRING
*Progress
,
1360 OUT EFI_STRING
*Results
1365 IP6_FORM_CALLBACK_INFO
*Private
;
1366 IP6_CONFIG_INSTANCE
*Ip6ConfigInstance
;
1367 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1368 EFI_STRING ConfigRequestHdr
;
1369 EFI_STRING ConfigRequest
;
1370 BOOLEAN AllocatedRequest
;
1374 if (This
== NULL
|| Progress
== NULL
|| Results
== NULL
) {
1375 return EFI_INVALID_PARAMETER
;
1378 *Progress
= Request
;
1379 if ((Request
!= NULL
) &&
1380 !HiiIsConfigHdrMatch (Request
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1381 return EFI_NOT_FOUND
;
1384 ConfigRequestHdr
= NULL
;
1385 ConfigRequest
= NULL
;
1386 AllocatedRequest
= FALSE
;
1389 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1390 Ip6ConfigInstance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1391 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1393 IfrNvData
= (IP6_CONFIG_IFR_NVDATA
*) AllocateZeroPool (BufferSize
);
1394 if (IfrNvData
== NULL
) {
1395 return EFI_OUT_OF_RESOURCES
;
1398 Status
= Ip6ConvertConfigNvDataToIfrNvData (IfrNvData
, Ip6ConfigInstance
);
1399 if (EFI_ERROR (Status
)) {
1403 ConfigRequest
= Request
;
1404 if ((Request
== NULL
) || (StrStr (Request
, L
"OFFSET") == NULL
)) {
1406 // Request has no request element, construct full request string.
1407 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1408 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
1410 ConfigRequestHdr
= HiiConstructConfigHdr (
1411 &gIp6ConfigNvDataGuid
,
1412 mIp6ConfigStorageName
,
1413 Private
->ChildHandle
1415 Size
= (StrLen (ConfigRequestHdr
) + 32 + 1) * sizeof (CHAR16
);
1416 ConfigRequest
= AllocateZeroPool (Size
);
1417 ASSERT (ConfigRequest
!= NULL
);
1418 AllocatedRequest
= TRUE
;
1422 L
"%s&OFFSET=0&WIDTH=%016LX",
1426 FreePool (ConfigRequestHdr
);
1430 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1432 Status
= gHiiConfigRouting
->BlockToConfig (
1435 (UINT8
*) IfrNvData
,
1442 FreePool (IfrNvData
);
1444 // Free the allocated config request string.
1446 if (AllocatedRequest
) {
1447 FreePool (ConfigRequest
);
1448 ConfigRequest
= NULL
;
1451 // Set Progress string to the original request string.
1453 if (Request
== NULL
) {
1455 } else if (StrStr (Request
, L
"OFFSET") == NULL
) {
1456 *Progress
= Request
+ StrLen (Request
);
1463 This function applies changes in a driver's configuration.
1464 Input is a Configuration, which has the routing data for this
1465 driver followed by name / value configuration pairs. The driver
1466 must apply those pairs to its configurable storage. If the
1467 driver's configuration is stored in a linear block of data
1468 and the driver's name / value pairs are in <BlockConfig>
1469 format, it may use the ConfigToBlock helper function (above) to
1470 simplify the job. Currently not implemented.
1472 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1473 @param[in] Configuration A null-terminated Unicode string in
1474 <ConfigString> format.
1475 @param[out] Progress A pointer to a string filled in with the
1476 offset of the most recent '&' before the
1477 first failing name / value pair (or the
1478 beginn ing of the string if the failure
1479 is in the first name / value pair) or
1480 the terminating NULL if all was
1483 @retval EFI_SUCCESS The results have been distributed or are
1484 awaiting distribution.
1485 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1486 parts of the results that must be
1487 stored awaiting possible future
1489 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1490 Results parameter would result
1491 in this type of error.
1492 @retval EFI_NOT_FOUND Target for the specified routing data
1497 Ip6FormRouteConfig (
1498 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1499 IN CONST EFI_STRING Configuration
,
1500 OUT EFI_STRING
*Progress
1503 if (This
== NULL
|| Configuration
== NULL
|| Progress
== NULL
) {
1504 return EFI_INVALID_PARAMETER
;
1508 // Check routing data in <ConfigHdr>.
1509 // Note: if only one Storage is used, then this checking could be skipped.
1511 if (!HiiIsConfigHdrMatch (Configuration
, &gIp6ConfigNvDataGuid
, mIp6ConfigStorageName
)) {
1512 *Progress
= Configuration
;
1513 return EFI_NOT_FOUND
;
1516 *Progress
= Configuration
+ StrLen (Configuration
);
1522 Display host addresses, route table, DNS addresses and gateway addresses in
1523 "IPv6 Current Setting" page.
1525 @param[in] Instance The IP6 config instance data.
1527 @retval EFI_SUCCESS The operation finished successfully.
1528 @retval Others Other errors as indicated.
1532 Ip6GetCurrentSetting (
1533 IN IP6_CONFIG_INSTANCE
*Instance
1536 EFI_IP6_CONFIG_PROTOCOL
*Ip6Config
;
1537 EFI_HII_HANDLE HiiHandle
;
1538 EFI_IP6_CONFIG_INTERFACE_INFO
*Data
;
1541 CHAR16 PortString
[ADDRESS_STR_MAX_SIZE
];
1542 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
1545 Ip6Config
= &Instance
->Ip6Config
;
1546 HiiHandle
= Instance
->CallbackInfo
.RegisteredHandle
;
1550 // Get current interface info.
1552 Status
= Ip6ConfigNvGetData (
1554 Ip6ConfigDataTypeInterfaceInfo
,
1558 if (EFI_ERROR (Status
)) {
1563 // Generate dynamic text opcode for host address and draw it.
1565 IfInfo
= (EFI_IP6_CONFIG_INTERFACE_INFO
*) Data
;
1566 Status
= Ip6ConvertAddressListToString (
1569 Ip6ConfigNvHostAddress
,
1570 IfInfo
->AddressInfo
,
1571 IfInfo
->AddressInfoCount
1573 if (EFI_ERROR (Status
)) {
1579 // Generate the dynamic text opcode for route table and draw it.
1581 Status
= Ip6ConvertAddressListToString (
1584 Ip6ConfigNvRouteTable
,
1588 if (EFI_ERROR (Status
)) {
1594 // Get DNS server list.
1599 Status
= Ip6ConfigNvGetData (
1601 Ip6ConfigDataTypeDnsServer
,
1605 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1614 // Generate the dynamic text opcode for DNS server and draw it.
1616 Status
= Ip6ConvertAddressListToString (
1619 Ip6ConfigNvDnsAddress
,
1621 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1623 if (EFI_ERROR (Status
)) {
1630 // Get gateway adderss list.
1638 Status
= Ip6ConfigNvGetData (
1640 Ip6ConfigDataTypeGateway
,
1644 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
1653 // Generate the dynamic text opcode for gateway and draw it.
1655 Status
= Ip6ConvertAddressListToString (
1658 Ip6ConfigNvGatewayAddress
,
1660 DataSize
/ sizeof (EFI_IPv6_ADDRESS
)
1662 if (EFI_ERROR (Status
)) {
1676 This function is called to provide results data to the driver.
1677 This data consists of a unique key that is used to identify
1678 which data is either being passed back or being asked for.
1680 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1681 @param[in] Action Specifies the type of action taken by the browser.
1682 @param[in] QuestionId A unique value which is sent to the original
1683 exporting driver so that it can identify the type
1684 of data to expect. The format of the data tends to
1685 vary based on the opcode that generated the callback.
1686 @param[in] Type The type of value for the question.
1687 @param[in] Value A pointer to the data being sent to the original
1689 @param[out] ActionRequest On return, points to the action requested by the
1692 @retval EFI_SUCCESS The callback successfully handled the action.
1693 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1694 variable and its data.
1695 @retval EFI_DEVICE_ERROR The variable could not be saved.
1696 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1697 callback. Currently not implemented.
1698 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.
1699 @retval Others Other errors as indicated.
1705 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1706 IN EFI_BROWSER_ACTION Action
,
1707 IN EFI_QUESTION_ID QuestionId
,
1709 IN EFI_IFR_TYPE_VALUE
*Value
,
1710 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1713 IP6_FORM_CALLBACK_INFO
*Private
;
1715 IP6_CONFIG_IFR_NVDATA
*IfrNvData
;
1718 IP6_CONFIG_INSTANCE
*Instance
;
1719 IP6_CONFIG_NVDATA
*Ip6NvData
;
1722 return EFI_INVALID_PARAMETER
;
1725 Private
= IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This
);
1726 Instance
= IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private
);
1727 Ip6NvData
= &Instance
->Ip6NvData
;
1729 if ((Action
== EFI_BROWSER_ACTION_FORM_OPEN
) || (Action
== EFI_BROWSER_ACTION_FORM_CLOSE
)){
1733 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
1734 return EFI_UNSUPPORTED
;
1737 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1738 return EFI_INVALID_PARAMETER
;
1742 // Retrieve uncommitted data from Browser
1745 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1746 IfrNvData
= AllocateZeroPool (BufferSize
);
1747 if (IfrNvData
== NULL
) {
1748 return EFI_OUT_OF_RESOURCES
;
1751 Status
= EFI_SUCCESS
;
1753 HiiGetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
);
1755 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1756 switch (QuestionId
) {
1757 case KEY_GET_CURRENT_SETTING
:
1758 Status
= Ip6GetCurrentSetting (Instance
);
1764 } else if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
1765 switch (QuestionId
) {
1766 case KEY_SAVE_CONFIG_CHANGES
:
1767 Status
= Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData
, Instance
);
1768 if (EFI_ERROR (Status
)) {
1772 Status
= Ip6GetCurrentSetting (Instance
);
1774 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
;
1777 case KEY_IGNORE_CONFIG_CHANGES
:
1778 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
1779 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
1780 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
1782 Ip6NvData
->ManualAddressCount
= 0;
1783 Ip6NvData
->GatewayAddressCount
= 0;
1784 Ip6NvData
->DnsAddressCount
= 0;
1786 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
;
1789 case KEY_SAVE_CHANGES
:
1790 Status
= Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData
, Instance
);
1791 if (EFI_ERROR (Status
)) {
1794 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
1797 case KEY_INTERFACE_ID
:
1798 Status
= Ip6ParseInterfaceIdFromString (IfrNvData
->InterfaceId
, &Ip6NvData
->InterfaceId
);
1799 if (EFI_ERROR (Status
)) {
1801 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1803 L
"Invalid Interface ID!",
1810 case KEY_MANUAL_ADDRESS
:
1811 Status
= Ip6ParseAddressListFromString (
1812 IfrNvData
->ManualAddress
,
1813 &Ip6NvData
->ManualAddress
,
1814 &Ip6NvData
->ManualAddressCount
1816 if (EFI_ERROR (Status
)) {
1818 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1820 L
"Invalid Host Addresses!",
1827 case KEY_GATEWAY_ADDRESS
:
1828 Status
= Ip6ParseAddressListFromString (
1829 IfrNvData
->GatewayAddress
,
1830 &Ip6NvData
->GatewayAddress
,
1831 &Ip6NvData
->GatewayAddressCount
1833 if (EFI_ERROR (Status
)) {
1835 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1837 L
"Invalid Gateway Addresses!",
1844 case KEY_DNS_ADDRESS
:
1845 Status
= Ip6ParseAddressListFromString (
1846 IfrNvData
->DnsAddress
,
1847 &Ip6NvData
->DnsAddress
,
1848 &Ip6NvData
->DnsAddressCount
1850 if (EFI_ERROR (Status
)) {
1852 EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
,
1854 L
"Invalid DNS Addresses!",
1866 if (!EFI_ERROR (Status
)) {
1868 // Pass changed uncommitted data back to Form Browser.
1870 BufferSize
= sizeof (IP6_CONFIG_IFR_NVDATA
);
1871 HiiSetBrowserData (NULL
, NULL
, BufferSize
, (UINT8
*) IfrNvData
, NULL
);
1874 FreePool (IfrNvData
);
1879 Install HII Config Access protocol for network device and allocate resources.
1881 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.
1883 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1884 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1885 @retval Others Other errors as indicated.
1890 IN OUT IP6_CONFIG_INSTANCE
*Instance
1895 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
1896 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1897 VENDOR_DEVICE_PATH VendorDeviceNode
;
1898 EFI_SERVICE_BINDING_PROTOCOL
*MnpSb
;
1900 CHAR16 MenuString
[128];
1901 CHAR16 PortString
[128];
1902 CHAR16
*OldMenuString
;
1903 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1905 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
1906 ASSERT (IpSb
!= NULL
);
1908 Status
= gBS
->HandleProtocol (
1910 &gEfiDevicePathProtocolGuid
,
1911 (VOID
**) &ParentDevicePath
1913 if (EFI_ERROR (Status
)) {
1917 CallbackInfo
= &Instance
->CallbackInfo
;
1918 CallbackInfo
->Signature
= IP6_FORM_CALLBACK_INFO_SIGNATURE
;
1921 // Construct device path node for EFI HII Config Access protocol,
1922 // which consists of controller physical device path and one hardware
1923 // vendor guid node.
1925 ZeroMem (&VendorDeviceNode
, sizeof (VENDOR_DEVICE_PATH
));
1926 VendorDeviceNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
1927 VendorDeviceNode
.Header
.SubType
= HW_VENDOR_DP
;
1929 CopyGuid (&VendorDeviceNode
.Guid
, &gEfiCallerIdGuid
);
1931 SetDevicePathNodeLength (&VendorDeviceNode
.Header
, sizeof (VENDOR_DEVICE_PATH
));
1932 CallbackInfo
->HiiVendorDevicePath
= AppendDevicePathNode (
1934 (EFI_DEVICE_PATH_PROTOCOL
*) &VendorDeviceNode
1936 if (CallbackInfo
->HiiVendorDevicePath
== NULL
) {
1937 Status
= EFI_OUT_OF_RESOURCES
;
1941 ConfigAccess
= &CallbackInfo
->HiiConfigAccess
;
1942 ConfigAccess
->ExtractConfig
= Ip6FormExtractConfig
;
1943 ConfigAccess
->RouteConfig
= Ip6FormRouteConfig
;
1944 ConfigAccess
->Callback
= Ip6FormCallback
;
1947 // Install Device Path Protocol and Config Access protocol on new handle
1949 Status
= gBS
->InstallMultipleProtocolInterfaces (
1950 &CallbackInfo
->ChildHandle
,
1951 &gEfiDevicePathProtocolGuid
,
1952 CallbackInfo
->HiiVendorDevicePath
,
1953 &gEfiHiiConfigAccessProtocolGuid
,
1957 if (!EFI_ERROR (Status
)) {
1959 // Open the Parent Handle for the child
1961 Status
= gBS
->OpenProtocol (
1963 &gEfiManagedNetworkServiceBindingProtocolGuid
,
1966 CallbackInfo
->ChildHandle
,
1967 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1971 if (EFI_ERROR (Status
)) {
1976 // Publish our HII data
1978 CallbackInfo
->RegisteredHandle
= HiiAddPackages (
1979 &gIp6ConfigNvDataGuid
,
1980 CallbackInfo
->ChildHandle
,
1985 if (CallbackInfo
->RegisteredHandle
== NULL
) {
1986 Status
= EFI_OUT_OF_RESOURCES
;
1991 // Append MAC string in the menu help string and tile help string
1993 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &MacString
);
1994 if (!EFI_ERROR (Status
)) {
1995 OldMenuString
= HiiGetString (
1996 CallbackInfo
->RegisteredHandle
,
1997 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2000 UnicodeSPrint (MenuString
, 128, L
"%s (MAC:%s)", OldMenuString
, MacString
);
2002 CallbackInfo
->RegisteredHandle
,
2003 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP
),
2007 UnicodeSPrint (PortString
, 128, L
"MAC:%s", MacString
);
2009 CallbackInfo
->RegisteredHandle
,
2010 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP
),
2015 FreePool (MacString
);
2016 FreePool (OldMenuString
);
2018 InitializeListHead (&Instance
->Ip6NvData
.ManualAddress
);
2019 InitializeListHead (&Instance
->Ip6NvData
.GatewayAddress
);
2020 InitializeListHead (&Instance
->Ip6NvData
.DnsAddress
);
2026 Ip6ConfigFormUnload (Instance
);
2031 Uninstall the HII Config Access protocol for network devices and free up the resources.
2033 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.
2037 Ip6ConfigFormUnload (
2038 IN OUT IP6_CONFIG_INSTANCE
*Instance
2042 IP6_FORM_CALLBACK_INFO
*CallbackInfo
;
2043 IP6_CONFIG_NVDATA
*Ip6NvData
;
2045 IpSb
= IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance
);
2046 ASSERT (IpSb
!= NULL
);
2048 CallbackInfo
= &Instance
->CallbackInfo
;
2050 if (CallbackInfo
->ChildHandle
!= NULL
) {
2053 // Close the child handle
2055 gBS
->CloseProtocol (
2057 &gEfiManagedNetworkServiceBindingProtocolGuid
,
2059 CallbackInfo
->ChildHandle
2062 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
2064 gBS
->UninstallMultipleProtocolInterfaces (
2065 CallbackInfo
->ChildHandle
,
2066 &gEfiDevicePathProtocolGuid
,
2067 CallbackInfo
->HiiVendorDevicePath
,
2068 &gEfiHiiConfigAccessProtocolGuid
,
2069 &CallbackInfo
->HiiConfigAccess
,
2074 if (CallbackInfo
->HiiVendorDevicePath
!= NULL
) {
2075 FreePool (CallbackInfo
->HiiVendorDevicePath
);
2078 if (CallbackInfo
->RegisteredHandle
!= NULL
) {
2080 // Remove HII package list
2082 HiiRemovePackages (CallbackInfo
->RegisteredHandle
);
2085 Ip6NvData
= &Instance
->Ip6NvData
;
2087 Ip6FreeAddressInfoList (&Ip6NvData
->ManualAddress
);
2088 Ip6FreeAddressInfoList (&Ip6NvData
->GatewayAddress
);
2089 Ip6FreeAddressInfoList (&Ip6NvData
->DnsAddress
);
2091 Ip6NvData
->ManualAddressCount
= 0;
2092 Ip6NvData
->GatewayAddressCount
= 0;
2093 Ip6NvData
->DnsAddressCount
= 0;