/*
 * Copyright (c) 2013 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * Copyright (c) 2010 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * 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;
 * neither the name of the copyright holders 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
 * OWNER 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.
 */

#include "base/inet.hh"

#include <cstddef>
#include <cstdio>
#include <sstream>
#include <string>

#include "base/compiler.hh"
#include "base/cprintf.hh"
#include "base/logging.hh"
#include "base/types.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Net, networking);
namespace networking
{

EthAddr::EthAddr()
{
    std::memset(data, 0, ETH_ADDR_LEN);
}

EthAddr::EthAddr(const uint8_t ea[ETH_ADDR_LEN])
{
    for (int i = 0; i < ETH_ADDR_LEN; ++i)
        data[i] = ea[i];
}

EthAddr::EthAddr(const eth_addr &ea)
{
    for (int i = 0; i < ETH_ADDR_LEN; ++i)
        data[i] = ea.data[i];
}

EthAddr::EthAddr(const std::string &addr)
{
    parse(addr);
}

const EthAddr &
EthAddr::operator=(const eth_addr &ea)
{
    *data = *ea.data;
    return *this;
}

const EthAddr &
EthAddr::operator=(const std::string &addr)
{
    parse(addr);
    return *this;
}

void
EthAddr::parse(const std::string &addr)
{
    // the hack below is to make sure that ETH_ADDR_LEN is 6 otherwise
    // the sscanf function won't work.
    int bytes[ETH_ADDR_LEN == 6 ? ETH_ADDR_LEN : -1];
    if (sscanf(addr.c_str(), "%x:%x:%x:%x:%x:%x", &bytes[0], &bytes[1],
               &bytes[2], &bytes[3], &bytes[4], &bytes[5]) != ETH_ADDR_LEN) {
        std::memset(data, 0xff, ETH_ADDR_LEN);
        return;
    }

    for (int i = 0; i < ETH_ADDR_LEN; ++i) {
        if (bytes[i] & ~0xff) {
            std::memset(data, 0xff, ETH_ADDR_LEN);
            return;
        }

        data[i] = bytes[i];
    }
}

std::string
EthAddr::string() const
{
    std::stringstream stream;
    stream << *this;
    return stream.str();
}

bool
operator==(const EthAddr &left, const EthAddr &right)
{
    return !std::memcmp(left.bytes(), right.bytes(), ETH_ADDR_LEN);
}

    std::ostream &
operator<<(std::ostream &stream, const EthAddr &ea)
{
    const uint8_t *a = ea.addr();
    ccprintf(stream, "%x:%x:%x:%x:%x:%x", a[0], a[1], a[2], a[3], a[4], a[5]);
    return stream;
}

std::string
IpAddress::string() const
{
    std::stringstream stream;
    stream << *this;
    return stream.str();
}

bool
operator==(const IpAddress &left, const IpAddress &right)
{
    return left.ip() == right.ip();
}

std::ostream &
operator<<(std::ostream &stream, const IpAddress &ia)
{
    uint32_t ip = ia.ip();
    ccprintf(stream, "%x.%x.%x.%x",
            (uint8_t)(ip >> 24), (uint8_t)(ip >> 16),
            (uint8_t)(ip >> 8),  (uint8_t)(ip >> 0));
    return stream;
}

std::string
IpNetmask::string() const
{
    std::stringstream stream;
    stream << *this;
    return stream.str();
}

bool
operator==(const IpNetmask &left, const IpNetmask &right)
{
    return (left.ip() == right.ip()) &&
        (left.netmask() == right.netmask());
}

std::ostream &
operator<<(std::ostream &stream, const IpNetmask &in)
{
    ccprintf(stream, "%s/%d", (const IpAddress &)in, in.netmask());
    return stream;
}

std::string
IpWithPort::string() const
{
    std::stringstream stream;
    stream << *this;
    return stream.str();
}

bool
operator==(const IpWithPort &left, const IpWithPort &right)
{
    return (left.ip() == right.ip()) && (left.port() == right.port());
}

std::ostream &
operator<<(std::ostream &stream, const IpWithPort &iwp)
{
    ccprintf(stream, "%s:%d", (const IpAddress &)iwp, iwp.port());
    return stream;
}

uint16_t
cksum(const IpPtr &ptr)
{
    int sum = ip_cksum_add(ptr->bytes(), ptr->hlen(), 0);
    return ip_cksum_carry(sum);
}

uint16_t
__tu_cksum(const IpPtr &ip)
{
    int tcplen = ip->len() - ip->hlen();
    int sum = ip_cksum_add(ip->payload(), tcplen, 0);
    sum = ip_cksum_add(&ip->ip_src, 8, sum); // source and destination
    sum += htons(ip->ip_p + tcplen);
    return ip_cksum_carry(sum);
}

uint16_t
__tu_cksum6(const Ip6Ptr &ip6)
{
   int tcplen = ip6->plen() - ip6->extensionLength();
   int sum = ip_cksum_add(ip6->payload(), tcplen, 0);
   sum = ip_cksum_add(ip6->src(), 32, sum);
   sum += htons(ip6->proto() + tcplen);
   return ip_cksum_carry(sum);
}

uint16_t
cksum(const TcpPtr &tcp)
{
    if (IpPtr(tcp.packet())) {
        return __tu_cksum(IpPtr(tcp.packet()));
    } else if (Ip6Ptr(tcp.packet())) {
        return __tu_cksum6(Ip6Ptr(tcp.packet()));
    } else {
        panic("Unrecognized IP packet format");
    }
    // Should never reach here
    return 0;
}

uint16_t
cksum(const UdpPtr &udp)
{
    if (IpPtr(udp.packet())) {
        return __tu_cksum(IpPtr(udp.packet()));
    } else if (Ip6Ptr(udp.packet())) {
        return __tu_cksum6(Ip6Ptr(udp.packet()));
    } else {
        panic("Unrecognized IP packet format");
    }
    return 0;
}

bool
IpHdr::options(std::vector<const IpOpt *> &vec) const
{
    vec.clear();

    const uint8_t *data = bytes() + sizeof(struct ip_hdr);
    int all = hlen() - sizeof(struct ip_hdr);
    while (all > 0) {
        const IpOpt *opt = (const IpOpt *)data;
        int len = opt->len();
        if (all < len)
            return false;

        vec.push_back(opt);
        all -= len;
        data += len;
    }

    return true;
}

namespace
{

bool
ip6Extension(uint8_t nxt)
{
    return nxt == IP_PROTO_HOPOPTS || nxt == IP_PROTO_ROUTING ||
        nxt == IP_PROTO_FRAGMENT || nxt == IP_PROTO_AH ||
        nxt == IP_PROTO_ESP || nxt == IP_PROTO_DSTOPTS;
}

} // anonymous namespace

/* Scan the IP6 header for all header extensions
 * and return the number of headers found
 */
int
Ip6Hdr::extensionLength() const
{
    const uint8_t *data = bytes() + IP6_HDR_LEN;
    uint8_t nxt = ip6_nxt;
    int len = 0;
    GEM5_VAR_USED int all = plen();

    while (ip6Extension(nxt)) {
        const Ip6Opt *ext = (const Ip6Opt *)data;
        nxt = ext->nxt();
        len += ext->len();
        data += ext->len();
        all -= ext->len();
        assert(all >= 0);
    }
    return len;
}

/* Scan the IP6 header for a particular extension
 * header type and return a pointer to it if it
 * exists, otherwise return NULL
 */
const Ip6Opt*
Ip6Hdr::getExt(uint8_t ext_type) const
{
    const uint8_t *data = bytes() + IP6_HDR_LEN;
    uint8_t nxt = ip6_nxt;
    Ip6Opt* opt = NULL;
    GEM5_VAR_USED int all = plen();

    while (ip6Extension(nxt)) {
        opt = (Ip6Opt *)data;
        if (nxt == ext_type) {
            break;
        }
        nxt = opt->nxt();
        data += opt->len();
        all -= opt->len();
        opt = NULL;
        assert(all >= 0);
    }
    return (const Ip6Opt*)opt;
}

/* Scan the IP6 header and any extension headers
 * to find what type of Layer 4 header exists
 * after this header
 */
uint8_t
Ip6Hdr::proto() const
{
    const uint8_t *data = bytes() + IP6_HDR_LEN;
    uint8_t nxt = ip6_nxt;
    GEM5_VAR_USED int all = plen();

    while (ip6Extension(nxt)) {
        const Ip6Opt *ext = (const Ip6Opt *)data;
        nxt = ext->nxt();
        data += ext->len();
        all -= ext->len();
        assert(all >= 0);
    }
    return nxt;
}

bool
TcpHdr::options(std::vector<const TcpOpt *> &vec) const
{
    vec.clear();

    const uint8_t *data = bytes() + sizeof(struct tcp_hdr);
    int all = off() - sizeof(struct tcp_hdr);
    while (all > 0) {
        const TcpOpt *opt = (const TcpOpt *)data;
        int len = opt->len();
        if (all < len)
            return false;

        vec.push_back(opt);
        all -= len;
        data += len;
    }

    return true;
}

int
hsplit(const EthPacketPtr &ptr)
{
    int split_point = 0;

    IpPtr ip(ptr);
    Ip6Ptr ip6(ptr);
    if (ip) {
        split_point = ip.pstart();

        TcpPtr tcp(ip);
        if (tcp)
            split_point = tcp.pstart();

        UdpPtr udp(ip);
        if (udp)
            split_point = udp.pstart();
    } else if (ip6) {
        split_point = ip6.pstart();

        TcpPtr tcp(ip6);
        if (tcp)
            split_point = tcp.pstart();
        UdpPtr udp(ip6);
        if (udp)
            split_point = udp.pstart();
    }
    return split_point;
}

} // namespace networking
} // namespace gem5
