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