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