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