/*
 * 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.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 *          Gabe Black
 *          Geoffrey Blake
 */

#ifndef __BASE_INET_HH__
#define __BASE_INET_HH__

#include <iosfwd>
#include <string>
#include <utility>
#include <vector>

#include "base/types.hh"
#include "dev/net/etherpkt.hh"
#include "dnet/os.h"
#include "dnet/eth.h"
#include "dnet/ip.h"
#include "dnet/ip6.h"
#include "dnet/addr.h"
#include "dnet/arp.h"
#include "dnet/icmp.h"
#include "dnet/tcp.h"
#include "dnet/udp.h"
#include "dnet/intf.h"
#include "dnet/route.h"
#include "dnet/fw.h"
#include "dnet/blob.h"
#include "dnet/rand.h"

namespace Net {

/*
 * Ethernet Stuff
 */
struct EthAddr : protected eth_addr
{
  protected:
    void parse(const std::string &addr);

  public:
    EthAddr();
    EthAddr(const uint8_t ea[ETH_ADDR_LEN]);
    EthAddr(const eth_addr &ea);
    EthAddr(const std::string &addr);
    const EthAddr &operator=(const eth_addr &ea);
    const EthAddr &operator=(const std::string &addr);

    int size() const { return sizeof(eth_addr); }

    const uint8_t *bytes() const { return &data[0]; }
    uint8_t *bytes() { return &data[0]; }

    const uint8_t *addr() const { return &data[0]; }
    bool unicast() const { return !(data[0] & 0x01); }
    bool multicast() const { return !unicast() && !broadcast(); }
    bool broadcast() const
    {
        bool isBroadcast = true;
        for (int i = 0; i < ETH_ADDR_LEN; ++i) {
            isBroadcast = isBroadcast && data[i] == 0xff;
        }

        return isBroadcast;
    }

    std::string string() const;

    operator uint64_t() const
    {
        uint64_t reg = 0;
        reg |= ((uint64_t)data[0]) << 40;
        reg |= ((uint64_t)data[1]) << 32;
        reg |= ((uint64_t)data[2]) << 24;
        reg |= ((uint64_t)data[3]) << 16;
        reg |= ((uint64_t)data[4]) << 8;
        reg |= ((uint64_t)data[5]) << 0;
        return reg;
    }

};

std::ostream &operator<<(std::ostream &stream, const EthAddr &ea);
bool operator==(const EthAddr &left, const EthAddr &right);

struct EthHdr : public eth_hdr
{
    bool isVlan() const { return (ntohs(eth_type) == ETH_TYPE_8021Q); }
    uint16_t type() const {
        if (!isVlan())
            return ntohs(eth_type);
        else
            // L3 type is now 16 bytes into the hdr with 802.1Q
            // instead of 12.  dnet/eth.h only supports 802.1
            return ntohs(*((uint16_t*)(((uint8_t *)this) + 16)));
    }
    uint16_t vlanId() const {
        if (isVlan())
            return ntohs(*((uint16_t*)(((uint8_t *)this) + 14)));
        else
            return 0x0000;
    }

    const EthAddr &src() const { return *(EthAddr *)&eth_src; }
    const EthAddr &dst() const { return *(EthAddr *)&eth_dst; }

    int size() const {
        if (!isVlan())
            return sizeof(eth_hdr);
        else
            return (sizeof(eth_hdr)+4);
    }

    const uint8_t *bytes() const { return (const uint8_t *)this; }
    const uint8_t *payload() const { return bytes() + size(); }
    uint8_t *bytes() { return (uint8_t *)this; }
    uint8_t *payload() { return bytes() + size(); }
};

class EthPtr
{
  protected:
    friend class IpPtr;
    friend class Ip6Ptr;
    EthPacketPtr p;

  public:
    EthPtr() {}
    EthPtr(const EthPacketPtr &ptr) : p(ptr) { }

    EthHdr *operator->() { return (EthHdr *)p->data; }
    EthHdr &operator*() { return *(EthHdr *)p->data; }
    operator EthHdr *() { return (EthHdr *)p->data; }

    const EthHdr *operator->() const { return (const EthHdr *)p->data; }
    const EthHdr &operator*() const { return *(const EthHdr *)p->data; }
    operator const EthHdr *() const { return (const EthHdr *)p->data; }

    const EthPtr &operator=(const EthPacketPtr &ptr) { p = ptr; return *this; }

    const EthPacketPtr packet() const { return p; }
    EthPacketPtr packet() { return p; }
    bool operator!() const { return !p; }
    operator bool() const { return (p != nullptr); }
    int off() const { return 0; }
    int pstart() const { return off() + ((const EthHdr*)p->data)->size(); }
};

/*
 * IP Stuff
 */
struct IpAddress
{
  protected:
    uint32_t _ip;

  public:
    IpAddress() : _ip(0)
    {}
    IpAddress(const uint32_t __ip) : _ip(__ip)
    {}

    uint32_t ip() const { return _ip; }

    std::string string() const;
};

std::ostream &operator<<(std::ostream &stream, const IpAddress &ia);
bool operator==(const IpAddress &left, const IpAddress &right);

struct IpNetmask : public IpAddress
{
  protected:
    uint8_t _netmask;

  public:
    IpNetmask() : IpAddress(), _netmask(0)
    {}
    IpNetmask(const uint32_t __ip, const uint8_t __netmask) :
        IpAddress(__ip), _netmask(__netmask)
    {}

    uint8_t netmask() const { return _netmask; }

    std::string string() const;
};

std::ostream &operator<<(std::ostream &stream, const IpNetmask &in);
bool operator==(const IpNetmask &left, const IpNetmask &right);

struct IpWithPort : public IpAddress
{
  protected:
    uint16_t _port;

  public:
    IpWithPort() : IpAddress(), _port(0)
    {}
    IpWithPort(const uint32_t __ip, const uint16_t __port) :
        IpAddress(__ip), _port(__port)
    {}

    uint8_t port() const { return _port; }

    std::string string() const;
};

std::ostream &operator<<(std::ostream &stream, const IpWithPort &iwp);
bool operator==(const IpWithPort &left, const IpWithPort &right);

struct IpOpt;
struct IpHdr : public ip_hdr
{
    uint8_t  version() const { return ip_v; }
    uint8_t  hlen() const { return ip_hl * 4; }
    uint8_t  tos() const { return ip_tos; }
    uint16_t len() const { return ntohs(ip_len); }
    uint16_t id() const { return ntohs(ip_id); }
    uint16_t frag_flags() const { return ntohs(ip_off) >> 13; }
    uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; }
    uint8_t  ttl() const { return ip_ttl; }
    uint8_t  proto() const { return ip_p; }
    uint16_t sum() const { return ip_sum; }
    uint32_t src() const { return ntohl(ip_src); }
    uint32_t dst() const { return ntohl(ip_dst); }

    void sum(uint16_t sum) { ip_sum = sum; }
    void id(uint16_t _id) { ip_id = htons(_id); }
    void len(uint16_t _len) { ip_len = htons(_len); }

    bool options(std::vector<const IpOpt *> &vec) const;

    int size() const { return hlen(); }
    const uint8_t *bytes() const { return (const uint8_t *)this; }
    const uint8_t *payload() const { return bytes() + size(); }
    uint8_t *bytes() { return (uint8_t *)this; }
    uint8_t *payload() { return bytes() + size(); }
};

class IpPtr
{
  protected:
    friend class TcpPtr;
    friend class UdpPtr;
    EthPacketPtr p;
    bool eth_hdr_vlan;

    void set(const EthPacketPtr &ptr)
    {
        p = 0;
        eth_hdr_vlan = false;

        if (ptr) {
            EthHdr *eth = (EthHdr *)ptr->data;
            if (eth->type() == ETH_TYPE_IP)
                p = ptr;
            if (eth->isVlan())
                eth_hdr_vlan = true;
        }
    }

  public:
    IpPtr() : p(0), eth_hdr_vlan(false) {}
    IpPtr(const EthPacketPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr); }
    IpPtr(const EthPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr.p); }
    IpPtr(const IpPtr &ptr) : p(ptr.p), eth_hdr_vlan(ptr.eth_hdr_vlan) { }

    IpHdr *get() { return (IpHdr *)(p->data + sizeof(eth_hdr) +
                                   ((eth_hdr_vlan) ? 4 : 0)); }
    IpHdr *operator->() { return get(); }
    IpHdr &operator*() { return *get(); }

    const IpHdr *get() const
    { return (const IpHdr *)(p->data + sizeof(eth_hdr) +
                            ((eth_hdr_vlan) ? 4 : 0)); }
    const IpHdr *operator->() const { return get(); }
    const IpHdr &operator*() const { return *get(); }

    const IpPtr &operator=(const EthPacketPtr &ptr) { set(ptr); return *this; }
    const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; }
    const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; }

    const EthPacketPtr packet() const { return p; }
    EthPacketPtr packet() { return p; }
    bool operator!() const { return !p; }
    operator bool() const { return (p != nullptr); }
    int off() const { return (sizeof(eth_hdr) + ((eth_hdr_vlan) ? 4 : 0)); }
    int pstart() const { return (off() + get()->size()); }
};

uint16_t cksum(const IpPtr &ptr);

struct IpOpt : public ip_opt
{
    uint8_t type() const { return opt_type; }
    uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); }
    uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); }
    uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); }
    uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; }

    bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); }
    bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); }
    bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); }

    const uint8_t *data() const { return opt_data.data8; }
    void sec(ip_opt_data_sec &sec) const;
    void lsrr(ip_opt_data_rr &rr) const;
    void ssrr(ip_opt_data_rr &rr) const;
    void ts(ip_opt_data_ts &ts) const;
    uint16_t satid() const { return ntohs(opt_data.satid); }
    uint16_t mtup() const { return ntohs(opt_data.mtu); }
    uint16_t mtur() const { return ntohs(opt_data.mtu); }
    void tr(ip_opt_data_tr &tr) const;
    uint16_t rtralt() const { return ntohs(opt_data.rtralt); }
    void sdb(std::vector<uint32_t> &vec) const;
};

/*
 * Ip6 Classes
 */
struct Ip6Opt;
struct Ip6Hdr : public ip6_hdr
{
    uint8_t version() const { return ip6_vfc; }
    uint32_t flow() const { return ntohl(ip6_flow); }
    uint16_t plen() const { return ntohs(ip6_plen); }
    uint16_t hlen() const { return IP6_HDR_LEN; }
    uint8_t nxt() const { return ip6_nxt; }
    uint8_t hlim() const { return ip6_hlim; }

    const uint8_t* src() const { return ip6_src.data; }
    const uint8_t* dst() const { return ip6_dst.data; }

    int extensionLength() const;
    const Ip6Opt* getExt(uint8_t ext) const;
    const Ip6Opt* fragmentExt() const { return getExt(IP_PROTO_FRAGMENT); }
    const Ip6Opt* rtTypeExt() const { return getExt(IP_PROTO_ROUTING); }
    const Ip6Opt* dstOptExt() const { return getExt(IP_PROTO_DSTOPTS); }
    uint8_t proto() const;

    void plen(uint16_t _plen) { ip6_plen = htons(_plen); }

    int size() const { return IP6_HDR_LEN + extensionLength(); }
    const uint8_t *bytes() const { return (const uint8_t *)this; }
    const uint8_t *payload() const { return bytes() + IP6_HDR_LEN
                                            + extensionLength(); }
    uint8_t *bytes() { return (uint8_t *)this; }
    uint8_t *payload() { return bytes() + IP6_HDR_LEN
                                + extensionLength(); }
};

class Ip6Ptr
{
  protected:
    friend class TcpPtr;
    friend class UdpPtr;
    EthPacketPtr p;
    bool eth_hdr_vlan;

    void set(const EthPacketPtr &ptr)
    {
        p = 0;
        eth_hdr_vlan = false;

        if (ptr) {
            EthHdr *eth = (EthHdr *)ptr->data;
            if (eth->type() == ETH_TYPE_IPV6)
                p = ptr;
            if (eth->isVlan())
                eth_hdr_vlan = true;
        }
    }

  public:
    Ip6Ptr() : p(0), eth_hdr_vlan(false) {}
    Ip6Ptr(const EthPacketPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr); }
    Ip6Ptr(const EthPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr.p); }
    Ip6Ptr(const Ip6Ptr &ptr) : p(ptr.p), eth_hdr_vlan(ptr.eth_hdr_vlan) { }

    Ip6Hdr *get() { return (Ip6Hdr *)(p->data + sizeof(eth_hdr)
                                      + ((eth_hdr_vlan) ? 4 : 0)); }
    Ip6Hdr *operator->() { return get(); }
    Ip6Hdr &operator*() { return *get(); }

    const Ip6Hdr *get() const
    { return (const Ip6Hdr *)(p->data + sizeof(eth_hdr)
                              + ((eth_hdr_vlan) ? 4 : 0)); }
    const Ip6Hdr *operator->() const { return get(); }
    const Ip6Hdr &operator*() const { return *get(); }

    const Ip6Ptr &operator=(const EthPacketPtr &ptr)
    { set(ptr); return *this; }
    const Ip6Ptr &operator=(const EthPtr &ptr)
    { set(ptr.p); return *this; }
    const Ip6Ptr &operator=(const Ip6Ptr &ptr)
    { p = ptr.p; return *this; }

    const EthPacketPtr packet() const { return p; }
    EthPacketPtr packet() { return p; }
    bool operator!() const { return !p; }
    operator bool() const { return (p != nullptr); }
    int off() const { return sizeof(eth_hdr) + ((eth_hdr_vlan) ? 4 : 0); }
    int pstart() const { return off() + get()->size(); }
};

// Dnet supplied ipv6 opt header is incomplete and
// newer NIC card filters expect a more robust
// ipv6 header option declaration.
struct ip6_opt_fragment {
    uint16_t offlg;
    uint32_t ident;
};

struct ip6_opt_routing_type2 {
    uint8_t type;
    uint8_t segleft;
    uint32_t reserved;
    ip6_addr_t addr;
};

#define HOME_ADDRESS_OPTION 0xC9
struct ip6_opt_dstopts {
    uint8_t type;
    uint8_t length;
    ip6_addr_t addr;
} __attribute__((packed));

struct ip6_opt_hdr
{
    uint8_t ext_nxt;
    uint8_t ext_len;
    union {
        struct ip6_opt_fragment fragment;
        struct ip6_opt_routing_type2 rtType2;
        struct ip6_opt_dstopts dstOpts;
    } ext_data;
} __attribute__((packed));

struct Ip6Opt : public ip6_opt_hdr
{
    uint8_t nxt() const { return ext_nxt; }
    uint8_t extlen() const { return ext_len; }
    uint8_t len() const { return extlen() + 8; }

    // Supporting the types of header extensions likely to be encountered:
    // fragment, routing type 2 and dstopts.

    // Routing type 2
    uint8_t  rtType2Type() const { return ext_data.rtType2.type; }
    uint8_t  rtType2SegLft() const { return ext_data.rtType2.segleft; }
    const uint8_t* rtType2Addr() const { return ext_data.rtType2.addr.data; }

    // Fragment
    uint16_t fragmentOfflg() const { return ntohs(ext_data.fragment.offlg); }
    uint32_t fragmentIdent() const { return ntohl(ext_data.fragment.ident); }

    // Dst Options/Home Address Option
    uint8_t dstOptType() const { return ext_data.dstOpts.type; }
    uint8_t dstOptLength() const { return ext_data.dstOpts.length; }
    const uint8_t* dstOptAddr() const { return ext_data.dstOpts.addr.data; }
};


/*
 * TCP Stuff
 */
struct TcpOpt;
struct TcpHdr : public tcp_hdr
{
    uint16_t sport() const { return ntohs(th_sport); }
    uint16_t dport() const { return ntohs(th_dport); }
    uint32_t seq() const { return ntohl(th_seq); }
    uint32_t ack() const { return ntohl(th_ack); }
    uint8_t  off() const { return th_off*4; }
    uint8_t  flags() const { return th_flags & 0x3f; }
    uint16_t win() const { return ntohs(th_win); }
    uint16_t sum() const { return th_sum; }
    uint16_t urp() const { return ntohs(th_urp); }

    void sum(uint16_t sum) { th_sum = sum; }
    void seq(uint32_t _seq) { th_seq = htonl(_seq); }
    void flags(uint8_t _flags) { th_flags  = _flags; }

    bool options(std::vector<const TcpOpt *> &vec) const;

    int size() const { return off(); }
    const uint8_t *bytes() const { return (const uint8_t *)this; }
    const uint8_t *payload() const { return bytes() + size(); }
    uint8_t *bytes() { return (uint8_t *)this; }
    uint8_t *payload() { return bytes() + size(); }
};

class TcpPtr
{
  protected:
    EthPacketPtr p;
    int _off;

    void set(const EthPacketPtr &ptr, int offset) { p = ptr; _off = offset; }
    void set(const IpPtr &ptr)
    {
        if (ptr && ptr->proto() == IP_PROTO_TCP)
            set(ptr.p, ptr.pstart());
        else
            set(0, 0);
    }
    void set(const Ip6Ptr &ptr)
    {
        if (ptr && ptr->proto() == IP_PROTO_TCP)
            set(ptr.p, ptr.pstart());
        else
            set(0, 0);
    }

  public:
    TcpPtr() : p(0), _off(0) {}
    TcpPtr(const IpPtr &ptr) : p(0), _off(0) { set(ptr); }
    TcpPtr(const Ip6Ptr &ptr) : p(0), _off(0) { set(ptr); }
    TcpPtr(const TcpPtr &ptr) : p(ptr.p), _off(ptr._off) {}

    TcpHdr *get() { return (TcpHdr *)(p->data + _off); }
    TcpHdr *operator->() { return get(); }
    TcpHdr &operator*() { return *get(); }

    const TcpHdr *get() const { return (const TcpHdr *)(p->data + _off); }
    const TcpHdr *operator->() const { return get(); }
    const TcpHdr &operator*() const { return *get(); }

    const TcpPtr &operator=(const IpPtr &i)
    { set(i); return *this; }
    const TcpPtr &operator=(const TcpPtr &t)
    { set(t.p, t._off); return *this; }

    const EthPacketPtr packet() const { return p; }
    EthPacketPtr packet() { return p; }
    bool operator!() const { return !p; }
    operator bool() const { return (p != nullptr); }
    int off() const { return _off; }
    int pstart() const { return off() + get()->size(); }
};

uint16_t cksum(const TcpPtr &ptr);

struct TcpOpt : public tcp_opt
{
    uint8_t type() const { return opt_type; }
    uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; }

    bool isopt(int opt) const { return type() == opt; }

    const uint8_t *data() const { return opt_data.data8; }

    uint16_t mss() const { return ntohs(opt_data.mss); }
    uint8_t wscale() const { return opt_data.wscale; }
    uint32_t echo() const { return ntohl(opt_data.echo); }
    uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); }
    uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); }
    uint32_t cc() const { return ntohl(opt_data.cc); }
    uint8_t cksum() const{ return opt_data.cksum; }
    const uint8_t *md5() const { return opt_data.md5; }

    int size() const { return len(); }
    const uint8_t *bytes() const { return (const uint8_t *)this; }
    const uint8_t *payload() const { return bytes() + size(); }
    uint8_t *bytes() { return (uint8_t *)this; }
    uint8_t *payload() { return bytes() + size(); }
};

/*
 * UDP Stuff
 */
struct UdpHdr : public udp_hdr
{
    uint16_t sport() const { return ntohs(uh_sport); }
    uint16_t dport() const { return ntohs(uh_dport); }
    uint16_t len() const { return ntohs(uh_ulen); }
    uint16_t sum() const { return uh_sum; }

    void sum(uint16_t sum) { uh_sum = sum; }
    void len(uint16_t _len) { uh_ulen = htons(_len); }

    int size() const { return sizeof(udp_hdr); }
    const uint8_t *bytes() const { return (const uint8_t *)this; }
    const uint8_t *payload() const { return bytes() + size(); }
    uint8_t *bytes() { return (uint8_t *)this; }
    uint8_t *payload() { return bytes() + size(); }
};

class UdpPtr
{
  protected:
    EthPacketPtr p;
    int _off;

    void set(const EthPacketPtr &ptr, int offset) { p = ptr; _off = offset; }
    void set(const IpPtr &ptr)
    {
        if (ptr && ptr->proto() == IP_PROTO_UDP)
            set(ptr.p, ptr.pstart());
        else
            set(0, 0);
    }
    void set(const Ip6Ptr &ptr)
    {
        if (ptr && ptr->proto() == IP_PROTO_UDP)
            set(ptr.p, ptr.pstart());
        else
            set(0, 0);
    }

  public:
    UdpPtr() : p(0), _off(0) {}
    UdpPtr(const IpPtr &ptr) : p(0), _off(0) { set(ptr); }
    UdpPtr(const Ip6Ptr &ptr) : p(0), _off(0) { set(ptr); }
    UdpPtr(const UdpPtr &ptr) : p(ptr.p), _off(ptr._off) {}

    UdpHdr *get() { return (UdpHdr *)(p->data + _off); }
    UdpHdr *operator->() { return get(); }
    UdpHdr &operator*() { return *get(); }

    const UdpHdr *get() const { return (const UdpHdr *)(p->data + _off); }
    const UdpHdr *operator->() const { return get(); }
    const UdpHdr &operator*() const { return *get(); }

    const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; }
    const UdpPtr &operator=(const UdpPtr &t)
    { set(t.p, t._off); return *this; }

    const EthPacketPtr packet() const { return p; }
    EthPacketPtr packet() { return p; }
    bool operator!() const { return !p; }
    operator bool() const { return (p != nullptr); }
    int off() const { return _off; }
    int pstart() const { return off() + get()->size(); }
};

uint16_t __tu_cksum6(const Ip6Ptr &ip6);
uint16_t __tu_cksum(const IpPtr &ip);
uint16_t cksum(const UdpPtr &ptr);

int hsplit(const EthPacketPtr &ptr);

} // namespace Net

#endif // __BASE_INET_HH__
