/** @file
  The ICMPv6 handle routines to process the ICMPv6 control messages.

  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  
  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.

**/

#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 eror 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 malformated.
  @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 malformated.
  @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);
}

