/** @file
  The ICMPv6 handle routines to process the ICMPv6 control messages.

  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip6Impl.h"

EFI_IP6_ICMP_TYPE mIp6SupportedIcmp[23] = {

  {
    ICMP_V6_DEST_UNREACHABLE,
    ICMP_V6_NO_ROUTE_TO_DEST
  },
  {
    ICMP_V6_DEST_UNREACHABLE,
    ICMP_V6_COMM_PROHIBITED
  },
  {
    ICMP_V6_DEST_UNREACHABLE,
    ICMP_V6_BEYOND_SCOPE
  },
  {
    ICMP_V6_DEST_UNREACHABLE,
    ICMP_V6_ADDR_UNREACHABLE
  },
  {
    ICMP_V6_DEST_UNREACHABLE,
    ICMP_V6_PORT_UNREACHABLE
  },
  {
    ICMP_V6_DEST_UNREACHABLE,
    ICMP_V6_SOURCE_ADDR_FAILED
  },
  {
    ICMP_V6_DEST_UNREACHABLE,
    ICMP_V6_ROUTE_REJECTED
  },

  {
    ICMP_V6_PACKET_TOO_BIG,
    ICMP_V6_DEFAULT_CODE
  },

  {
    ICMP_V6_TIME_EXCEEDED,
    ICMP_V6_TIMEOUT_HOP_LIMIT
  },
  {
    ICMP_V6_TIME_EXCEEDED,
    ICMP_V6_TIMEOUT_REASSEMBLE
  },

  {
    ICMP_V6_PARAMETER_PROBLEM,
    ICMP_V6_ERRONEOUS_HEADER
  },
  {
    ICMP_V6_PARAMETER_PROBLEM,
    ICMP_V6_UNRECOGNIZE_NEXT_HDR
  },
  {
    ICMP_V6_PARAMETER_PROBLEM,
    ICMP_V6_UNRECOGNIZE_OPTION
  },

  {
    ICMP_V6_ECHO_REQUEST,
    ICMP_V6_DEFAULT_CODE
  },
  {
    ICMP_V6_ECHO_REPLY,
    ICMP_V6_DEFAULT_CODE
  },

  {
    ICMP_V6_LISTENER_QUERY,
    ICMP_V6_DEFAULT_CODE
  },
  {
    ICMP_V6_LISTENER_REPORT,
    ICMP_V6_DEFAULT_CODE
  },
  {
    ICMP_V6_LISTENER_REPORT_2,
    ICMP_V6_DEFAULT_CODE
  },
  {
    ICMP_V6_LISTENER_DONE,
    ICMP_V6_DEFAULT_CODE
  },

  {
    ICMP_V6_ROUTER_SOLICIT,
    ICMP_V6_DEFAULT_CODE
  },
  {
    ICMP_V6_ROUTER_ADVERTISE,
    ICMP_V6_DEFAULT_CODE
  },
  {
    ICMP_V6_NEIGHBOR_SOLICIT,
    ICMP_V6_DEFAULT_CODE
  },
  {
    ICMP_V6_NEIGHBOR_ADVERTISE,
    ICMP_V6_DEFAULT_CODE
  },
};

/**
  Reply an ICMPv6 echo request.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the ICMPv6 informational message.
  @param[in]  Packet             The content of the ICMPv6 message with the IP head
                                 removed.

  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
  @retval EFI_SUCCESS            Successfully answered the ICMPv6 Echo request.
  @retval Others                 Failed to answer the ICMPv6 Echo request.

**/
EFI_STATUS
Ip6IcmpReplyEcho (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_INFORMATION_HEAD *Icmp;
  NET_BUF                   *Data;
  EFI_STATUS                Status;
  EFI_IP6_HEADER            ReplyHead;

  Status = EFI_OUT_OF_RESOURCES;
  //
  // make a copy the packet, it is really a bad idea to
  // send the MNP's buffer back to MNP.
  //
  Data = NetbufDuplicate (Packet, NULL, IP6_MAX_HEADLEN);
  if (Data == NULL) {
    goto Exit;
  }

  //
  // Change the ICMP type to echo reply, exchange the source
  // and destination, then send it. The source is updated to
  // use specific destination. See RFC1122. SRR/RR option
  // update is omitted.
  //
  Icmp = (IP6_ICMP_INFORMATION_HEAD *) NetbufGetByte (Data, 0, NULL);
  if (Icmp == NULL) {
    NetbufFree (Data);
    goto Exit;
  }

  Icmp->Head.Type     = ICMP_V6_ECHO_REPLY;
  Icmp->Head.Checksum = 0;

  //
  // Generate the IPv6 basic header
  // If the Echo Reply is a response to a Echo Request sent to one of the node's unicast address,
  // the Source address of the Echo Reply must be the same address.
  //
  ZeroMem (&ReplyHead, sizeof (EFI_IP6_HEADER));

  ReplyHead.PayloadLength  = HTONS ((UINT16) (Packet->TotalSize));
  ReplyHead.NextHeader     = IP6_ICMP;
  ReplyHead.HopLimit       = IpSb->CurHopLimit;
  IP6_COPY_ADDRESS (&ReplyHead.DestinationAddress, &Head->SourceAddress);

  if (Ip6IsOneOfSetAddress (IpSb, &Head->DestinationAddress, NULL, NULL)) {
    IP6_COPY_ADDRESS (&ReplyHead.SourceAddress, &Head->DestinationAddress);
  }

  //
  // If source is unspecified, Ip6Output will select a source for us
  //
  Status = Ip6Output (
             IpSb,
             NULL,
             NULL,
             Data,
             &ReplyHead,
             NULL,
             0,
             Ip6SysPacketSent,
             NULL
             );

Exit:
  NetbufFree (Packet);
  return Status;
}

/**
  Process Packet Too Big message sent by a router in response to a packet that
  it cannot forward because the packet is larger than the MTU of outgoing link.
  Since this driver already uses IPv6 minimum link MTU as the maximum packet size,
  if Packet Too Big message is still received, do not reduce the packet size, but
  rather include a Fragment header in the subsequent packets.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the ICMPv6 error packet.
  @param[in]  Packet             The content of the ICMPv6 error with the IP head
                                 removed.

  @retval EFI_SUCCESS            The ICMPv6 error processed successfully.
  @retval EFI_OUT_OF_RESOURCES   Failed to finish the operation due to lack of
                                 resource.
  @retval EFI_NOT_FOUND          The packet too big message is not sent to us.

**/
EFI_STATUS
Ip6ProcessPacketTooBig (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_ERROR_HEAD       Icmp;
  UINT32                    Mtu;
  IP6_ROUTE_ENTRY           *RouteEntry;
  EFI_IPv6_ADDRESS          *DestAddress;

  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
  Mtu         = NTOHL (Icmp.Fourth);
  DestAddress = &Icmp.IpHead.DestinationAddress;

  if (Mtu < IP6_MIN_LINK_MTU) {
    //
    // Normally the multicast address is considered to be on-link and not recorded
    // in route table. Here it is added into the table since the MTU information
    // need be recorded.
    //
    if (IP6_IS_MULTICAST (DestAddress)) {
      RouteEntry = Ip6CreateRouteEntry (DestAddress, 128, NULL);
      if (RouteEntry == NULL) {
        NetbufFree (Packet);
        return EFI_OUT_OF_RESOURCES;
      }

      RouteEntry->Flag = IP6_DIRECT_ROUTE | IP6_PACKET_TOO_BIG;
      InsertHeadList (&IpSb->RouteTable->RouteArea[128], &RouteEntry->Link);
      IpSb->RouteTable->TotalNum++;
    } else {
      RouteEntry = Ip6FindRouteEntry (IpSb->RouteTable, DestAddress, NULL);
      if (RouteEntry == NULL) {
        NetbufFree (Packet);
        return EFI_NOT_FOUND;
      }

      RouteEntry->Flag = RouteEntry->Flag | IP6_PACKET_TOO_BIG;

      Ip6FreeRouteEntry (RouteEntry);
    }
  }

  NetbufFree (Packet);
  return EFI_SUCCESS;
}

/**
  Process the ICMPv6 error packet, and deliver the packet to upper layer.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the ICMPv6 error packet.
  @param[in]  Packet             The content of the ICMPv6 error with the IP head
                                 removed.

  @retval EFI_SUCCESS            The ICMPv6 error processed successfully.
  @retval EFI_INVALID_PARAMETER  The packet is invalid.
  @retval Others                 Failed to process the packet.

**/
EFI_STATUS
Ip6ProcessIcmpError (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_ERROR_HEAD       Icmp;

  //
  // Check the validity of the packet
  //
  if (Packet->TotalSize < sizeof (Icmp)) {
    goto DROP;
  }

  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
  if (Icmp.Head.Type == ICMP_V6_PACKET_TOO_BIG) {
    return Ip6ProcessPacketTooBig (IpSb, Head, Packet);
  }

  //
  // Notify the upper-layer process that an ICMPv6 error message is received.
  //
  IP6_GET_CLIP_INFO (Packet)->Status = EFI_ICMP_ERROR;
  return Ip6Demultiplex (IpSb, Head, Packet);

DROP:
  NetbufFree (Packet);
  Packet = NULL;
  return EFI_INVALID_PARAMETER;
}

/**
  Process the ICMPv6 informational messages. If it is an ICMPv6 echo
  request, answer it. If it is a MLD message, trigger MLD routines to
  process it. If it is a ND message, trigger ND routines to process it.
  Otherwise, deliver it to upper layer.

  @param[in]  IpSb               The IP service that receivd the packet.
  @param[in]  Head               The IP head of the ICMPv6 informational packet.
  @param[in]  Packet             The content of the ICMPv6 informational packet
                                 with IP head removed.

  @retval EFI_INVALID_PARAMETER  The packet is invalid.
  @retval EFI_SUCCESS            The ICMPv6 informational message processed.
  @retval Others                 Failed to process ICMPv6 informational message.

**/
EFI_STATUS
Ip6ProcessIcmpInformation (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_INFORMATION_HEAD Icmp;
  EFI_STATUS                Status;

  NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
  NET_CHECK_SIGNATURE (Packet, NET_BUF_SIGNATURE);
  ASSERT (Head != NULL);

  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);
  Status = EFI_INVALID_PARAMETER;

  switch (Icmp.Head.Type) {
  case ICMP_V6_ECHO_REQUEST:
    //
    // If ICMPv6 echo, reply it
    //
    if (Icmp.Head.Code == 0) {
      Status = Ip6IcmpReplyEcho (IpSb, Head, Packet);
    }
    break;
  case ICMP_V6_LISTENER_QUERY:
    Status = Ip6ProcessMldQuery (IpSb, Head, Packet);
    break;
  case ICMP_V6_LISTENER_REPORT:
  case ICMP_V6_LISTENER_REPORT_2:
    Status = Ip6ProcessMldReport (IpSb, Head, Packet);
    break;
  case ICMP_V6_NEIGHBOR_SOLICIT:
    Status = Ip6ProcessNeighborSolicit (IpSb, Head, Packet);
    break;
  case ICMP_V6_NEIGHBOR_ADVERTISE:
    Status = Ip6ProcessNeighborAdvertise (IpSb, Head, Packet);
    break;
  case ICMP_V6_ROUTER_ADVERTISE:
    Status = Ip6ProcessRouterAdvertise (IpSb, Head, Packet);
    break;
  case ICMP_V6_REDIRECT:
    Status = Ip6ProcessRedirect (IpSb, Head, Packet);
    break;
  case ICMP_V6_ECHO_REPLY:
    Status = Ip6Demultiplex (IpSb, Head, Packet);
    break;
  default:
    Status = EFI_INVALID_PARAMETER;
    break;
  }

  return Status;
}

/**
  Handle the ICMPv6 packet. First validate the message format,
  then, according to the message types, process it as an informational packet or
  an error packet.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Head               The IP head of the ICMPv6 packet.
  @param[in]  Packet             The content of the ICMPv6 packet with IP head
                                 removed.

  @retval EFI_INVALID_PARAMETER  The packet is malformatted.
  @retval EFI_SUCCESS            The ICMPv6 message successfully processed.
  @retval Others                 Failed to handle the ICMPv6 packet.

**/
EFI_STATUS
Ip6IcmpHandle (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IP6_HEADER         *Head,
  IN NET_BUF                *Packet
  )
{
  IP6_ICMP_HEAD             Icmp;
  UINT16                    PseudoCheckSum;
  UINT16                    CheckSum;

  //
  // Check the validity of the incoming packet.
  //
  if (Packet->TotalSize < sizeof (Icmp)) {
    goto DROP;
  }

  NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp);

  //
  // Make sure checksum is valid.
  //
  PseudoCheckSum = NetIp6PseudoHeadChecksum (
                     &Head->SourceAddress,
                     &Head->DestinationAddress,
                     IP6_ICMP,
                     Packet->TotalSize
                     );
  CheckSum = (UINT16) ~NetAddChecksum (PseudoCheckSum, NetbufChecksum (Packet));
  if (CheckSum != 0) {
    goto DROP;
  }

  //
  // According to the packet type, call corresponding process
  //
  if (Icmp.Type <= ICMP_V6_ERROR_MAX) {
    return Ip6ProcessIcmpError (IpSb, Head, Packet);
  } else {
    return Ip6ProcessIcmpInformation (IpSb, Head, Packet);
  }

DROP:
  NetbufFree (Packet);
  return EFI_INVALID_PARAMETER;
}

/**
  Retrieve the Prefix address according to the PrefixLength by clear the useless
  bits.

  @param[in]       PrefixLength  The prefix length of the prefix.
  @param[in, out]  Prefix        On input, points to the original prefix address
                                 with dirty bits; on output, points to the updated
                                 address with useless bit clear.

**/
VOID
Ip6GetPrefix (
  IN     UINT8              PrefixLength,
  IN OUT EFI_IPv6_ADDRESS   *Prefix
  )
{
  UINT8                     Byte;
  UINT8                     Bit;
  UINT8                     Mask;
  UINT8                     Value;

  ASSERT ((Prefix != NULL) && (PrefixLength < IP6_PREFIX_MAX));

  if (PrefixLength == 0) {
    ZeroMem (Prefix, sizeof (EFI_IPv6_ADDRESS));
    return ;
  }

  if (PrefixLength >= IP6_PREFIX_MAX) {
    return ;
  }

  Byte  = (UINT8) (PrefixLength / 8);
  Bit   = (UINT8) (PrefixLength % 8);
  Value = Prefix->Addr[Byte];

  if (Byte > 0) {
    ZeroMem (Prefix->Addr + Byte, 16 - Byte);
  }

  if (Bit > 0) {
    Mask = (UINT8) (0xFF << (8 - Bit));
    Prefix->Addr[Byte] = (UINT8) (Value & Mask);
  }

}

/**
  Check whether the DestinationAddress is an anycast address.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  DestinationAddress Points to the Destination Address of the packet.

  @retval TRUE                   The DestinationAddress is anycast address.
  @retval FALSE                  The DestinationAddress is not anycast address.

**/
BOOLEAN
Ip6IsAnycast (
  IN IP6_SERVICE            *IpSb,
  IN EFI_IPv6_ADDRESS       *DestinationAddress
  )
{
  IP6_PREFIX_LIST_ENTRY     *PrefixEntry;
  EFI_IPv6_ADDRESS          Prefix;
  BOOLEAN                   Flag;

  ZeroMem (&Prefix, sizeof (EFI_IPv6_ADDRESS));

  Flag = FALSE;

  //
  // If the address is known as on-link or autonomous prefix, record it as
  // anycast address.
  //
  do {
    PrefixEntry = Ip6FindPrefixListEntry (IpSb, Flag, 255, DestinationAddress);
    if (PrefixEntry != NULL) {
      IP6_COPY_ADDRESS (&Prefix, &PrefixEntry->Prefix);
      Ip6GetPrefix (PrefixEntry->PrefixLength, &Prefix);
      if (EFI_IP6_EQUAL (&Prefix, DestinationAddress)) {
        return TRUE;
      }
    }

    Flag = (BOOLEAN) !Flag;
  } while (Flag);

  return FALSE;
}

/**
  Generate ICMPv6 error message and send it out to DestinationAddress. Currently
  Destination Unreachable message, Time Exceeded message and Parameter Problem
  message are supported.

  @param[in]  IpSb               The IP service that received the packet.
  @param[in]  Packet             The packet which invoking ICMPv6 error.
  @param[in]  SourceAddress      If not NULL, points to the SourceAddress.
                                 Otherwise, the IP layer will select a source address
                                 according to the DestinationAddress.
  @param[in]  DestinationAddress Points to the Destination Address of the ICMPv6
                                 error message.
  @param[in]  Type               The type of the ICMPv6 message.
  @param[in]  Code               The additional level of the ICMPv6 message.
  @param[in]  Pointer            If not NULL, identifies the octet offset within
                                 the invoking packet where the error was detected.

  @retval EFI_INVALID_PARAMETER  The packet is malformatted.
  @retval EFI_OUT_OF_RESOURCES   There is no sufficient resource to complete the
                                 operation.
  @retval EFI_SUCCESS            The ICMPv6 message was successfully sent out.
  @retval Others                 Failed to generate the ICMPv6 packet.

**/
EFI_STATUS
Ip6SendIcmpError (
  IN IP6_SERVICE            *IpSb,
  IN NET_BUF                *Packet,
  IN EFI_IPv6_ADDRESS       *SourceAddress       OPTIONAL,
  IN EFI_IPv6_ADDRESS       *DestinationAddress,
  IN UINT8                  Type,
  IN UINT8                  Code,
  IN UINT32                 *Pointer             OPTIONAL
  )
{
  UINT32                    PacketLen;
  NET_BUF                   *ErrorMsg;
  UINT16                    PayloadLen;
  EFI_IP6_HEADER            Head;
  IP6_ICMP_INFORMATION_HEAD *IcmpHead;
  UINT8                     *ErrorBody;

  if (DestinationAddress == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // An ICMPv6 error message must not be originated as a result of receiving
  // a packet whose source address does not uniquely identify a single node --
  // e.g., the IPv6 Unspecified Address, an IPv6 multicast address, or an address
  // known by the ICMP message originator to be an IPv6 anycast address.
  //
  if (NetIp6IsUnspecifiedAddr (DestinationAddress) ||
      IP6_IS_MULTICAST (DestinationAddress)        ||
      Ip6IsAnycast (IpSb, DestinationAddress)
      ) {
    return EFI_INVALID_PARAMETER;
  }

  switch (Type) {
  case ICMP_V6_DEST_UNREACHABLE:
  case ICMP_V6_TIME_EXCEEDED:
    break;

  case ICMP_V6_PARAMETER_PROBLEM:
    if (Pointer == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    break;

  default:
    return EFI_INVALID_PARAMETER;
  }

  PacketLen = sizeof (IP6_ICMP_ERROR_HEAD) + Packet->TotalSize;

  if (PacketLen > IpSb->MaxPacketSize) {
    PacketLen = IpSb->MaxPacketSize;
  }

  ErrorMsg = NetbufAlloc (PacketLen);
  if (ErrorMsg == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  PayloadLen = (UINT16) (PacketLen - sizeof (EFI_IP6_HEADER));

  //
  // Create the basic IPv6 header.
  //
  ZeroMem (&Head, sizeof (EFI_IP6_HEADER));

  Head.PayloadLength  = HTONS (PayloadLen);
  Head.NextHeader     = IP6_ICMP;
  Head.HopLimit       = IpSb->CurHopLimit;

  if (SourceAddress != NULL) {
    IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress);
  } else {
    ZeroMem (&Head.SourceAddress, sizeof (EFI_IPv6_ADDRESS));
  }

  IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress);

  NetbufReserve (ErrorMsg, sizeof (EFI_IP6_HEADER));

  //
  // Fill in the ICMP error message head
  //
  IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (ErrorMsg, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE);
  if (IcmpHead == NULL) {
    NetbufFree (ErrorMsg);
    return EFI_OUT_OF_RESOURCES;
  }

  ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD));
  IcmpHead->Head.Type = Type;
  IcmpHead->Head.Code = Code;

  if (Pointer != NULL) {
    IcmpHead->Fourth = HTONL (*Pointer);
  }

  //
  // Fill in the ICMP error message body
  //
  PayloadLen -= sizeof (IP6_ICMP_INFORMATION_HEAD);
  ErrorBody =  NetbufAllocSpace (ErrorMsg, PayloadLen, FALSE);
  if (ErrorBody != NULL) {
    ZeroMem (ErrorBody, PayloadLen);
    NetbufCopy (Packet, 0, PayloadLen, ErrorBody);
  }

  //
  // Transmit the packet
  //
  return Ip6Output (IpSb, NULL, NULL, ErrorMsg, &Head, NULL, 0, Ip6SysPacketSent, NULL);
}

