]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Application/IfConfig6/IfConfig6.c
Update network stack code to use StrnCpy instead of StrCpy.
[mirror_edk2.git] / NetworkPkg / Application / IfConfig6 / IfConfig6.c
1 /** @file
2 The implementation for Shell application IfConfig6.
3
4 Copyright (c) 2009 - 2014, 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 SHELL_PARAM_ITEM mIfConfig6CheckList[] = {
33 {
34 L"-b",
35 TypeFlag
36 },
37 {
38 L"-s",
39 TypeMaxValue
40 },
41 {
42 L"-l",
43 TypeValue
44 },
45 {
46 L"-r",
47 TypeValue
48 },
49 {
50 L"-?",
51 TypeFlag
52 },
53 {
54 NULL,
55 TypeMax
56 },
57 };
58
59 VAR_CHECK_ITEM mSetCheckList[] = {
60 {
61 L"auto",
62 0x00000001,
63 0x00000001,
64 FlagTypeSingle
65 },
66 {
67 L"man",
68 0x00000002,
69 0x00000001,
70 FlagTypeSingle
71 },
72 {
73 L"host",
74 0x00000004,
75 0x00000002,
76 FlagTypeSingle
77 },
78 {
79 L"dad",
80 0x00000008,
81 0x00000004,
82 FlagTypeSingle
83 },
84 {
85 L"gw",
86 0x00000010,
87 0x00000008,
88 FlagTypeSingle
89 },
90 {
91 L"dns",
92 0x00000020,
93 0x00000010,
94 FlagTypeSingle
95 },
96 {
97 L"id",
98 0x00000040,
99 0x00000020,
100 FlagTypeSingle
101 },
102 {
103 NULL,
104 0x0,
105 0x0,
106 FlagTypeSkipUnknown
107 },
108 };
109
110 /**
111 Split a string with specified separator and save the substring to a list.
112
113 @param[in] String The pointer of the input string.
114 @param[in] Separator The specified separator.
115
116 @return The pointer of headnode of ARG_LIST.
117
118 **/
119 ARG_LIST *
120 SplitStrToList (
121 IN CONST CHAR16 *String,
122 IN CHAR16 Separator
123 )
124 {
125 CHAR16 *Str;
126 CHAR16 *ArgStr;
127 ARG_LIST *ArgList;
128 ARG_LIST *ArgNode;
129
130 if (*String == L'\0') {
131 return NULL;
132 }
133
134 //
135 // Copy the CONST string to a local copy.
136 //
137 Str = (CHAR16 *) AllocateZeroPool (StrSize (String));
138 ASSERT (Str != NULL);
139 Str = StrnCpy (Str, String, StrLen (String));
140 ArgStr = Str;
141
142 //
143 // init a node for the list head.
144 //
145 ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
146 ASSERT (ArgNode != NULL);
147 ArgList = ArgNode;
148
149 //
150 // Split the local copy and save in the list node.
151 //
152 while (*Str != L'\0') {
153 if (*Str == Separator) {
154 *Str = L'\0';
155 ArgNode->Arg = ArgStr;
156 ArgStr = Str + 1;
157 ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));
158 ASSERT (ArgNode->Next != NULL);
159 ArgNode = ArgNode->Next;
160 }
161
162 Str++;
163 }
164
165 ArgNode->Arg = ArgStr;
166 ArgNode->Next = NULL;
167
168 return ArgList;
169 }
170
171 /**
172 Check the correctness of input Args with '-s' option.
173
174 @param[in] CheckList The pointer of VAR_CHECK_ITEM array.
175 @param[in] Name The pointer of input arg.
176 @param[in] Init The switch to execute the check.
177
178 @return The value of VAR_CHECK_CODE.
179
180 **/
181 VAR_CHECK_CODE
182 IfConfig6RetriveCheckListByName(
183 IN VAR_CHECK_ITEM *CheckList,
184 IN CHAR16 *Name,
185 IN BOOLEAN Init
186 )
187 {
188 STATIC UINT32 CheckDuplicate;
189 STATIC UINT32 CheckConflict;
190 VAR_CHECK_CODE RtCode;
191 UINT32 Index;
192 VAR_CHECK_ITEM Arg;
193
194 if (Init) {
195 CheckDuplicate = 0;
196 CheckConflict = 0;
197 return VarCheckOk;
198 }
199
200 RtCode = VarCheckOk;
201 Index = 0;
202 Arg = CheckList[Index];
203
204 //
205 // Check the Duplicated/Conflicted/Unknown input Args.
206 //
207 while (Arg.FlagStr != NULL) {
208 if (StrCmp (Arg.FlagStr, Name) == 0) {
209
210 if (CheckDuplicate & Arg.FlagID) {
211 RtCode = VarCheckDuplicate;
212 break;
213 }
214
215 if (CheckConflict & Arg.ConflictMask) {
216 RtCode = VarCheckConflict;
217 break;
218 }
219
220 CheckDuplicate |= Arg.FlagID;
221 CheckConflict |= Arg.ConflictMask;
222 break;
223 }
224
225 Arg = CheckList[++Index];
226 }
227
228 if (Arg.FlagStr == NULL) {
229 RtCode = VarCheckUnknown;
230 }
231
232 return RtCode;
233 }
234
235 /**
236 The notify function of create event when performing a manual config.
237
238 @param[in] Event The event this notify function registered to.
239 @param[in] Context Pointer to the context data registered to the event.
240
241 **/
242 VOID
243 EFIAPI
244 IfConfig6ManualAddressNotify (
245 IN EFI_EVENT Event,
246 IN VOID *Context
247 )
248 {
249 *((BOOLEAN *) Context) = TRUE;
250 }
251
252 /**
253 Print MAC address.
254
255 @param[in] Node The pointer of MAC address buffer.
256 @param[in] Size The size of MAC address buffer.
257
258 **/
259 VOID
260 IfConfig6PrintMacAddr (
261 IN UINT8 *Node,
262 IN UINT32 Size
263 )
264 {
265 UINTN Index;
266
267 ASSERT (Size <= MACADDRMAXSIZE);
268
269 for (Index = 0; Index < Size; Index++) {
270 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_MAC_ADDR_BODY), mHiiHandle, Node[Index]);
271 if (Index + 1 < Size) {
272 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
273 }
274 }
275
276 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_NEWLINE), mHiiHandle);
277 }
278
279 /**
280 Print IPv6 address.
281
282 @param[in] Ip The pointer of Ip bufffer in EFI_IPv6_ADDRESS format.
283 @param[in] PrefixLen The pointer of PrefixLen that describes the size Prefix.
284
285 **/
286 VOID
287 IfConfig6PrintIpAddr (
288 IN EFI_IPv6_ADDRESS *Ip,
289 IN UINT8 *PrefixLen
290 )
291 {
292 UINTN Index;
293 BOOLEAN Short;
294
295 Short = FALSE;
296
297 for (Index = 0; Index < PREFIXMAXLEN; Index = Index + 2) {
298
299 if (!Short && (Index + 1 < PREFIXMAXLEN) && (Index % 2 == 0) && (Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0)) {
300 //
301 // Deal with the case of ::.
302 //
303 if (Index == 0) {
304 //
305 // :: is at the beginning of the address.
306 //
307 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
308 }
309 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
310
311 while ((Ip->Addr[Index] == 0) && (Ip->Addr[Index + 1] == 0) && (Index < PREFIXMAXLEN)) {
312 Index = Index + 2;
313 if (Index > PREFIXMAXLEN - 2) {
314 break;
315 }
316 }
317
318 Short = TRUE;
319
320 if (Index == PREFIXMAXLEN) {
321 //
322 // :: is at the end of the address.
323 //
324 break;
325 }
326 }
327
328 if (Index < PREFIXMAXLEN - 1) {
329 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), mHiiHandle, Ip->Addr[Index]);
330 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_IP_ADDR_BODY), mHiiHandle, Ip->Addr[Index + 1]);
331 }
332
333 if (Index + 2 < PREFIXMAXLEN) {
334 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_COLON), mHiiHandle);
335 }
336 }
337
338 if (PrefixLen != NULL) {
339 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_INFO_PREFIX_LEN), mHiiHandle, *PrefixLen);
340 }
341 }
342
343 /**
344 Pick up host IPv6 address in string format from Args with "-s" option and convert it to EFI_IP6_CONFIG_MANUAL_ADDRESS format.
345
346 @param[in, out] Arg The pointer of the address of ARG_LIST which save Args with the "-s" option.
347 @param[out] Buf The pointer of the address of EFI_IP6_CONFIG_MANUAL_ADDRESS.
348 @param[out] BufSize The pointer of BufSize that describes the size of Buf in bytes.
349
350 @retval EFI_SUCCESS The convertion is successful.
351 @retval Others Does't find the host address, or it is an invalid IPv6 address in string format.
352
353 **/
354 EFI_STATUS
355 IfConfig6ParseManualAddressList (
356 IN OUT ARG_LIST **Arg,
357 OUT EFI_IP6_CONFIG_MANUAL_ADDRESS **Buf,
358 OUT UINTN *BufSize
359 )
360 {
361 EFI_STATUS Status;
362 EFI_IP6_CONFIG_MANUAL_ADDRESS *AddrBuf;
363 ARG_LIST *VarArg;
364 EFI_IPv6_ADDRESS Address;
365 UINT8 Prefix;
366 UINT8 AddrCnt;
367
368 Prefix = 0;
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 = StrnCpy (Str, ValueStr, StrLen (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 = StrnCpy (Str, ValueStr, StrLen (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