2 The implementation for Shell application IfConfig6.
4 Copyright (c) 2009 - 2011, 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/HiiLib.h>
23 #include <Library/NetLib.h>
25 #include <Protocol/Ip6.h>
26 #include <Protocol/Ip6Config.h>
28 #include "IfConfig6.h"
30 EFI_HII_HANDLE mHiiHandle
;
32 SHELL_PARAM_ITEM mIfConfig6CheckList
[] = {
59 VAR_CHECK_ITEM mSetCheckList
[] = {
111 Split a string with specified separator and save the substring to a list.
113 @param[in] String The pointer of the input string.
114 @param[in] Separator The specified separator.
116 @return The pointer of headnode of ARG_LIST.
121 IN CONST CHAR16
*String
,
130 if (*String
== L
'\0') {
135 // Copy the CONST string to a local copy.
137 Str
= (CHAR16
*) AllocateZeroPool (StrSize (String
));
138 ASSERT (Str
!= NULL
);
139 Str
= StrCpy (Str
, String
);
143 // init a node for the list head.
145 ArgNode
= (ARG_LIST
*) AllocateZeroPool (sizeof (ARG_LIST
));
146 ASSERT (ArgNode
!= NULL
);
150 // Split the local copy and save in the list node.
152 while (*Str
!= L
'\0') {
153 if (*Str
== Separator
) {
155 ArgNode
->Arg
= ArgStr
;
157 ArgNode
->Next
= (ARG_LIST
*) AllocateZeroPool (sizeof (ARG_LIST
));
158 ASSERT (ArgNode
->Next
!= NULL
);
159 ArgNode
= ArgNode
->Next
;
165 ArgNode
->Arg
= ArgStr
;
166 ArgNode
->Next
= NULL
;
172 Check the correctness of input Args with '-s' option.
174 @param[in] CheckList The pointer of VAR_CHECK_ITEM array.
175 @param[in] Name The pointer of input arg.
176 @param[in] Init The switch to execute the check.
178 @return The value of VAR_CHECK_CODE.
182 IfConfig6RetriveCheckListByName(
183 IN VAR_CHECK_ITEM
*CheckList
,
188 STATIC UINT32 CheckDuplicate
;
189 STATIC UINT32 CheckConflict
;
190 VAR_CHECK_CODE RtCode
;
202 Arg
= CheckList
[Index
];
205 // Check the Duplicated/Conflicted/Unknown input Args.
207 while (Arg
.FlagStr
!= NULL
) {
208 if (StrCmp (Arg
.FlagStr
, Name
) == 0) {
210 if (CheckDuplicate
& Arg
.FlagID
) {
211 RtCode
= VarCheckDuplicate
;
215 if (CheckConflict
& Arg
.ConflictMask
) {
216 RtCode
= VarCheckConflict
;
220 CheckDuplicate
|= Arg
.FlagID
;
221 CheckConflict
|= Arg
.ConflictMask
;
225 Arg
= CheckList
[++Index
];
228 if (Arg
.FlagStr
== NULL
) {
229 RtCode
= VarCheckUnknown
;
236 The notify function of create event when performing a manual config.
238 @param[in] Event The event this notify function registered to.
239 @param[in] Context Pointer to the context data registered to the event.
244 IfConfig6ManualAddressNotify (
249 *((BOOLEAN
*) Context
) = TRUE
;
255 @param[in] Node The pointer of MAC address buffer.
256 @param[in] Size The size of MAC address buffer.
260 IfConfig6PrintMacAddr (
267 ASSERT (Size
<= MACADDRMAXSIZE
);
269 for (Index
= 0; Index
< Size
; Index
++) {
270 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_BODY
), mHiiHandle
, Node
[Index
]);
271 if (Index
+ 1 < Size
) {
272 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
276 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
282 @param[in] Ip The pointer of Ip bufffer in EFI_IPv6_ADDRESS format.
283 @param[in] PrefixLen The pointer of PrefixLen that describes the size Prefix.
287 IfConfig6PrintIpAddr (
288 IN EFI_IPv6_ADDRESS
*Ip
,
297 for (Index
= 0; Index
< PREFIXMAXLEN
; Index
= Index
+ 2) {
299 if (!Short
&& (Index
+ 1 < PREFIXMAXLEN
) && (Index
% 2 == 0) && (Ip
->Addr
[Index
] == 0) && (Ip
->Addr
[Index
+ 1] == 0)) {
301 // Deal with the case of ::.
305 // :: is at the beginning of the address.
307 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
309 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
311 while ((Ip
->Addr
[Index
] == 0) && (Ip
->Addr
[Index
+ 1] == 0) && (Index
< PREFIXMAXLEN
)) {
313 if (Index
> PREFIXMAXLEN
- 2) {
320 if (Index
== PREFIXMAXLEN
) {
322 // :: is at the end of the address.
328 if (Index
< PREFIXMAXLEN
- 1) {
329 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY
), mHiiHandle
, Ip
->Addr
[Index
]);
330 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY
), mHiiHandle
, Ip
->Addr
[Index
+ 1]);
333 if (Index
+ 2 < PREFIXMAXLEN
) {
334 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON
), mHiiHandle
);
338 if (PrefixLen
!= NULL
) {
339 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN
), mHiiHandle
, *PrefixLen
);
344 Pick up host IPv6 address in string format from Args with "-s" option and convert it to EFI_IP6_CONFIG_MANUAL_ADDRESS format.
346 @param[in, out] Arg The pointer of the address of ARG_LIST which save Args with the "-s" option.
347 @param[out] Buf The pointer of the address of EFI_IP6_CONFIG_MANUAL_ADDRESS.
348 @param[out] BufSize The pointer of BufSize that describes the size of Buf in bytes.
350 @retval EFI_SUCCESS The convertion is successful.
351 @retval Others Does't find the host address, or it is an invalid IPv6 address in string format.
355 IfConfig6ParseManualAddressList (
356 IN OUT ARG_LIST
**Arg
,
357 OUT EFI_IP6_CONFIG_MANUAL_ADDRESS
**Buf
,
362 EFI_IP6_CONFIG_MANUAL_ADDRESS
*AddrBuf
;
364 EFI_IPv6_ADDRESS Address
;
372 Status
= EFI_SUCCESS
;
375 // Go through the list to check the correctness of input host ip6 address.
377 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
379 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
381 if (EFI_ERROR (Status
)) {
388 VarArg
= VarArg
->Next
;
393 return EFI_INVALID_PARAMETER
;
396 AddrBuf
= AllocateZeroPool (AddrCnt
* sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
));
397 ASSERT (AddrBuf
!= NULL
);
401 Status
= EFI_SUCCESS
;
404 // Go through the list to fill in the EFI_IP6_CONFIG_MANUAL_ADDRESS structure.
406 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
408 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
410 if (EFI_ERROR (Status
)) {
415 // If prefix length is not set, set it as Zero here. In the IfConfigSetInterfaceInfo()
416 // Zero prefix, length will be transfered to default prefix length.
418 if (Prefix
== 0xFF) {
421 AddrBuf
[AddrCnt
].IsAnycast
= FALSE
;
422 AddrBuf
[AddrCnt
].PrefixLength
= Prefix
;
423 IP6_COPY_ADDRESS (&AddrBuf
[AddrCnt
].Address
, &Address
);
424 VarArg
= VarArg
->Next
;
430 if (EFI_ERROR (Status
) && (Status
!= EFI_INVALID_PARAMETER
)) {
435 *BufSize
= AddrCnt
* sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
);
446 Pick up gw/dns IPv6 address in string format from Args with "-s" option and convert it to EFI_IPv6_ADDRESS format.
448 @param[in, out] Arg The pointer of the address of ARG_LIST that save Args with the "-s" option.
449 @param[out] Buf The pointer of the address of EFI_IPv6_ADDRESS.
450 @param[out] BufSize The pointer of BufSize that describes the size of Buf in bytes.
452 @retval EFI_SUCCESS The conversion is successful.
453 @retval Others Doesn't find the host address, or it is an invalid IPv6 address in string format.
457 IfConfig6ParseGwDnsAddressList (
458 IN OUT ARG_LIST
**Arg
,
459 OUT EFI_IPv6_ADDRESS
**Buf
,
464 EFI_IPv6_ADDRESS
*AddrBuf
;
466 EFI_IPv6_ADDRESS Address
;
474 Status
= EFI_SUCCESS
;
477 // Go through the list to check the correctness of input gw/dns address.
479 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
481 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
483 if (EFI_ERROR (Status
)) {
490 VarArg
= VarArg
->Next
;
495 return EFI_INVALID_PARAMETER
;
498 AddrBuf
= AllocateZeroPool (AddrCnt
* sizeof (EFI_IPv6_ADDRESS
));
499 ASSERT (AddrBuf
!= NULL
);
503 Status
= EFI_SUCCESS
;
506 // Go through the list to fill in the EFI_IPv6_ADDRESS structure.
508 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
510 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
512 if (EFI_ERROR (Status
)) {
516 IP6_COPY_ADDRESS (&AddrBuf
[AddrCnt
], &Address
);
518 VarArg
= VarArg
->Next
;
524 if (EFI_ERROR (Status
) && (Status
!= EFI_INVALID_PARAMETER
)) {
529 *BufSize
= AddrCnt
* sizeof (EFI_IPv6_ADDRESS
);
540 Parse InterfaceId in string format from Args with the "-s" option and convert it to EFI_IP6_CONFIG_INTERFACE_ID format.
542 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
543 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
545 @retval EFI_SUCCESS The get status processed successfullly.
546 @retval EFI_INVALID_PARAMETER The get status process failed.
550 IfConfig6ParseInterfaceId (
551 IN OUT ARG_LIST
**Arg
,
552 OUT EFI_IP6_CONFIG_INTERFACE_ID
**IfId
560 return EFI_INVALID_PARAMETER
;
565 ASSERT (IfId
!= NULL
);
566 *IfId
= AllocateZeroPool (sizeof (EFI_IP6_CONFIG_INTERFACE_ID
));
567 ASSERT (*IfId
!= NULL
);
569 while ((*IdStr
!= L
'\0') && (Index
< 8)) {
572 while ((*IdStr
!= L
':') && (*IdStr
!= L
'\0')) {
574 if ((*IdStr
<= L
'F') && (*IdStr
>= L
'A')) {
575 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'A' + 10);
576 } else if ((*IdStr
<= L
'f') && (*IdStr
>= L
'a')) {
577 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'a' + 10);
578 } else if ((*IdStr
<= L
'9') && (*IdStr
>= L
'0')) {
579 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'0');
582 return EFI_INVALID_PARAMETER
;
588 (*IfId
)->Id
[Index
++] = NodeVal
;
590 if (*IdStr
== L
':') {
600 Parse dad in string format from Args with the "-s" option and convert it to UINT32 format.
602 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
603 @param[out] Xmits The pointer of Xmits.
605 @retval EFI_SUCCESS The get status processed successfully.
606 @retval others The get status process failed.
610 IfConfig6ParseDadXmits (
611 IN OUT ARG_LIST
**Arg
,
618 return EFI_INVALID_PARAMETER
;
621 ValStr
= (*Arg
)->Arg
;
624 while (*ValStr
!= L
'\0') {
626 if ((*ValStr
<= L
'9') && (*ValStr
>= L
'0')) {
628 *Xmits
= (*Xmits
* 10) + (*ValStr
- L
'0');
632 return EFI_INVALID_PARAMETER
;
643 The get current status of all handles.
645 @param[in] ImageHandle The handle of ImageHandle.
646 @param[in] IfName The pointer of IfName(interface name).
647 @param[in] IfList The pointer of IfList(interface list).
649 @retval EFI_SUCCESS The get status processed successfully.
650 @retval others The get status process failed.
654 IfConfig6GetInterfaceInfo (
655 IN EFI_HANDLE ImageHandle
,
657 IN LIST_ENTRY
*IfList
663 EFI_HANDLE
*HandleBuffer
;
664 EFI_IP6_CONFIG_PROTOCOL
*Ip6Cfg
;
665 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
666 IFCONFIG6_INTERFACE_CB
*IfCb
;
676 // Locate all the handles with ip6 service binding protocol.
678 Status
= gBS
->LocateHandleBuffer (
680 &gEfiIp6ServiceBindingProtocolGuid
,
685 if (EFI_ERROR (Status
) || (HandleNum
== 0)) {
690 // Enumerate all handles that installed with ip6 service binding protocol.
692 for (HandleIndex
= 0; HandleIndex
< HandleNum
; HandleIndex
++) {
698 // Ip6config protocol and ip6 service binding protocol are installed
699 // on the same handle.
701 ASSERT (HandleBuffer
!= NULL
);
702 Status
= gBS
->HandleProtocol (
703 HandleBuffer
[HandleIndex
],
704 &gEfiIp6ConfigProtocolGuid
,
708 if (EFI_ERROR (Status
)) {
712 // Get the interface information size.
714 Status
= Ip6Cfg
->GetData (
716 Ip6ConfigDataTypeInterfaceInfo
,
721 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
722 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
726 IfInfo
= AllocateZeroPool (DataSize
);
728 if (IfInfo
== NULL
) {
729 Status
= EFI_OUT_OF_RESOURCES
;
733 // Get the interface info.
735 Status
= Ip6Cfg
->GetData (
737 Ip6ConfigDataTypeInterfaceInfo
,
742 if (EFI_ERROR (Status
)) {
743 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
747 // Check the interface name if required.
749 if ((IfName
!= NULL
) && (StrCmp (IfName
, IfInfo
->Name
) != 0)) {
756 // Get the size of dns server list.
758 Status
= Ip6Cfg
->GetData (
760 Ip6ConfigDataTypeDnsServer
,
765 if ((Status
!= EFI_BUFFER_TOO_SMALL
) && (Status
!= EFI_NOT_FOUND
)) {
766 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
770 IfCb
= AllocateZeroPool (sizeof (IFCONFIG6_INTERFACE_CB
) + DataSize
);
773 Status
= EFI_OUT_OF_RESOURCES
;
777 IfCb
->NicHandle
= HandleBuffer
[HandleIndex
];
778 IfCb
->IfInfo
= IfInfo
;
779 IfCb
->IfCfg
= Ip6Cfg
;
780 IfCb
->DnsCnt
= (UINT32
) (DataSize
/ sizeof (EFI_IPv6_ADDRESS
));
783 // Get the dns server list if has.
787 Status
= Ip6Cfg
->GetData (
789 Ip6ConfigDataTypeDnsServer
,
794 if (EFI_ERROR (Status
)) {
795 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
800 // Get the interface id if has.
802 DataSize
= sizeof (EFI_IP6_CONFIG_INTERFACE_ID
);
803 IfCb
->IfId
= AllocateZeroPool (DataSize
);
805 if (IfCb
->IfId
== NULL
) {
809 Status
= Ip6Cfg
->GetData (
811 Ip6ConfigDataTypeAltInterfaceId
,
816 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
817 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
821 if (Status
== EFI_NOT_FOUND
) {
822 FreePool (IfCb
->IfId
);
826 // Get the config policy.
828 DataSize
= sizeof (EFI_IP6_CONFIG_POLICY
);
829 Status
= Ip6Cfg
->GetData (
831 Ip6ConfigDataTypePolicy
,
836 if (EFI_ERROR (Status
)) {
837 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
841 // Get the dad transmits.
843 DataSize
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
844 Status
= Ip6Cfg
->GetData (
846 Ip6ConfigDataTypeDupAddrDetectTransmits
,
851 if (EFI_ERROR (Status
)) {
852 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
856 InsertTailList (IfList
, &IfCb
->Link
);
858 if ((IfName
!= NULL
) && (StrCmp (IfName
, IfInfo
->Name
) == 0)) {
860 // Only need the appointed interface, keep the allocated buffer.
868 if (HandleBuffer
!= NULL
) {
869 FreePool (HandleBuffer
);
876 if (IfInfo
!= NULL
) {
881 if (IfCb
->IfId
!= NULL
) {
882 FreePool (IfCb
->IfId
);
892 The list process of the IfConfig6 application.
894 @param[in] IfList The pointer of IfList(interface list).
896 @retval EFI_SUCCESS The IfConfig6 list processed successfully.
897 @retval others The IfConfig6 list process failed.
901 IfConfig6ShowInterfaceInfo (
902 IN LIST_ENTRY
*IfList
907 IFCONFIG6_INTERFACE_CB
*IfCb
;
910 Entry
= IfList
->ForwardLink
;
911 Status
= EFI_SUCCESS
;
913 if (IsListEmpty (IfList
)) {
914 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
918 // Go through the interface list.
920 while (Entry
!= IfList
) {
922 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
924 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK
), mHiiHandle
);
927 // Print interface name.
929 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME
), mHiiHandle
, IfCb
->IfInfo
->Name
);
932 // Print interface config policy.
934 if (IfCb
->Policy
== Ip6ConfigPolicyAutomatic
) {
935 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO
), mHiiHandle
);
937 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN
), mHiiHandle
);
941 // Print dad transmit.
943 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS
), mHiiHandle
, IfCb
->Xmits
);
946 // Print interface id if has.
948 if (IfCb
->IfId
!= NULL
) {
949 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD
), mHiiHandle
);
951 IfConfig6PrintMacAddr (
957 // Print mac address of the interface.
959 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD
), mHiiHandle
);
961 IfConfig6PrintMacAddr (
962 IfCb
->IfInfo
->HwAddress
.Addr
,
963 IfCb
->IfInfo
->HwAddressSize
967 // Print ip addresses list of the interface.
969 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_HEAD
), mHiiHandle
);
971 for (Index
= 0; Index
< IfCb
->IfInfo
->AddressInfoCount
; Index
++) {
972 IfConfig6PrintIpAddr (
973 &IfCb
->IfInfo
->AddressInfo
[Index
].Address
,
974 &IfCb
->IfInfo
->AddressInfo
[Index
].PrefixLength
976 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
980 // Print dns server addresses list of the interface if has.
982 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD
), mHiiHandle
);
984 for (Index
= 0; Index
< IfCb
->DnsCnt
; Index
++) {
985 IfConfig6PrintIpAddr (
986 &IfCb
->DnsAddr
[Index
],
989 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
993 // Print route table of the interface if has.
995 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD
), mHiiHandle
);
997 for (Index
= 0; Index
< IfCb
->IfInfo
->RouteCount
; Index
++) {
998 IfConfig6PrintIpAddr (
999 &IfCb
->IfInfo
->RouteTable
[Index
].Destination
,
1000 &IfCb
->IfInfo
->RouteTable
[Index
].PrefixLength
1002 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_JOINT
), mHiiHandle
);
1004 IfConfig6PrintIpAddr (
1005 &IfCb
->IfInfo
->RouteTable
[Index
].Gateway
,
1008 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
1011 Entry
= Entry
->ForwardLink
;
1014 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK
), mHiiHandle
);
1020 The clean process of the IfConfig6 application.
1022 @param[in] IfList The pointer of IfList(interface list).
1024 @retval EFI_SUCCESS The IfConfig6 clean processed successfully.
1025 @retval others The IfConfig6 clean process failed.
1029 IfConfig6ClearInterfaceInfo (
1030 IN LIST_ENTRY
*IfList
1035 IFCONFIG6_INTERFACE_CB
*IfCb
;
1036 EFI_IP6_CONFIG_POLICY Policy
;
1038 Policy
= Ip6ConfigPolicyAutomatic
;
1039 Entry
= IfList
->ForwardLink
;
1040 Status
= EFI_SUCCESS
;
1042 if (IsListEmpty (IfList
)) {
1043 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
1047 // Go through the interface list.
1049 while (Entry
!= IfList
) {
1051 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
1053 Status
= IfCb
->IfCfg
->SetData (
1055 Ip6ConfigDataTypePolicy
,
1056 sizeof (EFI_IP6_CONFIG_POLICY
),
1060 if (EFI_ERROR (Status
)) {
1064 Entry
= Entry
->ForwardLink
;
1071 The set process of the IfConfig6 application.
1073 @param[in] IfList The pointer of IfList(interface list).
1074 @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option).
1076 @retval EFI_SUCCESS The IfConfig6 set processed successfully.
1077 @retval others The IfConfig6 set process failed.
1081 IfConfig6SetInterfaceInfo (
1082 IN LIST_ENTRY
*IfList
,
1087 IFCONFIG6_INTERFACE_CB
*IfCb
;
1088 EFI_IP6_CONFIG_MANUAL_ADDRESS
*CfgManAddr
;
1089 EFI_IPv6_ADDRESS
*CfgAddr
;
1091 EFI_IP6_CONFIG_INTERFACE_ID
*InterfaceId
;
1094 UINTN CurDadXmitsLen
;
1095 EFI_IP6_CONFIG_POLICY Policy
;
1097 VAR_CHECK_CODE CheckCode
;
1098 EFI_EVENT TimeOutEvt
;
1099 EFI_EVENT MappedEvt
;
1100 BOOLEAN IsAddressOk
;
1105 BOOLEAN IsAddressSet
;
1106 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
1116 if (IsListEmpty (IfList
)) {
1117 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
1118 return EFI_INVALID_PARAMETER
;
1121 // Make sure to set only one interface each time.
1123 IfCb
= BASE_CR (IfList
->ForwardLink
, IFCONFIG6_INTERFACE_CB
, Link
);
1124 Status
= EFI_SUCCESS
;
1127 // Initialize check list mechanism.
1129 CheckCode
= IfConfig6RetriveCheckListByName(
1136 // Create events & timers for asynchronous settings.
1138 Status
= gBS
->CreateEvent (
1145 if (EFI_ERROR (Status
)) {
1149 Status
= gBS
->CreateEvent (
1152 IfConfig6ManualAddressNotify
,
1156 if (EFI_ERROR (Status
)) {
1160 // Parse the setting variables.
1162 while (VarArg
!= NULL
) {
1164 // Check invalid parameters (duplication & unknown & conflict).
1166 CheckCode
= IfConfig6RetriveCheckListByName(
1172 if (VarCheckOk
!= CheckCode
) {
1173 switch (CheckCode
) {
1174 case VarCheckDuplicate
:
1175 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1178 case VarCheckConflict
:
1179 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1182 case VarCheckUnknown
:
1183 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1190 VarArg
= VarArg
->Next
;
1194 // Process valid variables.
1196 if (StrCmp(VarArg
->Arg
, L
"auto") == 0) {
1198 // Set automaic config policy
1200 Policy
= Ip6ConfigPolicyAutomatic
;
1201 Status
= IfCb
->IfCfg
->SetData (
1203 Ip6ConfigDataTypePolicy
,
1204 sizeof (EFI_IP6_CONFIG_POLICY
),
1208 if (EFI_ERROR(Status
)) {
1212 VarArg
= VarArg
->Next
;
1214 } else if (StrCmp (VarArg
->Arg
, L
"man") == 0) {
1216 // Set manual config policy.
1218 Policy
= Ip6ConfigPolicyManual
;
1219 Status
= IfCb
->IfCfg
->SetData (
1221 Ip6ConfigDataTypePolicy
,
1222 sizeof (EFI_IP6_CONFIG_POLICY
),
1226 if (EFI_ERROR(Status
)) {
1230 VarArg
= VarArg
->Next
;
1232 } else if (StrCmp (VarArg
->Arg
, L
"host") == 0) {
1234 // Parse till the next tag or the end of command line.
1236 VarArg
= VarArg
->Next
;
1237 Status
= IfConfig6ParseManualAddressList (
1243 if (EFI_ERROR (Status
)) {
1244 if (Status
== EFI_INVALID_PARAMETER
) {
1245 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"host");
1252 // Set static host ip6 address list.
1253 // This is a asynchronous process.
1255 IsAddressOk
= FALSE
;
1257 Status
= IfCb
->IfCfg
->RegisterDataNotify (
1259 Ip6ConfigDataTypeManualAddress
,
1262 if (EFI_ERROR (Status
)) {
1266 Status
= IfCb
->IfCfg
->SetData (
1268 Ip6ConfigDataTypeManualAddress
,
1273 if (Status
== EFI_NOT_READY
) {
1275 // Get current dad transmits count.
1277 CurDadXmitsLen
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
1278 IfCb
->IfCfg
->GetData (
1280 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1285 gBS
->SetTimer (TimeOutEvt
, TimerRelative
, 50000000 + 10000000 * CurDadXmits
);
1287 while (EFI_ERROR (gBS
->CheckEvent (TimeOutEvt
))) {
1289 Status
= EFI_SUCCESS
;
1295 IfCb
->IfCfg
->UnregisterDataNotify (
1297 Ip6ConfigDataTypeManualAddress
,
1301 if (EFI_ERROR (Status
)) {
1302 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST
), mHiiHandle
, Status
);
1307 // Check whether the address is set successfully.
1311 Status
= IfCb
->IfCfg
->GetData (
1313 Ip6ConfigDataTypeInterfaceInfo
,
1318 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1319 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
1323 IfInfo
= AllocateZeroPool (DataSize
);
1325 if (IfInfo
== NULL
) {
1326 Status
= EFI_OUT_OF_RESOURCES
;
1330 Status
= IfCb
->IfCfg
->GetData (
1332 Ip6ConfigDataTypeInterfaceInfo
,
1337 if (EFI_ERROR (Status
)) {
1338 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
1342 for ( Index
= 0; Index
< (UINTN
) (AddrSize
/ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
)); Index
++) {
1343 IsAddressSet
= FALSE
;
1345 // By default, the prefix length 0 is regarded as 64.
1347 if (CfgManAddr
[Index
].PrefixLength
== 0) {
1348 CfgManAddr
[Index
].PrefixLength
= 64;
1351 for (Index2
= 0; Index2
< IfInfo
->AddressInfoCount
; Index2
++) {
1352 if (EFI_IP6_EQUAL (&IfInfo
->AddressInfo
[Index2
].Address
, &CfgManAddr
[Index
].Address
) &&
1353 (IfInfo
->AddressInfo
[Index2
].PrefixLength
== CfgManAddr
[Index
].PrefixLength
)) {
1354 IsAddressSet
= TRUE
;
1359 if (!IsAddressSet
) {
1360 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED
), mHiiHandle
);
1361 IfConfig6PrintIpAddr (
1362 &CfgManAddr
[Index
].Address
,
1363 &CfgManAddr
[Index
].PrefixLength
1368 } else if (StrCmp (VarArg
->Arg
, L
"gw") == 0) {
1370 // Parse till the next tag or the end of command line.
1372 VarArg
= VarArg
->Next
;
1373 Status
= IfConfig6ParseGwDnsAddressList (
1379 if (EFI_ERROR (Status
)) {
1380 if (Status
== EFI_INVALID_PARAMETER
) {
1381 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"gw");
1388 // Set static gateway ip6 address list.
1390 Status
= IfCb
->IfCfg
->SetData (
1392 Ip6ConfigDataTypeGateway
,
1397 if (EFI_ERROR (Status
)) {
1401 } else if (StrCmp (VarArg
->Arg
, L
"dns") == 0) {
1403 // Parse till the next tag or the end of command line.
1405 VarArg
= VarArg
->Next
;
1406 Status
= IfConfig6ParseGwDnsAddressList (
1412 if (EFI_ERROR (Status
)) {
1413 if (Status
== EFI_INVALID_PARAMETER
) {
1414 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"dns");
1421 // Set static dhs server ip6 address list.
1423 Status
= IfCb
->IfCfg
->SetData (
1425 Ip6ConfigDataTypeDnsServer
,
1430 if (EFI_ERROR (Status
)) {
1434 } else if (StrCmp (VarArg
->Arg
, L
"id") == 0) {
1436 // Parse till the next tag or the end of command line.
1438 VarArg
= VarArg
->Next
;
1439 Status
= IfConfig6ParseInterfaceId (&VarArg
, &InterfaceId
);
1441 if (EFI_ERROR (Status
)) {
1445 // Set alternative interface id.
1447 Status
= IfCb
->IfCfg
->SetData (
1449 Ip6ConfigDataTypeAltInterfaceId
,
1450 sizeof (EFI_IP6_CONFIG_INTERFACE_ID
),
1454 if (EFI_ERROR (Status
)) {
1458 } else if (StrCmp (VarArg
->Arg
, L
"dad") == 0) {
1460 // Parse till the next tag or the end of command line.
1462 VarArg
= VarArg
->Next
;
1463 Status
= IfConfig6ParseDadXmits (&VarArg
, &DadXmits
);
1465 if (EFI_ERROR (Status
)) {
1469 // Set dad transmits count.
1471 Status
= IfCb
->IfCfg
->SetData (
1473 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1474 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
),
1478 if (EFI_ERROR(Status
)) {
1486 if (CfgManAddr
!= NULL
) {
1487 FreePool (CfgManAddr
);
1490 if (CfgAddr
!= NULL
) {
1494 if (MappedEvt
!= NULL
) {
1495 gBS
->CloseEvent (MappedEvt
);
1498 if (TimeOutEvt
!= NULL
) {
1499 gBS
->CloseEvent (TimeOutEvt
);
1502 if (IfInfo
!= NULL
) {
1511 The IfConfig6 main process.
1513 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1515 @retval EFI_SUCCESS IfConfig6 processed successfully.
1516 @retval others The IfConfig6 process failed.
1521 IN IFCONFIG6_PRIVATE_DATA
*Private
1527 // Get configure information of all interfaces.
1529 Status
= IfConfig6GetInterfaceInfo (
1530 Private
->ImageHandle
,
1535 if (EFI_ERROR (Status
)) {
1539 switch (Private
->OpCode
) {
1540 case IfConfig6OpList
:
1541 Status
= IfConfig6ShowInterfaceInfo (&Private
->IfList
);
1544 case IfConfig6OpClear
:
1545 Status
= IfConfig6ClearInterfaceInfo (&Private
->IfList
);
1548 case IfConfig6OpSet
:
1549 Status
= IfConfig6SetInterfaceInfo (&Private
->IfList
, Private
->VarArg
);
1553 Status
= EFI_ABORTED
;
1562 The IfConfig6 cleanup process, free the allocated memory.
1564 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1569 IN IFCONFIG6_PRIVATE_DATA
*Private
1573 LIST_ENTRY
*NextEntry
;
1574 IFCONFIG6_INTERFACE_CB
*IfCb
;
1578 ASSERT (Private
!= NULL
);
1581 // Clean the list which save the set config Args.
1583 if (Private
->VarArg
!= NULL
) {
1584 ArgHead
= Private
->VarArg
;
1586 while (ArgHead
->Next
!= NULL
) {
1587 ArgNode
= ArgHead
->Next
;
1595 if (Private
->IfName
!= NULL
)
1596 FreePool (Private
->IfName
);
1600 // Clean the IFCONFIG6_INTERFACE_CB list.
1602 Entry
= Private
->IfList
.ForwardLink
;
1603 NextEntry
= Entry
->ForwardLink
;
1605 while (Entry
!= &Private
->IfList
) {
1607 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
1609 RemoveEntryList (&IfCb
->Link
);
1611 if (IfCb
->IfId
!= NULL
) {
1613 FreePool (IfCb
->IfId
);
1616 if (IfCb
->IfInfo
!= NULL
) {
1618 FreePool (IfCb
->IfInfo
);
1624 NextEntry
= Entry
->ForwardLink
;
1631 This is the declaration of an EFI image entry point. This entry point is
1632 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
1633 both device drivers and bus drivers.
1635 The entry point for the IfConfig6 application which parses the command line input and calls the IfConfig6 process.
1637 @param[in] ImageHandle The image handle of this application.
1638 @param[in] SystemTable The pointer to the EFI System Table.
1640 @retval EFI_SUCCESS The operation completed successfully.
1641 @retval Others Some errors occur.
1646 IfConfig6Initialize (
1647 IN EFI_HANDLE ImageHandle
,
1648 IN EFI_SYSTEM_TABLE
*SystemTable
1652 IFCONFIG6_PRIVATE_DATA
*Private
;
1653 LIST_ENTRY
*ParamPackage
;
1654 CONST CHAR16
*ValueStr
;
1656 CHAR16
*ProblemParam
;
1662 // Register our string package with HII and return the handle to it.
1664 mHiiHandle
= HiiAddPackages (&gEfiCallerIdGuid
, ImageHandle
, IfConfig6Strings
, NULL
);
1665 ASSERT (mHiiHandle
!= NULL
);
1667 Status
= ShellCommandLineParseEx (mIfConfig6CheckList
, &ParamPackage
, &ProblemParam
, TRUE
, FALSE
);
1668 if (EFI_ERROR (Status
)) {
1669 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND
), mHiiHandle
, ProblemParam
);
1674 // To handle no option.
1676 if (!ShellCommandLineGetFlag (ParamPackage
, L
"-r") && !ShellCommandLineGetFlag (ParamPackage
, L
"-s") &&
1677 !ShellCommandLineGetFlag (ParamPackage
, L
"-?") && !ShellCommandLineGetFlag (ParamPackage
, L
"-l")) {
1678 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_LACK_OPTION
), mHiiHandle
);
1682 // To handle conflict options.
1684 if (((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-s"))) ||
1685 ((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-l"))) ||
1686 ((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-?"))) ||
1687 ((ShellCommandLineGetFlag (ParamPackage
, L
"-s")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-l"))) ||
1688 ((ShellCommandLineGetFlag (ParamPackage
, L
"-s")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-?"))) ||
1689 ((ShellCommandLineGetFlag (ParamPackage
, L
"-l")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-?")))) {
1690 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_CONFLICT_OPTIONS
), mHiiHandle
);
1694 // To show the help information of ifconfig6 command.
1696 if (ShellCommandLineGetFlag (ParamPackage
, L
"-?")) {
1697 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_HELP
), mHiiHandle
);
1701 Status
= EFI_INVALID_PARAMETER
;
1703 Private
= AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA
));
1705 if (Private
== NULL
) {
1706 Status
= EFI_OUT_OF_RESOURCES
;
1710 InitializeListHead (&Private
->IfList
);
1713 // To get interface name for the list option.
1715 if (ShellCommandLineGetFlag (ParamPackage
, L
"-l")) {
1716 Private
->OpCode
= IfConfig6OpList
;
1717 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-l");
1718 if (ValueStr
!= NULL
) {
1719 Str
= (CHAR16
*) AllocateZeroPool (StrSize (ValueStr
));
1720 ASSERT (Str
!= NULL
);
1722 Str
= StrCpy (Str
, ValueStr
);
1723 Private
->IfName
= Str
;
1727 // To get interface name for the clear option.
1729 if (ShellCommandLineGetFlag (ParamPackage
, L
"-r")) {
1730 Private
->OpCode
= IfConfig6OpClear
;
1731 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-r");
1732 if (ValueStr
!= NULL
) {
1733 Str
= (CHAR16
*) AllocateZeroPool (StrSize (ValueStr
));
1734 ASSERT (Str
!= NULL
);
1736 Str
= StrCpy (Str
, ValueStr
);
1737 Private
->IfName
= Str
;
1741 // To get interface name and corresponding Args for the set option.
1743 if (ShellCommandLineGetFlag (ParamPackage
, L
"-s")) {
1745 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-s");
1746 if (ValueStr
== NULL
) {
1747 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_INTERFACE
), mHiiHandle
);
1751 // To split the configuration into multi-section.
1753 ArgList
= SplitStrToList (ValueStr
, L
' ');
1754 ASSERT (ArgList
!= NULL
);
1756 Private
->OpCode
= IfConfig6OpSet
;
1757 Private
->IfName
= ArgList
->Arg
;
1759 Private
->VarArg
= ArgList
->Next
;
1761 if (Private
->IfName
== NULL
|| Private
->VarArg
== NULL
) {
1762 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_COMMAND
), mHiiHandle
);
1767 // Main process of ifconfig6.
1769 Status
= IfConfig6 (Private
);
1773 ShellCommandLineFreeVarList (ParamPackage
);
1774 HiiRemovePackages (mHiiHandle
);
1775 if (Private
!= NULL
)
1776 IfConfig6Cleanup (Private
);