2 The implementation for Shell application IfConfig6.
4 Copyright (c) 2009 - 2016, 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.
16 #include <Library/ShellLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/BaseLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiHiiServicesLib.h>
23 #include <Library/HiiLib.h>
24 #include <Library/NetLib.h>
26 #include <Protocol/Ip6.h>
27 #include <Protocol/Ip6Config.h>
29 #include "IfConfig6.h"
32 // String token ID of ifconfig6 command help message text.
34 GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringIfconfig6HelpTokenId
= STRING_TOKEN (STR_IFCONFIG6_HELP
);
36 EFI_HII_HANDLE mHiiHandle
;
38 SHELL_PARAM_ITEM mIfConfig6CheckList
[] = {
61 VAR_CHECK_ITEM mSetCheckList
[] = {
113 Split a string with specified separator and save the substring to a list.
115 @param[in] String The pointer of the input string.
116 @param[in] Separator The specified separator.
118 @return The pointer of headnode of ARG_LIST.
123 IN CONST CHAR16
*String
,
132 if (String
== NULL
|| *String
== L
'\0') {
137 // Copy the CONST string to a local copy.
139 Str
= AllocateCopyPool (StrSize (String
), String
);
140 ASSERT (Str
!= NULL
);
144 // init a node for the list head.
146 ArgNode
= (ARG_LIST
*) AllocateZeroPool (sizeof (ARG_LIST
));
147 ASSERT (ArgNode
!= NULL
);
151 // Split the local copy and save in the list node.
153 while (*Str
!= L
'\0') {
154 if (*Str
== Separator
) {
156 ArgNode
->Arg
= ArgStr
;
158 ArgNode
->Next
= (ARG_LIST
*) AllocateZeroPool (sizeof (ARG_LIST
));
159 ASSERT (ArgNode
->Next
!= NULL
);
160 ArgNode
= ArgNode
->Next
;
166 ArgNode
->Arg
= ArgStr
;
167 ArgNode
->Next
= NULL
;
173 Check the correctness of input Args with '-s' option.
175 @param[in] CheckList The pointer of VAR_CHECK_ITEM array.
176 @param[in] Name The pointer of input arg.
177 @param[in] Init The switch to execute the check.
179 @return The value of VAR_CHECK_CODE.
183 IfConfig6RetriveCheckListByName(
184 IN VAR_CHECK_ITEM
*CheckList
,
189 STATIC UINT32 CheckDuplicate
;
190 STATIC UINT32 CheckConflict
;
191 VAR_CHECK_CODE RtCode
;
203 Arg
= CheckList
[Index
];
206 // Check the Duplicated/Conflicted/Unknown input Args.
208 while (Arg
.FlagStr
!= NULL
) {
209 if (StrCmp (Arg
.FlagStr
, Name
) == 0) {
211 if (CheckDuplicate
& Arg
.FlagID
) {
212 RtCode
= VarCheckDuplicate
;
216 if (CheckConflict
& Arg
.ConflictMask
) {
217 RtCode
= VarCheckConflict
;
221 CheckDuplicate
|= Arg
.FlagID
;
222 CheckConflict
|= Arg
.ConflictMask
;
226 Arg
= CheckList
[++Index
];
229 if (Arg
.FlagStr
== NULL
) {
230 RtCode
= VarCheckUnknown
;
237 The notify function of create event when performing a manual config.
239 @param[in] Event The event this notify function registered to.
240 @param[in] Context Pointer to the context data registered to the event.
245 IfConfig6ManualAddressNotify (
250 *((BOOLEAN
*) Context
) = TRUE
;
256 @param[in] Node The pointer of MAC address buffer.
257 @param[in] Size The size of MAC address buffer.
261 IfConfig6PrintMacAddr (
268 ASSERT (Size
<= MACADDRMAXSIZE
);
270 for (Index
= 0; Index
< Size
; Index
++) {
271 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_BODY
), mHiiHandle
, Node
[Index
]);
272 if (Index
+ 1 < Size
) {
273 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
277 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
283 @param[in] Ip The pointer of Ip bufffer in EFI_IPv6_ADDRESS format.
284 @param[in] PrefixLen The pointer of PrefixLen that describes the size Prefix.
288 IfConfig6PrintIpAddr (
289 IN EFI_IPv6_ADDRESS
*Ip
,
298 for (Index
= 0; Index
< PREFIXMAXLEN
; Index
= Index
+ 2) {
300 if (!Short
&& (Index
+ 1 < PREFIXMAXLEN
) && (Index
% 2 == 0) && (Ip
->Addr
[Index
] == 0) && (Ip
->Addr
[Index
+ 1] == 0)) {
302 // Deal with the case of ::.
306 // :: is at the beginning of the address.
308 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
310 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
312 while ((Ip
->Addr
[Index
] == 0) && (Ip
->Addr
[Index
+ 1] == 0) && (Index
< PREFIXMAXLEN
)) {
314 if (Index
> PREFIXMAXLEN
- 2) {
321 if (Index
== PREFIXMAXLEN
) {
323 // :: is at the end of the address.
329 if (Index
< PREFIXMAXLEN
- 1) {
330 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY
), mHiiHandle
, Ip
->Addr
[Index
]);
331 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY
), mHiiHandle
, Ip
->Addr
[Index
+ 1]);
334 if (Index
+ 2 < PREFIXMAXLEN
) {
335 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
339 if (PrefixLen
!= NULL
) {
340 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN
), mHiiHandle
, *PrefixLen
);
345 Pick up host IPv6 address in string format from Args with "-s" option and convert it to EFI_IP6_CONFIG_MANUAL_ADDRESS format.
347 @param[in, out] Arg The pointer of the address of ARG_LIST which save Args with the "-s" option.
348 @param[out] Buf The pointer of the address of EFI_IP6_CONFIG_MANUAL_ADDRESS.
349 @param[out] BufSize The pointer of BufSize that describes the size of Buf in bytes.
351 @retval EFI_SUCCESS The convertion is successful.
352 @retval Others Does't find the host address, or it is an invalid IPv6 address in string format.
356 IfConfig6ParseManualAddressList (
357 IN OUT ARG_LIST
**Arg
,
358 OUT EFI_IP6_CONFIG_MANUAL_ADDRESS
**Buf
,
363 EFI_IP6_CONFIG_MANUAL_ADDRESS
*AddrBuf
;
365 EFI_IPv6_ADDRESS Address
;
374 Status
= EFI_SUCCESS
;
377 // Go through the list to check the correctness of input host ip6 address.
379 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
381 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
383 if (EFI_ERROR (Status
)) {
390 VarArg
= VarArg
->Next
;
395 return EFI_INVALID_PARAMETER
;
398 AddrBuf
= AllocateZeroPool (AddrCnt
* sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
));
399 ASSERT (AddrBuf
!= NULL
);
403 Status
= EFI_SUCCESS
;
406 // Go through the list to fill in the EFI_IP6_CONFIG_MANUAL_ADDRESS structure.
408 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
410 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
412 if (EFI_ERROR (Status
)) {
417 // If prefix length is not set, set it as Zero here. In the IfConfigSetInterfaceInfo()
418 // Zero prefix, length will be transfered to default prefix length.
420 if (Prefix
== 0xFF) {
423 AddrBuf
[AddrCnt
].IsAnycast
= FALSE
;
424 AddrBuf
[AddrCnt
].PrefixLength
= Prefix
;
425 IP6_COPY_ADDRESS (&AddrBuf
[AddrCnt
].Address
, &Address
);
426 VarArg
= VarArg
->Next
;
432 if (EFI_ERROR (Status
) && (Status
!= EFI_INVALID_PARAMETER
)) {
437 *BufSize
= AddrCnt
* sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
);
448 Pick up gw/dns IPv6 address in string format from Args with "-s" option and convert it to EFI_IPv6_ADDRESS format.
450 @param[in, out] Arg The pointer of the address of ARG_LIST that save Args with the "-s" option.
451 @param[out] Buf The pointer of the address of EFI_IPv6_ADDRESS.
452 @param[out] BufSize The pointer of BufSize that describes the size of Buf in bytes.
454 @retval EFI_SUCCESS The conversion is successful.
455 @retval Others Doesn't find the host address, or it is an invalid IPv6 address in string format.
459 IfConfig6ParseGwDnsAddressList (
460 IN OUT ARG_LIST
**Arg
,
461 OUT EFI_IPv6_ADDRESS
**Buf
,
466 EFI_IPv6_ADDRESS
*AddrBuf
;
468 EFI_IPv6_ADDRESS Address
;
476 Status
= EFI_SUCCESS
;
479 // Go through the list to check the correctness of input gw/dns address.
481 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
483 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
485 if (EFI_ERROR (Status
)) {
492 VarArg
= VarArg
->Next
;
497 return EFI_INVALID_PARAMETER
;
500 AddrBuf
= AllocateZeroPool (AddrCnt
* sizeof (EFI_IPv6_ADDRESS
));
501 ASSERT (AddrBuf
!= NULL
);
505 Status
= EFI_SUCCESS
;
508 // Go through the list to fill in the EFI_IPv6_ADDRESS structure.
510 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
512 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
514 if (EFI_ERROR (Status
)) {
518 IP6_COPY_ADDRESS (&AddrBuf
[AddrCnt
], &Address
);
520 VarArg
= VarArg
->Next
;
526 if (EFI_ERROR (Status
) && (Status
!= EFI_INVALID_PARAMETER
)) {
531 *BufSize
= AddrCnt
* sizeof (EFI_IPv6_ADDRESS
);
542 Parse InterfaceId in string format from Args with the "-s" option and convert it to EFI_IP6_CONFIG_INTERFACE_ID format.
544 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
545 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
547 @retval EFI_SUCCESS The get status processed successfullly.
548 @retval EFI_INVALID_PARAMETER The get status process failed.
552 IfConfig6ParseInterfaceId (
553 IN OUT ARG_LIST
**Arg
,
554 OUT EFI_IP6_CONFIG_INTERFACE_ID
**IfId
562 return EFI_INVALID_PARAMETER
;
567 ASSERT (IfId
!= NULL
);
568 *IfId
= AllocateZeroPool (sizeof (EFI_IP6_CONFIG_INTERFACE_ID
));
569 ASSERT (*IfId
!= NULL
);
571 while ((*IdStr
!= L
'\0') && (Index
< 8)) {
574 while ((*IdStr
!= L
':') && (*IdStr
!= L
'\0')) {
576 if ((*IdStr
<= L
'F') && (*IdStr
>= L
'A')) {
577 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'A' + 10);
578 } else if ((*IdStr
<= L
'f') && (*IdStr
>= L
'a')) {
579 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'a' + 10);
580 } else if ((*IdStr
<= L
'9') && (*IdStr
>= L
'0')) {
581 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'0');
584 return EFI_INVALID_PARAMETER
;
590 (*IfId
)->Id
[Index
++] = NodeVal
;
592 if (*IdStr
== L
':') {
602 Parse dad in string format from Args with the "-s" option and convert it to UINT32 format.
604 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
605 @param[out] Xmits The pointer of Xmits.
607 @retval EFI_SUCCESS The get status processed successfully.
608 @retval others The get status process failed.
612 IfConfig6ParseDadXmits (
613 IN OUT ARG_LIST
**Arg
,
620 return EFI_INVALID_PARAMETER
;
623 ValStr
= (*Arg
)->Arg
;
626 while (*ValStr
!= L
'\0') {
628 if ((*ValStr
<= L
'9') && (*ValStr
>= L
'0')) {
630 *Xmits
= (*Xmits
* 10) + (*ValStr
- L
'0');
634 return EFI_INVALID_PARAMETER
;
645 The get current status of all handles.
647 @param[in] ImageHandle The handle of ImageHandle.
648 @param[in] IfName The pointer of IfName(interface name).
649 @param[in] IfList The pointer of IfList(interface list).
651 @retval EFI_SUCCESS The get status processed successfully.
652 @retval others The get status process failed.
656 IfConfig6GetInterfaceInfo (
657 IN EFI_HANDLE ImageHandle
,
659 IN LIST_ENTRY
*IfList
665 EFI_HANDLE
*HandleBuffer
;
666 EFI_IP6_CONFIG_PROTOCOL
*Ip6Cfg
;
667 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
668 IFCONFIG6_INTERFACE_CB
*IfCb
;
678 // Locate all the handles with ip6 service binding protocol.
680 Status
= gBS
->LocateHandleBuffer (
682 &gEfiIp6ServiceBindingProtocolGuid
,
687 if (EFI_ERROR (Status
) || (HandleNum
== 0)) {
692 // Enumerate all handles that installed with ip6 service binding protocol.
694 for (HandleIndex
= 0; HandleIndex
< HandleNum
; HandleIndex
++) {
700 // Ip6config protocol and ip6 service binding protocol are installed
701 // on the same handle.
703 ASSERT (HandleBuffer
!= NULL
);
704 Status
= gBS
->HandleProtocol (
705 HandleBuffer
[HandleIndex
],
706 &gEfiIp6ConfigProtocolGuid
,
710 if (EFI_ERROR (Status
)) {
714 // Get the interface information size.
716 Status
= Ip6Cfg
->GetData (
718 Ip6ConfigDataTypeInterfaceInfo
,
723 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
724 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
728 IfInfo
= AllocateZeroPool (DataSize
);
730 if (IfInfo
== NULL
) {
731 Status
= EFI_OUT_OF_RESOURCES
;
735 // Get the interface info.
737 Status
= Ip6Cfg
->GetData (
739 Ip6ConfigDataTypeInterfaceInfo
,
744 if (EFI_ERROR (Status
)) {
745 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
749 // Check the interface name if required.
751 if ((IfName
!= NULL
) && (StrCmp (IfName
, IfInfo
->Name
) != 0)) {
758 // Get the size of dns server list.
760 Status
= Ip6Cfg
->GetData (
762 Ip6ConfigDataTypeDnsServer
,
767 if ((Status
!= EFI_BUFFER_TOO_SMALL
) && (Status
!= EFI_NOT_FOUND
)) {
768 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
772 IfCb
= AllocateZeroPool (sizeof (IFCONFIG6_INTERFACE_CB
) + DataSize
);
775 Status
= EFI_OUT_OF_RESOURCES
;
779 IfCb
->NicHandle
= HandleBuffer
[HandleIndex
];
780 IfCb
->IfInfo
= IfInfo
;
781 IfCb
->IfCfg
= Ip6Cfg
;
782 IfCb
->DnsCnt
= (UINT32
) (DataSize
/ sizeof (EFI_IPv6_ADDRESS
));
785 // Get the dns server list if has.
789 Status
= Ip6Cfg
->GetData (
791 Ip6ConfigDataTypeDnsServer
,
796 if (EFI_ERROR (Status
)) {
797 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
802 // Get the interface id if has.
804 DataSize
= sizeof (EFI_IP6_CONFIG_INTERFACE_ID
);
805 IfCb
->IfId
= AllocateZeroPool (DataSize
);
807 if (IfCb
->IfId
== NULL
) {
811 Status
= Ip6Cfg
->GetData (
813 Ip6ConfigDataTypeAltInterfaceId
,
818 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
819 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
823 if (Status
== EFI_NOT_FOUND
) {
824 FreePool (IfCb
->IfId
);
828 // Get the config policy.
830 DataSize
= sizeof (EFI_IP6_CONFIG_POLICY
);
831 Status
= Ip6Cfg
->GetData (
833 Ip6ConfigDataTypePolicy
,
838 if (EFI_ERROR (Status
)) {
839 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
843 // Get the dad transmits.
845 DataSize
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
846 Status
= Ip6Cfg
->GetData (
848 Ip6ConfigDataTypeDupAddrDetectTransmits
,
853 if (EFI_ERROR (Status
)) {
854 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
858 InsertTailList (IfList
, &IfCb
->Link
);
860 if ((IfName
!= NULL
) && (StrCmp (IfName
, IfInfo
->Name
) == 0)) {
862 // Only need the appointed interface, keep the allocated buffer.
870 if (HandleBuffer
!= NULL
) {
871 FreePool (HandleBuffer
);
878 if (IfInfo
!= NULL
) {
883 if (IfCb
->IfId
!= NULL
) {
884 FreePool (IfCb
->IfId
);
894 The list process of the IfConfig6 application.
896 @param[in] IfList The pointer of IfList(interface list).
898 @retval EFI_SUCCESS The IfConfig6 list processed successfully.
899 @retval others The IfConfig6 list process failed.
903 IfConfig6ShowInterfaceInfo (
904 IN LIST_ENTRY
*IfList
909 IFCONFIG6_INTERFACE_CB
*IfCb
;
912 Entry
= IfList
->ForwardLink
;
913 Status
= EFI_SUCCESS
;
915 if (IsListEmpty (IfList
)) {
916 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
920 // Go through the interface list.
922 while (Entry
!= IfList
) {
924 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
926 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK
), mHiiHandle
);
929 // Print interface name.
931 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME
), mHiiHandle
, IfCb
->IfInfo
->Name
);
934 // Print interface config policy.
936 if (IfCb
->Policy
== Ip6ConfigPolicyAutomatic
) {
937 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO
), mHiiHandle
);
939 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN
), mHiiHandle
);
943 // Print dad transmit.
945 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS
), mHiiHandle
, IfCb
->Xmits
);
948 // Print interface id if has.
950 if (IfCb
->IfId
!= NULL
) {
951 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD
), mHiiHandle
);
953 IfConfig6PrintMacAddr (
959 // Print mac address of the interface.
961 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD
), mHiiHandle
);
963 IfConfig6PrintMacAddr (
964 IfCb
->IfInfo
->HwAddress
.Addr
,
965 IfCb
->IfInfo
->HwAddressSize
969 // Print ip addresses list of the interface.
971 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_HEAD
), mHiiHandle
);
973 for (Index
= 0; Index
< IfCb
->IfInfo
->AddressInfoCount
; Index
++) {
974 IfConfig6PrintIpAddr (
975 &IfCb
->IfInfo
->AddressInfo
[Index
].Address
,
976 &IfCb
->IfInfo
->AddressInfo
[Index
].PrefixLength
978 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
982 // Print dns server addresses list of the interface if has.
984 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD
), mHiiHandle
);
986 for (Index
= 0; Index
< IfCb
->DnsCnt
; Index
++) {
987 IfConfig6PrintIpAddr (
988 &IfCb
->DnsAddr
[Index
],
991 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
995 // Print route table of the interface if has.
997 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD
), mHiiHandle
);
999 for (Index
= 0; Index
< IfCb
->IfInfo
->RouteCount
; Index
++) {
1000 IfConfig6PrintIpAddr (
1001 &IfCb
->IfInfo
->RouteTable
[Index
].Destination
,
1002 &IfCb
->IfInfo
->RouteTable
[Index
].PrefixLength
1004 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_JOINT
), mHiiHandle
);
1006 IfConfig6PrintIpAddr (
1007 &IfCb
->IfInfo
->RouteTable
[Index
].Gateway
,
1010 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
1013 Entry
= Entry
->ForwardLink
;
1016 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK
), mHiiHandle
);
1022 The clean process of the IfConfig6 application.
1024 @param[in] IfList The pointer of IfList(interface list).
1026 @retval EFI_SUCCESS The IfConfig6 clean processed successfully.
1027 @retval others The IfConfig6 clean process failed.
1031 IfConfig6ClearInterfaceInfo (
1032 IN LIST_ENTRY
*IfList
1037 IFCONFIG6_INTERFACE_CB
*IfCb
;
1038 EFI_IP6_CONFIG_POLICY Policy
;
1040 Policy
= Ip6ConfigPolicyAutomatic
;
1041 Entry
= IfList
->ForwardLink
;
1042 Status
= EFI_SUCCESS
;
1044 if (IsListEmpty (IfList
)) {
1045 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
1049 // Go through the interface list.
1051 while (Entry
!= IfList
) {
1053 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
1055 Status
= IfCb
->IfCfg
->SetData (
1057 Ip6ConfigDataTypePolicy
,
1058 sizeof (EFI_IP6_CONFIG_POLICY
),
1062 if (EFI_ERROR (Status
)) {
1066 Entry
= Entry
->ForwardLink
;
1073 The set process of the IfConfig6 application.
1075 @param[in] IfList The pointer of IfList(interface list).
1076 @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option).
1078 @retval EFI_SUCCESS The IfConfig6 set processed successfully.
1079 @retval others The IfConfig6 set process failed.
1083 IfConfig6SetInterfaceInfo (
1084 IN LIST_ENTRY
*IfList
,
1089 IFCONFIG6_INTERFACE_CB
*IfCb
;
1090 EFI_IP6_CONFIG_MANUAL_ADDRESS
*CfgManAddr
;
1091 EFI_IPv6_ADDRESS
*CfgAddr
;
1093 EFI_IP6_CONFIG_INTERFACE_ID
*InterfaceId
;
1096 UINTN CurDadXmitsLen
;
1097 EFI_IP6_CONFIG_POLICY Policy
;
1099 VAR_CHECK_CODE CheckCode
;
1100 EFI_EVENT TimeOutEvt
;
1101 EFI_EVENT MappedEvt
;
1102 BOOLEAN IsAddressOk
;
1107 BOOLEAN IsAddressSet
;
1108 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
1118 if (IsListEmpty (IfList
)) {
1119 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
1120 return EFI_INVALID_PARAMETER
;
1123 // Make sure to set only one interface each time.
1125 IfCb
= BASE_CR (IfList
->ForwardLink
, IFCONFIG6_INTERFACE_CB
, Link
);
1126 Status
= EFI_SUCCESS
;
1129 // Initialize check list mechanism.
1131 CheckCode
= IfConfig6RetriveCheckListByName(
1138 // Create events & timers for asynchronous settings.
1140 Status
= gBS
->CreateEvent (
1147 if (EFI_ERROR (Status
)) {
1151 Status
= gBS
->CreateEvent (
1154 IfConfig6ManualAddressNotify
,
1158 if (EFI_ERROR (Status
)) {
1162 // Parse the setting variables.
1164 while (VarArg
!= NULL
) {
1166 // Check invalid parameters (duplication & unknown & conflict).
1168 CheckCode
= IfConfig6RetriveCheckListByName(
1174 if (VarCheckOk
!= CheckCode
) {
1175 switch (CheckCode
) {
1176 case VarCheckDuplicate
:
1177 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1180 case VarCheckConflict
:
1181 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1184 case VarCheckUnknown
:
1185 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1192 VarArg
= VarArg
->Next
;
1196 // Process valid variables.
1198 if (StrCmp(VarArg
->Arg
, L
"auto") == 0) {
1200 // Set automaic config policy
1202 Policy
= Ip6ConfigPolicyAutomatic
;
1203 Status
= IfCb
->IfCfg
->SetData (
1205 Ip6ConfigDataTypePolicy
,
1206 sizeof (EFI_IP6_CONFIG_POLICY
),
1210 if (EFI_ERROR(Status
)) {
1214 VarArg
= VarArg
->Next
;
1216 } else if (StrCmp (VarArg
->Arg
, L
"man") == 0) {
1218 // Set manual config policy.
1220 Policy
= Ip6ConfigPolicyManual
;
1221 Status
= IfCb
->IfCfg
->SetData (
1223 Ip6ConfigDataTypePolicy
,
1224 sizeof (EFI_IP6_CONFIG_POLICY
),
1228 if (EFI_ERROR(Status
)) {
1232 VarArg
= VarArg
->Next
;
1234 } else if (StrCmp (VarArg
->Arg
, L
"host") == 0) {
1236 // Parse till the next tag or the end of command line.
1238 VarArg
= VarArg
->Next
;
1239 Status
= IfConfig6ParseManualAddressList (
1245 if (EFI_ERROR (Status
)) {
1246 if (Status
== EFI_INVALID_PARAMETER
) {
1247 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"host");
1254 // Set static host ip6 address list.
1255 // This is a asynchronous process.
1257 IsAddressOk
= FALSE
;
1259 Status
= IfCb
->IfCfg
->RegisterDataNotify (
1261 Ip6ConfigDataTypeManualAddress
,
1264 if (EFI_ERROR (Status
)) {
1268 Status
= IfCb
->IfCfg
->SetData (
1270 Ip6ConfigDataTypeManualAddress
,
1275 if (Status
== EFI_NOT_READY
) {
1277 // Get current dad transmits count.
1279 CurDadXmitsLen
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
1280 IfCb
->IfCfg
->GetData (
1282 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1287 gBS
->SetTimer (TimeOutEvt
, TimerRelative
, 50000000 + 10000000 * CurDadXmits
);
1289 while (EFI_ERROR (gBS
->CheckEvent (TimeOutEvt
))) {
1291 Status
= EFI_SUCCESS
;
1297 IfCb
->IfCfg
->UnregisterDataNotify (
1299 Ip6ConfigDataTypeManualAddress
,
1303 if (EFI_ERROR (Status
)) {
1304 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST
), mHiiHandle
, Status
);
1309 // Check whether the address is set successfully.
1313 Status
= IfCb
->IfCfg
->GetData (
1315 Ip6ConfigDataTypeInterfaceInfo
,
1320 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1321 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
1325 IfInfo
= AllocateZeroPool (DataSize
);
1327 if (IfInfo
== NULL
) {
1328 Status
= EFI_OUT_OF_RESOURCES
;
1332 Status
= IfCb
->IfCfg
->GetData (
1334 Ip6ConfigDataTypeInterfaceInfo
,
1339 if (EFI_ERROR (Status
)) {
1340 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
1344 for ( Index
= 0; Index
< (UINTN
) (AddrSize
/ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
)); Index
++) {
1345 IsAddressSet
= FALSE
;
1347 // By default, the prefix length 0 is regarded as 64.
1349 if (CfgManAddr
[Index
].PrefixLength
== 0) {
1350 CfgManAddr
[Index
].PrefixLength
= 64;
1353 for (Index2
= 0; Index2
< IfInfo
->AddressInfoCount
; Index2
++) {
1354 if (EFI_IP6_EQUAL (&IfInfo
->AddressInfo
[Index2
].Address
, &CfgManAddr
[Index
].Address
) &&
1355 (IfInfo
->AddressInfo
[Index2
].PrefixLength
== CfgManAddr
[Index
].PrefixLength
)) {
1356 IsAddressSet
= TRUE
;
1361 if (!IsAddressSet
) {
1362 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED
), mHiiHandle
);
1363 IfConfig6PrintIpAddr (
1364 &CfgManAddr
[Index
].Address
,
1365 &CfgManAddr
[Index
].PrefixLength
1370 } else if (StrCmp (VarArg
->Arg
, L
"gw") == 0) {
1372 // Parse till the next tag or the end of command line.
1374 VarArg
= VarArg
->Next
;
1375 Status
= IfConfig6ParseGwDnsAddressList (
1381 if (EFI_ERROR (Status
)) {
1382 if (Status
== EFI_INVALID_PARAMETER
) {
1383 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"gw");
1390 // Set static gateway ip6 address list.
1392 Status
= IfCb
->IfCfg
->SetData (
1394 Ip6ConfigDataTypeGateway
,
1399 if (EFI_ERROR (Status
)) {
1403 } else if (StrCmp (VarArg
->Arg
, L
"dns") == 0) {
1405 // Parse till the next tag or the end of command line.
1407 VarArg
= VarArg
->Next
;
1408 Status
= IfConfig6ParseGwDnsAddressList (
1414 if (EFI_ERROR (Status
)) {
1415 if (Status
== EFI_INVALID_PARAMETER
) {
1416 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"dns");
1423 // Set static dhs server ip6 address list.
1425 Status
= IfCb
->IfCfg
->SetData (
1427 Ip6ConfigDataTypeDnsServer
,
1432 if (EFI_ERROR (Status
)) {
1436 } else if (StrCmp (VarArg
->Arg
, L
"id") == 0) {
1438 // Parse till the next tag or the end of command line.
1440 VarArg
= VarArg
->Next
;
1441 Status
= IfConfig6ParseInterfaceId (&VarArg
, &InterfaceId
);
1443 if (EFI_ERROR (Status
)) {
1447 // Set alternative interface id.
1449 Status
= IfCb
->IfCfg
->SetData (
1451 Ip6ConfigDataTypeAltInterfaceId
,
1452 sizeof (EFI_IP6_CONFIG_INTERFACE_ID
),
1456 if (EFI_ERROR (Status
)) {
1460 } else if (StrCmp (VarArg
->Arg
, L
"dad") == 0) {
1462 // Parse till the next tag or the end of command line.
1464 VarArg
= VarArg
->Next
;
1465 Status
= IfConfig6ParseDadXmits (&VarArg
, &DadXmits
);
1467 if (EFI_ERROR (Status
)) {
1471 // Set dad transmits count.
1473 Status
= IfCb
->IfCfg
->SetData (
1475 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1476 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
),
1480 if (EFI_ERROR(Status
)) {
1488 if (CfgManAddr
!= NULL
) {
1489 FreePool (CfgManAddr
);
1492 if (CfgAddr
!= NULL
) {
1496 if (MappedEvt
!= NULL
) {
1497 gBS
->CloseEvent (MappedEvt
);
1500 if (TimeOutEvt
!= NULL
) {
1501 gBS
->CloseEvent (TimeOutEvt
);
1504 if (IfInfo
!= NULL
) {
1513 The IfConfig6 main process.
1515 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1517 @retval EFI_SUCCESS IfConfig6 processed successfully.
1518 @retval others The IfConfig6 process failed.
1523 IN IFCONFIG6_PRIVATE_DATA
*Private
1529 // Get configure information of all interfaces.
1531 Status
= IfConfig6GetInterfaceInfo (
1532 Private
->ImageHandle
,
1537 if (EFI_ERROR (Status
)) {
1541 switch (Private
->OpCode
) {
1542 case IfConfig6OpList
:
1543 Status
= IfConfig6ShowInterfaceInfo (&Private
->IfList
);
1546 case IfConfig6OpClear
:
1547 Status
= IfConfig6ClearInterfaceInfo (&Private
->IfList
);
1550 case IfConfig6OpSet
:
1551 Status
= IfConfig6SetInterfaceInfo (&Private
->IfList
, Private
->VarArg
);
1555 Status
= EFI_ABORTED
;
1564 The IfConfig6 cleanup process, free the allocated memory.
1566 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1571 IN IFCONFIG6_PRIVATE_DATA
*Private
1575 LIST_ENTRY
*NextEntry
;
1576 IFCONFIG6_INTERFACE_CB
*IfCb
;
1580 ASSERT (Private
!= NULL
);
1583 // Clean the list which save the set config Args.
1585 if (Private
->VarArg
!= NULL
) {
1586 ArgHead
= Private
->VarArg
;
1588 while (ArgHead
->Next
!= NULL
) {
1589 ArgNode
= ArgHead
->Next
;
1597 if (Private
->IfName
!= NULL
)
1598 FreePool (Private
->IfName
);
1602 // Clean the IFCONFIG6_INTERFACE_CB list.
1604 Entry
= Private
->IfList
.ForwardLink
;
1605 NextEntry
= Entry
->ForwardLink
;
1607 while (Entry
!= &Private
->IfList
) {
1609 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
1611 RemoveEntryList (&IfCb
->Link
);
1613 if (IfCb
->IfId
!= NULL
) {
1615 FreePool (IfCb
->IfId
);
1618 if (IfCb
->IfInfo
!= NULL
) {
1620 FreePool (IfCb
->IfInfo
);
1626 NextEntry
= Entry
->ForwardLink
;
1633 This is the declaration of an EFI image entry point. This entry point is
1634 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
1635 both device drivers and bus drivers.
1637 The entry point for the IfConfig6 application which parses the command line input and calls the IfConfig6 process.
1639 @param[in] ImageHandle The image handle of this application.
1640 @param[in] SystemTable The pointer to the EFI System Table.
1642 @retval EFI_SUCCESS The operation completed successfully.
1643 @retval Others Some errors occur.
1648 IfConfig6Initialize (
1649 IN EFI_HANDLE ImageHandle
,
1650 IN EFI_SYSTEM_TABLE
*SystemTable
1654 IFCONFIG6_PRIVATE_DATA
*Private
;
1655 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
1656 LIST_ENTRY
*ParamPackage
;
1657 CONST CHAR16
*ValueStr
;
1659 CHAR16
*ProblemParam
;
1665 // Retrieve HII package list from ImageHandle
1667 Status
= gBS
->OpenProtocol (
1669 &gEfiHiiPackageListProtocolGuid
,
1670 (VOID
**) &PackageList
,
1673 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1675 if (EFI_ERROR (Status
)) {
1680 // Publish HII package list to HII Database.
1682 Status
= gHiiDatabase
->NewPackageList (
1688 if (EFI_ERROR (Status
)) {
1692 ASSERT (mHiiHandle
!= NULL
);
1694 Status
= ShellCommandLineParseEx (mIfConfig6CheckList
, &ParamPackage
, &ProblemParam
, TRUE
, FALSE
);
1695 if (EFI_ERROR (Status
)) {
1696 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND
), mHiiHandle
, ProblemParam
);
1701 // To handle no option.
1703 if (!ShellCommandLineGetFlag (ParamPackage
, L
"-r") && !ShellCommandLineGetFlag (ParamPackage
, L
"-s") &&
1704 !ShellCommandLineGetFlag (ParamPackage
, L
"-l")) {
1705 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_LACK_OPTION
), mHiiHandle
);
1709 // To handle conflict options.
1711 if (((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-s"))) ||
1712 ((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-l"))) ||
1713 ((ShellCommandLineGetFlag (ParamPackage
, L
"-s")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-l")))) {
1714 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_CONFLICT_OPTIONS
), mHiiHandle
);
1718 Status
= EFI_INVALID_PARAMETER
;
1720 Private
= AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA
));
1722 if (Private
== NULL
) {
1723 Status
= EFI_OUT_OF_RESOURCES
;
1727 InitializeListHead (&Private
->IfList
);
1730 // To get interface name for the list option.
1732 if (ShellCommandLineGetFlag (ParamPackage
, L
"-l")) {
1733 Private
->OpCode
= IfConfig6OpList
;
1734 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-l");
1735 if (ValueStr
!= NULL
) {
1736 Str
= AllocateCopyPool (StrSize (ValueStr
), ValueStr
);
1737 ASSERT (Str
!= NULL
);
1738 Private
->IfName
= Str
;
1742 // To get interface name for the clear option.
1744 if (ShellCommandLineGetFlag (ParamPackage
, L
"-r")) {
1745 Private
->OpCode
= IfConfig6OpClear
;
1746 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-r");
1747 if (ValueStr
!= NULL
) {
1748 Str
= AllocateCopyPool (StrSize (ValueStr
), ValueStr
);
1749 ASSERT (Str
!= NULL
);
1750 Private
->IfName
= Str
;
1754 // To get interface name and corresponding Args for the set option.
1756 if (ShellCommandLineGetFlag (ParamPackage
, L
"-s")) {
1758 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-s");
1759 if (ValueStr
== NULL
) {
1760 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_INTERFACE
), mHiiHandle
);
1764 // To split the configuration into multi-section.
1766 ArgList
= SplitStrToList (ValueStr
, L
' ');
1767 ASSERT (ArgList
!= NULL
);
1769 Private
->OpCode
= IfConfig6OpSet
;
1770 Private
->IfName
= ArgList
->Arg
;
1772 Private
->VarArg
= ArgList
->Next
;
1774 if (Private
->IfName
== NULL
|| Private
->VarArg
== NULL
) {
1775 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_COMMAND
), mHiiHandle
);
1780 // Main process of ifconfig6.
1782 Status
= IfConfig6 (Private
);
1786 ShellCommandLineFreeVarList (ParamPackage
);
1787 HiiRemovePackages (mHiiHandle
);
1788 if (Private
!= NULL
)
1789 IfConfig6Cleanup (Private
);