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