/** @file
  IP6 option support functions and routines.

  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<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"

/**
  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
  )
{
  UINT16                    Offset;
  UINT8                     OptionType;
  UINT16                    Length;

  Offset = 0;

  while (Offset < OptionLen) {
    OptionType = *(Option + Offset);
     Length    = (UINT16) (*(Option + Offset + 1) * 8);

    switch (OptionType) {
    case Ip6OptionPrefixInfo:
      if (Length != 32) {
        return FALSE;
      }

      break;

    case Ip6OptionMtu:
      if (Length != 8) {
        return FALSE;
      }

      break;

    default:
      //
      // Check the length of Ip6OptionEtherSource, Ip6OptionEtherTarget, and
      // Ip6OptionRedirected here. For unrecognized options, silently ignore
      // and continue processsing the message.
      //
      if (Length == 0) {
        return FALSE;
      }

      break;
    }

    Offset = (UINT16) (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;
}

