/** @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;
}
