inet.hh revision 2566
12381SN/A/*
22592SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32381SN/A * All rights reserved.
42381SN/A *
52381SN/A * Redistribution and use in source and binary forms, with or without
62381SN/A * modification, are permitted provided that the following conditions are
72381SN/A * met: redistributions of source code must retain the above copyright
82381SN/A * notice, this list of conditions and the following disclaimer;
92381SN/A * redistributions in binary form must reproduce the above copyright
102381SN/A * notice, this list of conditions and the following disclaimer in the
112381SN/A * documentation and/or other materials provided with the distribution;
122381SN/A * neither the name of the copyright holders nor the names of its
132381SN/A * contributors may be used to endorse or promote products derived from
142381SN/A * this software without specific prior written permission.
152381SN/A *
162381SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172381SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182381SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192381SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202381SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212381SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222381SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232381SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242381SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252381SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262381SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#ifndef __BASE_INET_HH__
302665Ssaidi@eecs.umich.edu#define __BASE_INET_HH__
312381SN/A
322381SN/A#include <iosfwd>
332381SN/A#include <string>
342381SN/A#include <utility>
352662Sstever@eecs.umich.edu#include <vector>
362381SN/A
372381SN/A#include "base/range.hh"
382381SN/A#include "dev/etherpkt.hh"
392381SN/A#include "sim/host.hh"
402381SN/A
413348Sbinkertn@umich.edu#include "dnet/os.h"
423348Sbinkertn@umich.edu#include "dnet/eth.h"
434022Sstever@eecs.umich.edu#include "dnet/ip.h"
443348Sbinkertn@umich.edu#include "dnet/ip6.h"
455735Snate@binkert.org#include "dnet/addr.h"
464024Sbinkertn@umich.edu#include "dnet/arp.h"
474610Ssaidi@eecs.umich.edu#include "dnet/icmp.h"
485735Snate@binkert.org#include "dnet/tcp.h"
493940Ssaidi@eecs.umich.edu#include "dnet/udp.h"
505314Sstever@gmail.com#include "dnet/intf.h"
512392SN/A#include "dnet/route.h"
522980Sgblack@eecs.umich.edu#include "dnet/fw.h"
534167Sbinkertn@umich.edu#include "dnet/blob.h"
542394SN/A#include "dnet/rand.h"
553940Ssaidi@eecs.umich.edu
562394SN/Anamespace Net {
573349Sbinkertn@umich.edu
582394SN/A/*
592812Srdreslin@umich.edu * Ethernet Stuff
602812Srdreslin@umich.edu */
614022Sstever@eecs.umich.edustruct EthAddr : protected eth_addr
624022Sstever@eecs.umich.edu{
635735Snate@binkert.org  protected:
645735Snate@binkert.org    void parse(const std::string &addr);
654022Sstever@eecs.umich.edu
665735Snate@binkert.org  public:
675735Snate@binkert.org    EthAddr();
685735Snate@binkert.org    EthAddr(const uint8_t ea[ETH_ADDR_LEN]);
694022Sstever@eecs.umich.edu    EthAddr(const eth_addr &ea);
704022Sstever@eecs.umich.edu    EthAddr(const std::string &addr);
714022Sstever@eecs.umich.edu    const EthAddr &operator=(const eth_addr &ea);
724022Sstever@eecs.umich.edu    const EthAddr &operator=(const std::string &addr);
734473Sstever@eecs.umich.edu
745319Sstever@gmail.com    int size() const { return sizeof(eth_addr); }
754022Sstever@eecs.umich.edu
764022Sstever@eecs.umich.edu    const uint8_t *bytes() const { return &data[0]; }
774022Sstever@eecs.umich.edu    uint8_t *bytes() { return &data[0]; }
784022Sstever@eecs.umich.edu
794022Sstever@eecs.umich.edu    const uint8_t *addr() const { return &data[0]; }
804022Sstever@eecs.umich.edu    bool unicast() const { return data[0] == 0x00; }
814022Sstever@eecs.umich.edu    bool multicast() const { return data[0] == 0x01; }
824022Sstever@eecs.umich.edu    bool broadcast() const { return data[0] == 0xff; }
834022Sstever@eecs.umich.edu    std::string string() const;
844022Sstever@eecs.umich.edu
854628Sstever@eecs.umich.edu    operator uint64_t() const
864022Sstever@eecs.umich.edu    {
874022Sstever@eecs.umich.edu        uint64_t reg = 0;
884626Sstever@eecs.umich.edu        reg |= ((uint64_t)data[0]) << 40;
894626Sstever@eecs.umich.edu        reg |= ((uint64_t)data[1]) << 32;
904626Sstever@eecs.umich.edu        reg |= ((uint64_t)data[2]) << 24;
914040Ssaidi@eecs.umich.edu        reg |= ((uint64_t)data[3]) << 16;
924040Ssaidi@eecs.umich.edu        reg |= ((uint64_t)data[4]) << 8;
935650Sgblack@eecs.umich.edu        reg |= ((uint64_t)data[5]) << 0;
945650Sgblack@eecs.umich.edu        return reg;
954870Sstever@eecs.umich.edu    }
964870Sstever@eecs.umich.edu
974870Sstever@eecs.umich.edu};
984870Sstever@eecs.umich.edu
994870Sstever@eecs.umich.edustd::ostream &operator<<(std::ostream &stream, const EthAddr &ea);
1004870Sstever@eecs.umich.edubool operator==(const EthAddr &left, const EthAddr &right);
1014870Sstever@eecs.umich.edu
1025314Sstever@gmail.comstruct EthHdr : public eth_hdr
1035314Sstever@gmail.com{
1044022Sstever@eecs.umich.edu    uint16_t type() const { return ntohs(eth_type); }
1054022Sstever@eecs.umich.edu    const EthAddr &src() const { return *(EthAddr *)&eth_src; }
1064022Sstever@eecs.umich.edu    const EthAddr &dst() const { return *(EthAddr *)&eth_dst; }
1074022Sstever@eecs.umich.edu
1085735Snate@binkert.org    int size() const { return sizeof(eth_hdr); }
1095735Snate@binkert.org
1105735Snate@binkert.org    const uint8_t *bytes() const { return (const uint8_t *)this; }
1114022Sstever@eecs.umich.edu    const uint8_t *payload() const { return bytes() + size(); }
1124022Sstever@eecs.umich.edu    uint8_t *bytes() { return (uint8_t *)this; }
1134626Sstever@eecs.umich.edu    uint8_t *payload() { return bytes() + size(); }
1144626Sstever@eecs.umich.edu};
1154626Sstever@eecs.umich.edu
1164022Sstever@eecs.umich.educlass EthPtr
1174626Sstever@eecs.umich.edu{
1184626Sstever@eecs.umich.edu  protected:
1194626Sstever@eecs.umich.edu    friend class IpPtr;
1204626Sstever@eecs.umich.edu    EthPacketPtr p;
1214022Sstever@eecs.umich.edu
1224022Sstever@eecs.umich.edu  public:
1236076Sgblack@eecs.umich.edu    EthPtr() {}
1244626Sstever@eecs.umich.edu    EthPtr(const EthPacketPtr &ptr) : p(ptr) { }
1254870Sstever@eecs.umich.edu
1265314Sstever@gmail.com    EthHdr *operator->() { return (EthHdr *)p->data; }
1274022Sstever@eecs.umich.edu    EthHdr &operator*() { return *(EthHdr *)p->data; }
1284022Sstever@eecs.umich.edu    operator EthHdr *() { return (EthHdr *)p->data; }
1294022Sstever@eecs.umich.edu
1305735Snate@binkert.org    const EthHdr *operator->() const { return (const EthHdr *)p->data; }
1315735Snate@binkert.org    const EthHdr &operator*() const { return *(const EthHdr *)p->data; }
1325735Snate@binkert.org    operator const EthHdr *() const { return (const EthHdr *)p->data; }
1335735Snate@binkert.org
1345735Snate@binkert.org    const EthPtr &operator=(const EthPacketPtr &ptr) { p = ptr; return *this; }
1355735Snate@binkert.org
1365735Snate@binkert.org    const EthPacketPtr packet() const { return p; }
1374022Sstever@eecs.umich.edu    EthPacketPtr packet() { return p; }
1385735Snate@binkert.org    bool operator!() const { return !p; }
1395735Snate@binkert.org    operator bool() const { return p; }
1404022Sstever@eecs.umich.edu};
1415735Snate@binkert.org
1424022Sstever@eecs.umich.edu/*
1434022Sstever@eecs.umich.edu * IP Stuff
1444022Sstever@eecs.umich.edu */
1455735Snate@binkert.orgstruct IpOpt;
1464022Sstever@eecs.umich.edustruct IpHdr : public ip_hdr
1474022Sstever@eecs.umich.edu{
1484022Sstever@eecs.umich.edu    uint8_t  version() const { return ip_v; }
1494022Sstever@eecs.umich.edu    uint8_t  hlen() const { return ip_hl * 4; }
1504022Sstever@eecs.umich.edu    uint8_t  tos() const { return ip_tos; }
1514022Sstever@eecs.umich.edu    uint16_t len() const { return ntohs(ip_len); }
1525735Snate@binkert.org    uint16_t id() const { return ntohs(ip_id); }
1535735Snate@binkert.org    uint16_t frag_flags() const { return ntohs(ip_off) >> 13; }
1545735Snate@binkert.org    uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; }
1554022Sstever@eecs.umich.edu    uint8_t  ttl() const { return ip_ttl; }
1564022Sstever@eecs.umich.edu    uint8_t  proto() const { return ip_p; }
1574022Sstever@eecs.umich.edu    uint16_t sum() const { return ip_sum; }
1584022Sstever@eecs.umich.edu    uint32_t src() const { return ntohl(ip_src); }
1594022Sstever@eecs.umich.edu    uint32_t dst() const { return ntohl(ip_dst); }
1604022Sstever@eecs.umich.edu
1614022Sstever@eecs.umich.edu    void sum(uint16_t sum) { ip_sum = sum; }
1624022Sstever@eecs.umich.edu
1634022Sstever@eecs.umich.edu    bool options(std::vector<const IpOpt *> &vec) const;
1644870Sstever@eecs.umich.edu
1654022Sstever@eecs.umich.edu    int size() const { return hlen(); }
1664022Sstever@eecs.umich.edu    const uint8_t *bytes() const { return (const uint8_t *)this; }
1674022Sstever@eecs.umich.edu    const uint8_t *payload() const { return bytes() + size(); }
1684626Sstever@eecs.umich.edu    uint8_t *bytes() { return (uint8_t *)this; }
1696076Sgblack@eecs.umich.edu    uint8_t *payload() { return bytes() + size(); }
1704870Sstever@eecs.umich.edu};
1715314Sstever@gmail.com
1724022Sstever@eecs.umich.educlass IpPtr
1735735Snate@binkert.org{
1745735Snate@binkert.org  protected:
1755735Snate@binkert.org    friend class TcpPtr;
1764022Sstever@eecs.umich.edu    friend class UdpPtr;
1774022Sstever@eecs.umich.edu    EthPacketPtr p;
1784022Sstever@eecs.umich.edu
1795735Snate@binkert.org    const IpHdr *h() const
1805735Snate@binkert.org    { return (const IpHdr *)(p->data + sizeof(eth_hdr)); }
1814022Sstever@eecs.umich.edu    IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); }
1824022Sstever@eecs.umich.edu
1835735Snate@binkert.org    void set(const EthPacketPtr &ptr)
1845735Snate@binkert.org    {
1855735Snate@binkert.org        EthHdr *eth = (EthHdr *)ptr->data;
1864022Sstever@eecs.umich.edu        if (eth->type() == ETH_TYPE_IP)
1875735Snate@binkert.org            p = ptr;
1885735Snate@binkert.org        else
1894022Sstever@eecs.umich.edu            p = 0;
1904022Sstever@eecs.umich.edu    }
1912381SN/A
1922662Sstever@eecs.umich.edu  public:
1932662Sstever@eecs.umich.edu    IpPtr() {}
1942662Sstever@eecs.umich.edu    IpPtr(const EthPacketPtr &ptr) { set(ptr); }
1952662Sstever@eecs.umich.edu    IpPtr(const EthPtr &ptr) { set(ptr.p); }
1962662Sstever@eecs.umich.edu    IpPtr(const IpPtr &ptr) : p(ptr.p) { }
1972381SN/A
1985314Sstever@gmail.com    IpHdr *operator->() { return h(); }
1992381SN/A    IpHdr &operator*() { return *h(); }
2002813Srdreslin@umich.edu    operator IpHdr *() { return h(); }
2015735Snate@binkert.org
2025735Snate@binkert.org    const IpHdr *operator->() const { return h(); }
2035735Snate@binkert.org    const IpHdr &operator*() const { return *h(); }
2044022Sstever@eecs.umich.edu    operator const IpHdr *() const { return h(); }
2055735Snate@binkert.org
2065735Snate@binkert.org    const IpPtr &operator=(const EthPacketPtr &ptr) { set(ptr); return *this; }
2075735Snate@binkert.org    const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; }
2085735Snate@binkert.org    const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; }
2095735Snate@binkert.org
2105735Snate@binkert.org    const EthPacketPtr packet() const { return p; }
2115735Snate@binkert.org    EthPacketPtr packet() { return p; }
2125735Snate@binkert.org    bool operator!() const { return !p; }
2135735Snate@binkert.org    operator bool() const { return p; }
2145735Snate@binkert.org    operator bool() { return p; }
2155735Snate@binkert.org};
2165735Snate@binkert.org
2175735Snate@binkert.orguint16_t cksum(const IpPtr &ptr);
2185735Snate@binkert.org
2195735Snate@binkert.orgstruct IpOpt : public ip_opt
2205735Snate@binkert.org{
2215735Snate@binkert.org    uint8_t type() const { return opt_type; }
2225735Snate@binkert.org    uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); }
2235735Snate@binkert.org    uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); }
2245735Snate@binkert.org    uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); }
2255735Snate@binkert.org    uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; }
2265735Snate@binkert.org
2275735Snate@binkert.org    bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); }
2285735Snate@binkert.org    bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); }
2295735Snate@binkert.org    bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); }
2305735Snate@binkert.org
2315735Snate@binkert.org    const uint8_t *data() const { return opt_data.data8; }
2325735Snate@binkert.org    void sec(ip_opt_data_sec &sec) const;
2335735Snate@binkert.org    void lsrr(ip_opt_data_rr &rr) const;
2345735Snate@binkert.org    void ssrr(ip_opt_data_rr &rr) const;
2355735Snate@binkert.org    void ts(ip_opt_data_ts &ts) const;
2365735Snate@binkert.org    uint16_t satid() const { return ntohs(opt_data.satid); }
2375735Snate@binkert.org    uint16_t mtup() const { return ntohs(opt_data.mtu); }
2384022Sstever@eecs.umich.edu    uint16_t mtur() const { return ntohs(opt_data.mtu); }
2394022Sstever@eecs.umich.edu    void tr(ip_opt_data_tr &tr) const;
2405735Snate@binkert.org    const uint32_t *addext() const { return &opt_data.addext[0]; }
2414870Sstever@eecs.umich.edu    uint16_t rtralt() const { return ntohs(opt_data.rtralt); }
2424870Sstever@eecs.umich.edu    void sdb(std::vector<uint32_t> &vec) const;
2435735Snate@binkert.org};
2444870Sstever@eecs.umich.edu
2454870Sstever@eecs.umich.edu/*
2462566SN/A * TCP Stuff
2475735Snate@binkert.org */
2485735Snate@binkert.orgstruct TcpOpt;
2495735Snate@binkert.orgstruct TcpHdr : public tcp_hdr
2505735Snate@binkert.org{
2515735Snate@binkert.org    uint16_t sport() const { return ntohs(th_sport); }
2525735Snate@binkert.org    uint16_t dport() const { return ntohs(th_dport); }
2532566SN/A    uint32_t seq() const { return ntohl(th_seq); }
2542566SN/A    uint32_t ack() const { return ntohl(th_ack); }
2552566SN/A    uint8_t  off() const { return th_off; }
2565735Snate@binkert.org    uint8_t  flags() const { return th_flags & 0x3f; }
2575735Snate@binkert.org    uint16_t win() const { return ntohs(th_win); }
2582381SN/A    uint16_t sum() const { return th_sum; }
2592381SN/A    uint16_t urp() const { return ntohs(th_urp); }
2605735Snate@binkert.org
2612381SN/A    void sum(uint16_t sum) { th_sum = sum; }
2622381SN/A
2635735Snate@binkert.org    bool options(std::vector<const TcpOpt *> &vec) const;
2645735Snate@binkert.org
2655735Snate@binkert.org    int size() const { return off(); }
2665735Snate@binkert.org    const uint8_t *bytes() const { return (const uint8_t *)this; }
2675735Snate@binkert.org    const uint8_t *payload() const { return bytes() + size(); }
2685735Snate@binkert.org    uint8_t *bytes() { return (uint8_t *)this; }
2695735Snate@binkert.org    uint8_t *payload() { return bytes() + size(); }
2702381SN/A};
2715735Snate@binkert.org
2725735Snate@binkert.orgclass TcpPtr
2735735Snate@binkert.org{
2745735Snate@binkert.org  protected:
2755735Snate@binkert.org    EthPacketPtr p;
2765735Snate@binkert.org    int off;
2775735Snate@binkert.org
2785735Snate@binkert.org    const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); }
2792641Sstever@eecs.umich.edu    TcpHdr *h() { return (TcpHdr *)(p->data + off); }
2805735Snate@binkert.org
2815735Snate@binkert.org    void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; }
2824870Sstever@eecs.umich.edu    void set(const IpPtr &ptr)
2834870Sstever@eecs.umich.edu    {
2844870Sstever@eecs.umich.edu        if (ptr->proto() == IP_PROTO_TCP)
2854870Sstever@eecs.umich.edu            set(ptr.p, sizeof(eth_hdr) + ptr->hlen());
2864870Sstever@eecs.umich.edu        else
2874870Sstever@eecs.umich.edu            set(0, 0);
2882641Sstever@eecs.umich.edu    }
2895735Snate@binkert.org
2902811Srdreslin@umich.edu  public:
2912811Srdreslin@umich.edu    TcpPtr() {}
2925735Snate@binkert.org    TcpPtr(const IpPtr &ptr) { set(ptr); }
2933218Sgblack@eecs.umich.edu    TcpPtr(const TcpPtr &ptr) : p(ptr.p), off(ptr.off) {}
2943218Sgblack@eecs.umich.edu
2955735Snate@binkert.org    TcpHdr *operator->() { return h(); }
2963218Sgblack@eecs.umich.edu    TcpHdr &operator*() { return *h(); }
2973218Sgblack@eecs.umich.edu    operator TcpHdr *() { return h(); }
2985735Snate@binkert.org
2995735Snate@binkert.org    const TcpHdr *operator->() const { return h(); }
3005735Snate@binkert.org    const TcpHdr &operator*() const { return *h(); }
3012623SN/A    operator const TcpHdr *() const { return h(); }
3025735Snate@binkert.org
3035735Snate@binkert.org    const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; }
3045735Snate@binkert.org    const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; }
3055735Snate@binkert.org
3065735Snate@binkert.org    const EthPacketPtr packet() const { return p; }
3075735Snate@binkert.org    EthPacketPtr packet() { return p; }
3085735Snate@binkert.org    bool operator!() const { return !p; }
3095735Snate@binkert.org    operator bool() const { return p; }
3105735Snate@binkert.org    operator bool() { return p; }
3115735Snate@binkert.org};
3125735Snate@binkert.org
3132641Sstever@eecs.umich.eduuint16_t cksum(const TcpPtr &ptr);
3142641Sstever@eecs.umich.edu
3152641Sstever@eecs.umich.edutypedef Range<uint16_t> SackRange;
3165315Sstever@gmail.com
3175315Sstever@gmail.comstruct TcpOpt : public tcp_opt
3185315Sstever@gmail.com{
3195315Sstever@gmail.com    uint8_t type() const { return opt_type; }
3205735Snate@binkert.org    uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; }
3215735Snate@binkert.org
3225735Snate@binkert.org    bool isopt(int opt) const { return type() == opt; }
3235735Snate@binkert.org
3245735Snate@binkert.org    const uint8_t *data() const { return opt_data.data8; }
3255735Snate@binkert.org
3265735Snate@binkert.org    uint16_t mss() const { return ntohs(opt_data.mss); }
3275735Snate@binkert.org    uint8_t wscale() const { return opt_data.wscale; }
3285314Sstever@gmail.com    bool sack(std::vector<SackRange> &vec) const;
3295314Sstever@gmail.com    uint32_t echo() const { return ntohl(opt_data.echo); }
3305314Sstever@gmail.com    uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); }
3315735Snate@binkert.org    uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); }
3325314Sstever@gmail.com    uint32_t cc() const { return ntohl(opt_data.cc); }
3335314Sstever@gmail.com    uint8_t cksum() const{ return opt_data.cksum; }
3345314Sstever@gmail.com    const uint8_t *md5() const { return opt_data.md5; }
3355314Sstever@gmail.com
3365314Sstever@gmail.com    int size() const { return len(); }
3375314Sstever@gmail.com    const uint8_t *bytes() const { return (const uint8_t *)this; }
3385314Sstever@gmail.com    const uint8_t *payload() const { return bytes() + size(); }
3395314Sstever@gmail.com    uint8_t *bytes() { return (uint8_t *)this; }
3405314Sstever@gmail.com    uint8_t *payload() { return bytes() + size(); }
3415314Sstever@gmail.com};
3425314Sstever@gmail.com
3435314Sstever@gmail.com/*
3445314Sstever@gmail.com * UDP Stuff
3455314Sstever@gmail.com */
3465735Snate@binkert.orgstruct UdpHdr : public udp_hdr
3475735Snate@binkert.org{
3485735Snate@binkert.org    uint16_t sport() const { return ntohs(uh_sport); }
3495314Sstever@gmail.com    uint16_t dport() const { return ntohs(uh_dport); }
3505315Sstever@gmail.com    uint16_t len() const { return ntohs(uh_ulen); }
3515735Snate@binkert.org    uint16_t sum() const { return uh_sum; }
3525735Snate@binkert.org
3535315Sstever@gmail.com    void sum(uint16_t sum) { uh_sum = sum; }
3545735Snate@binkert.org
3555735Snate@binkert.org    int size() const { return sizeof(udp_hdr); }
3565314Sstever@gmail.com    const uint8_t *bytes() const { return (const uint8_t *)this; }
3575314Sstever@gmail.com    const uint8_t *payload() const { return bytes() + size(); }
3585735Snate@binkert.org    uint8_t *bytes() { return (uint8_t *)this; }
3595735Snate@binkert.org    uint8_t *payload() { return bytes() + size(); }
3605735Snate@binkert.org};
3615735Snate@binkert.org
3625314Sstever@gmail.comclass UdpPtr
3635735Snate@binkert.org{
3645735Snate@binkert.org  protected:
3655735Snate@binkert.org    EthPacketPtr p;
3665315Sstever@gmail.com    int off;
3675735Snate@binkert.org
3685735Snate@binkert.org    const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); }
3695314Sstever@gmail.com    UdpHdr *h() { return (UdpHdr *)(p->data + off); }
3705735Snate@binkert.org
3715735Snate@binkert.org    void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; }
3725735Snate@binkert.org    void set(const IpPtr &ptr)
3735735Snate@binkert.org    {
3745735Snate@binkert.org        if (ptr->proto() == IP_PROTO_UDP)
3755314Sstever@gmail.com            set(ptr.p, sizeof(eth_hdr) + ptr->hlen());
3765314Sstever@gmail.com        else
3775314Sstever@gmail.com            set(0, 0);
3785735Snate@binkert.org    }
3795735Snate@binkert.org
3805735Snate@binkert.org  public:
3815735Snate@binkert.org    UdpPtr() {}
3825735Snate@binkert.org    UdpPtr(const IpPtr &ptr) { set(ptr); }
3835735Snate@binkert.org    UdpPtr(const UdpPtr &ptr) : p(ptr.p), off(ptr.off) {}
3845735Snate@binkert.org
3855735Snate@binkert.org    UdpHdr *operator->() { return h(); }
3862662Sstever@eecs.umich.edu    UdpHdr &operator*() { return *h(); }
3872641Sstever@eecs.umich.edu    operator UdpHdr *() { return h(); }
3885735Snate@binkert.org
3895735Snate@binkert.org    const UdpHdr *operator->() const { return h(); }
3904022Sstever@eecs.umich.edu    const UdpHdr &operator*() const { return *h(); }
3912811Srdreslin@umich.edu    operator const UdpHdr *() const { return h(); }
3925735Snate@binkert.org
3934022Sstever@eecs.umich.edu    const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; }
3942811Srdreslin@umich.edu    const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; }
3954022Sstever@eecs.umich.edu
3964022Sstever@eecs.umich.edu    const EthPacketPtr packet() const { return p; }
3974022Sstever@eecs.umich.edu    EthPacketPtr packet() { return p; }
3984022Sstever@eecs.umich.edu    bool operator!() const { return !p; }
3994870Sstever@eecs.umich.edu    operator bool() const { return p; }
4004022Sstever@eecs.umich.edu    operator bool() { return p; }
4014022Sstever@eecs.umich.edu};
4024022Sstever@eecs.umich.edu
4034040Ssaidi@eecs.umich.eduuint16_t cksum(const UdpPtr &ptr);
4046076Sgblack@eecs.umich.edu
4054870Sstever@eecs.umich.edu/* namespace Net */ }
4065314Sstever@gmail.com
4072812Srdreslin@umich.edu#endif // __BASE_INET_HH__
4084870Sstever@eecs.umich.edu