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