/*
 *  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 implements 6LoWPAN header compression.
 */

#include <openthread/config.h>

#include "lowpan.hpp"

#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/encoding.hpp"
#include "net/ip6.hpp"
#include "net/udp6.hpp"
#include "thread/network_data_leader.hpp"
#include "thread/thread_netif.hpp"

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

namespace ot {
namespace Lowpan {

Lowpan::Lowpan(ThreadNetif &aThreadNetif):
    ThreadNetifLocator(aThreadNetif)
{
}

otError Lowpan::CopyContext(const Context &aContext, Ip6::Address &aAddress)
{
    memcpy(&aAddress, aContext.mPrefix, aContext.mPrefixLength / CHAR_BIT);

    for (int i = (aContext.mPrefixLength & ~7); i < aContext.mPrefixLength; i++)
    {
        aAddress.mFields.m8[i / CHAR_BIT] &= ~(0x80 >> (i % CHAR_BIT));
        aAddress.mFields.m8[i / CHAR_BIT] |= aContext.mPrefix[i / CHAR_BIT] & (0x80 >> (i % CHAR_BIT));
    }

    return OT_ERROR_NONE;
}

otError Lowpan::ComputeIid(const Mac::Address &aMacAddr, const Context &aContext, Ip6::Address &aIpAddress)
{
    otError error = OT_ERROR_NONE;

    switch (aMacAddr.mLength)
    {
    case 2:
        aIpAddress.mFields.m16[4] = HostSwap16(0x0000);
        aIpAddress.mFields.m16[5] = HostSwap16(0x00ff);
        aIpAddress.mFields.m16[6] = HostSwap16(0xfe00);
        aIpAddress.mFields.m16[7] = HostSwap16(aMacAddr.mShortAddress);
        break;

    case Ip6::Address::kInterfaceIdentifierSize:
        aIpAddress.SetIid(aMacAddr.mExtAddress);
        break;

    default:
        ExitNow(error = OT_ERROR_PARSE);
    }

    if (aContext.mPrefixLength > 64)
    {
        for (int i = (aContext.mPrefixLength & ~7); i < aContext.mPrefixLength; i++)
        {
            aIpAddress.mFields.m8[i / CHAR_BIT] &= ~(0x80 >> (i % CHAR_BIT));
            aIpAddress.mFields.m8[i / CHAR_BIT] |= aContext.mPrefix[i / CHAR_BIT] & (0x80 >> (i % CHAR_BIT));
        }
    }

exit:
    return error;
}

int Lowpan::CompressSourceIid(const Mac::Address &aMacAddr, const Ip6::Address &aIpAddr, const Context &aContext,
                              uint16_t &aHcCtl, uint8_t *aBuf)
{
    uint8_t *cur = aBuf;
    Ip6::Address ipaddr;
    Mac::Address tmp;

    ComputeIid(aMacAddr, aContext, ipaddr);

    if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
    {
        aHcCtl |= kHcSrcAddrMode3;
    }
    else
    {
        tmp.mLength = sizeof(tmp.mShortAddress);
        tmp.mShortAddress = HostSwap16(aIpAddr.mFields.m16[7]);
        ComputeIid(tmp, aContext, ipaddr);

        if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
        {
            aHcCtl |= kHcSrcAddrMode2;
            cur[0] = aIpAddr.mFields.m8[14];
            cur[1] = aIpAddr.mFields.m8[15];
            cur += 2;
        }
        else
        {
            aHcCtl |= kHcSrcAddrMode1;
            memcpy(cur, aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize);
            cur += Ip6::Address::kInterfaceIdentifierSize;
        }
    }

    return static_cast<int>(cur - aBuf);
}

int Lowpan::CompressDestinationIid(const Mac::Address &aMacAddr, const Ip6::Address &aIpAddr, const Context &aContext,
                                   uint16_t &aHcCtl, uint8_t *aBuf)
{
    uint8_t *cur = aBuf;
    Ip6::Address ipaddr;
    Mac::Address tmp;

    ComputeIid(aMacAddr, aContext, ipaddr);

    if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
    {
        aHcCtl |= kHcDstAddrMode3;
    }
    else
    {
        tmp.mLength = sizeof(tmp.mShortAddress);
        tmp.mShortAddress = HostSwap16(aIpAddr.mFields.m16[7]);
        ComputeIid(tmp, aContext, ipaddr);

        if (memcmp(ipaddr.GetIid(), aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize) == 0)
        {
            aHcCtl |= kHcDstAddrMode2;
            cur[0] = aIpAddr.mFields.m8[14];
            cur[1] = aIpAddr.mFields.m8[15];
            cur += 2;
        }
        else
        {
            aHcCtl |= kHcDstAddrMode1;
            memcpy(cur, aIpAddr.GetIid(), Ip6::Address::kInterfaceIdentifierSize);
            cur += Ip6::Address::kInterfaceIdentifierSize;
        }
    }

    return static_cast<int>(cur - aBuf);
}

int Lowpan::CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, uint8_t *aBuf)
{
    NetworkData::Leader &networkData = GetNetif().GetNetworkDataLeader();
    uint8_t *cur = aBuf;
    Context multicastContext;

    aHcCtl |= kHcMulticast;

    for (unsigned int i = 2; i < sizeof(Ip6::Address); i++)
    {
        if (aIpAddr.mFields.m8[i])
        {
            // Check if multicast address can be compressed to 8-bits (ff02::00xx)
            if (aIpAddr.mFields.m8[1] == 0x02 && i >= 15)
            {
                aHcCtl |= kHcDstAddrMode3;
                cur[0] = aIpAddr.mFields.m8[15];
                cur++;
            }
            // Check if multicast address can be compressed to 32-bits (ffxx::00xx:xxxx)
            else if (i >= 13)
            {
                aHcCtl |= kHcDstAddrMode2;
                cur[0] = aIpAddr.mFields.m8[1];
                memcpy(cur + 1, aIpAddr.mFields.m8 + 13, 3);
                cur += 4;
            }
            // Check if multicast address can be compressed to 48-bits (ffxx::00xx:xxxx:xxxx)
            else if (i >= 11)
            {
                aHcCtl |= kHcDstAddrMode1;
                cur[0] = aIpAddr.mFields.m8[1];
                memcpy(cur + 1, aIpAddr.mFields.m8 + 11, 5);
                cur += 6;
            }
            else
            {
                // Check if multicast address can be compressed using Context ID 0.
                if (networkData.GetContext(0, multicastContext) == OT_ERROR_NONE &&
                    multicastContext.mPrefixLength == aIpAddr.mFields.m8[3] &&
                    memcmp(multicastContext.mPrefix, aIpAddr.mFields.m8 + 4, 8) == 0)
                {
                    aHcCtl |= kHcDstAddrContext | kHcDstAddrMode0;
                    memcpy(cur, aIpAddr.mFields.m8 + 1, 2);
                    memcpy(cur + 2, aIpAddr.mFields.m8 + 12, 4);
                    cur += 6;
                }
                else
                {
                    memcpy(cur, aIpAddr.mFields.m8, sizeof(Ip6::Address));
                    cur += sizeof(Ip6::Address);
                }
            }

            break;
        }
    }

    return static_cast<int>(cur - aBuf);
}

int Lowpan::Compress(Message &aMessage, const Mac::Address &aMacSource, const Mac::Address &aMacDest, uint8_t *aBuf)
{
    NetworkData::Leader &networkData = GetNetif().GetNetworkDataLeader();
    uint8_t *cur = aBuf;
    uint16_t hcCtl = 0;
    Ip6::Header ip6Header;
    uint8_t *ip6HeaderBytes = reinterpret_cast<uint8_t *>(&ip6Header);
    Context srcContext, dstContext;
    bool srcContextValid = true, dstContextValid = true;
    uint8_t nextHeader;
    uint8_t ecn = 0;
    uint8_t dscp = 0;

    aMessage.Read(aMessage.GetOffset(), sizeof(ip6Header), &ip6Header);

    if (networkData.GetContext(ip6Header.GetSource(), srcContext) != OT_ERROR_NONE ||
        srcContext.mCompressFlag == false)
    {
        networkData.GetContext(0, srcContext);
        srcContextValid = false;
    }

    if (networkData.GetContext(ip6Header.GetDestination(), dstContext) != OT_ERROR_NONE ||
        dstContext.mCompressFlag == false)
    {
        networkData.GetContext(0, dstContext);
        dstContextValid = false;
    }

    hcCtl = kHcDispatch;

    // Lowpan HC Control Bits
    cur += 2;

    // Context Identifier
    if (srcContext.mContextId != 0 || dstContext.mContextId != 0)
    {
        hcCtl |= kHcContextId;
        cur[0] = ((srcContext.mContextId << 4) | dstContext.mContextId) & 0xff;
        cur++;
    }

    dscp = ((ip6HeaderBytes[0] << 2) & 0x3c) | (ip6HeaderBytes[1] >> 6);
    ecn = (ip6HeaderBytes[1] << 2) & 0xc0;

    // Flow Label
    if (((ip6HeaderBytes[1] & 0x0f) == 0) && ((ip6HeaderBytes[2]) == 0) && ((ip6HeaderBytes[3]) == 0))
    {
        if (dscp == 0 && ecn == 0)
        {
            // Elide Flow Label and Traffic Class.
            hcCtl |= kHcTrafficClass | kHcFlowLabel;
        }
        else
        {
            // Elide Flow Label and carry Traffic Class in-line.
            hcCtl |= kHcFlowLabel;

            cur[0] = ecn | dscp;
            cur++;
        }
    }
    else if (dscp == 0)
    {
        // Carry Flow Label and ECN only with 2-bit padding.
        hcCtl |= kHcTrafficClass;

        cur[0] = ecn | (ip6HeaderBytes[1] & 0x0f);
        memcpy(cur + 1, ip6HeaderBytes + 2, 2);
        cur += 3;
    }
    else
    {
        // Carry Flow Label and Traffic Class in-line.
        cur[0] = ecn | dscp;
        cur[1] = ip6HeaderBytes[1] & 0x0f;
        memcpy(cur + 2, ip6HeaderBytes + 2, 2);
        cur += 4;
    }

    // Next Header
    switch (ip6Header.GetNextHeader())
    {
    case Ip6::kProtoHopOpts:
    case Ip6::kProtoUdp:
    case Ip6::kProtoIp6:
        hcCtl |= kHcNextHeader;
        break;

    default:
        cur[0] = static_cast<uint8_t>(ip6Header.GetNextHeader());
        cur++;
        break;
    }

    // Hop Limit
    switch (ip6Header.GetHopLimit())
    {
    case 1:
        hcCtl |= kHcHopLimit1;
        break;

    case 64:
        hcCtl |= kHcHopLimit64;
        break;

    case 255:
        hcCtl |= kHcHopLimit255;
        break;

    default:
        cur[0] = ip6Header.GetHopLimit();
        cur++;
        break;
    }

    // Source Address
    if (ip6Header.GetSource().IsUnspecified())
    {
        hcCtl |= kHcSrcAddrContext;
    }
    else if (ip6Header.GetSource().IsLinkLocal())
    {
        cur += CompressSourceIid(aMacSource, ip6Header.GetSource(), srcContext, hcCtl, cur);
    }
    else if (srcContextValid)
    {
        hcCtl |= kHcSrcAddrContext;
        cur += CompressSourceIid(aMacSource, ip6Header.GetSource(), srcContext, hcCtl, cur);
    }
    else
    {
        memcpy(cur, ip6Header.GetSource().mFields.m8, sizeof(ip6Header.GetSource()));
        cur += sizeof(Ip6::Address);
    }

    // Destination Address
    if (ip6Header.GetDestination().IsMulticast())
    {
        cur += CompressMulticast(ip6Header.GetDestination(), hcCtl, cur);
    }
    else if (ip6Header.GetDestination().IsLinkLocal())
    {
        cur += CompressDestinationIid(aMacDest, ip6Header.GetDestination(), dstContext, hcCtl, cur);
    }
    else if (dstContextValid)
    {
        hcCtl |= kHcDstAddrContext;
        cur += CompressDestinationIid(aMacDest, ip6Header.GetDestination(), dstContext, hcCtl, cur);
    }
    else
    {
        memcpy(cur, &ip6Header.GetDestination(), sizeof(ip6Header.GetDestination()));
        cur += sizeof(Ip6::Address);
    }

    aBuf[0] = hcCtl >> 8;
    aBuf[1] = hcCtl & 0xff;
    aMessage.MoveOffset(sizeof(ip6Header));

    nextHeader = static_cast<uint8_t>(ip6Header.GetNextHeader());

    while (1)
    {
        switch (nextHeader)
        {
        case Ip6::kProtoHopOpts:
            cur += CompressExtensionHeader(aMessage, cur, nextHeader);
            break;

        case Ip6::kProtoUdp:
            cur += CompressUdp(aMessage, cur);
            ExitNow();

        case Ip6::kProtoIp6:
            // For IP-in-IP the NH bit of the LOWPAN_NHC encoding MUST be set to zero.
            cur[0] = kExtHdrDispatch | kExtHdrEidIp6;
            cur++;

            cur += Compress(aMessage, aMacSource, aMacDest, cur);

        // fall through

        default:
            ExitNow();
        }
    }

exit:
    return static_cast<int>(cur - aBuf);
}

int Lowpan::CompressExtensionHeader(Message &aMessage, uint8_t *aBuf, uint8_t &aNextHeader)
{
    Ip6::ExtensionHeader extHeader;
    Ip6::OptionHeader optionHeader;
    uint8_t *cur = aBuf;
    uint8_t len;
    uint8_t padLength = 0;
    uint16_t offset;

    aMessage.Read(aMessage.GetOffset(), sizeof(extHeader), &extHeader);
    aMessage.MoveOffset(sizeof(extHeader));

    cur[0] = kExtHdrDispatch | kExtHdrEidHbh;

    switch (extHeader.GetNextHeader())
    {
    case Ip6::kProtoUdp:
    case Ip6::kProtoIp6:
        cur[0] |= kExtHdrNextHeader;
        break;

    default:
        cur++;
        cur[0] = static_cast<uint8_t>(extHeader.GetNextHeader());
        break;
    }

    cur++;

    len = (extHeader.GetLength() + 1) * 8 - sizeof(extHeader);

    // RFC 6282 says: "IPv6 Hop-by-Hop and Destination Options Headers may use a trailing
    // Pad1 or PadN to achieve 8-octet alignment. When there is a single trailing Pad1 or PadN
    // option of 7 octets or less and the containing header is a multiple of 8 octets, the trailing
    // Pad1 or PadN option MAY be elided by the compressor."
    if (aNextHeader == Ip6::kProtoHopOpts || aNextHeader == Ip6::kProtoDstOpts)
    {
        offset = aMessage.GetOffset();

        while (offset < len + aMessage.GetOffset())
        {
            aMessage.Read(offset, sizeof(optionHeader), &optionHeader);

            if (optionHeader.GetType() == Ip6::OptionPad1::kType)
            {
                offset += sizeof(Ip6::OptionPad1);
            }
            else
            {
                offset += sizeof(optionHeader) + optionHeader.GetLength();
            }
        }

        // Check if the last option can be compressed.
        if (optionHeader.GetType() == Ip6::OptionPad1::kType)
        {
            padLength = sizeof(Ip6::OptionPad1);
        }
        else if (optionHeader.GetType() == Ip6::OptionPadN::kType)
        {
            padLength = sizeof(optionHeader) + optionHeader.GetLength();
        }

        len -= padLength;
    }

    aNextHeader = static_cast<uint8_t>(extHeader.GetNextHeader());

    cur[0] = len;
    cur++;

    aMessage.Read(aMessage.GetOffset(), len, cur);
    aMessage.MoveOffset(len + padLength);
    cur += len;

    return static_cast<int>(cur - aBuf);
}

int Lowpan::CompressUdp(Message &aMessage, uint8_t *aBuf)
{
    Ip6::UdpHeader udpHeader;
    uint8_t *cur = aBuf;
    uint8_t *udpCtl = cur;
    uint16_t source;
    uint16_t destination;

    aMessage.Read(aMessage.GetOffset(), sizeof(udpHeader), &udpHeader);
    source = udpHeader.GetSourcePort();
    destination = udpHeader.GetDestinationPort();

    cur[0] = kUdpDispatch;
    cur++;

    if ((source & 0xfff0) == 0xf0b0 && (destination & 0xfff0) == 0xf0b0)
    {
        *udpCtl |= 3;
        *cur++ = (((source & 0xf) << 4) | (destination & 0xf)) & 0xff;
    }
    else if ((source & 0xff00) == 0xf000)
    {
        *udpCtl |= 2;
        *cur++ = source & 0xff;
        *cur++ = destination >> 8;
        *cur++ = destination & 0xff;
    }
    else if ((destination & 0xff00) == 0xf000)
    {
        *udpCtl |= 1;
        *cur++ = source >> 8;
        *cur++ = source & 0xff;
        *cur++ = destination & 0xff;
    }
    else
    {
        memcpy(cur, &udpHeader, Ip6::UdpHeader::GetLengthOffset());
        cur += Ip6::UdpHeader::GetLengthOffset();
    }

    memcpy(cur, reinterpret_cast<uint8_t *>(&udpHeader) + Ip6::UdpHeader::GetChecksumOffset(), 2);
    cur += 2;

    aMessage.MoveOffset(sizeof(udpHeader));

    return static_cast<int>(cur - aBuf);
}

otError Lowpan::DispatchToNextHeader(uint8_t aDispatch, Ip6::IpProto &aNextHeader)
{
    otError error = OT_ERROR_NONE;

    if ((aDispatch & kExtHdrDispatchMask) == kExtHdrDispatch)
    {
        switch (aDispatch & kExtHdrEidMask)
        {
        case kExtHdrEidHbh:
            aNextHeader = Ip6::kProtoHopOpts;
            ExitNow();

        case kExtHdrEidRouting:
            aNextHeader = Ip6::kProtoRouting;
            ExitNow();

        case kExtHdrEidFragment:
            aNextHeader = Ip6::kProtoFragment;
            ExitNow();

        case kExtHdrEidDst:
            aNextHeader = Ip6::kProtoDstOpts;
            ExitNow();

        case kExtHdrEidIp6:
            aNextHeader = Ip6::kProtoIp6;
            ExitNow();
        }
    }
    else if ((aDispatch & kUdpDispatchMask) == kUdpDispatch)
    {
        aNextHeader = Ip6::kProtoUdp;
        ExitNow();
    }

    error = OT_ERROR_PARSE;

exit:
    return error;
}

int Lowpan::DecompressBaseHeader(Ip6::Header &ip6Header, const Mac::Address &aMacSource, const Mac::Address &aMacDest,
                                 const uint8_t *aBuf, uint16_t aBufLength)
{
    NetworkData::Leader &networkData = GetNetif().GetNetworkDataLeader();
    otError error = OT_ERROR_PARSE;
    const uint8_t *cur = aBuf;
    uint16_t remaining = aBufLength;
    uint16_t hcCtl;
    Context srcContext, dstContext;
    bool srcContextValid = true, dstContextValid = true;
    Ip6::IpProto nextHeader;
    uint8_t *bytes;

    VerifyOrExit(remaining >= 2);
    hcCtl = static_cast<uint16_t>((cur[0] << 8) | cur[1]);
    cur += 2;
    remaining -= 2;

    // check Dispatch bits
    VerifyOrExit((hcCtl & kHcDispatchMask) == kHcDispatch);

    // Context Identifier
    srcContext.mPrefixLength = 0;
    dstContext.mPrefixLength = 0;

    if ((hcCtl & kHcContextId) != 0)
    {
        VerifyOrExit(remaining >= 1);

        if (networkData.GetContext(cur[0] >> 4, srcContext) != OT_ERROR_NONE)
        {
            srcContextValid = false;
        }

        if (networkData.GetContext(cur[0] & 0xf, dstContext) != OT_ERROR_NONE)
        {
            dstContextValid = false;
        }

        cur++;
        remaining--;
    }
    else
    {
        networkData.GetContext(0, srcContext);
        networkData.GetContext(0, dstContext);
    }

    memset(&ip6Header, 0, sizeof(ip6Header));
    ip6Header.Init();

    // Traffic Class and Flow Label
    if ((hcCtl & kHcTrafficFlowMask) != kHcTrafficFlow)
    {
        VerifyOrExit(remaining >= 1);

        bytes = reinterpret_cast<uint8_t *>(&ip6Header);
        bytes[1] |= (cur[0] & 0xc0) >> 2;

        if ((hcCtl & kHcTrafficClass) == 0)
        {
            bytes[0] |= (cur[0] >> 2) & 0x0f;
            bytes[1] |= (cur[0] << 6) & 0xc0;
            cur++;
            remaining--;
        }

        if ((hcCtl & kHcFlowLabel) == 0)
        {
            VerifyOrExit(remaining >= 3);
            bytes[1] |= cur[0] & 0x0f;
            bytes[2] |= cur[1];
            bytes[3] |= cur[2];
            cur += 3;
            remaining -= 3;
        }
    }

    // Next Header
    if ((hcCtl & kHcNextHeader) == 0)
    {
        VerifyOrExit(remaining >= 1);
        ip6Header.SetNextHeader(static_cast<Ip6::IpProto>(cur[0]));
        cur++;
        remaining--;
    }

    // Hop Limit
    switch (hcCtl & kHcHopLimitMask)
    {
    case kHcHopLimit1:
        ip6Header.SetHopLimit(1);
        break;

    case kHcHopLimit64:
        ip6Header.SetHopLimit(64);
        break;

    case kHcHopLimit255:
        ip6Header.SetHopLimit(255);
        break;

    default:
        VerifyOrExit(remaining >= 1);
        ip6Header.SetHopLimit(cur[0]);
        cur++;
        remaining--;
        break;
    }

    // Source Address
    switch (hcCtl & kHcSrcAddrModeMask)
    {
    case kHcSrcAddrMode0:
        if ((hcCtl & kHcSrcAddrContext) == 0)
        {
            VerifyOrExit(remaining >= sizeof(Ip6::Address));
            memcpy(&ip6Header.GetSource(), cur, sizeof(ip6Header.GetSource()));
            cur += sizeof(Ip6::Address);
            remaining -= sizeof(Ip6::Address);
        }

        break;

    case kHcSrcAddrMode1:
        VerifyOrExit(remaining >= Ip6::Address::kInterfaceIdentifierSize);
        ip6Header.GetSource().SetIid(cur);
        cur += Ip6::Address::kInterfaceIdentifierSize;
        remaining -= Ip6::Address::kInterfaceIdentifierSize;
        break;

    case kHcSrcAddrMode2:
        VerifyOrExit(remaining >= 2);
        ip6Header.GetSource().mFields.m8[11] = 0xff;
        ip6Header.GetSource().mFields.m8[12] = 0xfe;
        memcpy(ip6Header.GetSource().mFields.m8 + 14, cur, 2);
        cur += 2;
        remaining -= 2;
        break;

    case kHcSrcAddrMode3:
        ComputeIid(aMacSource, srcContext, ip6Header.GetSource());
        break;
    }

    if ((hcCtl & kHcSrcAddrModeMask) != kHcSrcAddrMode0)
    {
        if ((hcCtl & kHcSrcAddrContext) == 0)
        {
            ip6Header.GetSource().mFields.m16[0] = HostSwap16(0xfe80);
        }
        else
        {
            VerifyOrExit(srcContextValid);
            CopyContext(srcContext, ip6Header.GetSource());
        }
    }

    if ((hcCtl & kHcMulticast) == 0)
    {
        // Unicast Destination Address

        switch (hcCtl & kHcDstAddrModeMask)
        {
        case kHcDstAddrMode0:
            VerifyOrExit((hcCtl & kHcDstAddrContext) == 0);
            VerifyOrExit(remaining >= sizeof(Ip6::Address));
            memcpy(&ip6Header.GetDestination(), cur, sizeof(ip6Header.GetDestination()));
            cur += sizeof(Ip6::Address);
            remaining -= sizeof(Ip6::Address);
            break;

        case kHcDstAddrMode1:
            VerifyOrExit(remaining >= Ip6::Address::kInterfaceIdentifierSize);
            ip6Header.GetDestination().SetIid(cur);
            cur += Ip6::Address::kInterfaceIdentifierSize;
            remaining -= Ip6::Address::kInterfaceIdentifierSize;
            break;

        case kHcDstAddrMode2:
            VerifyOrExit(remaining >= 2);
            ip6Header.GetDestination().mFields.m8[11] = 0xff;
            ip6Header.GetDestination().mFields.m8[12] = 0xfe;
            memcpy(ip6Header.GetDestination().mFields.m8 + 14, cur, 2);
            cur += 2;
            remaining -= 2;
            break;

        case kHcDstAddrMode3:
            SuccessOrExit(ComputeIid(aMacDest, dstContext, ip6Header.GetDestination()));
            break;
        }

        if ((hcCtl & kHcDstAddrContext) == 0)
        {
            if ((hcCtl & kHcDstAddrModeMask) != 0)
            {
                ip6Header.GetDestination().mFields.m16[0] = HostSwap16(0xfe80);
            }
        }
        else
        {
            VerifyOrExit(dstContextValid);
            CopyContext(dstContext, ip6Header.GetDestination());
        }
    }
    else
    {
        // Multicast Destination Address

        ip6Header.GetDestination().mFields.m8[0] = 0xff;

        if ((hcCtl & kHcDstAddrContext) == 0)
        {
            switch (hcCtl & kHcDstAddrModeMask)
            {
            case kHcDstAddrMode0:
                VerifyOrExit(remaining >= sizeof(Ip6::Address));
                memcpy(ip6Header.GetDestination().mFields.m8, cur, sizeof(Ip6::Address));
                cur += sizeof(Ip6::Address);
                remaining -= sizeof(Ip6::Address);
                break;

            case kHcDstAddrMode1:
                VerifyOrExit(remaining >= 6);
                ip6Header.GetDestination().mFields.m8[1] = cur[0];
                memcpy(ip6Header.GetDestination().mFields.m8 + 11, cur + 1, 5);
                cur += 6;
                remaining -= 6;
                break;

            case kHcDstAddrMode2:
                VerifyOrExit(remaining >= 4);
                ip6Header.GetDestination().mFields.m8[1] = cur[0];
                memcpy(ip6Header.GetDestination().mFields.m8 + 13, cur + 1, 3);
                cur += 4;
                remaining -= 4;
                break;

            case kHcDstAddrMode3:
                VerifyOrExit(remaining >= 1);
                ip6Header.GetDestination().mFields.m8[1] = 0x02;
                ip6Header.GetDestination().mFields.m8[15] = cur[0];
                cur++;
                remaining--;
                break;
            }
        }
        else
        {
            switch (hcCtl & kHcDstAddrModeMask)
            {
            case 0:
                VerifyOrExit(remaining >= 6);
                VerifyOrExit(dstContextValid);
                ip6Header.GetDestination().mFields.m8[1] = cur[0];
                ip6Header.GetDestination().mFields.m8[2] = cur[1];
                ip6Header.GetDestination().mFields.m8[3] = dstContext.mPrefixLength;
                memcpy(ip6Header.GetDestination().mFields.m8 + 4, dstContext.mPrefix, 8);
                memcpy(ip6Header.GetDestination().mFields.m8 + 12, cur + 2, 4);
                cur += 6;
                remaining -= 6;
                break;

            default:
                ExitNow();
            }
        }
    }

    if ((hcCtl & kHcNextHeader) != 0)
    {
        VerifyOrExit(remaining >= 1);
        SuccessOrExit(DispatchToNextHeader(cur[0], nextHeader));
        ip6Header.SetNextHeader(nextHeader);
    }

    error = OT_ERROR_NONE;

exit:
    return (error == OT_ERROR_NONE) ? static_cast<int>(cur - aBuf) : -1;
}

int Lowpan::DecompressExtensionHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength)
{
    otError error = OT_ERROR_PARSE;
    const uint8_t *cur = aBuf;
    uint16_t remaining = aBufLength;
    uint8_t hdr[2];
    uint8_t len;
    Ip6::IpProto nextHeader;
    uint8_t ctl = cur[0];
    uint8_t padLength;
    Ip6::OptionPad1 optionPad1;
    Ip6::OptionPadN optionPadN;

    VerifyOrExit(remaining >= 1);
    cur++;
    remaining--;

    // next header
    if (ctl & kExtHdrNextHeader)
    {
        VerifyOrExit(remaining >= 1);

        len = cur[0];
        cur++;
        remaining--;

        VerifyOrExit(remaining >= len);
        SuccessOrExit(DispatchToNextHeader(cur[len], nextHeader));
        hdr[0] = static_cast<uint8_t>(nextHeader);
    }
    else
    {
        VerifyOrExit(remaining >= 2);

        hdr[0] = cur[0];
        len = cur[1];
        cur += 2;
        remaining -= 2;

        VerifyOrExit(remaining >= len);
    }

    // length
    hdr[1] = BitVectorBytes(sizeof(hdr) + len) - 1;

    SuccessOrExit(aMessage.Append(hdr, sizeof(hdr)));
    aMessage.MoveOffset(sizeof(hdr));

    // payload
    SuccessOrExit(aMessage.Append(cur, len));
    aMessage.MoveOffset(len);
    cur += len;

    // The RFC6282 says: "The trailing Pad1 or PadN option MAY be elided by the compressor.
    // A decompressor MUST ensure that the containing header is padded out to a multiple of 8 octets
    // in length, using a Pad1 or PadN option if necessary."
    padLength = 8 - ((len + sizeof(hdr)) & 0x07);

    if (padLength != 8)
    {
        if (padLength == 1)
        {
            optionPad1.Init();
            SuccessOrExit(aMessage.Append(&optionPad1, padLength));
        }
        else
        {
            optionPadN.Init(padLength);
            SuccessOrExit(aMessage.Append(&optionPadN, padLength));
        }

        aMessage.MoveOffset(padLength);
    }

    error = OT_ERROR_NONE;

exit:
    return (error == OT_ERROR_NONE) ? static_cast<int>(cur - aBuf) : -1;
}

int Lowpan::DecompressUdpHeader(Message &aMessage, const uint8_t *aBuf, uint16_t aBufLength, uint16_t aDatagramLength)
{
    otError error = OT_ERROR_PARSE;
    const uint8_t *cur = aBuf;
    uint16_t remaining = aBufLength;
    Ip6::UdpHeader udpHeader;
    uint8_t udpCtl;

    VerifyOrExit(remaining >= 1);
    udpCtl = cur[0];
    cur++;
    remaining--;

    memset(&udpHeader, 0, sizeof(udpHeader));

    // source and dest ports
    switch (udpCtl & kUdpPortMask)
    {
    case 0:
        VerifyOrExit(remaining >= 4);
        udpHeader.SetSourcePort(static_cast<uint16_t>((cur[0] << 8) | cur[1]));
        udpHeader.SetDestinationPort(static_cast<uint16_t>((cur[2] << 8) | cur[3]));
        cur += 4;
        remaining -= 4;
        break;

    case 1:
        VerifyOrExit(remaining >= 3);
        udpHeader.SetSourcePort(static_cast<uint16_t>((cur[0] << 8) | cur[1]));
        udpHeader.SetDestinationPort(0xf000 | cur[2]);
        cur += 3;
        remaining -= 3;
        break;

    case 2:
        VerifyOrExit(remaining >= 3);
        udpHeader.SetSourcePort(0xf000 | cur[0]);
        udpHeader.SetDestinationPort(static_cast<uint16_t>((cur[1] << 8) | cur[2]));
        cur += 3;
        remaining -= 3;
        break;

    case 3:
        VerifyOrExit(remaining >= 1);
        udpHeader.SetSourcePort(0xf0b0 | (cur[0] >> 4));
        udpHeader.SetDestinationPort(0xf0b0 | (cur[0] & 0xf));
        cur += 1;
        remaining -= 1;
        break;
    }

    // checksum
    if ((udpCtl & kUdpChecksum) != 0)
    {
        ExitNow();
    }
    else
    {
        VerifyOrExit(remaining >= 2);
        udpHeader.SetChecksum(static_cast<uint16_t>((cur[0] << 8) | cur[1]));
        cur += 2;
    }

    // length
    if (aDatagramLength == 0)
    {
        udpHeader.SetLength(sizeof(udpHeader) + static_cast<uint16_t>(aBufLength - (cur - aBuf)));
    }
    else
    {
        udpHeader.SetLength(aDatagramLength - aMessage.GetOffset());
    }

    SuccessOrExit(aMessage.Append(&udpHeader, sizeof(udpHeader)));
    aMessage.MoveOffset(sizeof(udpHeader));

    error = OT_ERROR_NONE;

exit:
    return (error == OT_ERROR_NONE) ? static_cast<int>(cur - aBuf) : -1;
}

int Lowpan::Decompress(Message &aMessage, const Mac::Address &aMacSource, const Mac::Address &aMacDest,
                       const uint8_t *aBuf, uint16_t aBufLength, uint16_t aDatagramLength)
{
    otError error = OT_ERROR_PARSE;
    Ip6::Header ip6Header;
    const uint8_t *cur = aBuf;
    uint16_t remaining = aBufLength;
    bool compressed;
    int rval;
    uint16_t ip6PayloadLength;
    uint16_t compressedLength = 0;
    uint16_t currentOffset = aMessage.GetOffset();

    VerifyOrExit(remaining >= 2);
    compressed = (((static_cast<uint16_t>(cur[0]) << 8) | cur[1]) & kHcNextHeader) != 0;

    VerifyOrExit((rval = DecompressBaseHeader(ip6Header, aMacSource, aMacDest, cur, remaining)) >= 0);

    cur += rval;
    remaining -= rval;

    SuccessOrExit(aMessage.Append(&ip6Header, sizeof(ip6Header)));
    SuccessOrExit(aMessage.MoveOffset(sizeof(ip6Header)));

    while (compressed)
    {
        VerifyOrExit(remaining >= 1);

        if ((cur[0] & kExtHdrDispatchMask) == kExtHdrDispatch)
        {
            if ((cur[0] & kExtHdrEidMask) == kExtHdrEidIp6)
            {
                compressed = false;

                cur++;
                remaining--;

                VerifyOrExit((rval = Decompress(aMessage, aMacSource, aMacDest, cur, remaining,
                                                aDatagramLength)) >= 0);
            }
            else
            {
                compressed = (cur[0] & kExtHdrNextHeader) != 0;
                VerifyOrExit((rval = DecompressExtensionHeader(aMessage, cur, remaining)) >= 0);
            }
        }
        else if ((cur[0] & kUdpDispatchMask) == kUdpDispatch)
        {
            compressed = false;
            VerifyOrExit((rval = DecompressUdpHeader(aMessage, cur, remaining, aDatagramLength)) >= 0);
        }
        else
        {
            ExitNow();
        }

        VerifyOrExit(remaining >= rval);
        cur += rval;
        remaining -= rval;
    }

    compressedLength = static_cast<uint16_t>(cur - aBuf);

    if (aDatagramLength)
    {
        ip6PayloadLength = HostSwap16(aDatagramLength - currentOffset - sizeof(Ip6::Header));
    }
    else
    {
        ip6PayloadLength = HostSwap16(aMessage.GetOffset() - currentOffset -
                                      sizeof(Ip6::Header) + aBufLength - compressedLength);
    }

    aMessage.Write(currentOffset + Ip6::Header::GetPayloadLengthOffset(),
                   sizeof(ip6PayloadLength), &ip6PayloadLength);

    error = OT_ERROR_NONE;

exit:
    return (error == OT_ERROR_NONE) ? static_cast<int>(compressedLength) : -1;
}

otError MeshHeader::Init(const uint8_t *aFrame, uint8_t aFrameLength)
{
    otError error = OT_ERROR_NONE;

    VerifyOrExit(aFrameLength >= 1, error = OT_ERROR_FAILED);
    mDispatchHopsLeft = *aFrame++;
    aFrameLength--;

    if (IsDeepHopsLeftField())
    {
        VerifyOrExit(aFrameLength >= 1, error = OT_ERROR_FAILED);
        mDeepHopsLeft = *aFrame++;
        aFrameLength--;
    }
    else
    {
        mDeepHopsLeft = 0;
    }

    VerifyOrExit(aFrameLength >= sizeof(mAddress), error = OT_ERROR_FAILED);
    memcpy(&mAddress, aFrame, sizeof(mAddress));

exit:
    return error;
}

otError MeshHeader::Init(const Message &aMessage)
{
    otError error = OT_ERROR_NONE;
    uint16_t offset = 0;
    uint16_t bytesRead;

    bytesRead = aMessage.Read(offset, sizeof(mDispatchHopsLeft), &mDispatchHopsLeft);
    VerifyOrExit(bytesRead == sizeof(mDispatchHopsLeft), error = OT_ERROR_FAILED);
    offset += bytesRead;

    if (IsDeepHopsLeftField())
    {
        bytesRead = aMessage.Read(offset, sizeof(mDeepHopsLeft), &mDeepHopsLeft);
        VerifyOrExit(bytesRead == sizeof(mDeepHopsLeft), error = OT_ERROR_FAILED);
        offset += bytesRead;
    }
    else
    {
        mDeepHopsLeft = 0;
    }

    bytesRead = aMessage.Read(offset, sizeof(mAddress), &mAddress);
    VerifyOrExit(bytesRead == sizeof(mAddress), error = OT_ERROR_FAILED);

exit:
    return error;
}

}  // namespace Lowpan
}  // namespace ot
