/** @file
  IP6 option support functions and routines.

  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip6Impl.h"

/**
  Validate the IP6 option format for both the packets we received
  and that we will transmit. It will compute the ICMPv6 error message fields
  if the option is malformatted.

  @param[in]  IpSb              The IP6 service data.
  @param[in]  Packet            The to be validated packet.
  @param[in]  Option            The first byte of the option.
  @param[in]  OptionLen         The length of the whole option.
  @param[in]  Pointer           Identifies the octet offset within
                                the invoking packet where the error was detected.


  @retval TRUE     The option is properly formatted.
  @retval FALSE    The option is malformatted.

**/
BOOLEAN
Ip6IsOptionValid (
  IN IP6_SERVICE  *IpSb,
  IN NET_BUF      *Packet,
  IN UINT8        *Option,
  IN UINT8        OptionLen,
  IN UINT32       Pointer
  )
{
  UINT8  Offset;
  UINT8  OptionType;

  Offset = 0;

  while (Offset < OptionLen) {
    OptionType = *(Option + Offset);

    switch (OptionType) {
      case Ip6OptionPad1:
        //
        // It is a Pad1 option
        //
        Offset++;
        break;
      case Ip6OptionPadN:
        //
        // It is a PadN option
        //
        Offset = (UINT8)(Offset + *(Option + Offset + 1) + 2);
        break;
      case Ip6OptionRouterAlert:
        //
        // It is a Router Alert Option
        //
        Offset += 4;
        break;
      default:
        //
        // The highest-order two bits specify the action must be taken if
        // the processing IPv6 node does not recognize the option type.
        //
        switch (OptionType & Ip6OptionMask) {
          case Ip6OptionSkip:
            Offset = (UINT8)(Offset + *(Option + Offset + 1));
            break;
          case Ip6OptionDiscard:
            return FALSE;
          case Ip6OptionParameterProblem:
            Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER);
            Ip6SendIcmpError (
              IpSb,
              Packet,
              NULL,
              &Packet->Ip.Ip6->SourceAddress,
              ICMP_V6_PARAMETER_PROBLEM,
              2,
              &Pointer
              );
            return FALSE;
          case Ip6OptionMask:
            if (!IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) {
              Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER);
              Ip6SendIcmpError (
                IpSb,
                Packet,
                NULL,
                &Packet->Ip.Ip6->SourceAddress,
                ICMP_V6_PARAMETER_PROBLEM,
                2,
                &Pointer
                );
            }

            return FALSE;
            break;
        }

        break;
    }
  }

  return TRUE;
}

/**
  Validate the IP6 option format for both the packets we received
  and that we will transmit. It supports the defined options in Neighbor
  Discovery messages.

  @param[in]  Option            The first byte of the option.
  @param[in]  OptionLen         The length of the whole option.

  @retval TRUE     The option is properly formatted.
  @retval FALSE    The option is malformatted.

**/
BOOLEAN
Ip6IsNDOptionValid (
  IN UINT8   *Option,
  IN UINT16  OptionLen
  )
{
  UINT32             Offset;
  UINT16             Length;
  IP6_OPTION_HEADER  *OptionHeader;

  if (Option == NULL) {
    ASSERT (Option != NULL);
    return FALSE;
  }

  Offset = 0;

  //
  // RFC 4861 states that Neighbor Discovery packet can contain zero or more
  // options. Start processing the options if at least Type + Length fields
  // fit within the input buffer.
  //
  while (Offset + sizeof (IP6_OPTION_HEADER) - 1 < OptionLen) {
    OptionHeader = (IP6_OPTION_HEADER *)(Option + Offset);
    Length       = (UINT16)OptionHeader->Length * 8;

    switch (OptionHeader->Type) {
      case Ip6OptionPrefixInfo:
        if (Length != 32) {
          return FALSE;
        }

        break;

      case Ip6OptionMtu:
        if (Length != 8) {
          return FALSE;
        }

        break;

      default:
        // RFC 4861 states that Length field cannot be 0.
        if (Length == 0) {
          return FALSE;
        }

        break;
    }

    //
    // Check whether recognized options are within the input buffer's scope.
    //
    switch (OptionHeader->Type) {
      case Ip6OptionEtherSource:
      case Ip6OptionEtherTarget:
      case Ip6OptionPrefixInfo:
      case Ip6OptionRedirected:
      case Ip6OptionMtu:
        if (Offset + Length > (UINT32)OptionLen) {
          return FALSE;
        }

        break;

      default:
        //
        // Unrecognized options can be either valid (but unused) or invalid
        // (garbage in between or right after valid options). Silently ignore.
        //
        break;
    }

    //
    // Advance to the next option.
    // Length already considers option header's Type + Length.
    //
    Offset += Length;
  }

  return TRUE;
}

/**
  Validate whether the NextHeader is a known valid protocol or one of the user configured
  protocols from the upper layer.

  @param[in]  IpSb          The IP6 service instance.
  @param[in]  NextHeader    The next header field.

  @retval TRUE              The NextHeader is a known valid protocol or user configured.
  @retval FALSE             The NextHeader is not a known valid protocol.

**/
BOOLEAN
Ip6IsValidProtocol (
  IN IP6_SERVICE  *IpSb,
  IN UINT8        NextHeader
  )
{
  LIST_ENTRY    *Entry;
  IP6_PROTOCOL  *IpInstance;

  if ((NextHeader == EFI_IP_PROTO_TCP) ||
      (NextHeader == EFI_IP_PROTO_UDP) ||
      (NextHeader == IP6_ICMP) ||
      (NextHeader == IP6_ESP)
      )
  {
    return TRUE;
  }

  if (IpSb == NULL) {
    return FALSE;
  }

  if (IpSb->Signature != IP6_SERVICE_SIGNATURE) {
    return FALSE;
  }

  NET_LIST_FOR_EACH (Entry, &IpSb->Children) {
    IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
    if (IpInstance->State == IP6_STATE_CONFIGED) {
      if (IpInstance->ConfigData.DefaultProtocol == NextHeader) {
        return TRUE;
      }
    }
  }

  return FALSE;
}

/**
  Validate the IP6 extension header format for both the packets we received
  and that we will transmit. It will compute the ICMPv6 error message fields
  if the option is mal-formatted.

  @param[in]  IpSb          The IP6 service instance. This is an optional parameter.
  @param[in]  Packet        The data of the packet. Ignored if NULL.
  @param[in]  NextHeader    The next header field in IPv6 basic header.
  @param[in]  ExtHdrs       The first byte of the option.
  @param[in]  ExtHdrsLen    The length of the whole option.
  @param[in]  Rcvd          The option is from the packet we received if TRUE,
                            otherwise, the option we want to transmit.
  @param[out] FormerHeader  The offset of NextHeader which points to Fragment
                            Header when we received, of the ExtHdrs.
                            Ignored if we transmit.
  @param[out] LastHeader    The pointer of NextHeader of the last extension
                            header processed by IP6.
  @param[out] RealExtsLen   The length of extension headers processed by IP6 layer.
                            This is an optional parameter that may be NULL.
  @param[out] UnFragmentLen The length of unfragmented length of extension headers.
                            This is an optional parameter that may be NULL.
  @param[out] Fragmented    Indicate whether the packet is fragmented.
                            This is an optional parameter that may be NULL.

  @retval     TRUE          The option is properly formatted.
  @retval     FALSE         The option is malformatted.

**/
BOOLEAN
Ip6IsExtsValid (
  IN IP6_SERVICE  *IpSb           OPTIONAL,
  IN NET_BUF      *Packet         OPTIONAL,
  IN UINT8        *NextHeader,
  IN UINT8        *ExtHdrs,
  IN UINT32       ExtHdrsLen,
  IN BOOLEAN      Rcvd,
  OUT UINT32      *FormerHeader   OPTIONAL,
  OUT UINT8       **LastHeader,
  OUT UINT32      *RealExtsLen    OPTIONAL,
  OUT UINT32      *UnFragmentLen  OPTIONAL,
  OUT BOOLEAN     *Fragmented     OPTIONAL
  )
{
  UINT32               Pointer;
  UINT32               Offset;
  UINT8                *Option;
  UINT8                OptionLen;
  BOOLEAN              Flag;
  UINT8                CountD;
  UINT8                CountA;
  IP6_FRAGMENT_HEADER  *FragmentHead;
  UINT16               FragmentOffset;
  IP6_ROUTING_HEADER   *RoutingHead;

  if (RealExtsLen != NULL) {
    *RealExtsLen = 0;
  }

  if (UnFragmentLen != NULL) {
    *UnFragmentLen = 0;
  }

  if (Fragmented != NULL) {
    *Fragmented = FALSE;
  }

  *LastHeader = NextHeader;

  if ((ExtHdrs == NULL) && (ExtHdrsLen == 0)) {
    return TRUE;
  }

  if (((ExtHdrs == NULL) && (ExtHdrsLen != 0)) || ((ExtHdrs != NULL) && (ExtHdrsLen == 0))) {
    return FALSE;
  }

  Pointer = 0;
  Offset  = 0;
  Flag    = FALSE;
  CountD  = 0;
  CountA  = 0;

  while (Offset <= ExtHdrsLen) {
    switch (*NextHeader) {
      case IP6_HOP_BY_HOP:
        if (Offset != 0) {
          if (!Rcvd) {
            return FALSE;
          }

          //
          // Hop-by-Hop Options header is restricted to appear immediately after an IPv6 header only.
          // If not, generate a ICMP parameter problem message with code value of 1.
          //
          if (Pointer == 0) {
            Pointer = sizeof (EFI_IP6_HEADER);
          } else {
            Pointer = Offset + sizeof (EFI_IP6_HEADER);
          }

          if ((IpSb != NULL) && (Packet != NULL) &&
              !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))
          {
            Ip6SendIcmpError (
              IpSb,
              Packet,
              NULL,
              &Packet->Ip.Ip6->SourceAddress,
              ICMP_V6_PARAMETER_PROBLEM,
              1,
              &Pointer
              );
          }

          return FALSE;
        }

        Flag = TRUE;

      //
      // Fall through
      //
      case IP6_DESTINATION:
        if (*NextHeader == IP6_DESTINATION) {
          CountD++;
        }

        if (CountD > 2) {
          return FALSE;
        }

        NextHeader = ExtHdrs + Offset;
        Pointer    = Offset;

        Offset++;
        Option    = ExtHdrs + Offset;
        OptionLen = (UINT8)((*Option + 1) * 8 - 2);
        Option++;
        Offset++;

        if ((IpSb != NULL) && (Packet != NULL) && !Ip6IsOptionValid (IpSb, Packet, Option, OptionLen, Offset)) {
          return FALSE;
        }

        Offset = Offset + OptionLen;

        if (Flag) {
          if (UnFragmentLen != NULL) {
            *UnFragmentLen = Offset;
          }

          Flag = FALSE;
        }

        break;

      case IP6_ROUTING:
        NextHeader  = ExtHdrs + Offset;
        RoutingHead = (IP6_ROUTING_HEADER *)NextHeader;

        //
        // Type 0 routing header is defined in RFC2460 and deprecated in RFC5095.
        // Thus all routing types are processed as unrecognized.
        //
        if (RoutingHead->SegmentsLeft == 0) {
          //
          // Ignore the routing header and proceed to process the next header.
          //
          Offset = Offset + (RoutingHead->HeaderLen + 1) * 8;

          if (UnFragmentLen != NULL) {
            *UnFragmentLen = Offset;
          }
        } else {
          //
          // Discard the packet and send an ICMP Parameter Problem, Code 0, message
          // to the packet's source address, pointing to the unrecognized routing
          // type.
          //
          Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER);
          if ((IpSb != NULL) && (Packet != NULL) &&
              !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))
          {
            Ip6SendIcmpError (
              IpSb,
              Packet,
              NULL,
              &Packet->Ip.Ip6->SourceAddress,
              ICMP_V6_PARAMETER_PROBLEM,
              0,
              &Pointer
              );
          }

          return FALSE;
        }

        break;

      case IP6_FRAGMENT:

        //
        // RFC2402, AH header should after fragment header.
        //
        if (CountA > 1) {
          return FALSE;
        }

        //
        // RFC2460, ICMP Parameter Problem message with code 0 should be sent
        // if the length of a fragment is not a multiple of 8 octets and the M
        // flag of that fragment is 1, pointing to the Payload length field of the
        // fragment packet.
        //
        if ((IpSb != NULL) && (Packet != NULL) && ((ExtHdrsLen % 8) != 0)) {
          //
          // Check whether it is the last fragment.
          //
          FragmentHead = (IP6_FRAGMENT_HEADER *)(ExtHdrs + Offset);
          if (FragmentHead == NULL) {
            return FALSE;
          }

          FragmentOffset = NTOHS (FragmentHead->FragmentOffset);

          if (((FragmentOffset & 0x1) == 0x1) &&
              !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))
          {
            Pointer = sizeof (UINT32);
            Ip6SendIcmpError (
              IpSb,
              Packet,
              NULL,
              &Packet->Ip.Ip6->SourceAddress,
              ICMP_V6_PARAMETER_PROBLEM,
              0,
              &Pointer
              );
            return FALSE;
          }
        }

        if (Fragmented != NULL) {
          *Fragmented = TRUE;
        }

        if (Rcvd && (FormerHeader != NULL)) {
          *FormerHeader = (UINT32)(NextHeader - ExtHdrs);
        }

        NextHeader = ExtHdrs + Offset;
        Offset     = Offset + 8;
        break;

      case IP6_AH:
        if (++CountA > 1) {
          return FALSE;
        }

        Option     = ExtHdrs + Offset;
        NextHeader = Option;
        Option++;
        //
        // RFC2402, Payload length is specified in 32-bit words, minus "2".
        //
        OptionLen = (UINT8)((*Option + 2) * 4);
        Offset    = Offset + OptionLen;
        break;

      case IP6_NO_NEXT_HEADER:
        *LastHeader = NextHeader;
        return FALSE;
        break;

      default:
        if (Ip6IsValidProtocol (IpSb, *NextHeader)) {
          *LastHeader = NextHeader;

          if (RealExtsLen != NULL) {
            *RealExtsLen = Offset;
          }

          return TRUE;
        }

        //
        // The Next Header value is unrecognized by the node, discard the packet and
        // send an ICMP parameter problem message with code value of 1.
        //
        if (Offset == 0) {
          //
          // The Next Header directly follows IPv6 basic header.
          //
          Pointer = 6;
        } else {
          if (Pointer == 0) {
            Pointer = sizeof (EFI_IP6_HEADER);
          } else {
            Pointer = Offset + sizeof (EFI_IP6_HEADER);
          }
        }

        if ((IpSb != NULL) && (Packet != NULL) &&
            !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress))
        {
          Ip6SendIcmpError (
            IpSb,
            Packet,
            NULL,
            &Packet->Ip.Ip6->SourceAddress,
            ICMP_V6_PARAMETER_PROBLEM,
            1,
            &Pointer
            );
        }

        return FALSE;
    }
  }

  *LastHeader = NextHeader;

  if (RealExtsLen != NULL) {
    *RealExtsLen = Offset;
  }

  return TRUE;
}

/**
  Generate an IPv6 router alert option in network order and output it through Buffer.

  @param[out]     Buffer         Points to a buffer to record the generated option.
  @param[in, out] BufferLen      The length of Buffer, in bytes.
  @param[in]      NextHeader     The 8-bit selector indicates the type of header
                                 immediately following the Hop-by-Hop Options header.

  @retval EFI_BUFFER_TOO_SMALL   The Buffer is too small to contain the generated
                                 option. BufferLen is updated for the required size.

  @retval EFI_SUCCESS            The option is generated and filled in to Buffer.

**/
EFI_STATUS
Ip6FillHopByHop (
  OUT UINT8     *Buffer,
  IN OUT UINTN  *BufferLen,
  IN UINT8      NextHeader
  )
{
  UINT8  BufferArray[8];

  if (*BufferLen < 8) {
    *BufferLen = 8;
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Form the Hop-By-Hop option in network order.
  // NextHeader (1 octet) + HdrExtLen (1 octet) + RouterAlertOption(4 octets) + PadN
  // The Hdr Ext Len is the length in 8-octet units, and does not including the first 8 octets.
  //
  ZeroMem (BufferArray, sizeof (BufferArray));
  BufferArray[0] = NextHeader;
  BufferArray[2] = 0x5;
  BufferArray[3] = 0x2;
  BufferArray[6] = 1;

  CopyMem (Buffer, BufferArray, sizeof (BufferArray));
  return EFI_SUCCESS;
}

/**
  Insert a Fragment Header to the Extension headers and output it in UpdatedExtHdrs.

  @param[in]  IpSb             The IP6 service instance to transmit the packet.
  @param[in]  NextHeader       The extension header type of first extension header.
  @param[in]  LastHeader       The extension header type of last extension header.
  @param[in]  ExtHdrs          The length of the original extension header.
  @param[in]  ExtHdrsLen       The length of the extension headers.
  @param[in]  FragmentOffset   The fragment offset of the data following the header.
  @param[out] UpdatedExtHdrs   The updated ExtHdrs with Fragment header inserted.
                               It's caller's responsibility to free this buffer.

  @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lake of
                               resource.
  @retval EFI_UNSUPPORTED      The extension header specified in ExtHdrs is not
                               supported currently.
  @retval EFI_SUCCESS          The operation performed successfully.

**/
EFI_STATUS
Ip6FillFragmentHeader (
  IN  IP6_SERVICE  *IpSb,
  IN  UINT8        NextHeader,
  IN  UINT8        LastHeader,
  IN  UINT8        *ExtHdrs,
  IN  UINT32       ExtHdrsLen,
  IN  UINT16       FragmentOffset,
  OUT UINT8        **UpdatedExtHdrs
  )
{
  UINT32               Length;
  UINT8                *Buffer;
  UINT32               FormerHeader;
  UINT32               Offset;
  UINT32               Part1Len;
  UINT32               HeaderLen;
  UINT8                Current;
  IP6_FRAGMENT_HEADER  FragmentHead;

  if (UpdatedExtHdrs == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Length = ExtHdrsLen + sizeof (IP6_FRAGMENT_HEADER);
  Buffer = AllocatePool (Length);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Offset       = 0;
  Part1Len     = 0;
  FormerHeader = 0;
  Current      = NextHeader;

  while ((ExtHdrs != NULL) && (Offset <= ExtHdrsLen)) {
    switch (NextHeader) {
      case IP6_ROUTING:
      case IP6_HOP_BY_HOP:
      case IP6_DESTINATION:
        Current    = NextHeader;
        NextHeader = *(ExtHdrs + Offset);

        if ((Current == IP6_DESTINATION) && (NextHeader != IP6_ROUTING)) {
          //
          // Destination Options header should occur at most twice, once before
          // a Routing header and once before the upper-layer header. Here we
          // find the one before the upper-layer header. Insert the Fragment
          // Header before it.
          //
          CopyMem (Buffer, ExtHdrs, Part1Len);
          *(Buffer + FormerHeader) = IP6_FRAGMENT;
          //
          // Exit the loop.
          //
          Offset = ExtHdrsLen + 1;
          break;
        }

        FormerHeader = Offset;
        HeaderLen    = (*(ExtHdrs + Offset + 1) + 1) * 8;
        Part1Len     = Part1Len + HeaderLen;
        Offset       = Offset + HeaderLen;
        break;

      case IP6_FRAGMENT:
        Current = NextHeader;

        if (Part1Len != 0) {
          CopyMem (Buffer, ExtHdrs, Part1Len);
        }

        *(Buffer + FormerHeader) = IP6_FRAGMENT;

        //
        // Exit the loop.
        //
        Offset = ExtHdrsLen + 1;
        break;

      case IP6_AH:
        Current    = NextHeader;
        NextHeader = *(ExtHdrs + Offset);
        //
        // RFC2402, Payload length is specified in 32-bit words, minus "2".
        //
        HeaderLen = (*(ExtHdrs + Offset + 1) + 2) * 4;
        Part1Len  = Part1Len + HeaderLen;
        Offset    = Offset + HeaderLen;
        break;

      default:
        if (Ip6IsValidProtocol (IpSb, NextHeader)) {
          Current = NextHeader;
          CopyMem (Buffer, ExtHdrs, Part1Len);
          *(Buffer + FormerHeader) = IP6_FRAGMENT;
          //
          // Exit the loop.
          //
          Offset = ExtHdrsLen + 1;
          break;
        }

        FreePool (Buffer);
        return EFI_UNSUPPORTED;
    }
  }

  //
  // Append the Fragment header. If the fragment offset indicates the fragment
  // is the first fragment.
  //
  if ((FragmentOffset & IP6_FRAGMENT_OFFSET_MASK) == 0) {
    FragmentHead.NextHeader = Current;
  } else {
    FragmentHead.NextHeader = LastHeader;
  }

  FragmentHead.Reserved       = 0;
  FragmentHead.FragmentOffset = HTONS (FragmentOffset);
  FragmentHead.Identification = mIp6Id;

  CopyMem (Buffer + Part1Len, &FragmentHead, sizeof (IP6_FRAGMENT_HEADER));

  if ((ExtHdrs != NULL) && (Part1Len < ExtHdrsLen)) {
    //
    // Append the part2 (fragmentable part) of Extension headers
    //
    CopyMem (
      Buffer + Part1Len + sizeof (IP6_FRAGMENT_HEADER),
      ExtHdrs + Part1Len,
      ExtHdrsLen - Part1Len
      );
  }

  *UpdatedExtHdrs = Buffer;

  return EFI_SUCCESS;
}
