/*
 *  Copyright (c) 2016, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of the copyright holder nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes definitions for IPv6 packet processing.
 */

#ifndef IP6_HEADERS_HPP_
#define IP6_HEADERS_HPP_

#include <stddef.h>

#include <openthread/types.h>

#include "common/encoding.hpp"
#include "common/message.hpp"
#include "net/ip6_address.hpp"
#include "net/netif.hpp"
#include "net/socket.hpp"

using ot::Encoding::BigEndian::HostSwap16;
using ot::Encoding::BigEndian::HostSwap32;

namespace ot {

/**
 * @namespace ot::Ip6
 *
 * @brief
 *   This namespace includes definitions for IPv6 networking.
 *
 */
namespace Ip6 {

/**
 * @addtogroup core-ipv6
 *
 * @brief
 *   This module includes definitions for the IPv6 network layer.
 *
 * @{
 *
 * @defgroup core-ip6-icmp6 ICMPv6
 * @defgroup core-ip6-ip6 IPv6
 * @defgroup core-ip6-mpl MPL
 * @defgroup core-ip6-netif Network Interfaces
 *
 * @}
 *
 */

/**
 * @addtogroup core-ip6-ip6
 *
 * @brief
 *   This module includes definitions for core IPv6 networking.
 *
 * @{
 *
 */

/**
 * Internet Protocol Numbers
 */
enum IpProto
{
    kProtoHopOpts  = 0,   ///< IPv6 Hop-by-Hop Option
    kProtoTcp      = 6,   ///< Transmission Control Protocol
    kProtoUdp      = 17,  ///< User Datagram
    kProtoIp6      = 41,  ///< IPv6 encapsulation
    kProtoRouting  = 43,  ///< Routing Header for IPv6
    kProtoFragment = 44,  ///< Fragment Header for IPv6
    kProtoIcmp6    = 58,  ///< ICMP for IPv6
    kProtoNone     = 59,  ///< No Next Header for IPv6
    kProtoDstOpts  = 60,  ///< Destination Options for IPv6
};

enum
{
    kVersionClassFlowSize = 4,  ///< Combined size of Version, Class, Flow Label in bytes.
};

/**
 * This structure represents an IPv6 header.
 *
 */
OT_TOOL_PACKED_BEGIN
struct HeaderPoD
{
    union
    {
        uint8_t   m8[kVersionClassFlowSize / sizeof(uint8_t)];
        uint16_t  m16[kVersionClassFlowSize / sizeof(uint16_t)];
        uint32_t  m32[kVersionClassFlowSize / sizeof(uint32_t)];
    } mVersionClassFlow;           ///< Version, Class, Flow Label
    uint16_t      mPayloadLength;  ///< Payload Length
    uint8_t       mNextHeader;     ///< Next Header
    uint8_t       mHopLimit;       ///< Hop Limit
    otIp6Address  mSource;         ///< Source
    otIp6Address  mDestination;    ///< Destination
} OT_TOOL_PACKED_END;

/**
 * This class implements IPv6 header generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class Header: private HeaderPoD
{
public:
    /**
     * This method initializes the IPv6 header.
     *
     */
    void Init(void) { mVersionClassFlow.m32[0] = 0; mVersionClassFlow.m8[0] = kVersion6; }

    /**
     * This method initializes the IPv6 header and sets Version, Traffic Control and Flow Label fields.
     *
     */
    void Init(uint32_t aVersionClassFlow) { mVersionClassFlow.m32[0] = HostSwap32(aVersionClassFlow); }

    /**
     * This method indicates whether or not the IPv6 Version is set to 6.
     *
     * @retval TRUE   If the IPv6 Version is set to 6.
     * @retval FALSE  If the IPv6 Version is not set to 6.
     *
     */
    bool IsVersion6(void) const { return (mVersionClassFlow.m8[0] & kVersionMask) == kVersion6; }

    /**
     * This method returns the IPv6 Payload Length value.
     *
     * @returns The IPv6 Payload Length value.
     *
     */
    uint16_t GetPayloadLength(void) { return HostSwap16(mPayloadLength); }

    /**
     * This method sets the IPv6 Payload Length value.
     *
     * @param[in]  aLength  The IPv6 Payload Length value.
     *
     */
    void SetPayloadLength(uint16_t aLength) { mPayloadLength = HostSwap16(aLength); }

    /**
     * This method returns the IPv6 Next Header value.
     *
     * @returns The IPv6 Next Header value.
     *
     */
    IpProto GetNextHeader(void) const { return static_cast<IpProto>(mNextHeader); }

    /**
     * This method sets the IPv6 Next Header value.
     *
     * @param[in]  aNextHeader  The IPv6 Next Header value.
     *
     */
    void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }

    /**
     * This method returns the IPv6 Hop Limit value.
     *
     * @returns The IPv6 Hop Limit value.
     *
     */
    uint8_t GetHopLimit(void) const { return mHopLimit; }

    /**
     * This method sets the IPv6 Hop Limit value.
     *
     * @param[in]  aHopLimit  The IPv6 Hop Limit value.
     *
     */
    void SetHopLimit(uint8_t aHopLimit) { mHopLimit = aHopLimit; }

    /**
     * This method returns the IPv6 Source address.
     *
     * @returns A reference to the IPv6 Source address.
     *
     */
    Address &GetSource(void) { return static_cast<Address &>(mSource); }

    /**
     * This method sets the IPv6 Source address.
     *
     * @param[in]  aSource  A reference to the IPv6 Source address.
     *
     */
    void SetSource(const Address &aSource) { mSource = aSource; }

    /**
     * This method returns the IPv6 Destination address.
     *
     * @returns A reference to the IPv6 Destination address.
     *
     */
    Address &GetDestination(void) { return static_cast<Address &>(mDestination); }

    /**
     * This method sets the IPv6 Destination address.
     *
     * @param[in]  aDestination  A reference to the IPv6 Destination address.
     *
     */
    void SetDestination(const Address &aDestination) { mDestination = aDestination; }

    /**
     * This static method returns the byte offset of the IPv6 Payload Length field.
     *
     * @returns The byte offset of the IPv6 Payload Length field.
     *
     */
    static uint8_t GetPayloadLengthOffset(void) { return offsetof(HeaderPoD, mPayloadLength); }

    /**
     * This static method returns the byte offset of the IPv6 Hop Limit field.
     *
     * @returns The byte offset of the IPv6 Hop Limit field.
     *
     */
    static uint8_t GetHopLimitOffset(void) { return offsetof(HeaderPoD, mHopLimit); }

    /**
     * This static method returns the size of the IPv6 Hop Limit field.
     *
     * @returns The size of the IPv6 Hop Limit field.
     *
     */
    static uint8_t GetHopLimitSize(void) { return sizeof(uint8_t); }

    /**
     * This static method returns the byte offset of the IPv6 Destination field.
     *
     * @returns The byte offset of the IPv6 Destination field.
     *
     */
    static uint8_t GetDestinationOffset(void) { return offsetof(HeaderPoD, mDestination); }

private:
    enum
    {
        kVersion6 = 0x60,
        kVersionMask = 0xf0,
    };
} OT_TOOL_PACKED_END;

/**
 * This class implements IPv6 Extension Header generation and processing.
 *
 */
OT_TOOL_PACKED_BEGIN
class ExtensionHeader
{
public:
    /**
     * This method returns the IPv6 Next Header value.
     *
     * @returns The IPv6 Next Header value.
     *
     */
    IpProto GetNextHeader(void) const { return static_cast<IpProto>(mNextHeader); }

    /**
     * This method sets the IPv6 Next Header value.
     *
     * @param[in]  aNextHeader  The IPv6 Next Header value.
     *
     */
    void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }

    /**
     * This method returns the IPv6 Header Extension Length value.
     *
     * @returns The IPv6 Header Extension Length value.
     *
     */
    uint8_t GetLength(void) const { return mLength; }

    /**
     * This method sets the IPv6 Header Extension Length value.
     *
     * @param[in]  aLength  The IPv6 Header Extension Length value.
     *
     */
    void SetLength(uint8_t aLength) { mLength = aLength; }

private:
    uint8_t mNextHeader;
    uint8_t mLength;
} OT_TOOL_PACKED_END;

/**
 * This class implements IPv6 Hop-by-Hop Options Header generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class HopByHopHeader: public ExtensionHeader
{
} OT_TOOL_PACKED_END;

/**
 * This class implements IPv6 Options generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class OptionHeader
{
public:
    /**
     * Default constructor.
     *
     */
    OptionHeader(void):
        mType(0),
        mLength(0) {}

    /**
     * This method returns the IPv6 Option Type value.
     *
     * @returns The IPv6 Option Type value.
     *
     */
    uint8_t GetType(void) const { return mType; }

    /**
     * This method sets the IPv6 Option Type value.
     *
     * @param[in]  aType  The IPv6 Option Type value.
     *
     */
    void SetType(uint8_t aType) { mType = aType; }

    /**
     * IPv6 Option Type actions for unrecognized IPv6 Options.
     *
     */
    enum Action
    {
        kActionSkip      = 0x00,  ///< skip over this option and continue processing the header
        kActionDiscard   = 0x40,  ///< discard the packet
        kActionForceIcmp = 0x80,  ///< discard the packet and forcibly send an ICMP Parameter Problem
        kActionIcmp      = 0xc0,  ///< discard packet and conditionally send an ICMP Parameter Problem
        kActionMask      = 0xc0,  ///< mask for action bits
    };

    /**
     * This method returns the IPv6 Option action for unrecognized IPv6 Options.
     *
     * @returns The IPv6 Option action for unrecognized IPv6 Options.
     *
     */
    Action GetAction(void) const { return static_cast<Action>(mType & kActionMask); }

    /**
     * This method returns the IPv6 Option Length value.
     *
     * @returns The IPv6 Option Length value.
     *
     */
    uint8_t GetLength(void) const { return mLength; }

    /**
     * This method sets the IPv6 Option Length value.
     *
     * @param[in]  aLength  The IPv6 Option Length value.
     *
     */
    void SetLength(uint8_t aLength) { mLength = aLength; }

private:
    uint8_t mType;
    uint8_t mLength;
} OT_TOOL_PACKED_END;

/**
 * This class implements IPv6 PadN Option generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class OptionPadN : public OptionHeader
{
public:
    enum
    {
        kType = 0x01,      ///< PadN type
        kData = 0x00,      ///< PadN specific data
        kMaxLength = 0x05  ///< Maximum length of PadN option data
    };

    /**
     * This method initializes the PadN header.
     *
     * @param[in]  aPadLength  The length of needed padding. Allowed value from
     *                         range 2-7.
     *
     */
    void Init(uint8_t aPadLength) {
        OptionHeader::SetType(kType);
        OptionHeader::SetLength(aPadLength - sizeof(OptionHeader));
        memset(mPad, kData, aPadLength - sizeof(OptionHeader));
    }

    /**
     * This method returns the total IPv6 Option Length value including option
     * header.
     *
     * @returns The total IPv6 Option Length.
     *
     */
    uint8_t GetTotalLength(void) const { return OptionHeader::GetLength() + sizeof(OptionHeader); }

private:
    uint8_t mPad[kMaxLength];
} OT_TOOL_PACKED_END;

/**
 * This class implements IPv6 Pad1 Option generation and parsing. Pad1 does not
 * followdefault option header structure.
 *
 */
OT_TOOL_PACKED_BEGIN
class OptionPad1
{
public:
    enum
    {
        kType = 0x00
    };

    /**
     * This method initializes the Pad1 header.
     *
     */
    void Init(void) { mType = kType; }

private:
    uint8_t mType;
} OT_TOOL_PACKED_END;


/**
 * This class implements IPv6 Fragment Header generation and parsing.
 *
 */
OT_TOOL_PACKED_BEGIN
class FragmentHeader
{
public:
    /**
     * This method initializes the IPv6 Fragment header.
     *
     */
    void Init(void) { mReserved = 0; mIdentification = 0; }

    /**
     * This method returns the IPv6 Next Header value.
     *
     * @returns The IPv6 Next Header value.
     *
     */
    IpProto GetNextHeader(void) const { return static_cast<IpProto>(mNextHeader); }

    /**
     * This method sets the IPv6 Next Header value.
     *
     * @param[in]  aNextHeader  The IPv6 Next Header value.
     *
     */
    void SetNextHeader(IpProto aNextHeader) { mNextHeader = static_cast<uint8_t>(aNextHeader); }

    /**
     * This method returns the Fragment Offset value.
     *
     * @returns The Fragment Offset value.
     *
     */
    uint16_t GetOffset(void) { return (HostSwap16(mOffsetMore) & kOffsetMask) >> kOffsetOffset; }

    /**
     * This method sets the Fragment Offset value.
     *
     * @param[in]  aOffset  The Fragment Offset value.
     */
    void SetOffset(uint16_t aOffset) {
        uint16_t tmp = HostSwap16(mOffsetMore);
        tmp = (tmp & ~kOffsetMask) | ((aOffset << kOffsetOffset) & kOffsetMask);
        mOffsetMore = HostSwap16(tmp);
    }

    /**
     * This method returns the M flag value.
     *
     * @returns The M flag value.
     *
     */
    bool IsMoreFlagSet(void) { return HostSwap16(mOffsetMore) & kMoreFlag; }

    /**
     * This method clears the M flag value.
     *
     */
    void ClearMoreFlag(void) { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) & ~kMoreFlag); }

    /**
     * This method sets the M flag value.
     *
     */
    void SetMoreFlag(void) { mOffsetMore = HostSwap16(HostSwap16(mOffsetMore) | kMoreFlag); }

private:
    uint8_t mNextHeader;
    uint8_t mReserved;

    enum
    {
        kOffsetOffset = 3,
        kOffsetMask = 0xfff8,
        kMoreFlag = 1,
    };
    uint16_t mOffsetMore;
    uint32_t mIdentification;
} OT_TOOL_PACKED_END;

/**
 * @}
 *
 */

}  // namespace Ip6
}  // namespace ot

#endif  // NET_IP6_HEADERS_HPP_
