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