2 The implementation for Shell application IfConfig6.
4 Copyright (c) 2009 - 2010, 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 EFI_GUID mEfiIfConfig6Guid
= EFI_IFCONFIG6_GUID
;
33 SHELL_PARAM_ITEM mIfConfig6CheckList
[] = {
60 VAR_CHECK_ITEM mSetCheckList
[] = {
112 Split a string with specified separator and save the substring to a list.
114 @param[in] String The pointer of the input string.
115 @param[in] Separator The specified separator.
117 @return The pointer of headnode of ARG_LIST.
122 IN CONST CHAR16
*String
,
131 if (*String
== L
'\0') {
136 // Copy the CONST string to a local copy.
138 Str
= (CHAR16
*) AllocateZeroPool (StrSize (String
));
139 ASSERT (Str
!= NULL
);
140 Str
= StrCpy (Str
, String
);
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] CheckList The pointer of Event.
240 @param[in] Context The pointer of Context.
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] Address 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
;
373 Status
= EFI_SUCCESS
;
376 // Go through the list to check the correctness of input host ip6 address.
378 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
380 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
382 if (EFI_ERROR (Status
)) {
389 VarArg
= VarArg
->Next
;
394 return EFI_INVALID_PARAMETER
;
397 AddrBuf
= AllocateZeroPool (AddrCnt
* sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
));
398 ASSERT (AddrBuf
!= NULL
);
402 Status
= EFI_SUCCESS
;
405 // Go through the list to fill in the EFI_IP6_CONFIG_MANUAL_ADDRESS structure.
407 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
409 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
411 if (EFI_ERROR (Status
)) {
416 // If prefix length is not set, set it as Zero here. In the IfConfigSetInterfaceInfo()
417 // Zero prefix, length will be transfered to default prefix length.
419 if (Prefix
== 0xFF) {
422 AddrBuf
[AddrCnt
].IsAnycast
= FALSE
;
423 AddrBuf
[AddrCnt
].PrefixLength
= Prefix
;
424 IP6_COPY_ADDRESS (&AddrBuf
[AddrCnt
].Address
, &Address
);
425 VarArg
= VarArg
->Next
;
431 if (EFI_ERROR (Status
) && (Status
!= EFI_INVALID_PARAMETER
)) {
436 *BufSize
= AddrCnt
* sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
);
447 Pick up gw/dns IPv6 address in string format from Args with "-s" option and convert it to EFI_IPv6_ADDRESS format.
449 @param[in, out] Arg The pointer of the address of ARG_LIST that save Args with the "-s" option.
450 @param[out] Buf The pointer of the address of EFI_IPv6_ADDRESS.
451 @param[out] Address The pointer of BufSize that describes the size of Buf in bytes.
453 @retval EFI_SUCCESS The conversion is successful.
454 @retval Others Doesn't find the host address, or it is an invalid IPv6 address in string format.
458 IfConfig6ParseGwDnsAddressList (
459 IN OUT ARG_LIST
**Arg
,
460 OUT EFI_IPv6_ADDRESS
**Buf
,
465 EFI_IPv6_ADDRESS
*AddrBuf
;
467 EFI_IPv6_ADDRESS Address
;
475 Status
= EFI_SUCCESS
;
478 // Go through the list to check the correctness of input gw/dns address.
480 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
482 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
484 if (EFI_ERROR (Status
)) {
491 VarArg
= VarArg
->Next
;
496 return EFI_INVALID_PARAMETER
;
499 AddrBuf
= AllocateZeroPool (AddrCnt
* sizeof (EFI_IPv6_ADDRESS
));
500 ASSERT (AddrBuf
!= NULL
);
504 Status
= EFI_SUCCESS
;
507 // Go through the list to fill in the EFI_IPv6_ADDRESS structure.
509 while ((!EFI_ERROR (Status
)) && (VarArg
!= NULL
)) {
511 Status
= NetLibStrToIp6andPrefix (VarArg
->Arg
, &Address
, &Prefix
);
513 if (EFI_ERROR (Status
)) {
517 IP6_COPY_ADDRESS (&AddrBuf
[AddrCnt
], &Address
);
519 VarArg
= VarArg
->Next
;
525 if (EFI_ERROR (Status
) && (Status
!= EFI_INVALID_PARAMETER
)) {
530 *BufSize
= AddrCnt
* sizeof (EFI_IPv6_ADDRESS
);
541 Parse InterfaceId in string format from Args with the "-s" option and convert it to EFI_IP6_CONFIG_INTERFACE_ID format.
543 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
544 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
546 @retval EFI_SUCCESS The get status processed successfullly.
547 @retval EFI_INVALID_PARAMETER The get status process failed.
551 IfConfig6ParseInterfaceId (
552 IN OUT ARG_LIST
**Arg
,
553 OUT EFI_IP6_CONFIG_INTERFACE_ID
**IfId
561 return EFI_INVALID_PARAMETER
;
566 ASSERT (IfId
!= NULL
);
567 *IfId
= AllocateZeroPool (sizeof (EFI_IP6_CONFIG_INTERFACE_ID
));
568 ASSERT (*IfId
!= NULL
);
570 while ((*IdStr
!= L
'\0') && (Index
< 8)) {
573 while ((*IdStr
!= L
':') && (*IdStr
!= L
'\0')) {
575 if ((*IdStr
<= L
'F') && (*IdStr
>= L
'A')) {
576 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'A' + 10);
577 } else if ((*IdStr
<= L
'f') && (*IdStr
>= L
'a')) {
578 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'a' + 10);
579 } else if ((*IdStr
<= L
'9') && (*IdStr
>= L
'0')) {
580 NodeVal
= (UINT8
)((NodeVal
<< 4) + *IdStr
- L
'0');
583 return EFI_INVALID_PARAMETER
;
589 (*IfId
)->Id
[Index
++] = NodeVal
;
591 if (*IdStr
== L
':') {
601 Parse dad in string format from Args with the "-s" option and convert it to UINT32 format.
603 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
604 @param[out] Xmits The pointer of Xmits.
606 @retval EFI_SUCCESS The get status processed successfully.
607 @retval others The get status process failed.
611 IfConfig6ParseDadXmits (
612 IN OUT ARG_LIST
**Arg
,
619 return EFI_INVALID_PARAMETER
;
622 ValStr
= (*Arg
)->Arg
;
625 while (*ValStr
!= L
'\0') {
627 if ((*ValStr
<= L
'9') && (*ValStr
>= L
'0')) {
629 *Xmits
= (*Xmits
* 10) + (*ValStr
- L
'0');
633 return EFI_INVALID_PARAMETER
;
644 The get current status of all handles.
646 @param[in] ImageHandle The handle of ImageHandle.
647 @param[in] IfName The pointer of IfName(interface name).
648 @param[in] IfList The pointer of IfList(interface list).
650 @retval EFI_SUCCESS The get status processed successfully.
651 @retval others The get status process failed.
655 IfConfig6GetInterfaceInfo (
656 IN EFI_HANDLE ImageHandle
,
658 IN LIST_ENTRY
*IfList
664 EFI_HANDLE
*HandleBuffer
;
665 EFI_IP6_CONFIG_PROTOCOL
*Ip6Cfg
;
666 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
667 IFCONFIG6_INTERFACE_CB
*IfCb
;
677 // Locate all the handles with ip6 service binding protocol.
679 Status
= gBS
->LocateHandleBuffer (
681 &gEfiIp6ServiceBindingProtocolGuid
,
686 if (EFI_ERROR (Status
) || (HandleNum
== 0)) {
691 // Enumerate all handles that installed with ip6 service binding protocol.
693 for (HandleIndex
= 0; HandleIndex
< HandleNum
; HandleIndex
++) {
699 // Ip6config protocol and ip6 service binding protocol are installed
700 // on the same handle.
702 ASSERT (HandleBuffer
!= NULL
);
703 Status
= gBS
->HandleProtocol (
704 HandleBuffer
[HandleIndex
],
705 &gEfiIp6ConfigProtocolGuid
,
709 if (EFI_ERROR (Status
)) {
713 // Get the interface information size.
715 Status
= Ip6Cfg
->GetData (
717 Ip6ConfigDataTypeInterfaceInfo
,
722 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
723 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
727 IfInfo
= AllocateZeroPool (DataSize
);
729 if (IfInfo
== NULL
) {
730 Status
= EFI_OUT_OF_RESOURCES
;
734 // Get the interface info.
736 Status
= Ip6Cfg
->GetData (
738 Ip6ConfigDataTypeInterfaceInfo
,
743 if (EFI_ERROR (Status
)) {
744 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
748 // Check the interface name if required.
750 if ((IfName
!= NULL
) && (StrCmp (IfName
, IfInfo
->Name
) != 0)) {
757 // Get the size of dns server list.
759 Status
= Ip6Cfg
->GetData (
761 Ip6ConfigDataTypeDnsServer
,
766 if ((Status
!= EFI_BUFFER_TOO_SMALL
) && (Status
!= EFI_NOT_FOUND
)) {
767 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
771 IfCb
= AllocateZeroPool (sizeof (IFCONFIG6_INTERFACE_CB
) + DataSize
);
774 Status
= EFI_OUT_OF_RESOURCES
;
778 IfCb
->NicHandle
= HandleBuffer
[HandleIndex
];
779 IfCb
->IfInfo
= IfInfo
;
780 IfCb
->IfCfg
= Ip6Cfg
;
781 IfCb
->DnsCnt
= (UINT32
) (DataSize
/ sizeof (EFI_IPv6_ADDRESS
));
784 // Get the dns server list if has.
788 Status
= Ip6Cfg
->GetData (
790 Ip6ConfigDataTypeDnsServer
,
795 if (EFI_ERROR (Status
)) {
796 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
801 // Get the interface id if has.
803 DataSize
= sizeof (EFI_IP6_CONFIG_INTERFACE_ID
);
804 IfCb
->IfId
= AllocateZeroPool (DataSize
);
806 if (IfCb
->IfId
== NULL
) {
810 Status
= Ip6Cfg
->GetData (
812 Ip6ConfigDataTypeAltInterfaceId
,
817 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
818 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
822 if (Status
== EFI_NOT_FOUND
) {
823 FreePool (IfCb
->IfId
);
827 // Get the config policy.
829 DataSize
= sizeof (EFI_IP6_CONFIG_POLICY
);
830 Status
= Ip6Cfg
->GetData (
832 Ip6ConfigDataTypePolicy
,
837 if (EFI_ERROR (Status
)) {
838 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
842 // Get the dad transmits.
844 DataSize
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
845 Status
= Ip6Cfg
->GetData (
847 Ip6ConfigDataTypeDupAddrDetectTransmits
,
852 if (EFI_ERROR (Status
)) {
853 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
857 InsertTailList (IfList
, &IfCb
->Link
);
859 if ((IfName
!= NULL
) && (StrCmp (IfName
, IfInfo
->Name
) == 0)) {
861 // Only need the appointed interface, keep the allocated buffer.
869 if (HandleBuffer
!= NULL
) {
870 FreePool (HandleBuffer
);
877 if (IfInfo
!= NULL
) {
882 if (IfCb
->IfId
!= NULL
) {
883 FreePool (IfCb
->IfId
);
893 The list process of the IfConfig6 application.
895 @param[in] IfList The pointer of IfList(interface list).
897 @retval EFI_SUCCESS The IfConfig6 list processed successfully.
898 @retval others The IfConfig6 list process failed.
902 IfConfig6ShowInterfaceInfo (
903 IN LIST_ENTRY
*IfList
908 IFCONFIG6_INTERFACE_CB
*IfCb
;
911 Entry
= IfList
->ForwardLink
;
912 Status
= EFI_SUCCESS
;
914 if (IsListEmpty (IfList
)) {
915 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
919 // Go through the interface list.
921 while (Entry
!= IfList
) {
923 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
925 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK
), mHiiHandle
);
928 // Print interface name.
930 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME
), mHiiHandle
, IfCb
->IfInfo
->Name
);
933 // Print interface config policy.
935 if (IfCb
->Policy
== Ip6ConfigPolicyAutomatic
) {
936 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO
), mHiiHandle
);
938 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN
), mHiiHandle
);
942 // Print dad transmit.
944 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS
), mHiiHandle
, IfCb
->Xmits
);
947 // Print interface id if has.
949 if (IfCb
->IfId
!= NULL
) {
950 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD
), mHiiHandle
);
952 IfConfig6PrintMacAddr (
958 // Print mac address of the interface.
960 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD
), mHiiHandle
);
962 IfConfig6PrintMacAddr (
963 IfCb
->IfInfo
->HwAddress
.Addr
,
964 IfCb
->IfInfo
->HwAddressSize
968 // Print ip addresses list of the interface.
970 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_HEAD
), mHiiHandle
);
972 for (Index
= 0; Index
< IfCb
->IfInfo
->AddressInfoCount
; Index
++) {
973 IfConfig6PrintIpAddr (
974 &IfCb
->IfInfo
->AddressInfo
[Index
].Address
,
975 &IfCb
->IfInfo
->AddressInfo
[Index
].PrefixLength
977 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
981 // Print dns server addresses list of the interface if has.
983 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD
), mHiiHandle
);
985 for (Index
= 0; Index
< IfCb
->DnsCnt
; Index
++) {
986 IfConfig6PrintIpAddr (
987 &IfCb
->DnsAddr
[Index
],
990 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
994 // Print route table of the interface if has.
996 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD
), mHiiHandle
);
998 for (Index
= 0; Index
< IfCb
->IfInfo
->RouteCount
; Index
++) {
999 IfConfig6PrintIpAddr (
1000 &IfCb
->IfInfo
->RouteTable
[Index
].Destination
,
1001 &IfCb
->IfInfo
->RouteTable
[Index
].PrefixLength
1003 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_JOINT
), mHiiHandle
);
1005 IfConfig6PrintIpAddr (
1006 &IfCb
->IfInfo
->RouteTable
[Index
].Gateway
,
1009 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE
), mHiiHandle
);
1012 Entry
= Entry
->ForwardLink
;
1015 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK
), mHiiHandle
);
1021 The clean process of the IfConfig6 application.
1023 @param[in] IfList The pointer of IfList(interface list).
1025 @retval EFI_SUCCESS The IfConfig6 clean processed successfully.
1026 @retval others The IfConfig6 clean process failed.
1030 IfConfig6ClearInterfaceInfo (
1031 IN LIST_ENTRY
*IfList
1036 IFCONFIG6_INTERFACE_CB
*IfCb
;
1037 EFI_IP6_CONFIG_POLICY Policy
;
1039 Policy
= Ip6ConfigPolicyAutomatic
;
1040 Entry
= IfList
->ForwardLink
;
1041 Status
= EFI_SUCCESS
;
1043 if (IsListEmpty (IfList
)) {
1044 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
1048 // Go through the interface list.
1050 while (Entry
!= IfList
) {
1052 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
1054 Status
= IfCb
->IfCfg
->SetData (
1056 Ip6ConfigDataTypePolicy
,
1057 sizeof (EFI_IP6_CONFIG_POLICY
),
1061 if (EFI_ERROR (Status
)) {
1065 Entry
= Entry
->ForwardLink
;
1072 The set process of the IfConfig6 application.
1074 @param[in] IfList The pointer of IfList(interface list).
1075 @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option).
1077 @retval EFI_SUCCESS The IfConfig6 set processed successfully.
1078 @retval others The IfConfig6 set process failed.
1082 IfConfig6SetInterfaceInfo (
1083 IN LIST_ENTRY
*IfList
,
1088 IFCONFIG6_INTERFACE_CB
*IfCb
;
1089 EFI_IP6_CONFIG_MANUAL_ADDRESS
*CfgManAddr
;
1090 EFI_IPv6_ADDRESS
*CfgAddr
;
1092 EFI_IP6_CONFIG_INTERFACE_ID
*InterfaceId
;
1095 UINTN CurDadXmitsLen
;
1096 EFI_IP6_CONFIG_POLICY Policy
;
1098 VAR_CHECK_CODE CheckCode
;
1099 EFI_EVENT TimeOutEvt
;
1100 EFI_EVENT MappedEvt
;
1101 BOOLEAN IsAddressOk
;
1106 BOOLEAN IsAddressSet
;
1107 EFI_IP6_CONFIG_INTERFACE_INFO
*IfInfo
;
1117 if (IsListEmpty (IfList
)) {
1118 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE
), mHiiHandle
);
1119 return EFI_INVALID_PARAMETER
;
1122 // Make sure to set only one interface each time.
1124 IfCb
= BASE_CR (IfList
->ForwardLink
, IFCONFIG6_INTERFACE_CB
, Link
);
1125 Status
= EFI_SUCCESS
;
1128 // Initialize check list mechanism.
1130 CheckCode
= IfConfig6RetriveCheckListByName(
1137 // Create events & timers for asynchronous settings.
1139 Status
= gBS
->CreateEvent (
1146 if (EFI_ERROR (Status
)) {
1150 Status
= gBS
->CreateEvent (
1153 IfConfig6ManualAddressNotify
,
1157 if (EFI_ERROR (Status
)) {
1161 // Parse the setting variables.
1163 while (VarArg
!= NULL
) {
1165 // Check invalid parameters (duplication & unknown & conflict).
1167 CheckCode
= IfConfig6RetriveCheckListByName(
1173 if (VarCheckOk
!= CheckCode
) {
1174 switch (CheckCode
) {
1175 case VarCheckDuplicate
:
1176 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1179 case VarCheckConflict
:
1180 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1183 case VarCheckUnknown
:
1184 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND
), mHiiHandle
, VarArg
->Arg
);
1191 VarArg
= VarArg
->Next
;
1195 // Process valid variables.
1197 if (StrCmp(VarArg
->Arg
, L
"auto") == 0) {
1199 // Set automaic config policy
1201 Policy
= Ip6ConfigPolicyAutomatic
;
1202 Status
= IfCb
->IfCfg
->SetData (
1204 Ip6ConfigDataTypePolicy
,
1205 sizeof (EFI_IP6_CONFIG_POLICY
),
1209 if (EFI_ERROR(Status
)) {
1213 VarArg
= VarArg
->Next
;
1215 } else if (StrCmp (VarArg
->Arg
, L
"man") == 0) {
1217 // Set manual config policy.
1219 Policy
= Ip6ConfigPolicyManual
;
1220 Status
= IfCb
->IfCfg
->SetData (
1222 Ip6ConfigDataTypePolicy
,
1223 sizeof (EFI_IP6_CONFIG_POLICY
),
1227 if (EFI_ERROR(Status
)) {
1231 VarArg
= VarArg
->Next
;
1233 } else if (StrCmp (VarArg
->Arg
, L
"host") == 0) {
1235 // Parse till the next tag or the end of command line.
1237 VarArg
= VarArg
->Next
;
1238 Status
= IfConfig6ParseManualAddressList (
1244 if (EFI_ERROR (Status
)) {
1245 if (Status
== EFI_INVALID_PARAMETER
) {
1246 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"host");
1253 // Set static host ip6 address list.
1254 // This is a asynchronous process.
1256 IsAddressOk
= FALSE
;
1258 Status
= IfCb
->IfCfg
->RegisterDataNotify (
1260 Ip6ConfigDataTypeManualAddress
,
1263 if (EFI_ERROR (Status
)) {
1267 Status
= IfCb
->IfCfg
->SetData (
1269 Ip6ConfigDataTypeManualAddress
,
1274 if (Status
== EFI_NOT_READY
) {
1276 // Get current dad transmits count.
1278 CurDadXmitsLen
= sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
);
1279 IfCb
->IfCfg
->GetData (
1281 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1286 gBS
->SetTimer (TimeOutEvt
, TimerRelative
, 50000000 + 10000000 * CurDadXmits
);
1288 while (EFI_ERROR (gBS
->CheckEvent (TimeOutEvt
))) {
1290 Status
= EFI_SUCCESS
;
1296 IfCb
->IfCfg
->UnregisterDataNotify (
1298 Ip6ConfigDataTypeManualAddress
,
1302 if (EFI_ERROR (Status
)) {
1303 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST
), mHiiHandle
, Status
);
1308 // Check whether the address is set successfully.
1312 Status
= IfCb
->IfCfg
->GetData (
1314 Ip6ConfigDataTypeInterfaceInfo
,
1319 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
1320 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
1324 IfInfo
= AllocateZeroPool (DataSize
);
1326 if (IfInfo
== NULL
) {
1327 Status
= EFI_OUT_OF_RESOURCES
;
1331 Status
= IfCb
->IfCfg
->GetData (
1333 Ip6ConfigDataTypeInterfaceInfo
,
1338 if (EFI_ERROR (Status
)) {
1339 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA
), mHiiHandle
, Status
);
1343 for ( Index
= 0; Index
< (UINTN
) (AddrSize
/ sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS
)); Index
++) {
1344 IsAddressSet
= FALSE
;
1346 // By default, the prefix length 0 is regarded as 64.
1348 if (CfgManAddr
[Index
].PrefixLength
== 0) {
1349 CfgManAddr
[Index
].PrefixLength
= 64;
1352 for (Index2
= 0; Index2
< IfInfo
->AddressInfoCount
; Index2
++) {
1353 if (EFI_IP6_EQUAL (&IfInfo
->AddressInfo
[Index2
].Address
, &CfgManAddr
[Index
].Address
) &&
1354 (IfInfo
->AddressInfo
[Index2
].PrefixLength
== CfgManAddr
[Index
].PrefixLength
)) {
1355 IsAddressSet
= TRUE
;
1360 if (!IsAddressSet
) {
1361 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED
), mHiiHandle
);
1362 IfConfig6PrintIpAddr (
1363 &CfgManAddr
[Index
].Address
,
1364 &CfgManAddr
[Index
].PrefixLength
1369 } else if (StrCmp (VarArg
->Arg
, L
"gw") == 0) {
1371 // Parse till the next tag or the end of command line.
1373 VarArg
= VarArg
->Next
;
1374 Status
= IfConfig6ParseGwDnsAddressList (
1380 if (EFI_ERROR (Status
)) {
1381 if (Status
== EFI_INVALID_PARAMETER
) {
1382 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"gw");
1389 // Set static gateway ip6 address list.
1391 Status
= IfCb
->IfCfg
->SetData (
1393 Ip6ConfigDataTypeGateway
,
1398 if (EFI_ERROR (Status
)) {
1402 } else if (StrCmp (VarArg
->Arg
, L
"dns") == 0) {
1404 // Parse till the next tag or the end of command line.
1406 VarArg
= VarArg
->Next
;
1407 Status
= IfConfig6ParseGwDnsAddressList (
1413 if (EFI_ERROR (Status
)) {
1414 if (Status
== EFI_INVALID_PARAMETER
) {
1415 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS
), mHiiHandle
, L
"dns");
1422 // Set static dhs server ip6 address list.
1424 Status
= IfCb
->IfCfg
->SetData (
1426 Ip6ConfigDataTypeDnsServer
,
1431 if (EFI_ERROR (Status
)) {
1435 } else if (StrCmp (VarArg
->Arg
, L
"id") == 0) {
1437 // Parse till the next tag or the end of command line.
1439 VarArg
= VarArg
->Next
;
1440 Status
= IfConfig6ParseInterfaceId (&VarArg
, &InterfaceId
);
1442 if (EFI_ERROR (Status
)) {
1446 // Set alternative interface id.
1448 Status
= IfCb
->IfCfg
->SetData (
1450 Ip6ConfigDataTypeAltInterfaceId
,
1451 sizeof (EFI_IP6_CONFIG_INTERFACE_ID
),
1455 if (EFI_ERROR (Status
)) {
1459 } else if (StrCmp (VarArg
->Arg
, L
"dad") == 0) {
1461 // Parse till the next tag or the end of command line.
1463 VarArg
= VarArg
->Next
;
1464 Status
= IfConfig6ParseDadXmits (&VarArg
, &DadXmits
);
1466 if (EFI_ERROR (Status
)) {
1470 // Set dad transmits count.
1472 Status
= IfCb
->IfCfg
->SetData (
1474 Ip6ConfigDataTypeDupAddrDetectTransmits
,
1475 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
),
1479 if (EFI_ERROR(Status
)) {
1487 if (CfgManAddr
!= NULL
) {
1488 FreePool (CfgManAddr
);
1491 if (CfgAddr
!= NULL
) {
1495 if (MappedEvt
!= NULL
) {
1496 gBS
->CloseEvent (MappedEvt
);
1499 if (TimeOutEvt
!= NULL
) {
1500 gBS
->CloseEvent (TimeOutEvt
);
1503 if (IfInfo
!= NULL
) {
1512 The IfConfig6 main process.
1514 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1516 @retval EFI_SUCCESS IfConfig6 processed successfully.
1517 @retval others The IfConfig6 process failed.
1522 IN IFCONFIG6_PRIVATE_DATA
*Private
1528 // Get configure information of all interfaces.
1530 Status
= IfConfig6GetInterfaceInfo (
1531 Private
->ImageHandle
,
1536 if (EFI_ERROR (Status
)) {
1540 switch (Private
->OpCode
) {
1541 case IfConfig6OpList
:
1542 Status
= IfConfig6ShowInterfaceInfo (&Private
->IfList
);
1545 case IfConfig6OpClear
:
1546 Status
= IfConfig6ClearInterfaceInfo (&Private
->IfList
);
1549 case IfConfig6OpSet
:
1550 Status
= IfConfig6SetInterfaceInfo (&Private
->IfList
, Private
->VarArg
);
1554 Status
= EFI_ABORTED
;
1563 The IfConfig6 cleanup process, free the allocated memory.
1565 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1570 IN IFCONFIG6_PRIVATE_DATA
*Private
1574 LIST_ENTRY
*NextEntry
;
1575 IFCONFIG6_INTERFACE_CB
*IfCb
;
1579 ASSERT (Private
!= NULL
);
1582 // Clean the list which save the set config Args.
1584 if (Private
->VarArg
!= NULL
) {
1585 ArgHead
= Private
->VarArg
;
1587 while (ArgHead
->Next
!= NULL
) {
1588 ArgNode
= ArgHead
->Next
;
1596 if (Private
->IfName
!= NULL
)
1597 FreePool (Private
->IfName
);
1601 // Clean the IFCONFIG6_INTERFACE_CB list.
1603 Entry
= Private
->IfList
.ForwardLink
;
1604 NextEntry
= Entry
->ForwardLink
;
1606 while (Entry
!= &Private
->IfList
) {
1608 IfCb
= BASE_CR (Entry
, IFCONFIG6_INTERFACE_CB
, Link
);
1610 RemoveEntryList (&IfCb
->Link
);
1612 if (IfCb
->IfId
!= NULL
) {
1614 FreePool (IfCb
->IfId
);
1617 if (IfCb
->IfInfo
!= NULL
) {
1619 FreePool (IfCb
->IfInfo
);
1625 NextEntry
= Entry
->ForwardLink
;
1632 This is the declaration of an EFI image entry point. This entry point is
1633 the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including
1634 both device drivers and bus drivers.
1636 The entry point for the IfConfig6 application which parses the command line input and calls the IfConfig6 process.
1638 @param[in] ImageHandle The image handle of this application.
1639 @param[in] SystemTable The pointer to the EFI System Table.
1641 @retval EFI_SUCCESS The operation completed successfully.
1642 @retval Others Some errors occur.
1647 IfConfig6Initialize (
1648 IN EFI_HANDLE ImageHandle
,
1649 IN EFI_SYSTEM_TABLE
*SystemTable
1653 IFCONFIG6_PRIVATE_DATA
*Private
;
1654 LIST_ENTRY
*ParamPackage
;
1655 CONST CHAR16
*ValueStr
;
1657 CHAR16
*ProblemParam
;
1663 // Register our string package with HII and return the handle to it.
1665 mHiiHandle
= HiiAddPackages (&gEfiCallerIdGuid
, ImageHandle
, IfConfig6Strings
, NULL
);
1666 ASSERT (mHiiHandle
!= NULL
);
1668 Status
= ShellCommandLineParseEx (mIfConfig6CheckList
, &ParamPackage
, &ProblemParam
, TRUE
, FALSE
);
1669 if (EFI_ERROR (Status
)) {
1670 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND
), mHiiHandle
, ProblemParam
);
1675 // To handle no option.
1677 if (!ShellCommandLineGetFlag (ParamPackage
, L
"-r") && !ShellCommandLineGetFlag (ParamPackage
, L
"-s") &&
1678 !ShellCommandLineGetFlag (ParamPackage
, L
"-?") && !ShellCommandLineGetFlag (ParamPackage
, L
"-l")) {
1679 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_LACK_OPTION
), mHiiHandle
);
1683 // To handle conflict options.
1685 if (((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-s"))) ||
1686 ((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-l"))) ||
1687 ((ShellCommandLineGetFlag (ParamPackage
, L
"-r")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-?"))) ||
1688 ((ShellCommandLineGetFlag (ParamPackage
, L
"-s")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-l"))) ||
1689 ((ShellCommandLineGetFlag (ParamPackage
, L
"-s")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-?"))) ||
1690 ((ShellCommandLineGetFlag (ParamPackage
, L
"-l")) && (ShellCommandLineGetFlag (ParamPackage
, L
"-?")))) {
1691 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_CONFLICT_OPTIONS
), mHiiHandle
);
1695 // To show the help information of ifconfig6 command.
1697 if (ShellCommandLineGetFlag (ParamPackage
, L
"-?")) {
1698 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_HELP
), mHiiHandle
);
1702 Status
= EFI_INVALID_PARAMETER
;
1704 Private
= AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA
));
1706 if (Private
== NULL
) {
1707 Status
= EFI_OUT_OF_RESOURCES
;
1711 InitializeListHead (&Private
->IfList
);
1714 // To get interface name for the list option.
1716 if (ShellCommandLineGetFlag (ParamPackage
, L
"-l")) {
1717 Private
->OpCode
= IfConfig6OpList
;
1718 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-l");
1719 if (ValueStr
!= NULL
) {
1720 Str
= (CHAR16
*) AllocateZeroPool (StrSize (ValueStr
));
1721 ASSERT (Str
!= NULL
);
1723 Str
= StrCpy (Str
, ValueStr
);
1724 Private
->IfName
= Str
;
1728 // To get interface name for the clear option.
1730 if (ShellCommandLineGetFlag (ParamPackage
, L
"-r")) {
1731 Private
->OpCode
= IfConfig6OpClear
;
1732 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-r");
1733 if (ValueStr
!= NULL
) {
1734 Str
= (CHAR16
*) AllocateZeroPool (StrSize (ValueStr
));
1735 ASSERT (Str
!= NULL
);
1737 Str
= StrCpy (Str
, ValueStr
);
1738 Private
->IfName
= Str
;
1742 // To get interface name and corresponding Args for the set option.
1744 if (ShellCommandLineGetFlag (ParamPackage
, L
"-s")) {
1746 ValueStr
= ShellCommandLineGetValue (ParamPackage
, L
"-s");
1747 if (ValueStr
== NULL
) {
1748 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_INTERFACE
), mHiiHandle
);
1752 // To split the configuration into multi-section.
1754 ArgList
= SplitStrToList (ValueStr
, L
' ');
1755 ASSERT (ArgList
!= NULL
);
1757 Private
->OpCode
= IfConfig6OpSet
;
1758 Private
->IfName
= ArgList
->Arg
;
1760 Private
->VarArg
= ArgList
->Next
;
1762 if (Private
->IfName
== NULL
|| Private
->VarArg
== NULL
) {
1763 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_COMMAND
), mHiiHandle
);
1768 // Main process of ifconfig6.
1770 Status
= IfConfig6 (Private
);
1774 ShellCommandLineFreeVarList (ParamPackage
);
1775 HiiRemovePackages (mHiiHandle
);
1776 if (Private
!= NULL
)
1777 IfConfig6Cleanup (Private
);