/** @file
  The implementation of common functions shared by IP6 driver.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip6Impl.h"

/**
  Build a array of EFI_IP6_ADDRESS_INFO to be returned to the caller. The number
  of EFI_IP6_ADDRESS_INFO is also returned. If AddressList is NULL,
  only the address count is returned.

  @param[in]  IpSb              The IP6 service binding instance.
  @param[out] AddressCount      The number of returned addresses.
  @param[out] AddressList       The pointer to the array of EFI_IP6_ADDRESS_INFO.
                                This is an optional parameter.


  @retval EFI_SUCCESS           The address array successfully built.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the address info.
  @retval EFI_INVALID_PARAMETER Any input parameter is invalid.

**/
EFI_STATUS
Ip6BuildEfiAddressList (
  IN IP6_SERVICE            *IpSb,
  OUT UINT32                *AddressCount,
  OUT EFI_IP6_ADDRESS_INFO  **AddressList OPTIONAL
  )
{
  UINT32                Count;
  LIST_ENTRY            *Entry;
  EFI_IP6_ADDRESS_INFO  *EfiAddrInfo;
  IP6_ADDRESS_INFO      *AddrInfo;

  if (AddressCount == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (IpSb->LinkLocalOk) {
    Count = 1 + IpSb->DefaultInterface->AddressCount;
  } else {
    Count = 0;
  }

  *AddressCount = Count;

  if ((AddressList == NULL) || (Count == 0)) {
    return EFI_SUCCESS;
  }

  if (*AddressList == NULL) {
    *AddressList = AllocatePool (sizeof (EFI_IP6_ADDRESS_INFO) * Count);
    if (*AddressList == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  EfiAddrInfo = *AddressList;

  IP6_COPY_ADDRESS (&EfiAddrInfo->Address, &IpSb->LinkLocalAddr);
  EfiAddrInfo->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH;

  EfiAddrInfo++;
  Count = 1;

  NET_LIST_FOR_EACH (Entry, &IpSb->DefaultInterface->AddressList) {
    AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);

    IP6_COPY_ADDRESS (&EfiAddrInfo->Address, &AddrInfo->Address);
    EfiAddrInfo->PrefixLength = AddrInfo->PrefixLength;

    EfiAddrInfo++;
    Count++;
  }

  ASSERT (Count == *AddressCount);

  return EFI_SUCCESS;
}

/**
  Generate the multicast addresses identify the group of all IPv6 nodes or IPv6
  routers defined in RFC4291.

  All Nodes Addresses: FF01::1, FF02::1.
  All Router Addresses: FF01::2, FF02::2, FF05::2.

  @param[in]  Router            If TRUE, generate all routers addresses,
                                else generate all node addresses.
  @param[in]  Scope             interface-local(1), link-local(2), or site-local(5)
  @param[out] Ip6Addr           The generated multicast address.

  @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
  @retval EFI_SUCCESS           The address is generated.

**/
EFI_STATUS
Ip6SetToAllNodeMulticast (
  IN  BOOLEAN          Router,
  IN  UINT8            Scope,
  OUT EFI_IPv6_ADDRESS *Ip6Addr
  )
{
  if (Ip6Addr == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (!Router && Scope == IP6_SITE_LOCAL_SCOPE) {
    return EFI_INVALID_PARAMETER;
  }

  ZeroMem (Ip6Addr, sizeof (EFI_IPv6_ADDRESS));
  Ip6Addr->Addr[0] = 0xFF;
  Ip6Addr->Addr[1] = Scope;

  if (!Router) {
    Ip6Addr->Addr[15] = 0x1;
  } else {
    Ip6Addr->Addr[15] = 0x2;
  }

  return EFI_SUCCESS;
}

/**
  This function converts MAC address to 64 bits interface ID according to RFC4291
  and returns the interface ID. Currently only 48-bit MAC address is supported by
  this function.

  @param[in, out]  IpSb      The IP6 service binding instance.

  @retval          NULL      The operation fails.
  @return                    Pointer to the generated interface ID.

**/
UINT8 *
Ip6CreateInterfaceID (
  IN OUT IP6_SERVICE         *IpSb
  )
{
  UINT8                      InterfaceId[8];
  UINT8                      Byte;
  EFI_MAC_ADDRESS            *MacAddr;
  UINT32                     AddrLen;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  AddrLen = IpSb->SnpMode.HwAddressSize;

  //
  // Currently only IEEE 802 48-bit MACs are supported to create link local address.
  //
  if (AddrLen != IP6_MAC_LEN || IpSb->InterfaceIdLen != IP6_IF_ID_LEN) {
    return NULL;
  }

  MacAddr = &IpSb->SnpMode.CurrentAddress;

  //
  // Convert MAC address to 64 bits interface ID according to Appendix A of RFC4291:
  // 1. Insert 0xFFFE to the middle
  // 2. Invert the universal/local bit - bit 6 in network order
  //
  CopyMem (InterfaceId, MacAddr, 3);
  InterfaceId[3] = 0xFF;
  InterfaceId[4] = 0xFE;
  CopyMem (&InterfaceId[5], &MacAddr->Addr[3], 3);

  Byte = (UINT8) (InterfaceId[0] & IP6_U_BIT);
  if (Byte == IP6_U_BIT) {
    InterfaceId[0] &= ~IP6_U_BIT;
  } else {
    InterfaceId[0] |= IP6_U_BIT;
  }

  //
  // Return the interface ID.
  //
  return AllocateCopyPool (IpSb->InterfaceIdLen, InterfaceId);
}

/**
  This function creates link-local address from interface identifier. The
  interface identifier is normally created from MAC address. It might be manually
  configured by administrator if the link-local address created from MAC address
  is a duplicate address.

  @param[in, out]  IpSb      The IP6 service binding instance.

  @retval          NULL      If the operation fails.
  @return                    The generated Link Local address, in network order.

**/
EFI_IPv6_ADDRESS *
Ip6CreateLinkLocalAddr (
  IN OUT IP6_SERVICE           *IpSb
  )
{
  EFI_IPv6_ADDRESS             *Ip6Addr;
  EFI_IP6_CONFIG_PROTOCOL      *Ip6Config;
  UINTN                        DataSize;
  EFI_IP6_CONFIG_INTERFACE_ID  InterfaceId;
  EFI_STATUS                   Status;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  if (IpSb->InterfaceId != NULL) {
    FreePool (IpSb->InterfaceId);
  }

  //
  // Get the interface id if it is manually configured.
  //
  Ip6Config = &IpSb->Ip6ConfigInstance.Ip6Config;
  DataSize  = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
  ZeroMem (&InterfaceId, DataSize);

  Status = Ip6Config->GetData (
                        Ip6Config,
                        Ip6ConfigDataTypeAltInterfaceId,
                        &DataSize,
                        &InterfaceId
                        );
  if (Status == EFI_NOT_FOUND) {
    //
    // Since the interface id is not configured, generate the interface id from
    // MAC address.
    //
    IpSb->InterfaceId = Ip6CreateInterfaceID (IpSb);
    if (IpSb->InterfaceId == NULL) {
      return NULL;
    }

    CopyMem (&InterfaceId, IpSb->InterfaceId, IpSb->InterfaceIdLen);
    //
    // Record the interface id.
    //
    Status = Ip6Config->SetData (
                          Ip6Config,
                          Ip6ConfigDataTypeAltInterfaceId,
                          DataSize,
                          &InterfaceId
                          );
    if (EFI_ERROR (Status)) {
      FreePool (IpSb->InterfaceId);
      IpSb->InterfaceId = NULL;
      return NULL;
    }
  } else if (!EFI_ERROR (Status)) {
    IpSb->InterfaceId = AllocateCopyPool (DataSize, &InterfaceId);
    if (IpSb->InterfaceId == NULL) {
      return NULL;
    }
  } else {
    return NULL;
  }

  //
  // Append FE80::/64 to the left of IPv6 address then return.
  //
  Ip6Addr = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));
  if (Ip6Addr == NULL) {
    FreePool (IpSb->InterfaceId);
    IpSb->InterfaceId = NULL;
    return NULL;
  }

  CopyMem (&Ip6Addr->Addr[8], IpSb->InterfaceId, IpSb->InterfaceIdLen);
  Ip6Addr->Addr[1] = 0x80;
  Ip6Addr->Addr[0] = 0xFE;

  return Ip6Addr;
}

/**
  Compute the solicited-node multicast address for an unicast or anycast address,
  by taking the low-order 24 bits of this address, and appending those bits to
  the prefix FF02:0:0:0:0:1:FF00::/104.

  @param[in]  Ip6Addr               The unicast or anycast address, in network order.
  @param[out] MulticastAddr         The generated solicited-node multicast address,
                                    in network order.

**/
VOID
Ip6CreateSNMulticastAddr (
  IN EFI_IPv6_ADDRESS  *Ip6Addr,
  OUT EFI_IPv6_ADDRESS *MulticastAddr
  )
{
  ASSERT (Ip6Addr != NULL && MulticastAddr != NULL);

  ZeroMem (MulticastAddr, sizeof (EFI_IPv6_ADDRESS));

  MulticastAddr->Addr[0]  = 0xFF;
  MulticastAddr->Addr[1]  = 0x02;
  MulticastAddr->Addr[11] = 0x1;
  MulticastAddr->Addr[12] = 0xFF;

  CopyMem (&MulticastAddr->Addr[13], &Ip6Addr->Addr[13], 3);
}

/**
  Insert a node IP6_ADDRESS_INFO to an IP6 interface.

  @param[in, out]  IpIf             Points to an IP6 interface.
  @param[in]       AddrInfo         Points to IP6_ADDRESS_INFO

**/
VOID
Ip6AddAddr (
  IN OUT IP6_INTERFACE *IpIf,
  IN IP6_ADDRESS_INFO  *AddrInfo
  )
{
  InsertHeadList (&IpIf->AddressList, &AddrInfo->Link);
  IpIf->AddressCount++;
}

/**
  Callback function which provided by user to remove one node in NetDestroyLinkList process.

  @param[in]    Entry           The entry to be removed.
  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.

  @retval EFI_SUCCESS           The entry has been removed successfully.
  @retval Others                Fail to remove the entry.

**/
EFI_STATUS
EFIAPI
Ip6DestroyChildEntryByAddr (
  IN LIST_ENTRY         *Entry,
  IN VOID               *Context
  )
{
  IP6_PROTOCOL                  *Instance;
  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;
  EFI_IPv6_ADDRESS              *Address;

  Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
  ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding;
  Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address;

  if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
    return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
  }

  return EFI_SUCCESS;
}

/**
  Destroy the IP instance if its StationAddress is removed. It is the help function
  for Ip6RemoveAddr().

  @param[in, out]  IpSb             Points to an IP6 service binding instance.
  @param[in]       Address          The to be removed address

**/
VOID
Ip6DestroyInstanceByAddress (
  IN OUT IP6_SERVICE   *IpSb,
  IN EFI_IPv6_ADDRESS  *Address
  )
{
  LIST_ENTRY                    *List;
  IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT  Context;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);

  List = &IpSb->Children;
  Context.ServiceBinding = &IpSb->ServiceBinding;
  Context.Address = Address;
  NetDestroyLinkList (
    List,
    Ip6DestroyChildEntryByAddr,
    &Context,
    NULL
    );
}

/**
  Remove the IPv6 address from the address list node points to IP6_ADDRESS_INFO.

  This function removes the matching IPv6 addresses from the address list and
  adjusts the address count of the address list. If IpSb is not NULL, this function
  calls Ip6LeaveGroup to see whether it should call Mnp->Groups() to remove the
  its solicited-node multicast MAC address from the filter list and sends out
  a Multicast Listener Done. If Prefix is NULL, all address in the address list
  will be removed. If Prefix is not NULL, the address that matching the Prefix
  with PrefixLength in the address list will be removed.

  @param[in]       IpSb             NULL or points to IP6 service binding instance.
  @param[in, out]  AddressList      Address list array.
  @param[in, out]  AddressCount     The count of addresses in address list array.
  @param[in]       Prefix           NULL or an IPv6 address prefix.
  @param[in]       PrefixLength     The length of Prefix.

  @retval    EFI_SUCCESS            The operation completed successfully.
  @retval    EFI_NOT_FOUND          The address matching the Prefix with PrefixLength
                                    cannot be found in the address list.
  @retval    EFI_INVALID_PARAMETER  Any input parameter is invalid.

**/
EFI_STATUS
Ip6RemoveAddr (
  IN IP6_SERVICE       *IpSb          OPTIONAL,
  IN OUT LIST_ENTRY    *AddressList,
  IN OUT UINT32        *AddressCount,
  IN EFI_IPv6_ADDRESS  *Prefix        OPTIONAL,
  IN UINT8             PrefixLength
  )
{
  EFI_STATUS           Status;
  LIST_ENTRY           *Entry;
  LIST_ENTRY           *Next;
  IP6_ADDRESS_INFO     *AddrInfo;
  EFI_IPv6_ADDRESS     SnMCastAddr;

  if (IsListEmpty (AddressList) || *AddressCount < 1 || PrefixLength > IP6_PREFIX_MAX) {
    return EFI_INVALID_PARAMETER;
  }

  Status = EFI_NOT_FOUND;

  NET_LIST_FOR_EACH_SAFE (Entry, Next, AddressList) {
    AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);

    if (Prefix == NULL ||
        (PrefixLength == 128 && EFI_IP6_EQUAL (Prefix, &AddrInfo->Address)) ||
        (PrefixLength == AddrInfo->PrefixLength && NetIp6IsNetEqual (Prefix, &AddrInfo->Address, PrefixLength))
        ) {
      if (IpSb != NULL) {
        NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
        Ip6CreateSNMulticastAddr (&AddrInfo->Address, &SnMCastAddr);
        Ip6LeaveGroup (IpSb, &SnMCastAddr);

        //
        // Destroy any instance who is using the dying address as the source address.
        //
        Ip6DestroyInstanceByAddress (IpSb, &AddrInfo->Address);
      }

      RemoveEntryList (Entry);
      FreePool (AddrInfo);
      (*AddressCount)--;

      Status = EFI_SUCCESS;
    }
  }

  return Status;
}

/**
  Check whether the incoming Ipv6 address is a solicited-node multicast address.

  @param[in]  Ip6               Ip6 address, in network order.

  @retval TRUE                  Yes, solicited-node multicast address
  @retval FALSE                 No

**/
BOOLEAN
Ip6IsSNMulticastAddr (
  IN EFI_IPv6_ADDRESS *Ip6
  )
{
  EFI_IPv6_ADDRESS    Sn;
  BOOLEAN             Flag;

  Ip6CreateSNMulticastAddr (Ip6, &Sn);
  Flag = FALSE;

  if (CompareMem (Sn.Addr, Ip6->Addr, 13) == 0) {
    Flag = TRUE;
  }

  return Flag;
}

/**
  Check whether the incoming IPv6 address is one of the maintained addresses in
  the IP6 service binding instance.

  @param[in]  IpSb              Points to a IP6 service binding instance.
  @param[in]  Address           The IP6 address to be checked.
  @param[out] Interface         If not NULL, output the IP6 interface which
                                maintains the Address.
  @param[out] AddressInfo       If not NULL, output the IP6 address information
                                of the Address.

  @retval TRUE                  Yes, it is one of the maintained address.
  @retval FALSE                 No, it is not one of the maintained address.

**/
BOOLEAN
Ip6IsOneOfSetAddress (
  IN  IP6_SERVICE           *IpSb,
  IN  EFI_IPv6_ADDRESS      *Address,
  OUT IP6_INTERFACE         **Interface   OPTIONAL,
  OUT IP6_ADDRESS_INFO      **AddressInfo OPTIONAL
  )
{
  LIST_ENTRY                *Entry;
  LIST_ENTRY                *Entry2;
  IP6_INTERFACE             *IpIf;
  IP6_ADDRESS_INFO          *TmpAddressInfo;

  //
  // Check link-local address first
  //
  if (IpSb->LinkLocalOk && EFI_IP6_EQUAL (&IpSb->LinkLocalAddr, Address)) {
    if (Interface != NULL) {
      *Interface = IpSb->DefaultInterface;
    }

    if (AddressInfo != NULL) {
      *AddressInfo = NULL;
    }

    return TRUE;
  }

  NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
    IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);

    NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
      TmpAddressInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);

      if (EFI_IP6_EQUAL (&TmpAddressInfo->Address, Address)) {
        if (Interface != NULL) {
          *Interface = IpIf;
        }

        if (AddressInfo != NULL) {
          *AddressInfo = TmpAddressInfo;
        }

        return TRUE;
      }
    }
  }

  return FALSE;
}

/**
  Check whether the incoming MAC address is valid.

  @param[in]  IpSb              Points to a IP6 service binding instance.
  @param[in]  LinkAddress       The MAC address.

  @retval TRUE                  Yes, it is valid.
  @retval FALSE                 No, it is not valid.

**/
BOOLEAN
Ip6IsValidLinkAddress (
  IN  IP6_SERVICE      *IpSb,
  IN  EFI_MAC_ADDRESS  *LinkAddress
  )
{
  UINT32               Index;

  //
  // TODO: might be updated later to be more acceptable.
  //
  for (Index = IpSb->SnpMode.HwAddressSize; Index < sizeof (EFI_MAC_ADDRESS); Index++) {
    if (LinkAddress->Addr[Index] != 0) {
      return FALSE;
    }
  }

  return TRUE;
}

/**
  Copy the PrefixLength bits from Src to Dest.

  @param[out] Dest              A pointer to the buffer to copy to.
  @param[in]  Src               A pointer to the buffer to copy from.
  @param[in]  PrefixLength      The number of bits to copy.

**/
VOID
Ip6CopyAddressByPrefix (
  OUT EFI_IPv6_ADDRESS *Dest,
  IN  EFI_IPv6_ADDRESS *Src,
  IN  UINT8            PrefixLength
  )
{
  UINT8 Byte;
  UINT8 Bit;
  UINT8 Mask;

  ASSERT (Dest != NULL && Src != NULL);
  ASSERT (PrefixLength <= IP6_PREFIX_MAX);

  Byte = (UINT8) (PrefixLength / 8);
  Bit  = (UINT8) (PrefixLength % 8);

  ZeroMem (Dest, sizeof (EFI_IPv6_ADDRESS));

  CopyMem (Dest, Src, Byte);

  if (Bit > 0) {
    Mask = (UINT8) (0xFF << (8 - Bit));
    ASSERT (Byte < 16);
    Dest->Addr[Byte] = (UINT8) (Src->Addr[Byte] & Mask);
  }
}

/**
  Get the MAC address for a multicast IP address. Call
  Mnp's McastIpToMac to find the MAC address instead of
  hard-coding the NIC to be Ethernet.

  @param[in]  Mnp                   The Mnp instance to get the MAC address.
  @param[in]  Multicast             The multicast IP address to translate.
  @param[out] Mac                   The buffer to hold the translated address.

  @retval EFI_SUCCESS               The multicast IP successfully
                                    translated to a multicast MAC address.
  @retval Other                     The address is not converted because an error occurred.

**/
EFI_STATUS
Ip6GetMulticastMac (
  IN  EFI_MANAGED_NETWORK_PROTOCOL *Mnp,
  IN  EFI_IPv6_ADDRESS             *Multicast,
  OUT EFI_MAC_ADDRESS              *Mac
  )
{
  EFI_IP_ADDRESS        EfiIp;

  IP6_COPY_ADDRESS (&EfiIp.v6, Multicast);

  return Mnp->McastIpToMac (Mnp, TRUE, &EfiIp, Mac);
}

/**
  Convert the multibyte field in IP header's byter order.
  In spite of its name, it can also be used to convert from
  host to network byte order.

  @param[in, out]  Head                  The IP head to convert.

  @return Point to the converted IP head.

**/
EFI_IP6_HEADER *
Ip6NtohHead (
  IN OUT EFI_IP6_HEADER *Head
  )
{
  Head->FlowLabelL    = NTOHS (Head->FlowLabelL);
  Head->PayloadLength = NTOHS (Head->PayloadLength);

  return Head;
}

