1 /** @file
2 The implementation for Shell command IfConfig6.
3
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5
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.
10
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.
13
14 **/
15 #include "UefiShellNetwork2CommandsLib.h"
16
17 enum {
18 IfConfig6OpList = 1,
19 IfConfig6OpSet = 2,
20 IfConfig6OpClear = 3
21 };
22
23 typedef enum {
24 VarCheckReserved = -1,
25 VarCheckOk = 0,
26 VarCheckDuplicate,
27 VarCheckConflict,
28 VarCheckUnknown,
29 VarCheckLackValue,
30 VarCheckOutOfMem
31 } VAR_CHECK_CODE;
32
33 typedef enum {
34 FlagTypeSingle = 0,
35 FlagTypeNeedVar,
36 FlagTypeNeedSet,
37 FlagTypeSkipUnknown
38 } VAR_CHECK_FLAG_TYPE;
39
40 #define MACADDRMAXSIZE 32
41 #define PREFIXMAXLEN 16
42
43 typedef struct _IFCONFIG6_INTERFACE_CB {
44 EFI_HANDLE NicHandle;
45 LIST_ENTRY Link;
46 EFI_IP6_CONFIG_PROTOCOL *IfCfg;
47 EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
48 EFI_IP6_CONFIG_INTERFACE_ID *IfId;
49 EFI_IP6_CONFIG_POLICY Policy;
50 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS Xmits;
51 UINT32 DnsCnt;
52 EFI_IPv6_ADDRESS DnsAddr[1];
53 } IFCONFIG6_INTERFACE_CB;
54
55 typedef struct _ARG_LIST ARG_LIST;
56
57 struct _ARG_LIST {
58 ARG_LIST *Next;
59 CHAR16 *Arg;
60 };
61
62 typedef struct _IFCONFIG6_PRIVATE_DATA {
63 EFI_HANDLE ImageHandle;
64 LIST_ENTRY IfList;
65
66 UINT32 OpCode;
67 CHAR16 *IfName;
68 ARG_LIST *VarArg;
69 } IFCONFIG6_PRIVATE_DATA;
70
71 typedef struct _VAR_CHECK_ITEM{
72 CHAR16 *FlagStr;
73 UINT32 FlagID;
74 UINT32 ConflictMask;
75 VAR_CHECK_FLAG_TYPE FlagType;
76 } VAR_CHECK_ITEM;
77
78
79 SHELL_PARAM_ITEM mIfConfig6CheckList[] = {
80 {
81 L"-b",
82 TypeFlag
83 },
84 {
85 L"-s",
86 TypeMaxValue
87 },
88 {
89 L"-l",
90 TypeValue
91 },
92 {
93 L"-r",
94 TypeValue
95 },
96 {
97 L"-?",
98 TypeFlag
99 },
100 {
101 NULL,
102 TypeMax
103 },
104 };
105
106 VAR_CHECK_ITEM mIfConfig6SetCheckList[] = {
107 {
108 L"auto",
109 0x00000001,
110 0x00000001,
111 FlagTypeSingle
112 },
113 {
114 L"man",
115 0x00000002,
116 0x00000001,
117 FlagTypeSingle
118 },
119 {
120 L"host",
121 0x00000004,
122 0x00000002,
123 FlagTypeSingle
124 },
125 {
126 L"dad",
127 0x00000008,
128 0x00000004,
129 FlagTypeSingle
130 },
131 {
132 L"gw",
133 0x00000010,
134 0x00000008,
135 FlagTypeSingle
136 },
137 {
138 L"dns",
139 0x00000020,
140 0x00000010,
141 FlagTypeSingle
142 },
143 {
144 L"id",
145 0x00000040,
146 0x00000020,
147 FlagTypeSingle
148 },
149 {
150 NULL,
151 0x0,
152 0x0,
153 FlagTypeSkipUnknown
154 },
155 };
156
157 /**
158 Free the ARG_LIST.
159
160 @param List Pointer to ARG_LIST to free.
161 **/
162 VOID
IfConfig6FreeArgList(ARG_LIST * List)163 IfConfig6FreeArgList (
164 ARG_LIST *List
165 )
166 {
167 ARG_LIST *Next;
168 while (List->Next != NULL) {
169 Next = List->Next;
170 FreePool (List);
171 List = Next;
172 }
173
174 FreePool (List);
175 }
176
177 /**
178 Split a string with specified separator and save the substring to a list.
179
180 @param[in] String The pointer of the input string.
181 @param[in] Separator The specified separator.
182
183 @return The pointer of headnode of ARG_LIST.
184
185 **/
186 ARG_LIST *
IfConfig6SplitStrToList(IN CONST CHAR16 * String,IN CHAR16 Separator)187 IfConfig6SplitStrToList (
188 IN CONST CHAR16 *String,
189 IN CHAR16 Separator
190 )
191 {
192 CHAR16 *Str;
193 CHAR16 *ArgStr;
194 ARG_LIST *ArgList;
195 ARG_LIST *ArgNode;
196
197 if (String == NULL || *String == L'\0') {
198 return NULL;
199 }
200
201 //
202 // Copy the CONST string to a local copy.
203 //
204 Str = AllocateCopyPool (StrSize (String), String);
205 if (Str == NULL) {
206 return NULL;
207 }
208 ArgStr = Str;
209
210 //
211 // init a node for the list head.
212 //
213 ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
214 if (ArgNode == NULL) {
215 return NULL;
216 }
217 ArgList = ArgNode;
218
219 //
220 // Split the local copy and save in the list node.
221 //
222 while (*Str != L'\0') {
223 if (*Str == Separator) {
224 *Str = L'\0';
225 ArgNode->Arg = ArgStr;
226 ArgStr = Str + 1;
227 ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
228 if (ArgNode->Next == NULL) {
229 //
230 // Free the local copy of string stored in the first node
231 //
232 FreePool (ArgList->Arg);
233 IfConfig6FreeArgList (ArgList);
234 return NULL;
235 }
236 ArgNode = ArgNode->Next;
237 }
238
239 Str++;
240 }
241
242 ArgNode->Arg = ArgStr;
243 ArgNode->Next = NULL;
244
245 return ArgList;
246 }
247
248 /**
249 Check the correctness of input Args with '-s' option.
250
251 @param[in] CheckList The pointer of VAR_CHECK_ITEM array.
252 @param[in] Name The pointer of input arg.
253 @param[in] Init The switch to execute the check.
254
255 @return The value of VAR_CHECK_CODE.
256
257 **/
258 VAR_CHECK_CODE
IfConfig6RetriveCheckListByName(IN VAR_CHECK_ITEM * CheckList,IN CHAR16 * Name,IN BOOLEAN Init)259 IfConfig6RetriveCheckListByName(
260 IN VAR_CHECK_ITEM *CheckList,
261 IN CHAR16 *Name,
262 IN BOOLEAN Init
263 )
264 {
265 STATIC UINT32 CheckDuplicate;
266 STATIC UINT32 CheckConflict;
267 VAR_CHECK_CODE RtCode;
268 UINT32 Index;
269 VAR_CHECK_ITEM Arg;
270
271 if (Init) {
272 CheckDuplicate = 0;
273 CheckConflict = 0;
274 return VarCheckOk;
275 }
276
277 RtCode = VarCheckOk;
278 Index = 0;
279 Arg = CheckList[Index];
280
281 //
282 // Check the Duplicated/Conflicted/Unknown input Args.
283 //
284 while (Arg.FlagStr != NULL) {
285 if (StrCmp (Arg.FlagStr, Name) == 0) {
286
287 if (CheckDuplicate & Arg.FlagID) {
288 RtCode = VarCheckDuplicate;
289 break;
290 }
291
292 if (CheckConflict & Arg.ConflictMask) {
293 RtCode = VarCheckConflict;
294 break;
295 }
296
297 CheckDuplicate |= Arg.FlagID;
298 CheckConflict |= Arg.ConflictMask;
299 break;
300 }
301
302 Arg = CheckList[++Index];
303 }
304
305 if (Arg.FlagStr == NULL) {
306 RtCode = VarCheckUnknown;
307 }
308
309 return RtCode;
310 }
311
312 /**
313 The notify function of create event when performing a manual config.
314
315 @param[in] Event The event this notify function registered to.
316 @param[in] Context Pointer to the context data registered to the event.
317
318 **/
319 VOID
320 EFIAPI
IfConfig6ManualAddressNotify(IN EFI_EVENT Event,IN VOID * Context)321 IfConfig6ManualAddressNotify (
322 IN EFI_EVENT Event,
323 IN VOID *Context
324 )
325 {
326 *((BOOLEAN *) Context) = TRUE;
327 }
328
329 /**
330 Print MAC address.
331
332 @param[in] Node The pointer of MAC address buffer.
333 @param[in] Size The size of MAC address buffer.
334
335 **/
336 VOID
IfConfig6PrintMacAddr(IN UINT8 * Node,IN UINT32 Size)337 IfConfig6PrintMacAddr (
338 IN UINT8 *Node,
339 IN UINT32 Size
340 )
341 {
342 UINTN Index;
343
344 ASSERT (Size <= MACADDRMAXSIZE);
345
346 for (Index = 0; Index < Size; Index++) {
347 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_BODY), gShellNetwork2HiiHandle, Node[Index]);
348 if (Index + 1 < Size) {
349 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
350 }
351 }
352
353 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
354 }
355
356 /**
357 Print IPv6 address.
358
359 @param[in] Ip The pointer of Ip bufffer in EFI_IPv6_ADDRESS format.
360 @param[in] PrefixLen The pointer of PrefixLen that describes the size Prefix.
361
362 **/
363 VOID
IfConfig6PrintIpAddr(IN EFI_IPv6_ADDRESS * Ip,IN UINT8 * PrefixLen)364 IfConfig6PrintIpAddr (
365 IN EFI_IPv6_ADDRESS *Ip,
366 IN UINT8 *PrefixLen
367 )
368 {
369 UINTN Index;
370 BOOLEAN Short;
371
372 Short = FALSE;
373
374 for (Index = 0; Index < PREFIXMAXLEN; Index = Index + 2) {
375
376 if (!Short && (Index + 1 < PREFIXMAXLEN) && (Index % 2 == 0) && (Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0)) {
377 //
378 // Deal with the case of ::.
379 //
380 if (Index == 0) {
381 //
382 // :: is at the beginning of the address.
383 //
384 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
385 }
386 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
387
388 while ((Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0) && (Index < PREFIXMAXLEN)) {
389 Index = Index + 2;
390 if (Index > PREFIXMAXLEN - 2) {
391 break;
392 }
393 }
394
395 Short = TRUE;
396
397 if (Index == PREFIXMAXLEN) {
398 //
399 // :: is at the end of the address.
400 //
401 break;
402 }
403 }
404
405 if (Index < PREFIXMAXLEN - 1) {
406 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), gShellNetwork2HiiHandle, Ip->Addr[Index]);
407 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), gShellNetwork2HiiHandle, Ip->Addr[Index + 1]);
408 }
409
410 if (Index + 2 < PREFIXMAXLEN) {
411 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), gShellNetwork2HiiHandle);
412 }
413 }
414
415 if (PrefixLen != NULL) {
416 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), gShellNetwork2HiiHandle, *PrefixLen);
417 }
418 }
419
420 /**
421 Pick up host IPv6 address in string format from Args with "-s" option and convert it to EFI_IP6_CONFIG_MANUAL_ADDRESS format.
422
423 @param[in, out] Arg The pointer of the address of ARG_LIST which save Args with the "-s" option.
424 @param[out] Buf The pointer of the address of EFI_IP6_CONFIG_MANUAL_ADDRESS.
425 @param[out] BufSize The pointer of BufSize that describes the size of Buf in bytes.
426
427 @retval EFI_SUCCESS The convertion is successful.
428 @retval Others Does't find the host address, or it is an invalid IPv6 address in string format.
429
430 **/
431 EFI_STATUS
IfConfig6ParseManualAddressList(IN OUT ARG_LIST ** Arg,OUT EFI_IP6_CONFIG_MANUAL_ADDRESS ** Buf,OUT UINTN * BufSize)432 IfConfig6ParseManualAddressList (
433 IN OUT ARG_LIST **Arg,
434 OUT EFI_IP6_CONFIG_MANUAL_ADDRESS **Buf,
435 OUT UINTN *BufSize
436 )
437 {
438 EFI_STATUS Status;
439 EFI_IP6_CONFIG_MANUAL_ADDRESS *AddrBuf;
440 ARG_LIST *VarArg;
441 EFI_IPv6_ADDRESS Address;
442 UINT8 Prefix;
443 UINT8 AddrCnt;
444
445 Prefix = 0;
446 AddrCnt = 0;
447 *BufSize = 0;
448 *Buf = NULL;
449 VarArg = *Arg;
450 Status = EFI_SUCCESS;
451
452 //
453 // Go through the list to check the correctness of input host ip6 address.
454 //
455 while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
456
457 Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
458
459 if (EFI_ERROR (Status)) {
460 //
461 // host ip ip ... gw
462 //
463 break;
464 }
465
466 VarArg = VarArg->Next;
467 AddrCnt++;
468 }
469
470 if (AddrCnt == 0) {
471 return EFI_INVALID_PARAMETER;
472 }
473
474 AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS));
475 ASSERT (AddrBuf != NULL);
476
477 AddrCnt = 0;
478 VarArg = *Arg;
479 Status = EFI_SUCCESS;
480
481 //
482 // Go through the list to fill in the EFI_IP6_CONFIG_MANUAL_ADDRESS structure.
483 //
484 while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
485
486 Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
487
488 if (EFI_ERROR (Status)) {
489 break;
490 }
491
492 //
493 // If prefix length is not set, set it as Zero here. In the IfConfigSetInterfaceInfo()
494 // Zero prefix, length will be transfered to default prefix length.
495 //
496 if (Prefix == 0xFF) {
497 Prefix = 0;
498 }
499 AddrBuf[AddrCnt].IsAnycast = FALSE;
500 AddrBuf[AddrCnt].PrefixLength = Prefix;
501 IP6_COPY_ADDRESS (&AddrBuf[AddrCnt].Address, &Address);
502 VarArg = VarArg->Next;
503 AddrCnt++;
504 }
505
506 *Arg = VarArg;
507
508 if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {
509 goto ON_ERROR;
510 }
511
512 *Buf = AddrBuf;
513 *BufSize = AddrCnt * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
514
515 return EFI_SUCCESS;
516
517 ON_ERROR:
518
519 FreePool (AddrBuf);
520 return Status;
521 }
522
523 /**
524 Pick up gw/dns IPv6 address in string format from Args with "-s" option and convert it to EFI_IPv6_ADDRESS format.
525
526 @param[in, out] Arg The pointer of the address of ARG_LIST that save Args with the "-s" option.
527 @param[out] Buf The pointer of the address of EFI_IPv6_ADDRESS.
528 @param[out] BufSize The pointer of BufSize that describes the size of Buf in bytes.
529
530 @retval EFI_SUCCESS The conversion is successful.
531 @retval Others Doesn't find the host address, or it is an invalid IPv6 address in string format.
532
533 **/
534 EFI_STATUS
IfConfig6ParseGwDnsAddressList(IN OUT ARG_LIST ** Arg,OUT EFI_IPv6_ADDRESS ** Buf,OUT UINTN * BufSize)535 IfConfig6ParseGwDnsAddressList (
536 IN OUT ARG_LIST **Arg,
537 OUT EFI_IPv6_ADDRESS **Buf,
538 OUT UINTN *BufSize
539 )
540 {
541 EFI_STATUS Status;
542 EFI_IPv6_ADDRESS *AddrBuf;
543 ARG_LIST *VarArg;
544 EFI_IPv6_ADDRESS Address;
545 UINT8 Prefix;
546 UINT8 AddrCnt;
547
548 AddrCnt = 0;
549 *BufSize = 0;
550 *Buf = NULL;
551 VarArg = *Arg;
552 Status = EFI_SUCCESS;
553
554 //
555 // Go through the list to check the correctness of input gw/dns address.
556 //
557 while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
558
559 Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
560
561 if (EFI_ERROR (Status)) {
562 //
563 // gw ip ip ... host
564 //
565 break;
566 }
567
568 VarArg = VarArg->Next;
569 AddrCnt++;
570 }
571
572 if (AddrCnt == 0) {
573 return EFI_INVALID_PARAMETER;
574 }
575
576 AddrBuf = AllocateZeroPool (AddrCnt * sizeof (EFI_IPv6_ADDRESS));
577 ASSERT (AddrBuf != NULL);
578
579 AddrCnt = 0;
580 VarArg = *Arg;
581 Status = EFI_SUCCESS;
582
583 //
584 // Go through the list to fill in the EFI_IPv6_ADDRESS structure.
585 //
586 while ((!EFI_ERROR (Status)) && (VarArg != NULL)) {
587
588 Status = NetLibStrToIp6andPrefix (VarArg->Arg, &Address, &Prefix);
589
590 if (EFI_ERROR (Status)) {
591 break;
592 }
593
594 IP6_COPY_ADDRESS (&AddrBuf[AddrCnt], &Address);
595
596 VarArg = VarArg->Next;
597 AddrCnt++;
598 }
599
600 *Arg = VarArg;
601
602 if (EFI_ERROR (Status) && (Status != EFI_INVALID_PARAMETER)) {
603 goto ON_ERROR;
604 }
605
606 *Buf = AddrBuf;
607 *BufSize = AddrCnt * sizeof (EFI_IPv6_ADDRESS);
608
609 return EFI_SUCCESS;
610
611 ON_ERROR:
612
613 FreePool (AddrBuf);
614 return Status;
615 }
616
617 /**
618 Parse InterfaceId in string format from Args with the "-s" option and convert it to EFI_IP6_CONFIG_INTERFACE_ID format.
619
620 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
621 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
622
623 @retval EFI_SUCCESS The get status processed successfullly.
624 @retval EFI_INVALID_PARAMETER The get status process failed.
625
626 **/
627 EFI_STATUS
IfConfig6ParseInterfaceId(IN OUT ARG_LIST ** Arg,OUT EFI_IP6_CONFIG_INTERFACE_ID ** IfId)628 IfConfig6ParseInterfaceId (
629 IN OUT ARG_LIST **Arg,
630 OUT EFI_IP6_CONFIG_INTERFACE_ID **IfId
631 )
632 {
633 UINT8 Index;
634 UINT8 NodeVal;
635 CHAR16 *IdStr;
636
637 if (*Arg == NULL) {
638 return EFI_INVALID_PARAMETER;
639 }
640
641 Index = 0;
642 IdStr = (*Arg)->Arg;
643 ASSERT (IfId != NULL);
644 *IfId = AllocateZeroPool (sizeof (EFI_IP6_CONFIG_INTERFACE_ID));
645 ASSERT (*IfId != NULL);
646
647 while ((*IdStr != L'\0') && (Index < 8)) {
648
649 NodeVal = 0;
650 while ((*IdStr != L':') && (*IdStr != L'\0')) {
651
652 if ((*IdStr <= L'F') && (*IdStr >= L'A')) {
653 NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'A' + 10);
654 } else if ((*IdStr <= L'f') && (*IdStr >= L'a')) {
655 NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'a' + 10);
656 } else if ((*IdStr <= L'9') && (*IdStr >= L'0')) {
657 NodeVal = (UINT8)((NodeVal << 4) + *IdStr - L'0');
658 } else {
659 FreePool (*IfId);
660 return EFI_INVALID_PARAMETER;
661 }
662
663 IdStr++;
664 }
665
666 (*IfId)->Id[Index++] = NodeVal;
667
668 if (*IdStr == L':') {
669 IdStr++;
670 }
671 }
672
673 *Arg = (*Arg)->Next;
674 return EFI_SUCCESS;
675 }
676
677 /**
678 Parse dad in string format from Args with the "-s" option and convert it to UINT32 format.
679
680 @param[in, out] Arg The pointer of the address of ARG_LIST that saves Args with the "-s" option.
681 @param[out] Xmits The pointer of Xmits.
682
683 @retval EFI_SUCCESS The get status processed successfully.
684 @retval others The get status process failed.
685
686 **/
687 EFI_STATUS
IfConfig6ParseDadXmits(IN OUT ARG_LIST ** Arg,OUT UINT32 * Xmits)688 IfConfig6ParseDadXmits (
689 IN OUT ARG_LIST **Arg,
690 OUT UINT32 *Xmits
691 )
692 {
693 CHAR16 *ValStr;
694
695 if (*Arg == NULL) {
696 return EFI_INVALID_PARAMETER;
697 }
698
699 ValStr = (*Arg)->Arg;
700 *Xmits = 0;
701
702 while (*ValStr != L'\0') {
703
704 if ((*ValStr <= L'9') && (*ValStr >= L'0')) {
705
706 *Xmits = (*Xmits * 10) + (*ValStr - L'0');
707
708 } else {
709
710 return EFI_INVALID_PARAMETER;
711 }
712
713 ValStr++;
714 }
715
716 *Arg = (*Arg)->Next;
717 return EFI_SUCCESS;
718 }
719
720 /**
721 The get current status of all handles.
722
723 @param[in] ImageHandle The handle of ImageHandle.
724 @param[in] IfName The pointer of IfName(interface name).
725 @param[in] IfList The pointer of IfList(interface list).
726
727 @retval EFI_SUCCESS The get status processed successfully.
728 @retval others The get status process failed.
729
730 **/
731 EFI_STATUS
IfConfig6GetInterfaceInfo(IN EFI_HANDLE ImageHandle,IN CHAR16 * IfName,IN LIST_ENTRY * IfList)732 IfConfig6GetInterfaceInfo (
733 IN EFI_HANDLE ImageHandle,
734 IN CHAR16 *IfName,
735 IN LIST_ENTRY *IfList
736 )
737 {
738 EFI_STATUS Status;
739 UINTN HandleIndex;
740 UINTN HandleNum;
741 EFI_HANDLE *HandleBuffer;
742 EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
743 EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
744 IFCONFIG6_INTERFACE_CB *IfCb;
745 UINTN DataSize;
746
747 HandleBuffer = NULL;
748 HandleNum = 0;
749
750 IfInfo = NULL;
751 IfCb = NULL;
752
753 //
754 // Locate all the handles with ip6 service binding protocol.
755 //
756 Status = gBS->LocateHandleBuffer (
757 ByProtocol,
758 &gEfiIp6ServiceBindingProtocolGuid,
759 NULL,
760 &HandleNum,
761 &HandleBuffer
762 );
763 if (EFI_ERROR (Status) || (HandleNum == 0)) {
764 return Status;
765 }
766
767 //
768 // Enumerate all handles that installed with ip6 service binding protocol.
769 //
770 for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {
771 IfCb = NULL;
772 IfInfo = NULL;
773 DataSize = 0;
774
775 //
776 // Ip6config protocol and ip6 service binding protocol are installed
777 // on the same handle.
778 //
779 ASSERT (HandleBuffer != NULL);
780 Status = gBS->HandleProtocol (
781 HandleBuffer[HandleIndex],
782 &gEfiIp6ConfigProtocolGuid,
783 (VOID **) &Ip6Cfg
784 );
785
786 if (EFI_ERROR (Status)) {
787 goto ON_ERROR;
788 }
789 //
790 // Get the interface information size.
791 //
792 Status = Ip6Cfg->GetData (
793 Ip6Cfg,
794 Ip6ConfigDataTypeInterfaceInfo,
795 &DataSize,
796 NULL
797 );
798
799 if (Status != EFI_BUFFER_TOO_SMALL) {
800 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
801 goto ON_ERROR;
802 }
803
804 IfInfo = AllocateZeroPool (DataSize);
805
806 if (IfInfo == NULL) {
807 Status = EFI_OUT_OF_RESOURCES;
808 goto ON_ERROR;
809 }
810 //
811 // Get the interface info.
812 //
813 Status = Ip6Cfg->GetData (
814 Ip6Cfg,
815 Ip6ConfigDataTypeInterfaceInfo,
816 &DataSize,
817 IfInfo
818 );
819
820 if (EFI_ERROR (Status)) {
821 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
822 goto ON_ERROR;
823 }
824 //
825 // Check the interface name if required.
826 //
827 if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) {
828 FreePool (IfInfo);
829 continue;
830 }
831
832 DataSize = 0;
833 //
834 // Get the size of dns server list.
835 //
836 Status = Ip6Cfg->GetData (
837 Ip6Cfg,
838 Ip6ConfigDataTypeDnsServer,
839 &DataSize,
840 NULL
841 );
842
843 if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {
844 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
845 goto ON_ERROR;
846 }
847
848 IfCb = AllocateZeroPool (sizeof (IFCONFIG6_INTERFACE_CB) + DataSize);
849
850 if (IfCb == NULL) {
851 Status = EFI_OUT_OF_RESOURCES;
852 goto ON_ERROR;
853 }
854
855 IfCb->NicHandle = HandleBuffer[HandleIndex];
856 IfCb->IfInfo = IfInfo;
857 IfCb->IfCfg = Ip6Cfg;
858 IfCb->DnsCnt = (UINT32) (DataSize / sizeof (EFI_IPv6_ADDRESS));
859
860 //
861 // Get the dns server list if has.
862 //
863 if (DataSize > 0) {
864
865 Status = Ip6Cfg->GetData (
866 Ip6Cfg,
867 Ip6ConfigDataTypeDnsServer,
868 &DataSize,
869 IfCb->DnsAddr
870 );
871
872 if (EFI_ERROR (Status)) {
873 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
874 goto ON_ERROR;
875 }
876 }
877 //
878 // Get the interface id if has.
879 //
880 DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
881 IfCb->IfId = AllocateZeroPool (DataSize);
882
883 if (IfCb->IfId == NULL) {
884 goto ON_ERROR;
885 }
886
887 Status = Ip6Cfg->GetData (
888 Ip6Cfg,
889 Ip6ConfigDataTypeAltInterfaceId,
890 &DataSize,
891 IfCb->IfId
892 );
893
894 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
895 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
896 goto ON_ERROR;
897 }
898
899 if (Status == EFI_NOT_FOUND) {
900 FreePool (IfCb->IfId);
901 IfCb->IfId = NULL;
902 }
903 //
904 // Get the config policy.
905 //
906 DataSize = sizeof (EFI_IP6_CONFIG_POLICY);
907 Status = Ip6Cfg->GetData (
908 Ip6Cfg,
909 Ip6ConfigDataTypePolicy,
910 &DataSize,
911 &IfCb->Policy
912 );
913
914 if (EFI_ERROR (Status)) {
915 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
916 goto ON_ERROR;
917 }
918 //
919 // Get the dad transmits.
920 //
921 DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
922 Status = Ip6Cfg->GetData (
923 Ip6Cfg,
924 Ip6ConfigDataTypeDupAddrDetectTransmits,
925 &DataSize,
926 &IfCb->Xmits
927 );
928
929 if (EFI_ERROR (Status)) {
930 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
931 goto ON_ERROR;
932 }
933
934 InsertTailList (IfList, &IfCb->Link);
935
936 if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) {
937 //
938 // Only need the appointed interface, keep the allocated buffer.
939 //
940 IfCb = NULL;
941 IfInfo = NULL;
942 break;
943 }
944 }
945
946 if (HandleBuffer != NULL) {
947 FreePool (HandleBuffer);
948 }
949
950 return EFI_SUCCESS;
951
952 ON_ERROR:
953
954 if (IfInfo != NULL) {
955 FreePool (IfInfo);
956 }
957
958 if (IfCb != NULL) {
959 if (IfCb->IfId != NULL) {
960 FreePool (IfCb->IfId);
961 }
962
963 FreePool (IfCb);
964 }
965
966 return Status;
967 }
968
969 /**
970 The list process of the IfConfig6 application.
971
972 @param[in] IfList The pointer of IfList(interface list).
973
974 @retval SHELL_SUCCESS The IfConfig6 list processed successfully.
975 @retval others The IfConfig6 list process failed.
976
977 **/
978 SHELL_STATUS
IfConfig6ShowInterfaceInfo(IN LIST_ENTRY * IfList)979 IfConfig6ShowInterfaceInfo (
980 IN LIST_ENTRY *IfList
981 )
982 {
983 LIST_ENTRY *Entry;
984 IFCONFIG6_INTERFACE_CB *IfCb;
985 UINTN Index;
986
987 Entry = IfList->ForwardLink;
988
989 if (IsListEmpty (IfList)) {
990 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
991 }
992
993 //
994 // Go through the interface list.
995 //
996 while (Entry != IfList) {
997
998 IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
999
1000 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), gShellNetwork2HiiHandle);
1001
1002 //
1003 // Print interface name.
1004 //
1005 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IF_NAME), gShellNetwork2HiiHandle, IfCb->IfInfo->Name);
1006
1007 //
1008 // Print interface config policy.
1009 //
1010 if (IfCb->Policy == Ip6ConfigPolicyAutomatic) {
1011 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_AUTO), gShellNetwork2HiiHandle);
1012 } else {
1013 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_POLICY_MAN), gShellNetwork2HiiHandle);
1014 }
1015
1016 //
1017 // Print dad transmit.
1018 //
1019 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DAD_TRANSMITS), gShellNetwork2HiiHandle, IfCb->Xmits);
1020
1021 //
1022 // Print interface id if has.
1023 //
1024 if (IfCb->IfId != NULL) {
1025 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_INTERFACE_ID_HEAD), gShellNetwork2HiiHandle);
1026
1027 IfConfig6PrintMacAddr (
1028 IfCb->IfId->Id,
1029 8
1030 );
1031 }
1032 //
1033 // Print mac address of the interface.
1034 //
1035 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_HEAD), gShellNetwork2HiiHandle);
1036
1037 IfConfig6PrintMacAddr (
1038 IfCb->IfInfo->HwAddress.Addr,
1039 IfCb->IfInfo->HwAddressSize
1040 );
1041
1042 //
1043 // Print ip addresses list of the interface.
1044 //
1045 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_HEAD), gShellNetwork2HiiHandle);
1046
1047 for (Index = 0; Index < IfCb->IfInfo->AddressInfoCount; Index++) {
1048 IfConfig6PrintIpAddr (
1049 &IfCb->IfInfo->AddressInfo[Index].Address,
1050 &IfCb->IfInfo->AddressInfo[Index].PrefixLength
1051 );
1052 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
1053 }
1054
1055 //
1056 // Print dns server addresses list of the interface if has.
1057 //
1058 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_DNS_ADDR_HEAD), gShellNetwork2HiiHandle);
1059
1060 for (Index = 0; Index < IfCb->DnsCnt; Index++) {
1061 IfConfig6PrintIpAddr (
1062 &IfCb->DnsAddr[Index],
1063 NULL
1064 );
1065 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
1066 }
1067
1068 //
1069 // Print route table of the interface if has.
1070 //
1071 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_ROUTE_HEAD), gShellNetwork2HiiHandle);
1072
1073 for (Index = 0; Index < IfCb->IfInfo->RouteCount; Index++) {
1074 IfConfig6PrintIpAddr (
1075 &IfCb->IfInfo->RouteTable[Index].Destination,
1076 &IfCb->IfInfo->RouteTable[Index].PrefixLength
1077 );
1078 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_JOINT), gShellNetwork2HiiHandle);
1079
1080 IfConfig6PrintIpAddr (
1081 &IfCb->IfInfo->RouteTable[Index].Gateway,
1082 NULL
1083 );
1084 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
1085 }
1086
1087 Entry = Entry->ForwardLink;
1088 }
1089
1090 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_BREAK), gShellNetwork2HiiHandle);
1091 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), gShellNetwork2HiiHandle);
1092
1093 return SHELL_SUCCESS;
1094 }
1095
1096 /**
1097 The clean process of the IfConfig6 application.
1098
1099 @param[in] IfList The pointer of IfList(interface list).
1100 @param[in] IfName The pointer of interface name.
1101
1102 @retval SHELL_SUCCESS The IfConfig6 clean processed successfully.
1103 @retval others The IfConfig6 clean process failed.
1104
1105 **/
1106 SHELL_STATUS
IfConfig6ClearInterfaceInfo(IN LIST_ENTRY * IfList,IN CHAR16 * IfName)1107 IfConfig6ClearInterfaceInfo (
1108 IN LIST_ENTRY *IfList,
1109 IN CHAR16 *IfName
1110 )
1111 {
1112 EFI_STATUS Status;
1113 SHELL_STATUS ShellStatus;
1114 LIST_ENTRY *Entry;
1115 IFCONFIG6_INTERFACE_CB *IfCb;
1116 EFI_IP6_CONFIG_POLICY Policy;
1117
1118 Entry = IfList->ForwardLink;
1119 Status = EFI_SUCCESS;
1120 ShellStatus = SHELL_SUCCESS;
1121
1122 if (IsListEmpty (IfList)) {
1123 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
1124 }
1125
1126 //
1127 // Go through the interface list.If the interface name is specified, then
1128 // need to refresh the configuration.
1129 //
1130 while (Entry != IfList) {
1131
1132 IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
1133
1134 if ((IfName != NULL) && (StrCmp (IfName, IfCb->IfInfo->Name) == 0)) {
1135 Policy = Ip6ConfigPolicyManual;
1136
1137 Status = IfCb->IfCfg->SetData (
1138 IfCb->IfCfg,
1139 Ip6ConfigDataTypePolicy,
1140 sizeof (EFI_IP6_CONFIG_POLICY),
1141 &Policy
1142 );
1143 if (EFI_ERROR (Status)) {
1144 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork2HiiHandle, L"ifconfig6");
1145 ShellStatus = SHELL_ACCESS_DENIED;
1146 break;
1147 }
1148 }
1149
1150 Policy = Ip6ConfigPolicyAutomatic;
1151
1152 Status = IfCb->IfCfg->SetData (
1153 IfCb->IfCfg,
1154 Ip6ConfigDataTypePolicy,
1155 sizeof (EFI_IP6_CONFIG_POLICY),
1156 &Policy
1157 );
1158
1159 if (EFI_ERROR (Status)) {
1160 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork2HiiHandle, L"ifconfig6");
1161 ShellStatus = SHELL_ACCESS_DENIED;
1162 break;
1163 }
1164
1165 Entry = Entry->ForwardLink;
1166 }
1167
1168 return ShellStatus;
1169 }
1170
1171 /**
1172 The set process of the IfConfig6 application.
1173
1174 @param[in] IfList The pointer of IfList(interface list).
1175 @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option).
1176
1177 @retval SHELL_SUCCESS The IfConfig6 set processed successfully.
1178 @retval others The IfConfig6 set process failed.
1179
1180 **/
1181 SHELL_STATUS
IfConfig6SetInterfaceInfo(IN LIST_ENTRY * IfList,IN ARG_LIST * VarArg)1182 IfConfig6SetInterfaceInfo (
1183 IN LIST_ENTRY *IfList,
1184 IN ARG_LIST *VarArg
1185 )
1186 {
1187 EFI_STATUS Status;
1188 SHELL_STATUS ShellStatus;
1189 IFCONFIG6_INTERFACE_CB *IfCb;
1190 EFI_IP6_CONFIG_MANUAL_ADDRESS *CfgManAddr;
1191 EFI_IPv6_ADDRESS *CfgAddr;
1192 UINTN AddrSize;
1193 EFI_IP6_CONFIG_INTERFACE_ID *InterfaceId;
1194 UINT32 DadXmits;
1195 UINT32 CurDadXmits;
1196 UINTN CurDadXmitsLen;
1197 EFI_IP6_CONFIG_POLICY Policy;
1198
1199 VAR_CHECK_CODE CheckCode;
1200 EFI_EVENT TimeOutEvt;
1201 EFI_EVENT MappedEvt;
1202 BOOLEAN IsAddressOk;
1203
1204 UINTN DataSize;
1205 UINT32 Index;
1206 UINT32 Index2;
1207 BOOLEAN IsAddressSet;
1208 EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
1209
1210 CfgManAddr = NULL;
1211 CfgAddr = NULL;
1212 TimeOutEvt = NULL;
1213 MappedEvt = NULL;
1214 IfInfo = NULL;
1215 InterfaceId = NULL;
1216 CurDadXmits = 0;
1217
1218 if (IsListEmpty (IfList)) {
1219 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), gShellNetwork2HiiHandle);
1220 return SHELL_INVALID_PARAMETER;
1221 }
1222 //
1223 // Make sure to set only one interface each time.
1224 //
1225 IfCb = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link);
1226 Status = EFI_SUCCESS;
1227 ShellStatus = SHELL_SUCCESS;
1228
1229 //
1230 // Initialize check list mechanism.
1231 //
1232 CheckCode = IfConfig6RetriveCheckListByName(
1233 NULL,
1234 NULL,
1235 TRUE
1236 );
1237
1238 //
1239 // Create events & timers for asynchronous settings.
1240 //
1241 Status = gBS->CreateEvent (
1242 EVT_TIMER,
1243 TPL_CALLBACK,
1244 NULL,
1245 NULL,
1246 &TimeOutEvt
1247 );
1248 if (EFI_ERROR (Status)) {
1249 ShellStatus = SHELL_ACCESS_DENIED;
1250 goto ON_EXIT;
1251 }
1252
1253 Status = gBS->CreateEvent (
1254 EVT_NOTIFY_SIGNAL,
1255 TPL_NOTIFY,
1256 IfConfig6ManualAddressNotify,
1257 &IsAddressOk,
1258 &MappedEvt
1259 );
1260 if (EFI_ERROR (Status)) {
1261 ShellStatus = SHELL_ACCESS_DENIED;
1262 goto ON_EXIT;
1263 }
1264 //
1265 // Parse the setting variables.
1266 //
1267 while (VarArg != NULL) {
1268 //
1269 // Check invalid parameters (duplication & unknown & conflict).
1270 //
1271 CheckCode = IfConfig6RetriveCheckListByName(
1272 mIfConfig6SetCheckList,
1273 VarArg->Arg,
1274 FALSE
1275 );
1276
1277 if (VarCheckOk != CheckCode) {
1278 switch (CheckCode) {
1279 case VarCheckDuplicate:
1280 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);
1281 break;
1282
1283 case VarCheckConflict:
1284 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);
1285 break;
1286
1287 case VarCheckUnknown:
1288 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), gShellNetwork2HiiHandle, VarArg->Arg);
1289 break;
1290
1291 default:
1292 break;
1293 }
1294
1295 VarArg = VarArg->Next;
1296 continue;
1297 }
1298 //
1299 // Process valid variables.
1300 //
1301 if (StrCmp(VarArg->Arg, L"auto") == 0) {
1302 //
1303 // Set automaic config policy
1304 //
1305 Policy = Ip6ConfigPolicyAutomatic;
1306 Status = IfCb->IfCfg->SetData (
1307 IfCb->IfCfg,
1308 Ip6ConfigDataTypePolicy,
1309 sizeof (EFI_IP6_CONFIG_POLICY),
1310 &Policy
1311 );
1312
1313 if (EFI_ERROR(Status)) {
1314 ShellStatus = SHELL_ACCESS_DENIED;
1315 goto ON_EXIT;
1316 }
1317
1318 VarArg= VarArg->Next;
1319
1320 if (StrCmp (VarArg->Arg, L"host") == 0) {
1321 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_IP_CONFIG), gShellNetwork2HiiHandle, Status);
1322 ShellStatus = SHELL_INVALID_PARAMETER;
1323 goto ON_EXIT;
1324 } else if (StrCmp (VarArg->Arg, L"gw") == 0) {
1325 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_GW_CONFIG), gShellNetwork2HiiHandle, Status);
1326 ShellStatus = SHELL_INVALID_PARAMETER;
1327 goto ON_EXIT;
1328 } else if (StrCmp (VarArg->Arg, L"dns") == 0) {
1329 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_DNS_CONFIG), gShellNetwork2HiiHandle, Status);
1330 ShellStatus = SHELL_INVALID_PARAMETER;
1331 goto ON_EXIT;
1332 }
1333
1334 } else if (StrCmp (VarArg->Arg, L"man") == 0) {
1335 //
1336 // Set manual config policy.
1337 //
1338 Policy = Ip6ConfigPolicyManual;
1339 Status = IfCb->IfCfg->SetData (
1340 IfCb->IfCfg,
1341 Ip6ConfigDataTypePolicy,
1342 sizeof (EFI_IP6_CONFIG_POLICY),
1343 &Policy
1344 );
1345
1346 if (EFI_ERROR(Status)) {
1347 ShellStatus = SHELL_ACCESS_DENIED;
1348 goto ON_EXIT;
1349 }
1350
1351 VarArg= VarArg->Next;
1352
1353 } else if (StrCmp (VarArg->Arg, L"host") == 0) {
1354 //
1355 // Parse till the next tag or the end of command line.
1356 //
1357 VarArg = VarArg->Next;
1358 Status = IfConfig6ParseManualAddressList (
1359 &VarArg,
1360 &CfgManAddr,
1361 &AddrSize
1362 );
1363
1364 if (EFI_ERROR (Status)) {
1365 if (Status == EFI_INVALID_PARAMETER) {
1366 ShellStatus = SHELL_INVALID_PARAMETER;
1367 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"host");
1368 continue;
1369 } else {
1370 ShellStatus = SHELL_ACCESS_DENIED;
1371 goto ON_EXIT;
1372 }
1373 }
1374 //
1375 // Set static host ip6 address list.
1376 // This is a asynchronous process.
1377 //
1378 IsAddressOk = FALSE;
1379
1380 Status = IfCb->IfCfg->RegisterDataNotify (
1381 IfCb->IfCfg,
1382 Ip6ConfigDataTypeManualAddress,
1383 MappedEvt
1384 );
1385 if (EFI_ERROR (Status)) {
1386 ShellStatus = SHELL_ACCESS_DENIED;
1387 goto ON_EXIT;
1388 }
1389
1390 Status = IfCb->IfCfg->SetData (
1391 IfCb->IfCfg,
1392 Ip6ConfigDataTypeManualAddress,
1393 AddrSize,
1394 CfgManAddr
1395 );
1396
1397 if (Status == EFI_NOT_READY) {
1398 //
1399 // Get current dad transmits count.
1400 //
1401 CurDadXmitsLen = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
1402 IfCb->IfCfg->GetData (
1403 IfCb->IfCfg,
1404 Ip6ConfigDataTypeDupAddrDetectTransmits,
1405 &CurDadXmitsLen,
1406 &CurDadXmits
1407 );
1408
1409 gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000 + 10000000 * CurDadXmits);
1410
1411 while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {
1412 if (IsAddressOk) {
1413 Status = EFI_SUCCESS;
1414 break;
1415 }
1416 }
1417 }
1418
1419 IfCb->IfCfg->UnregisterDataNotify (
1420 IfCb->IfCfg,
1421 Ip6ConfigDataTypeManualAddress,
1422 MappedEvt
1423 );
1424
1425 if (EFI_ERROR (Status)) {
1426 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST), gShellNetwork2HiiHandle, Status);
1427 ShellStatus = SHELL_ACCESS_DENIED;
1428 goto ON_EXIT;
1429 }
1430
1431 //
1432 // Check whether the address is set successfully.
1433 //
1434 DataSize = 0;
1435
1436 Status = IfCb->IfCfg->GetData (
1437 IfCb->IfCfg,
1438 Ip6ConfigDataTypeInterfaceInfo,
1439 &DataSize,
1440 NULL
1441 );
1442
1443 if (Status != EFI_BUFFER_TOO_SMALL) {
1444 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
1445 ShellStatus = SHELL_ACCESS_DENIED;
1446 goto ON_EXIT;
1447 }
1448
1449 IfInfo = AllocateZeroPool (DataSize);
1450
1451 if (IfInfo == NULL) {
1452 ShellStatus = SHELL_OUT_OF_RESOURCES;
1453 goto ON_EXIT;
1454 }
1455
1456 Status = IfCb->IfCfg->GetData (
1457 IfCb->IfCfg,
1458 Ip6ConfigDataTypeInterfaceInfo,
1459 &DataSize,
1460 IfInfo
1461 );
1462
1463 if (EFI_ERROR (Status)) {
1464 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), gShellNetwork2HiiHandle, Status);
1465 ShellStatus = SHELL_ACCESS_DENIED;
1466 goto ON_EXIT;
1467 }
1468
1469 for ( Index = 0; Index < (UINTN) (AddrSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); Index++) {
1470 IsAddressSet = FALSE;
1471 //
1472 // By default, the prefix length 0 is regarded as 64.
1473 //
1474 if (CfgManAddr[Index].PrefixLength == 0) {
1475 CfgManAddr[Index].PrefixLength = 64;
1476 }
1477
1478 for (Index2 = 0; Index2 < IfInfo->AddressInfoCount; Index2++) {
1479 if (EFI_IP6_EQUAL (&IfInfo->AddressInfo[Index2].Address, &CfgManAddr[Index].Address) &&
1480 (IfInfo->AddressInfo[Index2].PrefixLength == CfgManAddr[Index].PrefixLength)) {
1481 IsAddressSet = TRUE;
1482 break;
1483 }
1484 }
1485
1486 if (!IsAddressSet) {
1487 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED), gShellNetwork2HiiHandle);
1488 IfConfig6PrintIpAddr (
1489 &CfgManAddr[Index].Address,
1490 &CfgManAddr[Index].PrefixLength
1491 );
1492 }
1493 }
1494
1495 } else if (StrCmp (VarArg->Arg, L"gw") == 0) {
1496 //
1497 // Parse till the next tag or the end of command line.
1498 //
1499 VarArg = VarArg->Next;
1500 Status = IfConfig6ParseGwDnsAddressList (
1501 &VarArg,
1502 &CfgAddr,
1503 &AddrSize
1504 );
1505
1506 if (EFI_ERROR (Status)) {
1507 if (Status == EFI_INVALID_PARAMETER) {
1508 ShellStatus = SHELL_INVALID_PARAMETER;
1509 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"gw");
1510 continue;
1511 } else {
1512 ShellStatus = SHELL_ACCESS_DENIED;
1513 goto ON_EXIT;
1514 }
1515 }
1516 //
1517 // Set static gateway ip6 address list.
1518 //
1519 Status = IfCb->IfCfg->SetData (
1520 IfCb->IfCfg,
1521 Ip6ConfigDataTypeGateway,
1522 AddrSize,
1523 CfgAddr
1524 );
1525
1526 if (EFI_ERROR (Status)) {
1527 ShellStatus = SHELL_ACCESS_DENIED;
1528 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_GW), gShellNetwork2HiiHandle, Status);
1529 goto ON_EXIT;
1530 }
1531
1532 } else if (StrCmp (VarArg->Arg, L"dns") == 0) {
1533 //
1534 // Parse till the next tag or the end of command line.
1535 //
1536 VarArg = VarArg->Next;
1537 Status = IfConfig6ParseGwDnsAddressList (
1538 &VarArg,
1539 &CfgAddr,
1540 &AddrSize
1541 );
1542
1543 if (EFI_ERROR (Status)) {
1544 if (Status == EFI_INVALID_PARAMETER) {
1545 ShellStatus = SHELL_INVALID_PARAMETER;
1546 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), gShellNetwork2HiiHandle, L"dns");
1547 continue;
1548 } else {
1549 ShellStatus = SHELL_ACCESS_DENIED;
1550 goto ON_EXIT;
1551 }
1552 }
1553 //
1554 // Set static DNS server ip6 address list.
1555 //
1556 Status = IfCb->IfCfg->SetData (
1557 IfCb->IfCfg,
1558 Ip6ConfigDataTypeDnsServer,
1559 AddrSize,
1560 CfgAddr
1561 );
1562
1563 if (EFI_ERROR (Status)) {
1564 ShellStatus = SHELL_ACCESS_DENIED;
1565 goto ON_EXIT;
1566 }
1567
1568 } else if (StrCmp (VarArg->Arg, L"id") == 0) {
1569 //
1570 // Parse till the next tag or the end of command line.
1571 //
1572 VarArg = VarArg->Next;
1573 Status = IfConfig6ParseInterfaceId (&VarArg, &InterfaceId);
1574
1575 if (EFI_ERROR (Status)) {
1576 ShellStatus = SHELL_INVALID_PARAMETER;
1577 goto ON_EXIT;
1578 }
1579 //
1580 // Set alternative interface id.
1581 //
1582 Status = IfCb->IfCfg->SetData (
1583 IfCb->IfCfg,
1584 Ip6ConfigDataTypeAltInterfaceId,
1585 sizeof (EFI_IP6_CONFIG_INTERFACE_ID),
1586 InterfaceId
1587 );
1588
1589 if (EFI_ERROR (Status)) {
1590 ShellStatus = SHELL_ACCESS_DENIED;
1591 goto ON_EXIT;
1592 }
1593
1594 } else if (StrCmp (VarArg->Arg, L"dad") == 0) {
1595 //
1596 // Parse till the next tag or the end of command line.
1597 //
1598 VarArg = VarArg->Next;
1599 Status = IfConfig6ParseDadXmits (&VarArg, &DadXmits);
1600
1601 if (EFI_ERROR (Status)) {
1602 ShellStatus = SHELL_ACCESS_DENIED;
1603 goto ON_EXIT;
1604 }
1605 //
1606 // Set dad transmits count.
1607 //
1608 Status = IfCb->IfCfg->SetData (
1609 IfCb->IfCfg,
1610 Ip6ConfigDataTypeDupAddrDetectTransmits,
1611 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),
1612 &DadXmits
1613 );
1614
1615 if (EFI_ERROR(Status)) {
1616 ShellStatus = SHELL_ACCESS_DENIED;
1617 goto ON_EXIT;
1618 }
1619 }
1620 }
1621
1622 ON_EXIT:
1623
1624 if (CfgManAddr != NULL) {
1625 FreePool (CfgManAddr);
1626 }
1627
1628 if (CfgAddr != NULL) {
1629 FreePool (CfgAddr);
1630 }
1631
1632 if (MappedEvt != NULL) {
1633 gBS->CloseEvent (MappedEvt);
1634 }
1635
1636 if (TimeOutEvt != NULL) {
1637 gBS->CloseEvent (TimeOutEvt);
1638 }
1639
1640 if (IfInfo != NULL) {
1641 FreePool (IfInfo);
1642 }
1643
1644 return ShellStatus;
1645
1646 }
1647
1648 /**
1649 The IfConfig6 main process.
1650
1651 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1652
1653 @retval SHELL_SUCCESS IfConfig6 processed successfully.
1654 @retval others The IfConfig6 process failed.
1655
1656 **/
1657 SHELL_STATUS
IfConfig6(IN IFCONFIG6_PRIVATE_DATA * Private)1658 IfConfig6 (
1659 IN IFCONFIG6_PRIVATE_DATA *Private
1660 )
1661 {
1662 EFI_STATUS Status;
1663 SHELL_STATUS ShellStatus;
1664
1665 ShellStatus = SHELL_SUCCESS;
1666
1667 //
1668 // Get configure information of all interfaces.
1669 //
1670 Status = IfConfig6GetInterfaceInfo (
1671 Private->ImageHandle,
1672 Private->IfName,
1673 &Private->IfList
1674 );
1675
1676 if (EFI_ERROR (Status)) {
1677 ShellStatus = SHELL_NOT_FOUND;
1678 goto ON_EXIT;
1679 }
1680
1681 switch (Private->OpCode) {
1682 case IfConfig6OpList:
1683 ShellStatus = IfConfig6ShowInterfaceInfo (&Private->IfList);
1684 break;
1685
1686 case IfConfig6OpClear:
1687 ShellStatus = IfConfig6ClearInterfaceInfo (&Private->IfList, Private->IfName);
1688 break;
1689
1690 case IfConfig6OpSet:
1691 ShellStatus = IfConfig6SetInterfaceInfo (&Private->IfList, Private->VarArg);
1692 break;
1693
1694 default:
1695 ShellStatus = SHELL_UNSUPPORTED;
1696 }
1697
1698 ON_EXIT:
1699
1700 return ShellStatus;
1701 }
1702
1703 /**
1704 The IfConfig6 cleanup process, free the allocated memory.
1705
1706 @param[in] Private The pointer of IFCONFIG6_PRIVATE_DATA.
1707
1708 **/
1709 VOID
IfConfig6Cleanup(IN IFCONFIG6_PRIVATE_DATA * Private)1710 IfConfig6Cleanup (
1711 IN IFCONFIG6_PRIVATE_DATA *Private
1712 )
1713 {
1714 LIST_ENTRY *Entry;
1715 LIST_ENTRY *NextEntry;
1716 IFCONFIG6_INTERFACE_CB *IfCb;
1717
1718 ASSERT (Private != NULL);
1719
1720 //
1721 // Clean the list which save the set config Args.
1722 //
1723 if (Private->VarArg != NULL) {
1724 IfConfig6FreeArgList (Private->VarArg);
1725 }
1726
1727 if (Private->IfName != NULL)
1728 FreePool (Private->IfName);
1729
1730
1731 //
1732 // Clean the IFCONFIG6_INTERFACE_CB list.
1733 //
1734 Entry = Private->IfList.ForwardLink;
1735 NextEntry = Entry->ForwardLink;
1736
1737 while (Entry != &Private->IfList) {
1738
1739 IfCb = BASE_CR (Entry, IFCONFIG6_INTERFACE_CB, Link);
1740
1741 RemoveEntryList (&IfCb->Link);
1742
1743 if (IfCb->IfId != NULL) {
1744
1745 FreePool (IfCb->IfId);
1746 }
1747
1748 if (IfCb->IfInfo != NULL) {
1749
1750 FreePool (IfCb->IfInfo);
1751 }
1752
1753 FreePool (IfCb);
1754
1755 Entry = NextEntry;
1756 NextEntry = Entry->ForwardLink;
1757 }
1758
1759 FreePool (Private);
1760 }
1761
1762 /**
1763 Function for 'ifconfig6' command.
1764
1765 @param[in] ImageHandle Handle to the Image (NULL if Internal).
1766 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
1767
1768 @retval SHELL_SUCCESS ifconfig6 command processed successfully.
1769 @retval others The ifconfig6 command process failed.
1770
1771 **/
1772 SHELL_STATUS
1773 EFIAPI
ShellCommandRunIfconfig6(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)1774 ShellCommandRunIfconfig6 (
1775 IN EFI_HANDLE ImageHandle,
1776 IN EFI_SYSTEM_TABLE *SystemTable
1777 )
1778 {
1779 EFI_STATUS Status;
1780 SHELL_STATUS ShellStatus;
1781 IFCONFIG6_PRIVATE_DATA *Private;
1782 LIST_ENTRY *ParamPackage;
1783 CONST CHAR16 *ValueStr;
1784 ARG_LIST *ArgList;
1785 CHAR16 *ProblemParam;
1786 CHAR16 *Str;
1787
1788 Private = NULL;
1789 Status = EFI_INVALID_PARAMETER;
1790 ShellStatus = SHELL_SUCCESS;
1791
1792 Status = ShellCommandLineParseEx (mIfConfig6CheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);
1793 if (EFI_ERROR (Status)) {
1794 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_COMMAND), gShellNetwork2HiiHandle, L"ifconfig6", ProblemParam);
1795 ShellStatus = SHELL_INVALID_PARAMETER;
1796 goto ON_EXIT;
1797 }
1798
1799 //
1800 // To handle no option.
1801 //
1802 if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") &&
1803 !ShellCommandLineGetFlag (ParamPackage, L"-?") && !ShellCommandLineGetFlag (ParamPackage, L"-l")) {
1804 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_LACK_OPTION), gShellNetwork2HiiHandle);
1805 ShellStatus = SHELL_INVALID_PARAMETER;
1806 goto ON_EXIT;
1807 }
1808 //
1809 // To handle conflict options.
1810 //
1811 if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) ||
1812 ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||
1813 ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||
1814 ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||
1815 ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-?"))) ||
1816 ((ShellCommandLineGetFlag (ParamPackage, L"-l")) && (ShellCommandLineGetFlag (ParamPackage, L"-?")))) {
1817 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_CONFLICT_OPTIONS), gShellNetwork2HiiHandle);
1818 ShellStatus = SHELL_INVALID_PARAMETER;
1819 goto ON_EXIT;
1820 }
1821
1822 Private = AllocateZeroPool (sizeof (IFCONFIG6_PRIVATE_DATA));
1823
1824 if (Private == NULL) {
1825 ShellStatus = SHELL_OUT_OF_RESOURCES;
1826 goto ON_EXIT;
1827 }
1828
1829 InitializeListHead (&Private->IfList);
1830
1831 //
1832 // To get interface name for the list option.
1833 //
1834 if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {
1835 Private->OpCode = IfConfig6OpList;
1836 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");
1837 if (ValueStr != NULL) {
1838 Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);
1839 if (Str == NULL) {
1840 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
1841 ShellStatus = SHELL_OUT_OF_RESOURCES;
1842 goto ON_EXIT;
1843 }
1844 Private->IfName = Str;
1845 }
1846 }
1847 //
1848 // To get interface name for the clear option.
1849 //
1850 if (ShellCommandLineGetFlag (ParamPackage, L"-r")) {
1851 Private->OpCode = IfConfig6OpClear;
1852 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r");
1853 if (ValueStr != NULL) {
1854 Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);
1855 if (Str == NULL) {
1856 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
1857 ShellStatus = SHELL_OUT_OF_RESOURCES;
1858 goto ON_EXIT;
1859 }
1860 Private->IfName = Str;
1861 }
1862 }
1863 //
1864 // To get interface name and corresponding Args for the set option.
1865 //
1866 if (ShellCommandLineGetFlag (ParamPackage, L"-s")) {
1867
1868 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");
1869 if (ValueStr == NULL) {
1870 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_INTERFACE), gShellNetwork2HiiHandle);
1871 ShellStatus = SHELL_INVALID_PARAMETER;
1872 goto ON_EXIT;
1873 }
1874 //
1875 // To split the configuration into multi-section.
1876 //
1877 ArgList = IfConfig6SplitStrToList (ValueStr, L' ');
1878 if (ArgList == NULL) {
1879 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork2HiiHandle, L"ifconfig6");
1880 ShellStatus = SHELL_OUT_OF_RESOURCES;
1881 goto ON_EXIT;
1882 }
1883
1884 Private->OpCode = IfConfig6OpSet;
1885 Private->IfName = ArgList->Arg;
1886
1887 Private->VarArg = ArgList->Next;
1888
1889 if (Private->IfName == NULL || Private->VarArg == NULL) {
1890 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_COMMAND), gShellNetwork2HiiHandle);
1891 ShellStatus = SHELL_INVALID_PARAMETER;
1892 goto ON_EXIT;
1893 }
1894 }
1895 //
1896 // Main process of ifconfig6.
1897 //
1898 ShellStatus = IfConfig6 (Private);
1899
1900 ON_EXIT:
1901
1902 ShellCommandLineFreeVarList (ParamPackage);
1903 if (Private != NULL) {
1904 IfConfig6Cleanup (Private);
1905 }
1906 return ShellStatus;
1907
1908 }
1909
1910