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