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