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