/** @file

Copyright (c) 2005 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

Module Name:

  NetLib.c

Abstract:



**/

#include <PiDxe.h>

#include <Protocol/ServiceBinding.h>
#include <Protocol/SimpleNetwork.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/NicIp4Config.h>

#include <Library/NetLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/MemoryAllocationLib.h>


//
// All the supported IP4 maskes in host byte order.
//
IP4_ADDR  mIp4AllMasks[IP4_MASK_NUM] = {
  0x00000000,
  0x80000000,
  0xC0000000,
  0xE0000000,
  0xF0000000,
  0xF8000000,
  0xFC000000,
  0xFE000000,

  0xFF000000,
  0xFF800000,
  0xFFC00000,
  0xFFE00000,
  0xFFF00000,
  0xFFF80000,
  0xFFFC0000,
  0xFFFE0000,

  0xFFFF0000,
  0xFFFF8000,
  0xFFFFC000,
  0xFFFFE000,
  0xFFFFF000,
  0xFFFFF800,
  0xFFFFFC00,
  0xFFFFFE00,

  0xFFFFFF00,
  0xFFFFFF80,
  0xFFFFFFC0,
  0xFFFFFFE0,
  0xFFFFFFF0,
  0xFFFFFFF8,
  0xFFFFFFFC,
  0xFFFFFFFE,
  0xFFFFFFFF,
};

EFI_IPv4_ADDRESS  mZeroIp4Addr = {{0, 0, 0, 0}};

/**
  Converts the low nibble of a byte  to hex unicode character.

  @param  Nibble  lower nibble of a byte.

  @return Hex unicode character.

**/
CHAR16
NibbleToHexChar (
  IN UINT8      Nibble
  )
{
  //
  // Porting Guide:
  // This library interface is simply obsolete.
  // Include the source code to user code.
  //

  Nibble &= 0x0F;
  if (Nibble <= 0x9) {
    return (CHAR16)(Nibble + L'0');
  }

  return (CHAR16)(Nibble - 0xA + L'A');
}

/**
  Return the length of the mask. If the mask is invalid,
  return the invalid length 33, which is IP4_MASK_NUM.
  NetMask is in the host byte order.

  @param  NetMask               The netmask to get the length from

  @return The length of the netmask, IP4_MASK_NUM if the mask isn't
  @return supported.

**/
INTN
NetGetMaskLength (
  IN IP4_ADDR               NetMask
  )
{
  INTN                      Index;

  for (Index = 0; Index < IP4_MASK_NUM; Index++) {
    if (NetMask == mIp4AllMasks[Index]) {
      break;
    }
  }

  return Index;
}



/**
  Return the class of the address, such as class a, b, c.
  Addr is in host byte order.

  @param  Addr                  The address to get the class from

  @return IP address class, such as IP4_ADDR_CLASSA

**/
INTN
NetGetIpClass (
  IN IP4_ADDR               Addr
  )
{
  UINT8                     ByteOne;

  ByteOne = (UINT8) (Addr >> 24);

  if ((ByteOne & 0x80) == 0) {
    return IP4_ADDR_CLASSA;

  } else if ((ByteOne & 0xC0) == 0x80) {
    return IP4_ADDR_CLASSB;

  } else if ((ByteOne & 0xE0) == 0xC0) {
    return IP4_ADDR_CLASSC;

  } else if ((ByteOne & 0xF0) == 0xE0) {
    return IP4_ADDR_CLASSD;

  } else {
    return IP4_ADDR_CLASSE;

  }
}


/**
  Check whether the IP is a valid unicast address according to
  the netmask. If NetMask is zero, use the IP address's class to
  get the default mask.

  @param  Ip                    The IP to check againist
  @param  NetMask               The mask of the IP

  @return TRUE if IP is a valid unicast address on the network, otherwise FALSE

**/
BOOLEAN
Ip4IsUnicast (
  IN IP4_ADDR               Ip,
  IN IP4_ADDR               NetMask
  )
{
  INTN                      Class;

  Class = NetGetIpClass (Ip);

  if ((Ip == 0) || (Class >= IP4_ADDR_CLASSD)) {
    return FALSE;
  }

  if (NetMask == 0) {
    NetMask = mIp4AllMasks[Class << 3];
  }

  if (((Ip &~NetMask) == ~NetMask) || ((Ip &~NetMask) == 0)) {
    return FALSE;
  }

  return TRUE;
}


/**
  Initialize a random seed using current time.

  None

  @return The random seed initialized with current time.

**/
UINT32
NetRandomInitSeed (
  VOID
  )
{
  EFI_TIME                  Time;
  UINT32                    Seed;

  gRT->GetTime (&Time, NULL);
  Seed = (~Time.Hour << 24 | Time.Second << 16 | Time.Minute << 8 | Time.Day);
  Seed ^= Time.Nanosecond;
  Seed ^= Time.Year << 7;

  return Seed;
}


/**
  Extract a UINT32 from a byte stream, then convert it to host
  byte order. Use this function to avoid alignment error.

  @param  Buf                   The buffer to extract the UINT32.

  @return The UINT32 extracted.

**/
UINT32
NetGetUint32 (
  IN UINT8                  *Buf
  )
{
  UINT32                    Value;

  NetCopyMem (&Value, Buf, sizeof (UINT32));
  return NTOHL (Value);
}


/**
  Put a UINT32 to the byte stream. Convert it from host byte order
  to network byte order before putting.

  @param  Buf                   The buffer to put the UINT32
  @param  Data                  The data to put

  @return None

**/
VOID
NetPutUint32 (
  IN UINT8                  *Buf,
  IN UINT32                 Data
  )
{
  Data = HTONL (Data);
  NetCopyMem (Buf, &Data, sizeof (UINT32));
}


/**
  Remove the first entry on the list

  @param  Head                  The list header

  @return The entry that is removed from the list, NULL if the list is empty.

**/
NET_LIST_ENTRY *
NetListRemoveHead (
  NET_LIST_ENTRY            *Head
  )
{
  NET_LIST_ENTRY            *First;

  ASSERT (Head != NULL);

  if (NetListIsEmpty (Head)) {
    return NULL;
  }

  First                         = Head->ForwardLink;
  Head->ForwardLink             = First->ForwardLink;
  First->ForwardLink->BackLink  = Head;

  DEBUG_CODE (
    First->ForwardLink  = (LIST_ENTRY     *) NULL;
    First->BackLink     = (LIST_ENTRY     *) NULL;
  );

  return First;
}


/**
  Remove the last entry on the list

  @param  Head                  The list head

  @return The entry that is removed from the list, NULL if the list is empty.

**/
NET_LIST_ENTRY *
NetListRemoveTail (
  NET_LIST_ENTRY            *Head
  )
{
  NET_LIST_ENTRY            *Last;

  ASSERT (Head != NULL);

  if (NetListIsEmpty (Head)) {
    return NULL;
  }

  Last                        = Head->BackLink;
  Head->BackLink              = Last->BackLink;
  Last->BackLink->ForwardLink = Head;

  DEBUG_CODE (
    Last->ForwardLink = (LIST_ENTRY     *) NULL;
    Last->BackLink    = (LIST_ENTRY     *) NULL;
  );

  return Last;
}


/**
  Insert the NewEntry after the PrevEntry

  @param  PrevEntry             The previous entry to insert after
  @param  NewEntry              The new entry to insert

  @return None

**/
VOID
NetListInsertAfter (
  IN NET_LIST_ENTRY         *PrevEntry,
  IN NET_LIST_ENTRY         *NewEntry
  )
{
  NewEntry->BackLink                = PrevEntry;
  NewEntry->ForwardLink             = PrevEntry->ForwardLink;
  PrevEntry->ForwardLink->BackLink  = NewEntry;
  PrevEntry->ForwardLink            = NewEntry;
}


/**
  Insert the NewEntry before the PostEntry

  @param  PostEntry             The entry to insert before
  @param  NewEntry              The new entry to insert

  @return None

**/
VOID
NetListInsertBefore (
  IN NET_LIST_ENTRY *PostEntry,
  IN NET_LIST_ENTRY *NewEntry
  )
{
  NewEntry->ForwardLink             = PostEntry;
  NewEntry->BackLink                = PostEntry->BackLink;
  PostEntry->BackLink->ForwardLink  = NewEntry;
  PostEntry->BackLink               = NewEntry;
}


/**
  Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.

  @param  Map                   The netmap to initialize

  @return None

**/
VOID
NetMapInit (
  IN NET_MAP                *Map
  )
{
  ASSERT (Map != NULL);

  NetListInit (&Map->Used);
  NetListInit (&Map->Recycled);
  Map->Count = 0;
}


/**
  To clean up the netmap, that is, release allocated memories.

  @param  Map                   The netmap to clean up.

  @return None

**/
VOID
NetMapClean (
  IN NET_MAP                *Map
  )
{
  NET_MAP_ITEM              *Item;
  NET_LIST_ENTRY            *Entry;
  NET_LIST_ENTRY            *Next;

  ASSERT (Map != NULL);

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Map->Used) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);

    NetListRemoveEntry (&Item->Link);
    Map->Count--;

    NetFreePool (Item);
  }

  ASSERT ((Map->Count == 0) && NetListIsEmpty (&Map->Used));

  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Map->Recycled) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);

    NetListRemoveEntry (&Item->Link);
    NetFreePool (Item);
  }

  ASSERT (NetListIsEmpty (&Map->Recycled));
}


/**
  Test whether the netmap is empty

  @param  Map                   The net map to test

  @return TRUE if the netmap is empty, otherwise FALSE.

**/
BOOLEAN
NetMapIsEmpty (
  IN NET_MAP                *Map
  )
{
  ASSERT (Map != NULL);
  return (BOOLEAN) (Map->Count == 0);
}


/**
  Return the number of the <Key, Value> pairs in the netmap.

  @param  Map                   The netmap to get the entry number

  @return The entry number in the netmap.

**/
UINTN
NetMapGetCount (
  IN NET_MAP                *Map
  )
{
  return Map->Count;
}


/**
  Allocate an item for the netmap. It will try to allocate
  a batch of items and return one.

  @param  Map                   The netmap to allocate item for

  @return The allocated item or NULL

**/
STATIC
NET_MAP_ITEM *
NetMapAllocItem (
  IN NET_MAP                *Map
  )
{
  NET_MAP_ITEM              *Item;
  NET_LIST_ENTRY            *Head;
  UINTN                     Index;

  ASSERT (Map != NULL);

  Head = &Map->Recycled;

  if (NetListIsEmpty (Head)) {
    for (Index = 0; Index < NET_MAP_INCREAMENT; Index++) {
      Item = NetAllocatePool (sizeof (NET_MAP_ITEM));

      if (Item == NULL) {
        if (Index == 0) {
          return NULL;
        }

        break;
      }

      NetListInsertHead (Head, &Item->Link);
    }
  }

  Item = NET_LIST_HEAD (Head, NET_MAP_ITEM, Link);
  NetListRemoveHead (Head);

  return Item;
}


/**
  Allocate an item to save the <Key, Value> pair to the head of the netmap.

  @param  Map                   The netmap to insert into
  @param  Key                   The user's key
  @param  Value                 The user's value for the key

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the item
  @retval EFI_SUCCESS           The item is inserted to the head

**/
EFI_STATUS
NetMapInsertHead (
  IN NET_MAP                *Map,
  IN VOID                   *Key,
  IN VOID                   *Value    OPTIONAL
  )
{
  NET_MAP_ITEM              *Item;

  ASSERT (Map != NULL);

  Item = NetMapAllocItem (Map);

  if (Item == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Item->Key   = Key;
  Item->Value = Value;
  NetListInsertHead (&Map->Used, &Item->Link);

  Map->Count++;
  return EFI_SUCCESS;
}


/**
  Allocate an item to save the <Key, Value> pair to the tail of the netmap.

  @param  Map                   The netmap to insert into
  @param  Key                   The user's key
  @param  Value                 The user's value for the key

  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the item
  @retval EFI_SUCCESS           The item is inserted to the tail

**/
EFI_STATUS
NetMapInsertTail (
  IN NET_MAP                *Map,
  IN VOID                   *Key,
  IN VOID                   *Value    OPTIONAL
  )
{
  NET_MAP_ITEM              *Item;

  ASSERT (Map != NULL);

  Item = NetMapAllocItem (Map);

  if (Item == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Item->Key   = Key;
  Item->Value = Value;
  NetListInsertTail (&Map->Used, &Item->Link);

  Map->Count++;

  return EFI_SUCCESS;
}


/**
  Check whther the item is in the Map

  @param  Map                   The netmap to search within
  @param  Item                  The item to search

  @return TRUE if the item is in the netmap, otherwise FALSE.

**/
STATIC
BOOLEAN
NetItemInMap (
  IN NET_MAP                *Map,
  IN NET_MAP_ITEM           *Item
  )
{
  NET_LIST_ENTRY            *ListEntry;

  NET_LIST_FOR_EACH (ListEntry, &Map->Used) {
    if (ListEntry == &Item->Link) {
      return TRUE;
    }
  }

  return FALSE;
}


/**
  Find the key in the netmap

  @param  Map                   The netmap to search within
  @param  Key                   The key to search

  @return The point to the item contains the Key, or NULL if Key isn't in the map.

**/
NET_MAP_ITEM *
NetMapFindKey (
  IN  NET_MAP               *Map,
  IN  VOID                  *Key
  )
{
  NET_LIST_ENTRY          *Entry;
  NET_MAP_ITEM            *Item;

  ASSERT (Map != NULL);

  NET_LIST_FOR_EACH (Entry, &Map->Used) {
    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);

    if (Item->Key == Key) {
      return Item;
    }
  }

  return NULL;
}


/**
  Remove the item from the netmap

  @param  Map                   The netmap to remove the item from
  @param  Item                  The item to remove
  @param  Value                 The variable to receive the value if not NULL

  @return The key of the removed item.

**/
VOID *
NetMapRemoveItem (
  IN  NET_MAP             *Map,
  IN  NET_MAP_ITEM        *Item,
  OUT VOID                **Value           OPTIONAL
  )
{
  ASSERT ((Map != NULL) && (Item != NULL));
  ASSERT (NetItemInMap (Map, Item));

  NetListRemoveEntry (&Item->Link);
  Map->Count--;
  NetListInsertHead (&Map->Recycled, &Item->Link);

  if (Value != NULL) {
    *Value = Item->Value;
  }

  return Item->Key;
}


/**
  Remove the first entry on the netmap

  @param  Map                   The netmap to remove the head from
  @param  Value                 The variable to receive the value if not NULL

  @return The key of the item removed

**/
VOID *
NetMapRemoveHead (
  IN  NET_MAP               *Map,
  OUT VOID                  **Value         OPTIONAL
  )
{
  NET_MAP_ITEM  *Item;

  //
  // Often, it indicates a programming error to remove
  // the first entry in an empty list
  //
  ASSERT (Map && !NetListIsEmpty (&Map->Used));

  Item = NET_LIST_HEAD (&Map->Used, NET_MAP_ITEM, Link);
  NetListRemoveEntry (&Item->Link);
  Map->Count--;
  NetListInsertHead (&Map->Recycled, &Item->Link);

  if (Value != NULL) {
    *Value = Item->Value;
  }

  return Item->Key;
}


/**
  Remove the last entry on the netmap

  @param  Map                   The netmap to remove the tail from
  @param  Value                 The variable to receive the value if not NULL

  @return The key of the item removed

**/
VOID *
NetMapRemoveTail (
  IN  NET_MAP               *Map,
  OUT VOID                  **Value       OPTIONAL
  )
{
  NET_MAP_ITEM              *Item;

  //
  // Often, it indicates a programming error to remove
  // the last entry in an empty list
  //
  ASSERT (Map && !NetListIsEmpty (&Map->Used));

  Item = NET_LIST_TAIL (&Map->Used, NET_MAP_ITEM, Link);
  NetListRemoveEntry (&Item->Link);
  Map->Count--;
  NetListInsertHead (&Map->Recycled, &Item->Link);

  if (Value != NULL) {
    *Value = Item->Value;
  }

  return Item->Key;
}


/**
  Iterate through the netmap and call CallBack for each item. It will
  contiue the traverse if CallBack returns EFI_SUCCESS, otherwise, break
  from the loop. It returns the CallBack's last return value. This
  function is delete safe for the current item.

  @param  Map                   The Map to iterate through
  @param  CallBack              The callback function to call for each item.
  @param  Arg                   The opaque parameter to the callback

  @return It returns the CallBack's last return value.

**/
EFI_STATUS
NetMapIterate (
  IN NET_MAP                *Map,
  IN NET_MAP_CALLBACK       CallBack,
  IN VOID                   *Arg
  )
{

  NET_LIST_ENTRY            *Entry;
  NET_LIST_ENTRY            *Next;
  NET_LIST_ENTRY            *Head;
  NET_MAP_ITEM              *Item;
  EFI_STATUS                Result;

  ASSERT ((Map != NULL) && (CallBack != NULL));

  Head = &Map->Used;

  if (NetListIsEmpty (Head)) {
    return EFI_SUCCESS;
  }

  NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {
    Item   = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);
    Result = CallBack (Map, Item, Arg);

    if (EFI_ERROR (Result)) {
      return Result;
    }
  }

  return EFI_SUCCESS;
}


/**
  This is the default unload handle for all the network drivers.

  @param  ImageHandle           The drivers' driver image.

  @retval EFI_SUCCESS           The image is unloaded.
  @retval Others                Failed to unload the image.

**/
EFI_STATUS
EFIAPI
NetLibDefaultUnload (
  IN EFI_HANDLE             ImageHandle
  )
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        *DeviceHandleBuffer;
  UINTN                             DeviceHandleCount;
  UINTN                             Index;
  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding;
  EFI_COMPONENT_NAME_PROTOCOL       *ComponentName;
  EFI_DRIVER_CONFIGURATION_PROTOCOL *DriverConfiguration;
  EFI_DRIVER_DIAGNOSTICS_PROTOCOL   *DriverDiagnostics;

  //
  // Get the list of all the handles in the handle database.
  // If there is an error getting the list, then the unload
  // operation fails.
  //
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  NULL,
                  NULL,
                  &DeviceHandleCount,
                  &DeviceHandleBuffer
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Disconnect the driver specified by ImageHandle from all
  // the devices in the handle database.
  //
  for (Index = 0; Index < DeviceHandleCount; Index++) {
    Status = gBS->DisconnectController (
                    DeviceHandleBuffer[Index],
                    ImageHandle,
                    NULL
                    );
  }

  //
  // Uninstall all the protocols installed in the driver entry point
  //
  for (Index = 0; Index < DeviceHandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    DeviceHandleBuffer[Index],
                    &gEfiDriverBindingProtocolGuid,
                    (VOID **) &DriverBinding
                    );

    if (EFI_ERROR (Status)) {
      continue;
    }

    if (DriverBinding->ImageHandle != ImageHandle) {
      continue;
    }

    gBS->UninstallProtocolInterface (
          ImageHandle,
          &gEfiDriverBindingProtocolGuid,
          DriverBinding
          );
    Status = gBS->HandleProtocol (
                    DeviceHandleBuffer[Index],
                    &gEfiComponentNameProtocolGuid,
                    (VOID **) &ComponentName
                    );
    if (!EFI_ERROR (Status)) {
      gBS->UninstallProtocolInterface (
             ImageHandle,
             &gEfiComponentNameProtocolGuid,
             ComponentName
             );
    }

    Status = gBS->HandleProtocol (
                    DeviceHandleBuffer[Index],
                    &gEfiDriverConfigurationProtocolGuid,
                    (VOID **) &DriverConfiguration
                    );

    if (!EFI_ERROR (Status)) {
      gBS->UninstallProtocolInterface (
            ImageHandle,
            &gEfiDriverConfigurationProtocolGuid,
            DriverConfiguration
            );
    }

    Status = gBS->HandleProtocol (
                    DeviceHandleBuffer[Index],
                    &gEfiDriverDiagnosticsProtocolGuid,
                    (VOID **) &DriverDiagnostics
                    );

    if (!EFI_ERROR (Status)) {
      gBS->UninstallProtocolInterface (
            ImageHandle,
            &gEfiDriverDiagnosticsProtocolGuid,
            DriverDiagnostics
            );
    }
  }

  //
  // Free the buffer containing the list of handles from the handle database
  //
  if (DeviceHandleBuffer != NULL) {
    gBS->FreePool (DeviceHandleBuffer);
  }

  return EFI_SUCCESS;
}



/**
  Create a child of the service that is identified by ServiceBindingGuid.

  @param  Controller            The controller which has the service installed.
  @param  Image                 The image handle used to open service.
  @param  ServiceBindingGuid    The service's Guid.
  @param  ChildHandle           The handle to receive the create child

  @retval EFI_SUCCESS           The child is successfully created.
  @retval Others                Failed to create the child.

**/
EFI_STATUS
NetLibCreateServiceChild (
  IN  EFI_HANDLE            Controller,
  IN  EFI_HANDLE            Image,
  IN  EFI_GUID              *ServiceBindingGuid,
  OUT EFI_HANDLE            *ChildHandle
  )
{
  EFI_STATUS                    Status;
  EFI_SERVICE_BINDING_PROTOCOL  *Service;


  ASSERT ((ServiceBindingGuid != NULL) && (ChildHandle != NULL));

  //
  // Get the ServiceBinding Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  ServiceBindingGuid,
                  (VOID **) &Service,
                  Image,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Create a child
  //
  Status = Service->CreateChild (Service, ChildHandle);
  return Status;
}


/**
  Destory a child of the service that is identified by ServiceBindingGuid.

  @param  Controller            The controller which has the service installed.
  @param  Image                 The image handle used to open service.
  @param  ServiceBindingGuid    The service's Guid.
  @param  ChildHandle           The child to destory

  @retval EFI_SUCCESS           The child is successfully destoried.
  @retval Others                Failed to destory the child.

**/
EFI_STATUS
NetLibDestroyServiceChild (
  IN  EFI_HANDLE            Controller,
  IN  EFI_HANDLE            Image,
  IN  EFI_GUID              *ServiceBindingGuid,
  IN  EFI_HANDLE            ChildHandle
  )
{
  EFI_STATUS                    Status;
  EFI_SERVICE_BINDING_PROTOCOL  *Service;

  ASSERT (ServiceBindingGuid != NULL);

  //
  // Get the ServiceBinding Protocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  ServiceBindingGuid,
                  (VOID **) &Service,
                  Image,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // destory the child
  //
  Status = Service->DestroyChild (Service, ChildHandle);
  return Status;
}


/**
  Convert the mac address of the simple network protocol installed on
  SnpHandle to a unicode string. Callers are responsible for freeing the
  string storage.

  @param  SnpHandle             The handle where the simple network protocol is
                                installed on.
  @param  ImageHandle           The image handle used to act as the agent handle to
                                get the simple network protocol.
  @param  MacString             The pointer to store the address of the string
                                representation of  the mac address.

  @retval EFI_OUT_OF_RESOURCES  There are not enough memory resource.
  @retval other                 Failed to open the simple network protocol.

**/
EFI_STATUS
NetLibGetMacString (
  IN           EFI_HANDLE  SnpHandle,
  IN           EFI_HANDLE  ImageHandle,
  IN OUT       CHAR16      **MacString
  )
{
  EFI_STATUS                   Status;
  EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;
  EFI_SIMPLE_NETWORK_MODE      *Mode;
  CHAR16                       *MacAddress;
  UINTN                        Index;

  *MacString = NULL;

  //
  // Get the Simple Network protocol from the SnpHandle.
  //
  Status = gBS->OpenProtocol (
                  SnpHandle,
                  &gEfiSimpleNetworkProtocolGuid,
                  (VOID **) &Snp,
                  ImageHandle,
                  SnpHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Mode = Snp->Mode;

  //
  // It takes 2 unicode characters to represent a 1 byte binary buffer.
  // Plus one unicode character for the null-terminator.
  //
  MacAddress = NetAllocatePool ((2 * Mode->HwAddressSize + 1) * sizeof (CHAR16));
  if (MacAddress == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Convert the mac address into a unicode string.
  //
  for (Index = 0; Index < Mode->HwAddressSize; Index++) {
    MacAddress[Index * 2]     = NibbleToHexChar ((UINT8) (Mode->CurrentAddress.Addr[Index] >> 4));
    MacAddress[Index * 2 + 1] = NibbleToHexChar (Mode->CurrentAddress.Addr[Index]);
  }

  MacAddress[Mode->HwAddressSize * 2] = L'\0';

  *MacString = MacAddress;

  return EFI_SUCCESS;
}

/**
  Check the default address used by the IPv4 driver is static or dynamic (acquired
  from DHCP).

  @param  Controller     The controller handle which has the NIC Ip4 Config Protocol
                         relative with the default address to judge.

  @retval TRUE           If the default address is static.
  @retval FALSE          If the default address is acquired from DHCP.

**/
STATIC
BOOLEAN
NetLibDefaultAddressIsStatic (
  IN EFI_HANDLE  Controller
  )
{
  EFI_STATUS                   Status;
  EFI_NIC_IP4_CONFIG_PROTOCOL  *NicIp4;
  UINTN                        Len;
  NIC_IP4_CONFIG_INFO          *ConfigInfo;
  BOOLEAN                      IsStatic;

  Status = gBS->HandleProtocol (
                  Controller,
                  &gEfiNicIp4ConfigProtocolGuid,
                  (VOID **) &NicIp4
                  );
  if (EFI_ERROR (Status)) {
    return TRUE;
  }

  Len = 0;
  Status = NicIp4->GetInfo (NicIp4, &Len, NULL);
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return TRUE;
  }

  ConfigInfo = NetAllocatePool (Len);
  if (ConfigInfo == NULL) {
    return TRUE;
  }

  IsStatic = TRUE;
  Status = NicIp4->GetInfo (NicIp4, &Len, ConfigInfo);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  IsStatic = (BOOLEAN) (ConfigInfo->Source == IP4_CONFIG_SOURCE_STATIC);

ON_EXIT:

  NetFreePool (ConfigInfo);

  return IsStatic;
}

/**
  Create an IPv4 device path node.

  @param  Node                  Pointer to the IPv4 device path node.
  @param  Controller            The handle where the NIC IP4 config protocol resides.
  @param  LocalIp               The local IPv4 address.
  @param  LocalPort             The local port.
  @param  RemoteIp              The remote IPv4 address.
  @param  RemotePort            The remote port.
  @param  Protocol              The protocol type in the IP header.
  @param  UseDefaultAddress     Whether this instance is using default address or not.

  @retval None
**/
VOID
NetLibCreateIPv4DPathNode (
  IN OUT IPv4_DEVICE_PATH  *Node,
  IN EFI_HANDLE            Controller,
  IN IP4_ADDR              LocalIp,
  IN UINT16                LocalPort,
  IN IP4_ADDR              RemoteIp,
  IN UINT16                RemotePort,
  IN UINT16                Protocol,
  IN BOOLEAN               UseDefaultAddress
  )
{
  Node->Header.Type    = MESSAGING_DEVICE_PATH;
  Node->Header.SubType = MSG_IPv4_DP;
  SetDevicePathNodeLength (&Node->Header, 19);

  NetCopyMem (&Node->LocalIpAddress, &LocalIp, sizeof (EFI_IPv4_ADDRESS));
  NetCopyMem (&Node->RemoteIpAddress, &RemoteIp, sizeof (EFI_IPv4_ADDRESS));

  Node->LocalPort  = LocalPort;
  Node->RemotePort = RemotePort;

  Node->Protocol = Protocol;

  if (!UseDefaultAddress) {
    Node->StaticIpAddress = TRUE;
  } else {
    Node->StaticIpAddress = NetLibDefaultAddressIsStatic (Controller);
  }
}


/**
  Find the UNDI/SNP handle from controller and protocol GUID.
  For example, IP will open a MNP child to transmit/receive
  packets, when MNP is stopped, IP should also be stopped. IP
  needs to find its own private data which is related the IP's
  service binding instance that is install on UNDI/SNP handle.
  Now, the controller is either a MNP or ARP child handle. But
  IP opens these handle BY_DRIVER, use that info, we can get the
  UNDI/SNP handle.

  @param  Controller            Then protocol handle to check
  @param  ProtocolGuid          The protocol that is related with the handle.

  @return The UNDI/SNP handle or NULL.

**/
EFI_HANDLE
NetLibGetNicHandle (
  IN EFI_HANDLE             Controller,
  IN EFI_GUID               *ProtocolGuid
  )
{
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenBuffer;
  EFI_HANDLE                          Handle;
  EFI_STATUS                          Status;
  UINTN                               OpenCount;
  UINTN                               Index;

  Status = gBS->OpenProtocolInformation (
                  Controller,
                  ProtocolGuid,
                  &OpenBuffer,
                  &OpenCount
                  );

  if (EFI_ERROR (Status)) {
    return NULL;
  }

  Handle = NULL;

  for (Index = 0; Index < OpenCount; Index++) {
    if (OpenBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
      Handle = OpenBuffer[Index].ControllerHandle;
      break;
    }
  }

  gBS->FreePool (OpenBuffer);
  return Handle;
}

EFI_STATUS
NetLibInstallAllDriverProtocols (
  IN EFI_HANDLE                         ImageHandle,
  IN EFI_SYSTEM_TABLE                   *SystemTable,
  IN EFI_DRIVER_BINDING_PROTOCOL        *DriverBinding,
  IN EFI_HANDLE                         DriverBindingHandle,
  IN EFI_COMPONENT_NAME_PROTOCOL        *ComponentName,       OPTIONAL
  IN EFI_DRIVER_CONFIGURATION_PROTOCOL  *DriverConfiguration, OPTIONAL
  IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL    *DriverDiagnostics    OPTIONAL
  )
/*++

Routine Description:

  Intialize a driver by installing the Driver Binding Protocol onto the
  driver's DriverBindingHandle.  This is typically the same as the driver's
  ImageHandle, but it can be different if the driver produces multiple
  DriverBinding Protocols.  This function also initializes the EFI Driver
  Library that initializes the global variables gST, gBS, gRT.

Arguments:

  ImageHandle         - The image handle of the driver
  SystemTable         - The EFI System Table that was passed to the driver's
                        entry point
  DriverBinding       - A Driver Binding Protocol instance that this driver
                        is producing.
  DriverBindingHandle - The handle that DriverBinding is to be installe onto.
                        If this parameter is NULL, then a new handle is created.
  ComponentName       - A Component Name Protocol instance that this driver is
                        producing.
  DriverConfiguration - A Driver Configuration Protocol instance that this
                        driver is producing.
  DriverDiagnostics   - A Driver Diagnostics Protocol instance that this
                        driver is producing.

Returns:

  EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle
  Otherwise, then return status from gBS->InstallProtocolInterface()

--*/
{
  return NetLibInstallAllDriverProtocolsWithUnload (
           ImageHandle,
           SystemTable,
           DriverBinding,
           DriverBindingHandle,
           ComponentName,
           DriverConfiguration,
           DriverDiagnostics,
           NetLibDefaultUnload
           );
}

EFI_STATUS
NetLibInstallAllDriverProtocolsWithUnload (
  IN EFI_HANDLE                         ImageHandle,
  IN EFI_SYSTEM_TABLE                   *SystemTable,
  IN EFI_DRIVER_BINDING_PROTOCOL        *DriverBinding,
  IN EFI_HANDLE                         DriverBindingHandle,
  IN EFI_COMPONENT_NAME_PROTOCOL        *ComponentName,       OPTIONAL
  IN EFI_DRIVER_CONFIGURATION_PROTOCOL  *DriverConfiguration,   OPTIONAL
  IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL    *DriverDiagnostics,     OPTIONAL
  IN NET_LIB_DRIVER_UNLOAD              Unload
  )
/*++

Routine Description:

  Intialize a driver by installing the Driver Binding Protocol onto the
  driver's DriverBindingHandle.  This is typically the same as the driver's
  ImageHandle, but it can be different if the driver produces multiple
  DriverBinding Protocols.  This function also initializes the EFI Driver
  Library that initializes the global variables gST, gBS, gRT.

Arguments:

  ImageHandle         - The image handle of the driver
  SystemTable         - The EFI System Table that was passed to the driver's
                        entry point
  DriverBinding       - A Driver Binding Protocol instance that this driver
                        is producing.
  DriverBindingHandle - The handle that DriverBinding is to be installe onto.
                        If this parameter is NULL, then a new handle is created.
  ComponentName       - A Component Name Protocol instance that this driver is
                        producing.
  DriverConfiguration - A Driver Configuration Protocol instance that this
                        driver is producing.
  DriverDiagnostics   - A Driver Diagnostics Protocol instance that this
                        driver is producing.
  Unload    - The customized unload to install.

Returns:

  EFI_SUCCESS if all the protocols were installed onto DriverBindingHandle
  Otherwise, then return status from gBS->InstallProtocolInterface()

--*/
{
  EFI_STATUS                Status;
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;

  Status = EfiLibInstallAllDriverProtocols (
             ImageHandle,
             SystemTable,
             DriverBinding,
             DriverBindingHandle,
             ComponentName,
             DriverConfiguration,
             DriverDiagnostics
             );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Retrieve the Loaded Image Protocol from Image Handle
  //
  Status = gBS->OpenProtocol (
                  ImageHandle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **) &LoadedImage,
                  ImageHandle,
                  ImageHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Fill in the Unload() service of the Loaded Image Protocol
  //
  LoadedImage->Unload = (Unload == NULL) ? NetLibDefaultUnload : Unload;
  return EFI_SUCCESS;
}

