Changeset 77662 in vbox for trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
- Timestamp:
- Mar 12, 2019 12:40:12 PM (6 years ago)
- Location:
- trunk/src/VBox/Devices/EFI/FirmwareNew
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/FirmwareNew
-
Property svn:mergeinfo
changed from (toggle deleted branches)
to (toggle deleted branches)/vendor/edk2/current 103735-103757,103769-103776 /vendor/edk2/current 103735-103757,103769-103776,129194-129237
-
Property svn:mergeinfo
changed from (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
r58466 r77662 2 2 Network library. 3 3 4 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR> 4 Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR> 5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR> 5 6 This program and the accompanying materials 6 7 are licensed and made available under the terms and conditions of the BSD License … … 19 20 #include <Protocol/ServiceBinding.h> 20 21 #include <Protocol/SimpleNetwork.h> 22 #include <Protocol/AdapterInformation.h> 21 23 #include <Protocol/ManagedNetwork.h> 22 #include <Protocol/ HiiConfigRouting.h>24 #include <Protocol/Ip4Config2.h> 23 25 #include <Protocol/ComponentName.h> 24 26 #include <Protocol/ComponentName2.h> 25 #include <Protocol/HiiConfigAccess.h> 26 27 #include <Guid/NicIp4ConfigNvData.h> 27 28 28 #include <Guid/SmBios.h> 29 29 … … 36 36 #include <Library/MemoryAllocationLib.h> 37 37 #include <Library/DevicePathLib.h> 38 #include <Library/HiiLib.h>39 38 #include <Library/PrintLib.h> 40 39 #include <Library/UefiLib.h> 41 40 42 #define NIC_ITEM_CONFIG_SIZE sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE41 #define NIC_ITEM_CONFIG_SIZE (sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE) 43 42 #define DEFAULT_ZERO_START ((UINTN) ~0) 44 43 … … 200 199 time it is called to avoid the problem if SNP is unloaded. 201 200 This code snip is copied from MNP. 201 If Packet is NULL, then ASSERT(). 202 202 203 203 @param[in] Packet The Syslog packet … … 220 220 EFI_EVENT TimeoutEvent; 221 221 UINT8 *TxBuf; 222 223 ASSERT (Packet != NULL); 222 224 223 225 Snp = SyslogLocateSnp (); … … 304 306 and user's message. 305 307 306 @param[in] Level Syslog se rvity level308 @param[in] Level Syslog severity level 307 309 @param[in] Module The module that generates the log 308 310 @param[in] File The file that contains the current log … … 312 314 @param[out] Buf The buffer to put the packet data 313 315 314 @return The length of the syslog packet built .316 @return The length of the syslog packet built, 0 represents no packet is built. 315 317 316 318 **/ … … 326 328 ) 327 329 { 330 EFI_STATUS Status; 328 331 ETHER_HEAD *Ether; 329 332 IP4_HEAD *Ip4; … … 381 384 // 382 385 Pri = ((NET_SYSLOG_FACILITY & 31) << 3) | (Level & 7); 383 gRT->GetTime (&Time, NULL); 384 ASSERT ((Time.Month <= 12) && (Time.Month >= 1)); 386 Status = gRT->GetTime (&Time, NULL); 387 if (EFI_ERROR (Status)) { 388 return 0; 389 } 385 390 386 391 // … … 399 404 Time.Second 400 405 ); 401 Len--;402 406 403 407 Len += (UINT32) AsciiSPrint ( … … 410 414 File 411 415 ); 412 Len --;416 Len ++; 413 417 414 418 // … … 441 445 ) 442 446 447 If Format is NULL, then ASSERT(). 448 443 449 @param Format The ASCII format string. 444 450 @param ... The variable length parameter whose format is determined … … 459 465 CHAR8 *Buf; 460 466 467 ASSERT (Format != NULL); 468 461 469 Buf = (CHAR8 *) AllocatePool (NET_DEBUG_MSG_LEN); 462 470 … … 478 486 Because it isn't open the SNP BY_DRIVER, apply caution when using it. 479 487 480 @param Level The se rvity level of the message.488 @param Level The severity level of the message. 481 489 @param Module The Moudle that generates the log. 482 490 @param File The file that contains the log. … … 485 493 486 494 @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 487 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the packet 495 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the packet. 496 @retval EFI_DEVICE_ERROR Device error occurs. 488 497 @retval EFI_SUCCESS The log is discard because that it is more verbose 489 498 than the mNetDebugLevelMax. Or, it has been sent out. … … 506 515 // Check whether the message should be sent out 507 516 // 508 if (Message == NULL ) {517 if (Message == NULL || File == NULL || Module == NULL) { 509 518 return EFI_INVALID_PARAMETER; 510 519 } … … 539 548 Packet 540 549 ); 541 542 mSyslogPacketSeq++; 543 Status = SyslogSendPacket (Packet, Len); 550 if (Len == 0) { 551 Status = EFI_DEVICE_ERROR; 552 } else { 553 mSyslogPacketSeq++; 554 Status = SyslogSendPacket (Packet, Len); 555 } 556 544 557 FreePool (Packet); 545 558 … … 568 581 INTN Index; 569 582 570 for (Index = 0; Index < IP4_MASK_NUM; Index++) {583 for (Index = 0; Index <= IP4_MASK_MAX; Index++) { 571 584 if (NetMask == gIp4AllMasks[Index]) { 572 585 break; … … 582 595 Return the class of the IP address, such as class A, B, C. 583 596 Addr is in host byte order. 597 598 [ATTENTION] 599 Classful addressing (IP class A/B/C) has been deprecated according to RFC4632. 600 Caller of this function could only check the returned value against 601 IP4_ADDR_CLASSD (multicast) or IP4_ADDR_CLASSE (reserved) now. 584 602 585 603 The address of class A starts with 0. … … 631 649 /** 632 650 Check whether the IP is a valid unicast address according to 633 the netmask. If NetMask is zero, use the IP address's class to get the default mask. 634 635 If Ip is 0, IP is not a valid unicast address. 636 Class D address is used for multicasting and class E address is reserved for future. If Ip 637 belongs to class D or class E, IP is not a valid unicast address. 638 If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address. 651 the netmask. 652 653 ASSERT if NetMask is zero. 654 655 If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address, 656 except when the originator is one of the endpoints of a point-to-point link with a 31-bit 657 mask (RFC3021). 639 658 640 659 @param[in] Ip The IP to check against. … … 651 670 ) 652 671 { 653 INTN Class; 654 655 Class = NetGetIpClass (Ip); 656 657 if ((Ip == 0) || (Class >= IP4_ADDR_CLASSD)) { 672 ASSERT (NetMask != 0); 673 674 if (Ip == 0 || IP4_IS_LOCAL_BROADCAST (Ip)) { 658 675 return FALSE; 659 676 } 660 677 661 if (Net Mask == 0) {662 NetMask = gIp4AllMasks[Class << 3];663 }664 665 if (((Ip &~NetMask) == ~NetMask) || ((Ip &~NetMask) == 0)){666 return FALSE;678 if (NetGetMaskLength (NetMask) != 31) { 679 if (((Ip &~NetMask) == ~NetMask) || ((Ip &~NetMask) == 0)) { 680 return FALSE; 681 } 682 } else { 683 return TRUE; 667 684 } 668 685 … … 672 689 /** 673 690 Check whether the incoming IPv6 address is a valid unicast address. 691 692 ASSERT if Ip6 is NULL. 674 693 675 694 If the address is a multicast address has binary 0xFF at the start, it is not … … 693 712 UINT8 Index; 694 713 714 ASSERT (Ip6 != NULL); 715 695 716 if (Ip6->Addr[0] == 0xFF) { 696 717 return FALSE; … … 715 736 Check whether the incoming Ipv6 address is the unspecified address or not. 716 737 738 ASSERT if Ip6 is NULL. 739 717 740 @param[in] Ip6 - Ip6 address, in network order. 718 741 … … 728 751 { 729 752 UINT8 Index; 753 754 ASSERT (Ip6 != NULL); 730 755 731 756 for (Index = 0; Index < 16; Index++) { … … 741 766 Check whether the incoming Ipv6 address is a link-local address. 742 767 768 ASSERT if Ip6 is NULL. 769 743 770 @param[in] Ip6 - Ip6 address, in network order. 744 771 … … 776 803 /** 777 804 Check whether the Ipv6 address1 and address2 are on the connected network. 805 806 ASSERT if Ip1 or Ip2 is NULL. 807 ASSERT if PrefixLength exceeds or equals to IP6_PREFIX_MAX. 778 808 779 809 @param[in] Ip1 - Ip6 address1, in network order. … … 797 827 UINT8 Mask; 798 828 799 ASSERT ((Ip1 != NULL) && (Ip2 != NULL) && (PrefixLength < IP6_PREFIX_ NUM));829 ASSERT ((Ip1 != NULL) && (Ip2 != NULL) && (PrefixLength < IP6_PREFIX_MAX)); 800 830 801 831 if (PrefixLength == 0) { … … 814 844 815 845 ASSERT (Byte < 16); 846 if (Byte >= 16) { 847 return FALSE; 848 } 816 849 if ((Ip1->Addr[Byte] & Mask) != (Ip2->Addr[Byte] & Mask)) { 817 850 return FALSE; … … 825 858 /** 826 859 Switches the endianess of an IPv6 address 860 861 ASSERT if Ip6 is NULL. 827 862 828 863 This function swaps the bytes in a 128-bit IPv6 address to switch the value … … 844 879 UINT64 Low; 845 880 881 ASSERT (Ip6 != NULL); 882 846 883 CopyMem (&High, Ip6, sizeof (UINT64)); 847 884 CopyMem (&Low, &Ip6->Addr[8], sizeof (UINT64)); … … 857 894 858 895 /** 859 Initialize a random seed using current time .860 861 Get current time first. Then initialize a random seed based on some basic862 mathematics operation on the hour, day, minute, second, nanosecond and year863 of the current time.896 Initialize a random seed using current time and monotonic count. 897 898 Get current time and monotonic count first. Then initialize a random seed 899 based on some basic mathematics operation on the hour, day, minute, second, 900 nanosecond and year of the current time and the monotonic count value. 864 901 865 902 @return The random seed initialized with current time. … … 874 911 EFI_TIME Time; 875 912 UINT32 Seed; 913 UINT64 MonotonicCount; 876 914 877 915 gRT->GetTime (&Time, NULL); 878 Seed = ( ~Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second);916 Seed = (Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second); 879 917 Seed ^= Time.Nanosecond; 880 918 Seed ^= Time.Year << 7; 881 919 920 gBS->GetNextMonotonicCount (&MonotonicCount); 921 Seed += (UINT32) MonotonicCount; 922 882 923 return Seed; 883 924 } … … 886 927 /** 887 928 Extract a UINT32 from a byte stream. 929 930 ASSERT if Buf is NULL. 888 931 889 932 Copy a UINT32 from a byte stream, then converts it from Network … … 903 946 UINT32 Value; 904 947 948 ASSERT (Buf != NULL); 949 905 950 CopyMem (&Value, Buf, sizeof (UINT32)); 906 951 return NTOHL (Value); … … 910 955 /** 911 956 Put a UINT32 to the byte stream in network byte order. 957 958 ASSERT if Buf is NULL. 912 959 913 960 Converts a UINT32 from host byte order to network byte order. Then copy it to the … … 925 972 ) 926 973 { 974 ASSERT (Buf != NULL); 975 927 976 Data = HTONL (Data); 928 977 CopyMem (Buf, &Data, sizeof (UINT32)); … … 1023 1072 Insert a new node entry after a designated node entry of a doubly linked list. 1024 1073 1074 ASSERT if PrevEntry or NewEntry is NULL. 1075 1025 1076 Inserts a new node entry donated by NewEntry after the node entry donated by PrevEntry 1026 1077 of the doubly linked list. … … 1037 1088 ) 1038 1089 { 1090 ASSERT (PrevEntry != NULL && NewEntry != NULL); 1091 1039 1092 NewEntry->BackLink = PrevEntry; 1040 1093 NewEntry->ForwardLink = PrevEntry->ForwardLink; … … 1047 1100 Insert a new node entry before a designated node entry of a doubly linked list. 1048 1101 1102 ASSERT if PostEntry or NewEntry is NULL. 1103 1049 1104 Inserts a new node entry donated by NewEntry after the node entry donated by PostEntry 1050 1105 of the doubly linked list. … … 1061 1116 ) 1062 1117 { 1118 ASSERT (PostEntry != NULL && NewEntry != NULL); 1119 1063 1120 NewEntry->ForwardLink = PostEntry; 1064 1121 NewEntry->BackLink = PostEntry->BackLink; … … 1150 1207 if NumberOfChildren is 0. 1151 1208 1152 @retval T URE Found the input Handle in ChildHandleBuffer.1209 @retval TRUE Found the input Handle in ChildHandleBuffer. 1153 1210 @retval FALSE Can't find the input Handle in ChildHandleBuffer. 1154 1211 … … 1259 1316 If Map is NULL, then ASSERT(). 1260 1317 1261 1262 1318 @param[in] Map The net map to test. 1263 1319 … … 1279 1335 Return the number of the <Key, Value> pairs in the netmap. 1280 1336 1337 If Map is NULL, then ASSERT(). 1338 1281 1339 @param[in] Map The netmap to get the entry number. 1282 1340 … … 1290 1348 ) 1291 1349 { 1350 ASSERT (Map != NULL); 1292 1351 return Map->Count; 1293 1352 } … … 1354 1413 1355 1414 If Map is NULL, then ASSERT(). 1415 If Key is NULL, then ASSERT(). 1356 1416 1357 1417 @param[in, out] Map The netmap to insert into. … … 1373 1433 NET_MAP_ITEM *Item; 1374 1434 1375 ASSERT (Map != NULL );1435 ASSERT (Map != NULL && Key != NULL); 1376 1436 1377 1437 Item = NetMapAllocItem (Map); … … 1398 1458 1399 1459 If Map is NULL, then ASSERT(). 1460 If Key is NULL, then ASSERT(). 1400 1461 1401 1462 @param[in, out] Map The netmap to insert into. … … 1417 1478 NET_MAP_ITEM *Item; 1418 1479 1419 ASSERT (Map != NULL );1480 ASSERT (Map != NULL && Key != NULL); 1420 1481 1421 1482 Item = NetMapAllocItem (Map); … … 1437 1498 /** 1438 1499 Check whether the item is in the Map and return TRUE if it is. 1500 1501 If Map is NULL, then ASSERT(). 1502 If Item is NULL, then ASSERT(). 1439 1503 1440 1504 @param[in] Map The netmap to search within. … … 1452 1516 LIST_ENTRY *ListEntry; 1453 1517 1518 ASSERT (Map != NULL && Item != NULL); 1519 1454 1520 NET_LIST_FOR_EACH (ListEntry, &Map->Used) { 1455 1521 if (ListEntry == &Item->Link) { … … 1469 1535 1470 1536 If Map is NULL, then ASSERT(). 1537 If Key is NULL, then ASSERT(). 1471 1538 1472 1539 @param[in] Map The netmap to search within. … … 1486 1553 NET_MAP_ITEM *Item; 1487 1554 1488 ASSERT (Map != NULL );1555 ASSERT (Map != NULL && Key != NULL); 1489 1556 1490 1557 NET_LIST_FOR_EACH (Entry, &Map->Used) { … … 1635 1702 Iterate through the netmap and call CallBack for each item. 1636 1703 1637 It will conti ue the traverse if CallBack returns EFI_SUCCESS, otherwise, break1704 It will continue the traverse if CallBack returns EFI_SUCCESS, otherwise, break 1638 1705 from the loop. It returns the CallBack's last return value. This function is 1639 1706 delete safe for the current item. … … 1684 1751 1685 1752 return EFI_SUCCESS; 1686 }1687 1688 1689 /**1690 Internal function to get the child handle of the NIC handle.1691 1692 @param[in] Controller NIC controller handle.1693 @param[out] ChildHandle Returned child handle.1694 1695 @retval EFI_SUCCESS Successfully to get child handle.1696 @retval Others Failed to get child handle.1697 1698 **/1699 EFI_STATUS1700 NetGetChildHandle (1701 IN EFI_HANDLE Controller,1702 OUT EFI_HANDLE *ChildHandle1703 )1704 {1705 EFI_STATUS Status;1706 EFI_HANDLE *Handles;1707 UINTN HandleCount;1708 UINTN Index;1709 EFI_DEVICE_PATH_PROTOCOL *ChildDeviceDevicePath;1710 VENDOR_DEVICE_PATH *VendorDeviceNode;1711 1712 //1713 // Locate all EFI Hii Config Access protocols1714 //1715 Status = gBS->LocateHandleBuffer (1716 ByProtocol,1717 &gEfiHiiConfigAccessProtocolGuid,1718 NULL,1719 &HandleCount,1720 &Handles1721 );1722 if (EFI_ERROR (Status) || (HandleCount == 0)) {1723 return Status;1724 }1725 1726 Status = EFI_NOT_FOUND;1727 1728 for (Index = 0; Index < HandleCount; Index++) {1729 1730 Status = EfiTestChildHandle (Controller, Handles[Index], &gEfiManagedNetworkServiceBindingProtocolGuid);1731 if (!EFI_ERROR (Status)) {1732 //1733 // Get device path on the child handle1734 //1735 Status = gBS->HandleProtocol (1736 Handles[Index],1737 &gEfiDevicePathProtocolGuid,1738 (VOID **) &ChildDeviceDevicePath1739 );1740 1741 if (!EFI_ERROR (Status)) {1742 while (!IsDevicePathEnd (ChildDeviceDevicePath)) {1743 ChildDeviceDevicePath = NextDevicePathNode (ChildDeviceDevicePath);1744 //1745 // Parse one instance1746 //1747 if (ChildDeviceDevicePath->Type == HARDWARE_DEVICE_PATH &&1748 ChildDeviceDevicePath->SubType == HW_VENDOR_DP) {1749 VendorDeviceNode = (VENDOR_DEVICE_PATH *) ChildDeviceDevicePath;1750 if (CompareMem (&VendorDeviceNode->Guid, &gEfiNicIp4ConfigVariableGuid, sizeof (EFI_GUID)) == 0) {1751 //1752 // Found item matched gEfiNicIp4ConfigVariableGuid1753 //1754 *ChildHandle = Handles[Index];1755 FreePool (Handles);1756 return EFI_SUCCESS;1757 }1758 }1759 }1760 }1761 }1762 }1763 1764 FreePool (Handles);1765 return Status;1766 1753 } 1767 1754 … … 2169 2156 Get MAC address associated with the network service handle. 2170 2157 2158 If MacAddress is NULL, then ASSERT(). 2159 If AddressSize is NULL, then ASSERT(). 2160 2171 2161 There should be MNP Service Binding Protocol installed on the input ServiceHandle. 2172 2162 If SNP is installed on the ServiceHandle or its parent handle, MAC address will … … 2273 2263 to a unicode string. Callers are responsible for freeing the string storage. 2274 2264 2265 If MacString is NULL, then ASSERT(). 2266 2275 2267 Locate simple network protocol associated with the Service Binding Handle and 2276 2268 get the mac address from SNP. Then convert the mac address into a unicode … … 2306 2298 CHAR16 *String; 2307 2299 UINTN Index; 2300 UINTN BufferSize; 2308 2301 2309 2302 ASSERT (MacString != NULL); … … 2322 2315 // Plus one unicode character for the null-terminator. 2323 2316 // 2324 String = AllocateZeroPool ((2 * HwAddressSize + 5 + 1) * sizeof (CHAR16)); 2317 BufferSize = (2 * HwAddressSize + 5 + 1) * sizeof (CHAR16); 2318 String = AllocateZeroPool (BufferSize); 2325 2319 if (String == NULL) { 2326 2320 return EFI_OUT_OF_RESOURCES; … … 2333 2327 HwAddress = &MacAddress.Addr[0]; 2334 2328 for (Index = 0; Index < HwAddressSize; Index++) { 2335 String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, *(HwAddress++), 2); 2329 UnicodeValueToStringS ( 2330 String, 2331 BufferSize - ((UINTN)String - (UINTN)*MacString), 2332 PREFIX_ZERO | RADIX_HEX, 2333 *(HwAddress++), 2334 2 2335 ); 2336 String += StrnLenS (String, (BufferSize - ((UINTN)String - (UINTN)*MacString)) / sizeof (CHAR16)); 2336 2337 } 2337 2338 … … 2342 2343 if (VlanId != 0) { 2343 2344 *String++ = L'\\'; 2344 String += UnicodeValueToString (String, PREFIX_ZERO | RADIX_HEX, VlanId, 4); 2345 UnicodeValueToStringS ( 2346 String, 2347 BufferSize - ((UINTN)String - (UINTN)*MacString), 2348 PREFIX_ZERO | RADIX_HEX, 2349 VlanId, 2350 4 2351 ); 2352 String += StrnLenS (String, (BufferSize - ((UINTN)String - (UINTN)*MacString)) / sizeof (CHAR16)); 2345 2353 } 2346 2354 … … 2355 2363 /** 2356 2364 Detect media status for specified network device. 2365 2366 If MediaPresent is NULL, then ASSERT(). 2357 2367 2358 2368 The underlying UNDI driver may or may not support reporting media status from … … 2464 2474 ); 2465 2475 ASSERT (MCastFilter != NULL); 2476 if (MCastFilter == NULL) { 2477 Status = EFI_OUT_OF_RESOURCES; 2478 goto Exit; 2479 } 2466 2480 2467 2481 ResetMCastFilters = FALSE; … … 2562 2576 2563 2577 /** 2578 2579 Detect media state for a network device. This routine will wait for a period of time at 2580 a specified checking interval when a certain network is under connecting until connection 2581 process finishs or timeout. If Aip protocol is supported by low layer drivers, three kinds 2582 of media states can be detected: EFI_SUCCESS, EFI_NOT_READY and EFI_NO_MEDIA, represents 2583 connected state, connecting state and no media state respectively. When function detects 2584 the current state is EFI_NOT_READY, it will loop to wait for next time's check until state 2585 turns to be EFI_SUCCESS or EFI_NO_MEDIA. If Aip protocol is not supported, function will 2586 call NetLibDetectMedia() and return state directly. 2587 2588 @param[in] ServiceHandle The handle where network service binding protocols are 2589 installed on. 2590 @param[in] Timeout The maximum number of 100ns units to wait when network 2591 is connecting. Zero value means detect once and return 2592 immediately. 2593 @param[out] MediaState The pointer to the detected media state. 2594 2595 @retval EFI_SUCCESS Media detection success. 2596 @retval EFI_INVALID_PARAMETER ServiceHandle is not a valid network device handle or 2597 MediaState pointer is NULL. 2598 @retval EFI_DEVICE_ERROR A device error occurred. 2599 @retval EFI_TIMEOUT Network is connecting but timeout. 2600 2601 **/ 2602 EFI_STATUS 2603 EFIAPI 2604 NetLibDetectMediaWaitTimeout ( 2605 IN EFI_HANDLE ServiceHandle, 2606 IN UINT64 Timeout, 2607 OUT EFI_STATUS *MediaState 2608 ) 2609 { 2610 EFI_STATUS Status; 2611 EFI_HANDLE SnpHandle; 2612 EFI_SIMPLE_NETWORK_PROTOCOL *Snp; 2613 EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; 2614 EFI_ADAPTER_INFO_MEDIA_STATE *MediaInfo; 2615 BOOLEAN MediaPresent; 2616 UINTN DataSize; 2617 EFI_STATUS TimerStatus; 2618 EFI_EVENT Timer; 2619 UINT64 TimeRemained; 2620 2621 if (MediaState == NULL) { 2622 return EFI_INVALID_PARAMETER; 2623 } 2624 *MediaState = EFI_SUCCESS; 2625 MediaInfo = NULL; 2626 2627 // 2628 // Get SNP handle 2629 // 2630 Snp = NULL; 2631 SnpHandle = NetLibGetSnpHandle (ServiceHandle, &Snp); 2632 if (SnpHandle == NULL) { 2633 return EFI_INVALID_PARAMETER; 2634 } 2635 2636 Status = gBS->HandleProtocol ( 2637 SnpHandle, 2638 &gEfiAdapterInformationProtocolGuid, 2639 (VOID *) &Aip 2640 ); 2641 if (EFI_ERROR (Status)) { 2642 2643 MediaPresent = TRUE; 2644 Status = NetLibDetectMedia (ServiceHandle, &MediaPresent); 2645 if (!EFI_ERROR (Status)) { 2646 if (MediaPresent) { 2647 *MediaState = EFI_SUCCESS; 2648 } else { 2649 *MediaState = EFI_NO_MEDIA; 2650 } 2651 } 2652 2653 // 2654 // NetLibDetectMedia doesn't support EFI_NOT_READY status, return now! 2655 // 2656 return Status; 2657 } 2658 2659 Status = Aip->GetInformation ( 2660 Aip, 2661 &gEfiAdapterInfoMediaStateGuid, 2662 (VOID **) &MediaInfo, 2663 &DataSize 2664 ); 2665 if (!EFI_ERROR (Status)) { 2666 2667 *MediaState = MediaInfo->MediaState; 2668 FreePool (MediaInfo); 2669 if (*MediaState != EFI_NOT_READY || Timeout < MEDIA_STATE_DETECT_TIME_INTERVAL) { 2670 2671 return EFI_SUCCESS; 2672 } 2673 } else { 2674 2675 if (MediaInfo != NULL) { 2676 FreePool (MediaInfo); 2677 } 2678 2679 if (Status == EFI_UNSUPPORTED) { 2680 2681 // 2682 // If gEfiAdapterInfoMediaStateGuid is not supported, call NetLibDetectMedia to get media state! 2683 // 2684 MediaPresent = TRUE; 2685 Status = NetLibDetectMedia (ServiceHandle, &MediaPresent); 2686 if (!EFI_ERROR (Status)) { 2687 if (MediaPresent) { 2688 *MediaState = EFI_SUCCESS; 2689 } else { 2690 *MediaState = EFI_NO_MEDIA; 2691 } 2692 } 2693 return Status; 2694 } 2695 2696 return Status; 2697 } 2698 2699 // 2700 // Loop to check media state 2701 // 2702 2703 Timer = NULL; 2704 TimeRemained = Timeout; 2705 Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer); 2706 if (EFI_ERROR (Status)) { 2707 return EFI_DEVICE_ERROR; 2708 } 2709 2710 do { 2711 Status = gBS->SetTimer ( 2712 Timer, 2713 TimerRelative, 2714 MEDIA_STATE_DETECT_TIME_INTERVAL 2715 ); 2716 if (EFI_ERROR (Status)) { 2717 gBS->CloseEvent(Timer); 2718 return EFI_DEVICE_ERROR; 2719 } 2720 2721 do { 2722 TimerStatus = gBS->CheckEvent (Timer); 2723 if (!EFI_ERROR (TimerStatus)) { 2724 2725 TimeRemained -= MEDIA_STATE_DETECT_TIME_INTERVAL; 2726 Status = Aip->GetInformation ( 2727 Aip, 2728 &gEfiAdapterInfoMediaStateGuid, 2729 (VOID **) &MediaInfo, 2730 &DataSize 2731 ); 2732 if (!EFI_ERROR (Status)) { 2733 2734 *MediaState = MediaInfo->MediaState; 2735 FreePool (MediaInfo); 2736 } else { 2737 2738 if (MediaInfo != NULL) { 2739 FreePool (MediaInfo); 2740 } 2741 gBS->CloseEvent(Timer); 2742 return Status; 2743 } 2744 } 2745 } while (TimerStatus == EFI_NOT_READY); 2746 } while (*MediaState == EFI_NOT_READY && TimeRemained >= MEDIA_STATE_DETECT_TIME_INTERVAL); 2747 2748 gBS->CloseEvent(Timer); 2749 if (*MediaState == EFI_NOT_READY && TimeRemained < MEDIA_STATE_DETECT_TIME_INTERVAL) { 2750 return EFI_TIMEOUT; 2751 } else { 2752 return EFI_SUCCESS; 2753 } 2754 } 2755 2756 /** 2564 2757 Check the default address used by the IPv4 driver is static or dynamic (acquired 2565 2758 from DHCP). 2566 2759 2567 If the controller handle does not have the NIC Ip4 Config Protocol installed, the 2568 default address is static. If the EFI variable to save the configuration is not found, 2569 the default address is static. Otherwise, get the result from the EFI variable which 2570 saving the configuration. 2571 2572 @param[in] Controller The controller handle which has the NIC Ip4 Config Protocol 2760 If the controller handle does not have the EFI_IP4_CONFIG2_PROTOCOL installed, the 2761 default address is static. If failed to get the policy from Ip4 Config2 Protocol, 2762 the default address is static. Otherwise, get the result from Ip4 Config2 Protocol. 2763 2764 @param[in] Controller The controller handle which has the EFI_IP4_CONFIG2_PROTOCOL 2573 2765 relative with the default address to judge. 2574 2766 … … 2583 2775 { 2584 2776 EFI_STATUS Status; 2585 EFI_ HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;2586 UINTN Len;2587 NIC_IP4_CONFIG_INFO *ConfigInfo;2777 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2; 2778 UINTN DataSize; 2779 EFI_IP4_CONFIG2_POLICY Policy; 2588 2780 BOOLEAN IsStatic; 2589 EFI_STRING ConfigHdr; 2590 EFI_STRING ConfigResp; 2591 EFI_STRING AccessProgress; 2592 EFI_STRING AccessResults; 2593 EFI_STRING String; 2594 EFI_HANDLE ChildHandle; 2595 2596 ConfigInfo = NULL; 2597 ConfigHdr = NULL; 2598 ConfigResp = NULL; 2599 AccessProgress = NULL; 2600 AccessResults = NULL; 2601 IsStatic = TRUE; 2602 2603 Status = gBS->LocateProtocol ( 2604 &gEfiHiiConfigRoutingProtocolGuid, 2605 NULL, 2606 (VOID **) &HiiConfigRouting 2607 ); 2608 if (EFI_ERROR (Status)) { 2609 return TRUE; 2610 } 2611 2612 Status = NetGetChildHandle (Controller, &ChildHandle); 2613 if (EFI_ERROR (Status)) { 2614 return TRUE; 2615 } 2616 2617 // 2618 // Construct config request string header 2619 // 2620 ConfigHdr = HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, ChildHandle); 2621 if (ConfigHdr == NULL) { 2622 return TRUE; 2623 } 2624 2625 Len = StrLen (ConfigHdr); 2626 ConfigResp = AllocateZeroPool ((Len + NIC_ITEM_CONFIG_SIZE * 2 + 100) * sizeof (CHAR16)); 2627 if (ConfigResp == NULL) { 2628 goto ON_EXIT; 2629 } 2630 StrCpy (ConfigResp, ConfigHdr); 2631 2632 String = ConfigResp + Len; 2633 UnicodeSPrint ( 2634 String, 2635 (8 + 4 + 7 + 4 + 1) * sizeof (CHAR16), 2636 L"&OFFSET=%04X&WIDTH=%04X", 2637 OFFSET_OF (NIC_IP4_CONFIG_INFO, Source), 2638 sizeof (UINT32) 2639 ); 2640 2641 Status = HiiConfigRouting->ExtractConfig ( 2642 HiiConfigRouting, 2643 ConfigResp, 2644 &AccessProgress, 2645 &AccessResults 2646 ); 2781 2782 Ip4Config2 = NULL; 2783 2784 DataSize = sizeof (EFI_IP4_CONFIG2_POLICY); 2785 2786 IsStatic = TRUE; 2787 2788 // 2789 // Get Ip4Config2 policy. 2790 // 2791 Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **) &Ip4Config2); 2647 2792 if (EFI_ERROR (Status)) { 2648 2793 goto ON_EXIT; 2649 2794 } 2650 2795 2651 ConfigInfo = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE); 2652 if (ConfigInfo == NULL) { 2653 goto ON_EXIT; 2654 } 2655 2656 ConfigInfo->Source = IP4_CONFIG_SOURCE_STATIC; 2657 Len = NIC_ITEM_CONFIG_SIZE; 2658 Status = HiiConfigRouting->ConfigToBlock ( 2659 HiiConfigRouting, 2660 AccessResults, 2661 (UINT8 *) ConfigInfo, 2662 &Len, 2663 &AccessProgress 2664 ); 2796 Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypePolicy, &DataSize, &Policy); 2665 2797 if (EFI_ERROR (Status)) { 2666 2798 goto ON_EXIT; 2667 2799 } 2668 2800 2669 IsStatic = (BOOLEAN) ( ConfigInfo->Source == IP4_CONFIG_SOURCE_STATIC);2801 IsStatic = (BOOLEAN) (Policy == Ip4Config2PolicyStatic); 2670 2802 2671 2803 ON_EXIT: 2672 2804 2673 if (AccessResults != NULL) {2674 FreePool (AccessResults);2675 }2676 if (ConfigInfo != NULL) {2677 FreePool (ConfigInfo);2678 }2679 if (ConfigResp != NULL) {2680 FreePool (ConfigResp);2681 }2682 if (ConfigHdr != NULL) {2683 FreePool (ConfigHdr);2684 }2685 2686 2805 return IsStatic; 2687 2806 } … … 2689 2808 /** 2690 2809 Create an IPv4 device path node. 2810 2811 If Node is NULL, then ASSERT(). 2691 2812 2692 2813 The header type of IPv4 device path node is MESSAGING_DEVICE_PATH. … … 2717 2838 ) 2718 2839 { 2840 ASSERT (Node != NULL); 2841 2719 2842 Node->Header.Type = MESSAGING_DEVICE_PATH; 2720 2843 Node->Header.SubType = MSG_IPv4_DP; … … 2746 2869 /** 2747 2870 Create an IPv6 device path node. 2871 2872 If Node is NULL, then ASSERT(). 2873 If LocalIp is NULL, then ASSERT(). 2874 If RemoteIp is NULL, then ASSERT(). 2748 2875 2749 2876 The header type of IPv6 device path node is MESSAGING_DEVICE_PATH. … … 2772 2899 ) 2773 2900 { 2901 ASSERT (Node != NULL && LocalIp != NULL && RemoteIp != NULL); 2902 2774 2903 Node->Header.Type = MESSAGING_DEVICE_PATH; 2775 2904 Node->Header.SubType = MSG_IPv6_DP; … … 2795 2924 /** 2796 2925 Find the UNDI/SNP handle from controller and protocol GUID. 2926 2927 If ProtocolGuid is NULL, then ASSERT(). 2797 2928 2798 2929 For example, IP will open a MNP child to transmit/receive … … 2823 2954 UINTN Index; 2824 2955 2956 ASSERT (ProtocolGuid != NULL); 2957 2825 2958 Status = gBS->OpenProtocolInformation ( 2826 2959 Controller, … … 2864 2997 ) 2865 2998 { 2866 UINT8 Index; 2867 CHAR8 *Ip4Str; 2868 CHAR8 *TempStr; 2869 UINTN NodeVal; 2870 2871 if ((String == NULL) || (Ip4Address == NULL)) { 2999 RETURN_STATUS Status; 3000 CHAR8 *EndPointer; 3001 3002 Status = AsciiStrToIpv4Address (String, &EndPointer, Ip4Address, NULL); 3003 if (RETURN_ERROR (Status) || (*EndPointer != '\0')) { 2872 3004 return EFI_INVALID_PARAMETER; 2873 } 2874 2875 Ip4Str = (CHAR8 *) String; 2876 2877 for (Index = 0; Index < 4; Index++) { 2878 TempStr = Ip4Str; 2879 2880 while ((*Ip4Str != '\0') && (*Ip4Str != '.')) { 2881 Ip4Str++; 2882 } 2883 2884 // 2885 // The IPv4 address is X.X.X.X 2886 // 2887 if (*Ip4Str == '.') { 2888 if (Index == 3) { 2889 return EFI_INVALID_PARAMETER; 2890 } 2891 } else { 2892 if (Index != 3) { 2893 return EFI_INVALID_PARAMETER; 2894 } 2895 } 2896 2897 // 2898 // Convert the string to IPv4 address. AsciiStrDecimalToUintn stops at the 2899 // first character that is not a valid decimal character, '.' or '\0' here. 2900 // 2901 NodeVal = AsciiStrDecimalToUintn (TempStr); 2902 if (NodeVal > 0xFF) { 2903 return EFI_INVALID_PARAMETER; 2904 } 2905 2906 Ip4Address->Addr[Index] = (UINT8) NodeVal; 2907 2908 Ip4Str++; 2909 } 2910 2911 return EFI_SUCCESS; 3005 } else { 3006 return EFI_SUCCESS; 3007 } 2912 3008 } 2913 3009 … … 2915 3011 /** 2916 3012 Convert one Null-terminated ASCII string to EFI_IPv6_ADDRESS. The format of the 2917 string is defined in RFC 4291 - Text Pepresentation of Addresses.3013 string is defined in RFC 4291 - Text Representation of Addresses. 2918 3014 2919 3015 @param[in] String The pointer to the Ascii string. … … 2931 3027 ) 2932 3028 { 2933 UINT8 Index; 2934 CHAR8 *Ip6Str; 2935 CHAR8 *TempStr; 2936 CHAR8 *TempStr2; 2937 UINT8 NodeCnt; 2938 UINT8 TailNodeCnt; 2939 UINT8 AllowedCnt; 2940 UINTN NodeVal; 2941 BOOLEAN Short; 2942 BOOLEAN Update; 2943 BOOLEAN LeadZero; 2944 UINT8 LeadZeroCnt; 2945 UINT8 Cnt; 2946 2947 if ((String == NULL) || (Ip6Address == NULL)) { 3029 RETURN_STATUS Status; 3030 CHAR8 *EndPointer; 3031 3032 Status = AsciiStrToIpv6Address (String, &EndPointer, Ip6Address, NULL); 3033 if (RETURN_ERROR (Status) || (*EndPointer != '\0')) { 2948 3034 return EFI_INVALID_PARAMETER; 2949 } 2950 2951 Ip6Str = (CHAR8 *) String; 2952 AllowedCnt = 6; 2953 LeadZeroCnt = 0; 2954 2955 // 2956 // An IPv6 address leading with : looks strange. 2957 // 2958 if (*Ip6Str == ':') { 2959 if (*(Ip6Str + 1) != ':') { 2960 return EFI_INVALID_PARAMETER; 2961 } else { 2962 AllowedCnt = 7; 2963 } 2964 } 2965 2966 ZeroMem (Ip6Address, sizeof (EFI_IPv6_ADDRESS)); 2967 2968 NodeCnt = 0; 2969 TailNodeCnt = 0; 2970 Short = FALSE; 2971 Update = FALSE; 2972 LeadZero = FALSE; 2973 2974 for (Index = 0; Index < 15; Index = (UINT8) (Index + 2)) { 2975 TempStr = Ip6Str; 2976 2977 while ((*Ip6Str != '\0') && (*Ip6Str != ':')) { 2978 Ip6Str++; 2979 } 2980 2981 if ((*Ip6Str == '\0') && (Index != 14)) { 2982 return EFI_INVALID_PARAMETER; 2983 } 2984 2985 if (*Ip6Str == ':') { 2986 if (*(Ip6Str + 1) == ':') { 2987 if ((NodeCnt > 6) || 2988 ((*(Ip6Str + 2) != '\0') && (AsciiStrHexToUintn (Ip6Str + 2) == 0))) { 2989 // 2990 // ::0 looks strange. report error to user. 2991 // 2992 return EFI_INVALID_PARAMETER; 2993 } 2994 if ((NodeCnt == 6) && (*(Ip6Str + 2) != '\0') && 2995 (AsciiStrHexToUintn (Ip6Str + 2) != 0)) { 2996 return EFI_INVALID_PARAMETER; 2997 } 2998 2999 // 3000 // Skip the abbreviation part of IPv6 address. 3001 // 3002 TempStr2 = Ip6Str + 2; 3003 while ((*TempStr2 != '\0')) { 3004 if (*TempStr2 == ':') { 3005 if (*(TempStr2 + 1) == ':') { 3006 // 3007 // :: can only appear once in IPv6 address. 3008 // 3009 return EFI_INVALID_PARAMETER; 3010 } 3011 3012 TailNodeCnt++; 3013 if (TailNodeCnt >= (AllowedCnt - NodeCnt)) { 3014 // 3015 // :: indicates one or more groups of 16 bits of zeros. 3016 // 3017 return EFI_INVALID_PARAMETER; 3018 } 3019 } 3020 3021 TempStr2++; 3022 } 3023 3024 Short = TRUE; 3025 Update = TRUE; 3026 3027 Ip6Str = Ip6Str + 2; 3028 } else { 3029 if (*(Ip6Str + 1) == '\0') { 3030 return EFI_INVALID_PARAMETER; 3031 } 3032 Ip6Str++; 3033 NodeCnt++; 3034 if ((Short && (NodeCnt > 6)) || (!Short && (NodeCnt > 7))) { 3035 // 3036 // There are more than 8 groups of 16 bits of zeros. 3037 // 3038 return EFI_INVALID_PARAMETER; 3039 } 3040 } 3041 } 3042 3043 // 3044 // Convert the string to IPv6 address. AsciiStrHexToUintn stops at the first 3045 // character that is not a valid hexadecimal character, ':' or '\0' here. 3046 // 3047 NodeVal = AsciiStrHexToUintn (TempStr); 3048 if ((NodeVal > 0xFFFF) || (Index > 14)) { 3049 return EFI_INVALID_PARAMETER; 3050 } 3051 if (NodeVal != 0) { 3052 if ((*TempStr == '0') && 3053 ((*(TempStr + 2) == ':') || (*(TempStr + 3) == ':') || 3054 (*(TempStr + 2) == '\0') || (*(TempStr + 3) == '\0'))) { 3055 return EFI_INVALID_PARAMETER; 3056 } 3057 if ((*TempStr == '0') && (*(TempStr + 4) != '\0') && 3058 (*(TempStr + 4) != ':')) { 3059 return EFI_INVALID_PARAMETER; 3060 } 3061 } else { 3062 if (((*TempStr == '0') && (*(TempStr + 1) == '0') && 3063 ((*(TempStr + 2) == ':') || (*(TempStr + 2) == '\0'))) || 3064 ((*TempStr == '0') && (*(TempStr + 1) == '0') && (*(TempStr + 2) == '0') && 3065 ((*(TempStr + 3) == ':') || (*(TempStr + 3) == '\0')))) { 3066 return EFI_INVALID_PARAMETER; 3067 } 3068 } 3069 3070 Cnt = 0; 3071 while ((TempStr[Cnt] != ':') && (TempStr[Cnt] != '\0')) { 3072 Cnt++; 3073 } 3074 if (LeadZeroCnt == 0) { 3075 if ((Cnt == 4) && (*TempStr == '0')) { 3076 LeadZero = TRUE; 3077 LeadZeroCnt++; 3078 } 3079 if ((Cnt != 0) && (Cnt < 4)) { 3080 LeadZero = FALSE; 3081 LeadZeroCnt++; 3082 } 3083 } else { 3084 if ((Cnt == 4) && (*TempStr == '0') && !LeadZero) { 3085 return EFI_INVALID_PARAMETER; 3086 } 3087 if ((Cnt != 0) && (Cnt < 4) && LeadZero) { 3088 return EFI_INVALID_PARAMETER; 3089 } 3090 } 3091 3092 Ip6Address->Addr[Index] = (UINT8) (NodeVal >> 8); 3093 Ip6Address->Addr[Index + 1] = (UINT8) (NodeVal & 0xFF); 3094 3095 // 3096 // Skip the groups of zeros by :: 3097 // 3098 if (Short && Update) { 3099 Index = (UINT8) (16 - (TailNodeCnt + 2) * 2); 3100 Update = FALSE; 3101 } 3102 } 3103 3104 if ((!Short && Index != 16) || (*Ip6Str != '\0')) { 3105 return EFI_INVALID_PARAMETER; 3106 } 3107 3108 return EFI_SUCCESS; 3035 } else { 3036 return EFI_SUCCESS; 3037 } 3109 3038 } 3110 3039 … … 3118 3047 @retval EFI_SUCCESS Convert to IPv4 address successfully. 3119 3048 @retval EFI_INVALID_PARAMETER The string is mal-formated or Ip4Address is NULL. 3120 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resource.3121 3049 3122 3050 **/ … … 3128 3056 ) 3129 3057 { 3130 CHAR8 *Ip4Str; 3131 EFI_STATUS Status; 3132 3133 if ((String == NULL) || (Ip4Address == NULL)) { 3058 RETURN_STATUS Status; 3059 CHAR16 *EndPointer; 3060 3061 Status = StrToIpv4Address (String, &EndPointer, Ip4Address, NULL); 3062 if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) { 3134 3063 return EFI_INVALID_PARAMETER; 3135 } 3136 3137 Ip4Str = (CHAR8 *) AllocatePool ((StrLen (String) + 1) * sizeof (CHAR8)); 3138 if (Ip4Str == NULL) { 3139 return EFI_OUT_OF_RESOURCES; 3140 } 3141 3142 UnicodeStrToAsciiStr (String, Ip4Str); 3143 3144 Status = NetLibAsciiStrToIp4 (Ip4Str, Ip4Address); 3145 3146 FreePool (Ip4Str); 3147 3148 return Status; 3064 } else { 3065 return EFI_SUCCESS; 3066 } 3149 3067 } 3150 3068 … … 3152 3070 /** 3153 3071 Convert one Null-terminated Unicode string to EFI_IPv6_ADDRESS. The format of 3154 the string is defined in RFC 4291 - Text Pepresentation of Addresses.3072 the string is defined in RFC 4291 - Text Representation of Addresses. 3155 3073 3156 3074 @param[in] String The pointer to the Ascii string. … … 3159 3077 @retval EFI_SUCCESS Convert to IPv6 address successfully. 3160 3078 @retval EFI_INVALID_PARAMETER The string is mal-formated or Ip6Address is NULL. 3161 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resource.3162 3079 3163 3080 **/ … … 3169 3086 ) 3170 3087 { 3171 CHAR8 *Ip6Str; 3172 EFI_STATUS Status; 3173 3174 if ((String == NULL) || (Ip6Address == NULL)) { 3088 RETURN_STATUS Status; 3089 CHAR16 *EndPointer; 3090 3091 Status = StrToIpv6Address (String, &EndPointer, Ip6Address, NULL); 3092 if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) { 3175 3093 return EFI_INVALID_PARAMETER; 3176 } 3177 3178 Ip6Str = (CHAR8 *) AllocatePool ((StrLen (String) + 1) * sizeof (CHAR8)); 3179 if (Ip6Str == NULL) { 3180 return EFI_OUT_OF_RESOURCES; 3181 } 3182 3183 UnicodeStrToAsciiStr (String, Ip6Str); 3184 3185 Status = NetLibAsciiStrToIp6 (Ip6Str, Ip6Address); 3186 3187 FreePool (Ip6Str); 3188 3189 return Status; 3094 } else { 3095 return EFI_SUCCESS; 3096 } 3190 3097 } 3191 3098 3192 3099 /** 3193 3100 Convert one Null-terminated Unicode string to EFI_IPv6_ADDRESS and prefix length. 3194 The format of the string is defined in RFC 4291 - Text Pepresentation of Addresses3101 The format of the string is defined in RFC 4291 - Text Representation of Addresses 3195 3102 Prefixes: ipv6-address/prefix-length. 3196 3103 … … 3201 3108 @retval EFI_SUCCESS Convert to IPv6 address successfully. 3202 3109 @retval EFI_INVALID_PARAMETER The string is mal-formated or Ip6Address is NULL. 3203 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resource.3204 3110 3205 3111 **/ … … 3212 3118 ) 3213 3119 { 3214 CHAR8 *Ip6Str; 3215 CHAR8 *PrefixStr; 3216 CHAR8 *TempStr; 3217 EFI_STATUS Status; 3218 UINT8 Length; 3219 3220 if ((String == NULL) || (Ip6Address == NULL) || (PrefixLength == NULL)) { 3120 RETURN_STATUS Status; 3121 CHAR16 *EndPointer; 3122 3123 Status = StrToIpv6Address (String, &EndPointer, Ip6Address, PrefixLength); 3124 if (RETURN_ERROR (Status) || (*EndPointer != L'\0')) { 3221 3125 return EFI_INVALID_PARAMETER; 3222 }3223 3224 Ip6Str = (CHAR8 *) AllocatePool ((StrLen (String) + 1) * sizeof (CHAR8));3225 if (Ip6Str == NULL) {3226 return EFI_OUT_OF_RESOURCES;3227 }3228 3229 UnicodeStrToAsciiStr (String, Ip6Str);3230 3231 //3232 // Get the sub string describing prefix length.3233 //3234 TempStr = Ip6Str;3235 while (*TempStr != '\0' && (*TempStr != '/')) {3236 TempStr++;3237 }3238 3239 if (*TempStr == '/') {3240 PrefixStr = TempStr + 1;3241 3126 } else { 3242 PrefixStr = NULL; 3243 } 3244 3245 // 3246 // Get the sub string describing IPv6 address and convert it. 3247 // 3248 *TempStr = '\0'; 3249 3250 Status = NetLibAsciiStrToIp6 (Ip6Str, Ip6Address); 3251 if (EFI_ERROR (Status)) { 3252 goto Exit; 3253 } 3254 3255 // 3256 // If input string doesn't indicate the prefix length, return 0xff. 3257 // 3258 Length = 0xFF; 3259 3260 // 3261 // Convert the string to prefix length 3262 // 3263 if (PrefixStr != NULL) { 3264 3265 Status = EFI_INVALID_PARAMETER; 3266 Length = 0; 3267 while (*PrefixStr != '\0') { 3268 if (NET_IS_DIGIT (*PrefixStr)) { 3269 Length = (UINT8) (Length * 10 + (*PrefixStr - '0')); 3270 if (Length >= IP6_PREFIX_NUM) { 3271 goto Exit; 3272 } 3273 } else { 3274 goto Exit; 3275 } 3276 3277 PrefixStr++; 3278 } 3279 } 3280 3281 *PrefixLength = Length; 3282 Status = EFI_SUCCESS; 3283 3284 Exit: 3285 3286 FreePool (Ip6Str); 3287 return Status; 3127 return EFI_SUCCESS; 3128 } 3288 3129 } 3289 3130 … … 3388 3229 } 3389 3230 3390 StrCpy (String, Buffer);3231 StrCpyS (String, StringSize / sizeof (CHAR16), Buffer); 3391 3232 3392 3233 return EFI_SUCCESS; … … 3395 3236 /** 3396 3237 This function obtains the system guid from the smbios table. 3238 3239 If SystemGuid is NULL, then ASSERT(). 3397 3240 3398 3241 @param[out] SystemGuid The pointer of the returned system guid. … … 3408 3251 ) 3409 3252 { 3410 EFI_STATUS Status; 3411 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable; 3412 SMBIOS_STRUCTURE_POINTER Smbios; 3413 SMBIOS_STRUCTURE_POINTER SmbiosEnd; 3414 CHAR8 *String; 3253 EFI_STATUS Status; 3254 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable; 3255 SMBIOS_TABLE_3_0_ENTRY_POINT *Smbios30Table; 3256 SMBIOS_STRUCTURE_POINTER Smbios; 3257 SMBIOS_STRUCTURE_POINTER SmbiosEnd; 3258 CHAR8 *String; 3259 3260 ASSERT (SystemGuid != NULL); 3415 3261 3416 3262 SmbiosTable = NULL; 3417 Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable); 3418 3419 if (EFI_ERROR (Status) || SmbiosTable == NULL) { 3420 return EFI_NOT_FOUND; 3421 } 3422 3423 Smbios.Hdr = (SMBIOS_STRUCTURE *) (UINTN) SmbiosTable->TableAddress; 3424 SmbiosEnd.Raw = (UINT8 *) (UINTN) (SmbiosTable->TableAddress + SmbiosTable->TableLength); 3263 Status = EfiGetSystemConfigurationTable (&gEfiSmbios3TableGuid, (VOID **) &Smbios30Table); 3264 if (!(EFI_ERROR (Status) || Smbios30Table == NULL)) { 3265 Smbios.Hdr = (SMBIOS_STRUCTURE *) (UINTN) Smbios30Table->TableAddress; 3266 SmbiosEnd.Raw = (UINT8 *) (UINTN) (Smbios30Table->TableAddress + Smbios30Table->TableMaximumSize); 3267 } else { 3268 Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &SmbiosTable); 3269 if (EFI_ERROR (Status) || SmbiosTable == NULL) { 3270 return EFI_NOT_FOUND; 3271 } 3272 Smbios.Hdr = (SMBIOS_STRUCTURE *) (UINTN) SmbiosTable->TableAddress; 3273 SmbiosEnd.Raw = (UINT8 *) ((UINTN) SmbiosTable->TableAddress + SmbiosTable->TableLength); 3274 } 3425 3275 3426 3276 do { … … 3474 3324 return EFI_NOT_FOUND; 3475 3325 } 3326 3327 /** 3328 Create Dns QName according the queried domain name. 3329 3330 If DomainName is NULL, then ASSERT(). 3331 3332 QName is a domain name represented as a sequence of labels, 3333 where each label consists of a length octet followed by that 3334 number of octets. The QName terminates with the zero 3335 length octet for the null label of the root. Caller should 3336 take responsibility to free the buffer in returned pointer. 3337 3338 @param DomainName The pointer to the queried domain name string. 3339 3340 @retval NULL Failed to fill QName. 3341 @return QName filled successfully. 3342 3343 **/ 3344 CHAR8 * 3345 EFIAPI 3346 NetLibCreateDnsQName ( 3347 IN CHAR16 *DomainName 3348 ) 3349 { 3350 CHAR8 *QueryName; 3351 UINTN QueryNameSize; 3352 CHAR8 *Header; 3353 CHAR8 *Tail; 3354 UINTN Len; 3355 UINTN Index; 3356 3357 ASSERT (DomainName != NULL); 3358 3359 QueryName = NULL; 3360 QueryNameSize = 0; 3361 Header = NULL; 3362 Tail = NULL; 3363 3364 // 3365 // One byte for first label length, one byte for terminated length zero. 3366 // 3367 QueryNameSize = StrLen (DomainName) + 2; 3368 3369 if (QueryNameSize > DNS_MAX_NAME_SIZE) { 3370 return NULL; 3371 } 3372 3373 QueryName = AllocateZeroPool (QueryNameSize); 3374 if (QueryName == NULL) { 3375 return NULL; 3376 } 3377 3378 Header = QueryName; 3379 Tail = Header + 1; 3380 Len = 0; 3381 for (Index = 0; DomainName[Index] != 0; Index++) { 3382 *Tail = (CHAR8) DomainName[Index]; 3383 if (*Tail == '.') { 3384 *Header = (CHAR8) Len; 3385 Header = Tail; 3386 Tail ++; 3387 Len = 0; 3388 } else { 3389 Tail++; 3390 Len++; 3391 } 3392 } 3393 *Header = (CHAR8) Len; 3394 *Tail = 0; 3395 3396 return QueryName; 3397 }
Note:
See TracChangeset
for help on using the changeset viewer.