VirtualBox

Ignore:
Timestamp:
Mar 12, 2019 12:40:12 PM (6 years ago)
Author:
vboxsync
Message:

EFI: First step in UDK2018 merge. Does not build yet.

Location:
trunk/src/VBox/Devices/EFI/FirmwareNew
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/FirmwareNew

  • trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c

    r58466 r77662  
    22  Network library.
    33
    4 Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
     4Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
     5(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
    56This program and the accompanying materials
    67are licensed and made available under the terms and conditions of the BSD License
     
    1920#include <Protocol/ServiceBinding.h>
    2021#include <Protocol/SimpleNetwork.h>
     22#include <Protocol/AdapterInformation.h>
    2123#include <Protocol/ManagedNetwork.h>
    22 #include <Protocol/HiiConfigRouting.h>
     24#include <Protocol/Ip4Config2.h>
    2325#include <Protocol/ComponentName.h>
    2426#include <Protocol/ComponentName2.h>
    25 #include <Protocol/HiiConfigAccess.h>
    26 
    27 #include <Guid/NicIp4ConfigNvData.h>
     27
    2828#include <Guid/SmBios.h>
    2929
     
    3636#include <Library/MemoryAllocationLib.h>
    3737#include <Library/DevicePathLib.h>
    38 #include <Library/HiiLib.h>
    3938#include <Library/PrintLib.h>
    4039#include <Library/UefiLib.h>
    4140
    42 #define NIC_ITEM_CONFIG_SIZE   sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE
     41#define NIC_ITEM_CONFIG_SIZE   (sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE)
    4342#define DEFAULT_ZERO_START     ((UINTN) ~0)
    4443
     
    200199  time it is called to avoid the problem if SNP is unloaded.
    201200  This code snip is copied from MNP.
     201  If Packet is NULL, then ASSERT().
    202202
    203203  @param[in] Packet          The Syslog packet
     
    220220  EFI_EVENT                   TimeoutEvent;
    221221  UINT8                       *TxBuf;
     222
     223  ASSERT (Packet != NULL);
    222224
    223225  Snp = SyslogLocateSnp ();
     
    304306  and user's message.
    305307
    306   @param[in]  Level     Syslog servity level
     308  @param[in]  Level     Syslog severity level
    307309  @param[in]  Module    The module that generates the log
    308310  @param[in]  File      The file that contains the current log
     
    312314  @param[out] Buf       The buffer to put the packet data
    313315
    314   @return The length of the syslog packet built.
     316  @return The length of the syslog packet built, 0 represents no packet is built.
    315317
    316318**/
     
    326328  )
    327329{
     330  EFI_STATUS                Status;
    328331  ETHER_HEAD                *Ether;
    329332  IP4_HEAD                  *Ip4;
     
    381384  //
    382385  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  }
    385390
    386391  //
     
    399404                    Time.Second
    400405                    );
    401   Len--;
    402406
    403407  Len += (UINT32) AsciiSPrint (
     
    410414                    File
    411415                    );
    412   Len--;
     416  Len ++;
    413417
    414418  //
     
    441445         )
    442446
     447  If Format is NULL, then ASSERT().
     448
    443449  @param Format  The ASCII format string.
    444450  @param ...     The variable length parameter whose format is determined
     
    459465  CHAR8                     *Buf;
    460466
     467  ASSERT (Format != NULL);
     468
    461469  Buf = (CHAR8 *) AllocatePool (NET_DEBUG_MSG_LEN);
    462470
     
    478486  Because it isn't open the SNP BY_DRIVER, apply caution when using it.
    479487
    480   @param Level    The servity level of the message.
     488  @param Level    The severity level of the message.
    481489  @param Module   The Moudle that generates the log.
    482490  @param File     The file that contains the log.
     
    485493
    486494  @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.
    488497  @retval EFI_SUCCESS           The log is discard because that it is more verbose
    489498                                than the mNetDebugLevelMax. Or, it has been sent out.
     
    506515  // Check whether the message should be sent out
    507516  //
    508   if (Message == NULL) {
     517  if (Message == NULL || File == NULL || Module == NULL) {
    509518    return EFI_INVALID_PARAMETER;
    510519  }
     
    539548          Packet
    540549          );
    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
    544557  FreePool (Packet);
    545558
     
    568581  INTN                      Index;
    569582
    570   for (Index = 0; Index < IP4_MASK_NUM; Index++) {
     583  for (Index = 0; Index <= IP4_MASK_MAX; Index++) {
    571584    if (NetMask == gIp4AllMasks[Index]) {
    572585      break;
     
    582595  Return the class of the IP address, such as class A, B, C.
    583596  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.
    584602
    585603  The address of class A  starts with 0.
     
    631649/**
    632650  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).
    639658
    640659  @param[in]  Ip                    The IP to check against.
     
    651670  )
    652671{
    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)) {
    658675    return FALSE;
    659676  }
    660677
    661   if (NetMask == 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;
    667684  }
    668685
     
    672689/**
    673690  Check whether the incoming IPv6 address is a valid unicast address.
     691
     692  ASSERT if Ip6 is NULL.
    674693
    675694  If the address is a multicast address has binary 0xFF at the start, it is not
     
    693712  UINT8 Index;
    694713
     714  ASSERT (Ip6 != NULL);
     715
    695716  if (Ip6->Addr[0] == 0xFF) {
    696717    return FALSE;
     
    715736  Check whether the incoming Ipv6 address is the unspecified address or not.
    716737
     738  ASSERT if Ip6 is NULL.
     739
    717740  @param[in] Ip6   - Ip6 address, in network order.
    718741
     
    728751{
    729752  UINT8 Index;
     753
     754  ASSERT (Ip6 != NULL);
    730755
    731756  for (Index = 0; Index < 16; Index++) {
     
    741766  Check whether the incoming Ipv6 address is a link-local address.
    742767
     768  ASSERT if Ip6 is NULL.
     769
    743770  @param[in] Ip6   - Ip6 address, in network order.
    744771
     
    776803/**
    777804  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.
    778808
    779809  @param[in] Ip1          - Ip6 address1, in network order.
     
    797827  UINT8 Mask;
    798828
    799   ASSERT ((Ip1 != NULL) && (Ip2 != NULL) && (PrefixLength < IP6_PREFIX_NUM));
     829  ASSERT ((Ip1 != NULL) && (Ip2 != NULL) && (PrefixLength < IP6_PREFIX_MAX));
    800830
    801831  if (PrefixLength == 0) {
     
    814844
    815845    ASSERT (Byte < 16);
     846    if (Byte >= 16) {
     847      return FALSE;
     848    }
    816849    if ((Ip1->Addr[Byte] & Mask) != (Ip2->Addr[Byte] & Mask)) {
    817850      return FALSE;
     
    825858/**
    826859  Switches the endianess of an IPv6 address
     860
     861  ASSERT if Ip6 is NULL.
    827862
    828863  This function swaps the bytes in a 128-bit IPv6 address to switch the value
     
    844879  UINT64 Low;
    845880
     881  ASSERT (Ip6 != NULL);
     882
    846883  CopyMem (&High, Ip6, sizeof (UINT64));
    847884  CopyMem (&Low, &Ip6->Addr[8], sizeof (UINT64));
     
    857894
    858895/**
    859   Initialize a random seed using current time.
    860 
    861   Get current time first. Then initialize a random seed based on some basic
    862   mathematics operation on the hour, day, minute, second, nanosecond and year
    863   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.
    864901
    865902  @return The random seed initialized with current time.
     
    874911  EFI_TIME                  Time;
    875912  UINT32                    Seed;
     913  UINT64                    MonotonicCount;
    876914
    877915  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);
    879917  Seed ^= Time.Nanosecond;
    880918  Seed ^= Time.Year << 7;
    881919
     920  gBS->GetNextMonotonicCount (&MonotonicCount);
     921  Seed += (UINT32) MonotonicCount;
     922
    882923  return Seed;
    883924}
     
    886927/**
    887928  Extract a UINT32 from a byte stream.
     929
     930  ASSERT if Buf is NULL.
    888931
    889932  Copy a UINT32 from a byte stream, then converts it from Network
     
    903946  UINT32                    Value;
    904947
     948  ASSERT (Buf != NULL);
     949
    905950  CopyMem (&Value, Buf, sizeof (UINT32));
    906951  return NTOHL (Value);
     
    910955/**
    911956  Put a UINT32 to the byte stream in network byte order.
     957
     958  ASSERT if Buf is NULL.
    912959
    913960  Converts a UINT32 from host byte order to network byte order. Then copy it to the
     
    925972  )
    926973{
     974  ASSERT (Buf != NULL);
     975
    927976  Data = HTONL (Data);
    928977  CopyMem (Buf, &Data, sizeof (UINT32));
     
    10231072  Insert a new node entry after a designated node entry of a doubly linked list.
    10241073
     1074  ASSERT if PrevEntry or NewEntry is NULL.
     1075
    10251076  Inserts a new node entry donated by NewEntry after the node entry donated by PrevEntry
    10261077  of the doubly linked list.
     
    10371088  )
    10381089{
     1090  ASSERT (PrevEntry != NULL && NewEntry != NULL);
     1091
    10391092  NewEntry->BackLink                = PrevEntry;
    10401093  NewEntry->ForwardLink             = PrevEntry->ForwardLink;
     
    10471100  Insert a new node entry before a designated node entry of a doubly linked list.
    10481101
     1102  ASSERT if PostEntry or NewEntry is NULL.
     1103
    10491104  Inserts a new node entry donated by NewEntry after the node entry donated by PostEntry
    10501105  of the doubly linked list.
     
    10611116  )
    10621117{
     1118  ASSERT (PostEntry != NULL && NewEntry != NULL);
     1119
    10631120  NewEntry->ForwardLink             = PostEntry;
    10641121  NewEntry->BackLink                = PostEntry->BackLink;
     
    11501207                                 if NumberOfChildren is 0.
    11511208
    1152   @retval TURE                   Found the input Handle in ChildHandleBuffer.
     1209  @retval TRUE                   Found the input Handle in ChildHandleBuffer.
    11531210  @retval FALSE                  Can't find the input Handle in ChildHandleBuffer.
    11541211
     
    12591316  If Map is NULL, then ASSERT().
    12601317
    1261 
    12621318  @param[in]  Map                   The net map to test.
    12631319
     
    12791335  Return the number of the <Key, Value> pairs in the netmap.
    12801336
     1337  If Map is NULL, then ASSERT().
     1338
    12811339  @param[in]  Map                   The netmap to get the entry number.
    12821340
     
    12901348  )
    12911349{
     1350  ASSERT (Map != NULL);
    12921351  return Map->Count;
    12931352}
     
    13541413
    13551414  If Map is NULL, then ASSERT().
     1415  If Key is NULL, then ASSERT().
    13561416
    13571417  @param[in, out]  Map                   The netmap to insert into.
     
    13731433  NET_MAP_ITEM              *Item;
    13741434
    1375   ASSERT (Map != NULL);
     1435  ASSERT (Map != NULL && Key != NULL);
    13761436
    13771437  Item = NetMapAllocItem (Map);
     
    13981458
    13991459  If Map is NULL, then ASSERT().
     1460  If Key is NULL, then ASSERT().
    14001461
    14011462  @param[in, out]  Map                   The netmap to insert into.
     
    14171478  NET_MAP_ITEM              *Item;
    14181479
    1419   ASSERT (Map != NULL);
     1480  ASSERT (Map != NULL && Key != NULL);
    14201481
    14211482  Item = NetMapAllocItem (Map);
     
    14371498/**
    14381499  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().
    14391503
    14401504  @param[in]  Map                   The netmap to search within.
     
    14521516  LIST_ENTRY            *ListEntry;
    14531517
     1518  ASSERT (Map != NULL && Item != NULL);
     1519
    14541520  NET_LIST_FOR_EACH (ListEntry, &Map->Used) {
    14551521    if (ListEntry == &Item->Link) {
     
    14691535
    14701536  If Map is NULL, then ASSERT().
     1537  If Key is NULL, then ASSERT().
    14711538
    14721539  @param[in]  Map                   The netmap to search within.
     
    14861553  NET_MAP_ITEM            *Item;
    14871554
    1488   ASSERT (Map != NULL);
     1555  ASSERT (Map != NULL && Key != NULL);
    14891556
    14901557  NET_LIST_FOR_EACH (Entry, &Map->Used) {
     
    16351702  Iterate through the netmap and call CallBack for each item.
    16361703
    1637   It will contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
     1704  It will continue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
    16381705  from the loop. It returns the CallBack's last return value. This function is
    16391706  delete safe for the current item.
     
    16841751
    16851752  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_STATUS
    1700 NetGetChildHandle (
    1701   IN EFI_HANDLE         Controller,
    1702   OUT EFI_HANDLE        *ChildHandle
    1703   )
    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 protocols
    1714   //
    1715   Status = gBS->LocateHandleBuffer (
    1716                  ByProtocol,
    1717                  &gEfiHiiConfigAccessProtocolGuid,
    1718                  NULL,
    1719                  &HandleCount,
    1720                  &Handles
    1721                  );
    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 handle
    1734       //
    1735       Status = gBS->HandleProtocol (
    1736                      Handles[Index],
    1737                      &gEfiDevicePathProtocolGuid,
    1738                      (VOID **) &ChildDeviceDevicePath
    1739                      );
    1740 
    1741       if (!EFI_ERROR (Status)) {
    1742         while (!IsDevicePathEnd (ChildDeviceDevicePath)) {
    1743           ChildDeviceDevicePath = NextDevicePathNode (ChildDeviceDevicePath);
    1744           //
    1745           // Parse one instance
    1746           //
    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 gEfiNicIp4ConfigVariableGuid
    1753               //
    1754               *ChildHandle = Handles[Index];
    1755               FreePool (Handles);
    1756               return EFI_SUCCESS;
    1757             }
    1758           }
    1759         }
    1760       }
    1761     }
    1762   }
    1763 
    1764   FreePool (Handles);
    1765   return Status;
    17661753}
    17671754
     
    21692156  Get MAC address associated with the network service handle.
    21702157
     2158  If MacAddress is NULL, then ASSERT().
     2159  If AddressSize is NULL, then ASSERT().
     2160
    21712161  There should be MNP Service Binding Protocol installed on the input ServiceHandle.
    21722162  If SNP is installed on the ServiceHandle or its parent handle, MAC address will
     
    22732263  to a unicode string. Callers are responsible for freeing the string storage.
    22742264
     2265  If MacString is NULL, then ASSERT().
     2266
    22752267  Locate simple network protocol associated with the Service Binding Handle and
    22762268  get the mac address from SNP. Then convert the mac address into a unicode
     
    23062298  CHAR16                       *String;
    23072299  UINTN                        Index;
     2300  UINTN                        BufferSize;
    23082301
    23092302  ASSERT (MacString != NULL);
     
    23222315  // Plus one unicode character for the null-terminator.
    23232316  //
    2324   String = AllocateZeroPool ((2 * HwAddressSize + 5 + 1) * sizeof (CHAR16));
     2317  BufferSize = (2 * HwAddressSize + 5 + 1) * sizeof (CHAR16);
     2318  String = AllocateZeroPool (BufferSize);
    23252319  if (String == NULL) {
    23262320    return EFI_OUT_OF_RESOURCES;
     
    23332327  HwAddress = &MacAddress.Addr[0];
    23342328  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));
    23362337  }
    23372338
     
    23422343  if (VlanId != 0) {
    23432344    *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));
    23452353  }
    23462354
     
    23552363/**
    23562364  Detect media status for specified network device.
     2365
     2366  If MediaPresent is NULL, then ASSERT().
    23572367
    23582368  The underlying UNDI driver may or may not support reporting media status from
     
    24642474                      );
    24652475      ASSERT (MCastFilter != NULL);
     2476      if (MCastFilter == NULL) {
     2477        Status = EFI_OUT_OF_RESOURCES;
     2478        goto Exit;
     2479      }
    24662480
    24672481      ResetMCastFilters = FALSE;
     
    25622576
    25632577/**
     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**/
     2602EFI_STATUS
     2603EFIAPI
     2604NetLibDetectMediaWaitTimeout (
     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/**
    25642757  Check the default address used by the IPv4 driver is static or dynamic (acquired
    25652758  from DHCP).
    25662759
    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
    25732765                              relative with the default address to judge.
    25742766
     
    25832775{
    25842776  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;
    25882780  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);
    26472792  if (EFI_ERROR (Status)) {
    26482793    goto ON_EXIT;
    26492794  }
    26502795
    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);
    26652797  if (EFI_ERROR (Status)) {
    26662798    goto ON_EXIT;
    26672799  }
    26682800
    2669   IsStatic = (BOOLEAN) (ConfigInfo->Source == IP4_CONFIG_SOURCE_STATIC);
     2801  IsStatic = (BOOLEAN) (Policy == Ip4Config2PolicyStatic);
    26702802
    26712803ON_EXIT:
    26722804
    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 
    26862805  return IsStatic;
    26872806}
     
    26892808/**
    26902809  Create an IPv4 device path node.
     2810
     2811  If Node is NULL, then ASSERT().
    26912812
    26922813  The header type of IPv4 device path node is MESSAGING_DEVICE_PATH.
     
    27172838  )
    27182839{
     2840  ASSERT (Node != NULL);
     2841
    27192842  Node->Header.Type    = MESSAGING_DEVICE_PATH;
    27202843  Node->Header.SubType = MSG_IPv4_DP;
     
    27462869/**
    27472870  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().
    27482875
    27492876  The header type of IPv6 device path node is MESSAGING_DEVICE_PATH.
     
    27722899  )
    27732900{
     2901  ASSERT (Node != NULL && LocalIp != NULL && RemoteIp != NULL);
     2902
    27742903  Node->Header.Type    = MESSAGING_DEVICE_PATH;
    27752904  Node->Header.SubType = MSG_IPv6_DP;
     
    27952924/**
    27962925  Find the UNDI/SNP handle from controller and protocol GUID.
     2926
     2927  If ProtocolGuid is NULL, then ASSERT().
    27972928
    27982929  For example, IP will open a MNP child to transmit/receive
     
    28232954  UINTN                               Index;
    28242955
     2956  ASSERT (ProtocolGuid != NULL);
     2957
    28252958  Status = gBS->OpenProtocolInformation (
    28262959                  Controller,
     
    28642997  )
    28652998{
    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')) {
    28723004    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  }
    29123008}
    29133009
     
    29153011/**
    29163012  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.
    29183014
    29193015  @param[in]      String         The pointer to the Ascii string.
     
    29313027  )
    29323028{
    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')) {
    29483034    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  }
    31093038}
    31103039
     
    31183047  @retval EFI_SUCCESS            Convert to IPv4 address successfully.
    31193048  @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.
    31213049
    31223050**/
     
    31283056  )
    31293057{
    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')) {
    31343063    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  }
    31493067}
    31503068
     
    31523070/**
    31533071  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.
    31553073
    31563074  @param[in]      String         The pointer to the Ascii string.
     
    31593077  @retval EFI_SUCCESS            Convert to IPv6 address successfully.
    31603078  @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.
    31623079
    31633080**/
     
    31693086  )
    31703087{
    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')) {
    31753093    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  }
    31903097}
    31913098
    31923099/**
    31933100  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 Addresses
     3101  The format of the string is defined in RFC 4291 - Text Representation of Addresses
    31953102  Prefixes: ipv6-address/prefix-length.
    31963103
     
    32013108  @retval EFI_SUCCESS            Convert to IPv6 address successfully.
    32023109  @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.
    32043110
    32053111**/
     
    32123118  )
    32133119{
    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')) {
    32213125    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;
    32413126  } 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  }
    32883129}
    32893130
     
    33883229  }
    33893230
    3390   StrCpy (String, Buffer);
     3231  StrCpyS (String, StringSize / sizeof (CHAR16), Buffer);
    33913232
    33923233  return EFI_SUCCESS;
     
    33953236/**
    33963237  This function obtains the system guid from the smbios table.
     3238
     3239  If SystemGuid is NULL, then ASSERT().
    33973240
    33983241  @param[out]  SystemGuid     The pointer of the returned system guid.
     
    34083251  )
    34093252{
    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);
    34153261
    34163262  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  }
    34253275
    34263276  do {
     
    34743324  return EFI_NOT_FOUND;
    34753325}
     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**/
     3344CHAR8 *
     3345EFIAPI
     3346NetLibCreateDnsQName (
     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.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette