inet.hh revision 1762
12391SN/A/*
22391SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
32391SN/A * All rights reserved.
42391SN/A *
52391SN/A * Redistribution and use in source and binary forms, with or without
62391SN/A * modification, are permitted provided that the following conditions are
72391SN/A * met: redistributions of source code must retain the above copyright
82391SN/A * notice, this list of conditions and the following disclaimer;
92391SN/A * redistributions in binary form must reproduce the above copyright
102391SN/A * notice, this list of conditions and the following disclaimer in the
112391SN/A * documentation and/or other materials provided with the distribution;
122391SN/A * neither the name of the copyright holders nor the names of its
132391SN/A * contributors may be used to endorse or promote products derived from
142391SN/A * this software without specific prior written permission.
152391SN/A *
162391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292914Ssaidi@eecs.umich.edu#ifndef __BASE_INET_HH__
302391SN/A#define __BASE_INET_HH__
312391SN/A
322391SN/A#include <iosfwd>
332391SN/A#include <string>
342391SN/A#include <utility>
352391SN/A#include <vector>
362391SN/A
372391SN/A#include "base/range.hh"
382391SN/A#include "dev/etherpkt.hh"
392391SN/A#include "sim/host.hh"
402391SN/A
412391SN/A#include "dnet/os.h"
423348Sbinkertn@umich.edu#include "dnet/eth.h"
432391SN/A#include "dnet/ip.h"
442391SN/A#include "dnet/ip6.h"
453879Ssaidi@eecs.umich.edu#include "dnet/addr.h"
462394SN/A#include "dnet/arp.h"
472391SN/A#include "dnet/icmp.h"
482415SN/A#include "dnet/tcp.h"
493348Sbinkertn@umich.edu#include "dnet/udp.h"
502394SN/A#include "dnet/intf.h"
512391SN/A#include "dnet/route.h"
522423SN/A#include "dnet/fw.h"
532391SN/A#include "dnet/blob.h"
543012Ssaidi@eecs.umich.edu#include "dnet/rand.h"
554467Sstever@eecs.umich.edu
562391SN/Anamespace Net {
573012Ssaidi@eecs.umich.edu
582391SN/A/*
592391SN/A * Ethernet Stuff
602391SN/A */
614626Sstever@eecs.umich.edustruct EthAddr : protected eth_addr
624626Sstever@eecs.umich.edu{
634626Sstever@eecs.umich.edu  protected:
642391SN/A    void parse(const std::string &addr);
653012Ssaidi@eecs.umich.edu
662391SN/A  public:
672391SN/A    EthAddr();
682391SN/A    EthAddr(const uint8_t ea[ETH_ADDR_LEN]);
692391SN/A    EthAddr(const eth_addr &ea);
703751Sgblack@eecs.umich.edu    EthAddr(const std::string &addr);
713751Sgblack@eecs.umich.edu    const EthAddr &operator=(const eth_addr &ea);
723751Sgblack@eecs.umich.edu    const EthAddr &operator=(const std::string &addr);
733751Sgblack@eecs.umich.edu
743012Ssaidi@eecs.umich.edu    int size() const { return sizeof(eth_addr); }
752391SN/A
762391SN/A    const uint8_t *bytes() const { return &data[0]; }
772541SN/A    uint8_t *bytes() { return &data[0]; }
782541SN/A
792541SN/A    const uint8_t *addr() const { return &data[0]; }
804470Sstever@eecs.umich.edu    bool unicast() const { return data[0] == 0x00; }
814470Sstever@eecs.umich.edu    bool multicast() const { return data[0] == 0x01; }
824470Sstever@eecs.umich.edu    bool broadcast() const { return data[0] == 0xff; }
834470Sstever@eecs.umich.edu    std::string string() const;
844467Sstever@eecs.umich.edu
854467Sstever@eecs.umich.edu    operator uint64_t() const
864467Sstever@eecs.umich.edu    {
874467Sstever@eecs.umich.edu        uint64_t reg = 0;
882541SN/A        reg |= ((uint64_t)data[0]) << 40;
892541SN/A        reg |= ((uint64_t)data[1]) << 32;
902391SN/A        reg |= ((uint64_t)data[2]) << 24;
912391SN/A        reg |= ((uint64_t)data[3]) << 16;
923012Ssaidi@eecs.umich.edu        reg |= ((uint64_t)data[4]) << 8;
933918Ssaidi@eecs.umich.edu        reg |= ((uint64_t)data[5]) << 0;
942416SN/A        return reg;
952391SN/A    }
962391SN/A
972391SN/A};
982391SN/A
992391SN/Astd::ostream &operator<<(std::ostream &stream, const EthAddr &ea);
1003012Ssaidi@eecs.umich.edubool operator==(const EthAddr &left, const EthAddr &right);
1014040Ssaidi@eecs.umich.edu
1022391SN/Astruct EthHdr : public eth_hdr
1033012Ssaidi@eecs.umich.edu{
1042391SN/A    uint16_t type() const { return ntohs(eth_type); }
1052391SN/A    const EthAddr &src() const { return *(EthAddr *)&eth_src; }
1062391SN/A    const EthAddr &dst() const { return *(EthAddr *)&eth_dst; }
1072408SN/A
1082408SN/A    int size() const { return sizeof(eth_hdr); }
1092408SN/A
1102409SN/A    const uint8_t *bytes() const { return (const uint8_t *)this; }
1112409SN/A    const uint8_t *payload() const { return bytes() + size(); }
1122408SN/A    uint8_t *bytes() { return (uint8_t *)this; }
1132408SN/A    uint8_t *payload() { return bytes() + size(); }
1143012Ssaidi@eecs.umich.edu};
1153349Sbinkertn@umich.edu
1163012Ssaidi@eecs.umich.educlass EthPtr
1173012Ssaidi@eecs.umich.edu{
1183012Ssaidi@eecs.umich.edu  protected:
1192413SN/A    friend class IpPtr;
1203170Sstever@eecs.umich.edu    PacketPtr p;
1213170Sstever@eecs.umich.edu
1223170Sstever@eecs.umich.edu  public:
1233170Sstever@eecs.umich.edu    EthPtr() {}
1243170Sstever@eecs.umich.edu    EthPtr(const PacketPtr &ptr) : p(ptr) { }
1254626Sstever@eecs.umich.edu
1263170Sstever@eecs.umich.edu    EthHdr *operator->() { return (EthHdr *)p->data; }
1274626Sstever@eecs.umich.edu    EthHdr &operator*() { return *(EthHdr *)p->data; }
1283170Sstever@eecs.umich.edu    operator EthHdr *() { return (EthHdr *)p->data; }
1293170Sstever@eecs.umich.edu
1303170Sstever@eecs.umich.edu    const EthHdr *operator->() const { return (const EthHdr *)p->data; }
1313170Sstever@eecs.umich.edu    const EthHdr &operator*() const { return *(const EthHdr *)p->data; }
1323170Sstever@eecs.umich.edu    operator const EthHdr *() const { return (const EthHdr *)p->data; }
1333170Sstever@eecs.umich.edu
1343170Sstever@eecs.umich.edu    const EthPtr &operator=(const PacketPtr &ptr) { p = ptr; return *this; }
1353170Sstever@eecs.umich.edu
1363170Sstever@eecs.umich.edu    const PacketPtr packet() const { return p; }
1373170Sstever@eecs.umich.edu    PacketPtr packet() { return p; }
1383170Sstever@eecs.umich.edu    bool operator!() const { return !p; }
1393170Sstever@eecs.umich.edu    operator bool() const { return p; }
1403170Sstever@eecs.umich.edu};
1413170Sstever@eecs.umich.edu
1423170Sstever@eecs.umich.edu/*
1433170Sstever@eecs.umich.edu * IP Stuff
1443170Sstever@eecs.umich.edu */
1453170Sstever@eecs.umich.edustruct IpOpt;
1463170Sstever@eecs.umich.edustruct IpHdr : public ip_hdr
1473170Sstever@eecs.umich.edu{
1483170Sstever@eecs.umich.edu    uint8_t  version() const { return ip_v; }
1493170Sstever@eecs.umich.edu    uint8_t  hlen() const { return ip_hl * 4; }
1503170Sstever@eecs.umich.edu    uint8_t  tos() const { return ip_tos; }
1513170Sstever@eecs.umich.edu    uint16_t len() const { return ntohs(ip_len); }
1523170Sstever@eecs.umich.edu    uint16_t id() const { return ntohs(ip_id); }
1533170Sstever@eecs.umich.edu    uint16_t frag_flags() const { return ntohs(ip_off) >> 13; }
1543170Sstever@eecs.umich.edu    uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; }
1553170Sstever@eecs.umich.edu    uint8_t  ttl() const { return ip_ttl; }
1564626Sstever@eecs.umich.edu    uint8_t  proto() const { return ip_p; }
1573170Sstever@eecs.umich.edu    uint16_t sum() const { return ip_sum; }
1584626Sstever@eecs.umich.edu    uint32_t src() const { return ntohl(ip_src); }
1593170Sstever@eecs.umich.edu    uint32_t dst() const { return ntohl(ip_dst); }
1604626Sstever@eecs.umich.edu
1613170Sstever@eecs.umich.edu    void sum(uint16_t sum) { ip_sum = sum; }
1623170Sstever@eecs.umich.edu
1633170Sstever@eecs.umich.edu    bool options(std::vector<const IpOpt *> &vec) const;
1643170Sstever@eecs.umich.edu
1653170Sstever@eecs.umich.edu    int size() const { return hlen(); }
1663170Sstever@eecs.umich.edu    const uint8_t *bytes() const { return (const uint8_t *)this; }
1673170Sstever@eecs.umich.edu    const uint8_t *payload() const { return bytes() + size(); }
1683170Sstever@eecs.umich.edu    uint8_t *bytes() { return (uint8_t *)this; }
1693170Sstever@eecs.umich.edu    uint8_t *payload() { return bytes() + size(); }
1703170Sstever@eecs.umich.edu};
1713170Sstever@eecs.umich.edu
1723170Sstever@eecs.umich.educlass IpPtr
1733170Sstever@eecs.umich.edu{
1743170Sstever@eecs.umich.edu  protected:
1753170Sstever@eecs.umich.edu    friend class TcpPtr;
1763170Sstever@eecs.umich.edu    friend class UdpPtr;
1773170Sstever@eecs.umich.edu    PacketPtr p;
1783170Sstever@eecs.umich.edu
1793170Sstever@eecs.umich.edu    const IpHdr *h() const
1803170Sstever@eecs.umich.edu    { return (const IpHdr *)(p->data + sizeof(eth_hdr)); }
1813170Sstever@eecs.umich.edu    IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); }
1823170Sstever@eecs.umich.edu
1833170Sstever@eecs.umich.edu    void set(const PacketPtr &ptr)
1843170Sstever@eecs.umich.edu    {
1853170Sstever@eecs.umich.edu        EthHdr *eth = (EthHdr *)ptr->data;
1863170Sstever@eecs.umich.edu        if (eth->type() == ETH_TYPE_IP)
1873170Sstever@eecs.umich.edu            p = ptr;
1883170Sstever@eecs.umich.edu        else
1893170Sstever@eecs.umich.edu            p = 0;
1903170Sstever@eecs.umich.edu    }
1913170Sstever@eecs.umich.edu
1923170Sstever@eecs.umich.edu  public:
1933170Sstever@eecs.umich.edu    IpPtr() {}
1943170Sstever@eecs.umich.edu    IpPtr(const PacketPtr &ptr) { set(ptr); }
1953170Sstever@eecs.umich.edu    IpPtr(const EthPtr &ptr) { set(ptr.p); }
1963170Sstever@eecs.umich.edu    IpPtr(const IpPtr &ptr) : p(ptr.p) { }
1973170Sstever@eecs.umich.edu
1984040Ssaidi@eecs.umich.edu    IpHdr *operator->() { return h(); }
1993170Sstever@eecs.umich.edu    IpHdr &operator*() { return *h(); }
2003170Sstever@eecs.umich.edu    operator IpHdr *() { return h(); }
2013170Sstever@eecs.umich.edu
2023170Sstever@eecs.umich.edu    const IpHdr *operator->() const { return h(); }
2033170Sstever@eecs.umich.edu    const IpHdr &operator*() const { return *h(); }
2044626Sstever@eecs.umich.edu    operator const IpHdr *() const { return h(); }
2054626Sstever@eecs.umich.edu
2064626Sstever@eecs.umich.edu    const IpPtr &operator=(const PacketPtr &ptr) { set(ptr); return *this; }
2074626Sstever@eecs.umich.edu    const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; }
2084626Sstever@eecs.umich.edu    const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; }
2094626Sstever@eecs.umich.edu
2104626Sstever@eecs.umich.edu    const PacketPtr packet() const { return p; }
2114626Sstever@eecs.umich.edu    PacketPtr packet() { return p; }
2124626Sstever@eecs.umich.edu    bool operator!() const { return !p; }
2134626Sstever@eecs.umich.edu    operator bool() const { return p; }
2144626Sstever@eecs.umich.edu    operator bool() { return p; }
2154626Sstever@eecs.umich.edu};
2164626Sstever@eecs.umich.edu
2174626Sstever@eecs.umich.eduuint16_t cksum(const IpPtr &ptr);
2184626Sstever@eecs.umich.edu
2194626Sstever@eecs.umich.edustruct IpOpt : public ip_opt
2204626Sstever@eecs.umich.edu{
2214626Sstever@eecs.umich.edu    uint8_t type() const { return opt_type; }
2224626Sstever@eecs.umich.edu    uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); }
2234626Sstever@eecs.umich.edu    uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); }
2244626Sstever@eecs.umich.edu    uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); }
2254626Sstever@eecs.umich.edu    uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; }
2264626Sstever@eecs.umich.edu
2274626Sstever@eecs.umich.edu    bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); }
2284626Sstever@eecs.umich.edu    bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); }
2294626Sstever@eecs.umich.edu    bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); }
2304626Sstever@eecs.umich.edu
2314626Sstever@eecs.umich.edu    const uint8_t *data() const { return opt_data.data8; }
2324626Sstever@eecs.umich.edu    void sec(ip_opt_data_sec &sec) const;
2334626Sstever@eecs.umich.edu    void lsrr(ip_opt_data_rr &rr) const;
2344626Sstever@eecs.umich.edu    void ssrr(ip_opt_data_rr &rr) const;
2352413SN/A    void ts(ip_opt_data_ts &ts) const;
2364040Ssaidi@eecs.umich.edu    uint16_t satid() const { return ntohs(opt_data.satid); }
2374040Ssaidi@eecs.umich.edu    uint16_t mtup() const { return ntohs(opt_data.mtu); }
2382414SN/A    uint16_t mtur() const { return ntohs(opt_data.mtu); }
2394626Sstever@eecs.umich.edu    void tr(ip_opt_data_tr &tr) const;
2404626Sstever@eecs.umich.edu    const uint32_t *addext() const { return &opt_data.addext[0]; }
2414626Sstever@eecs.umich.edu    uint16_t rtralt() const { return ntohs(opt_data.rtralt); }
2424626Sstever@eecs.umich.edu    void sdb(std::vector<uint32_t> &vec) const;
2433175Srdreslin@umich.edu};
2444626Sstever@eecs.umich.edu
2454626Sstever@eecs.umich.edu/*
2464626Sstever@eecs.umich.edu * TCP Stuff
2474626Sstever@eecs.umich.edu */
2484040Ssaidi@eecs.umich.edustruct TcpOpt;
2494040Ssaidi@eecs.umich.edustruct TcpHdr : public tcp_hdr
2504040Ssaidi@eecs.umich.edu{
2514040Ssaidi@eecs.umich.edu    uint16_t sport() const { return ntohs(th_sport); }
2524040Ssaidi@eecs.umich.edu    uint16_t dport() const { return ntohs(th_dport); }
2534040Ssaidi@eecs.umich.edu    uint32_t seq() const { return ntohl(th_seq); }
2544040Ssaidi@eecs.umich.edu    uint32_t ack() const { return ntohl(th_ack); }
2554040Ssaidi@eecs.umich.edu    uint8_t  off() const { return th_off; }
2564040Ssaidi@eecs.umich.edu    uint8_t  flags() const { return th_flags & 0x3f; }
2574040Ssaidi@eecs.umich.edu    uint16_t win() const { return ntohs(th_win); }
2584052Ssaidi@eecs.umich.edu    uint16_t sum() const { return th_sum; }
2594626Sstever@eecs.umich.edu    uint16_t urp() const { return ntohs(th_urp); }
2604040Ssaidi@eecs.umich.edu
2614040Ssaidi@eecs.umich.edu    void sum(uint16_t sum) { th_sum = sum; }
2624040Ssaidi@eecs.umich.edu
2634052Ssaidi@eecs.umich.edu    bool options(std::vector<const TcpOpt *> &vec) const;
2644626Sstever@eecs.umich.edu
2654626Sstever@eecs.umich.edu    int size() const { return off(); }
2664040Ssaidi@eecs.umich.edu    const uint8_t *bytes() const { return (const uint8_t *)this; }
2674052Ssaidi@eecs.umich.edu    const uint8_t *payload() const { return bytes() + size(); }
2684626Sstever@eecs.umich.edu    uint8_t *bytes() { return (uint8_t *)this; }
2694626Sstever@eecs.umich.edu    uint8_t *payload() { return bytes() + size(); }
2704040Ssaidi@eecs.umich.edu};
2714040Ssaidi@eecs.umich.edu
2724040Ssaidi@eecs.umich.educlass TcpPtr
2734040Ssaidi@eecs.umich.edu{
2744040Ssaidi@eecs.umich.edu  protected:
2754626Sstever@eecs.umich.edu    PacketPtr p;
2764040Ssaidi@eecs.umich.edu    int off;
2774626Sstever@eecs.umich.edu
2784626Sstever@eecs.umich.edu    const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); }
2794626Sstever@eecs.umich.edu    TcpHdr *h() { return (TcpHdr *)(p->data + off); }
2804626Sstever@eecs.umich.edu
2814626Sstever@eecs.umich.edu    void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; }
2824040Ssaidi@eecs.umich.edu    void set(const IpPtr &ptr)
2834626Sstever@eecs.umich.edu    {
2844626Sstever@eecs.umich.edu        if (ptr->proto() == IP_PROTO_TCP)
2854626Sstever@eecs.umich.edu            set(ptr.p, sizeof(eth_hdr) + ptr->hlen());
2864626Sstever@eecs.umich.edu        else
2874626Sstever@eecs.umich.edu            set(0, 0);
2884626Sstever@eecs.umich.edu    }
2894626Sstever@eecs.umich.edu
2904626Sstever@eecs.umich.edu  public:
2914626Sstever@eecs.umich.edu    TcpPtr() {}
2924626Sstever@eecs.umich.edu    TcpPtr(const IpPtr &ptr) { set(ptr); }
2934626Sstever@eecs.umich.edu    TcpPtr(const TcpPtr &ptr) : p(ptr.p), off(ptr.off) {}
2944626Sstever@eecs.umich.edu
2954040Ssaidi@eecs.umich.edu    TcpHdr *operator->() { return h(); }
2962413SN/A    TcpHdr &operator*() { return *h(); }
2972413SN/A    operator TcpHdr *() { return h(); }
2982420SN/A
2994626Sstever@eecs.umich.edu    const TcpHdr *operator->() const { return h(); }
3004626Sstever@eecs.umich.edu    const TcpHdr &operator*() const { return *h(); }
3014626Sstever@eecs.umich.edu    operator const TcpHdr *() const { return h(); }
3024626Sstever@eecs.umich.edu
3034626Sstever@eecs.umich.edu    const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; }
3044626Sstever@eecs.umich.edu    const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; }
3054626Sstever@eecs.umich.edu
3064626Sstever@eecs.umich.edu    const PacketPtr packet() const { return p; }
3074626Sstever@eecs.umich.edu    PacketPtr packet() { return p; }
3084626Sstever@eecs.umich.edu    bool operator!() const { return !p; }
3094626Sstever@eecs.umich.edu    operator bool() const { return p; }
3104626Sstever@eecs.umich.edu    operator bool() { return p; }
3114626Sstever@eecs.umich.edu};
3124626Sstever@eecs.umich.edu
3134626Sstever@eecs.umich.eduuint16_t cksum(const TcpPtr &ptr);
3144626Sstever@eecs.umich.edu
3154626Sstever@eecs.umich.edutypedef Range<uint16_t> SackRange;
3164626Sstever@eecs.umich.edu
3174626Sstever@eecs.umich.edustruct TcpOpt : public tcp_opt
3184626Sstever@eecs.umich.edu{
3194626Sstever@eecs.umich.edu    uint8_t type() const { return opt_type; }
3204626Sstever@eecs.umich.edu    uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; }
3214626Sstever@eecs.umich.edu
3224626Sstever@eecs.umich.edu    bool isopt(int opt) const { return type() == opt; }
3234626Sstever@eecs.umich.edu
3244626Sstever@eecs.umich.edu    const uint8_t *data() const { return opt_data.data8; }
3252641Sstever@eecs.umich.edu
3262413SN/A    uint16_t mss() const { return ntohs(opt_data.mss); }
3272413SN/A    uint8_t wscale() const { return opt_data.wscale; }
3284626Sstever@eecs.umich.edu    bool sack(std::vector<SackRange> &vec) const;
3292413SN/A    uint32_t echo() const { return ntohl(opt_data.echo); }
3302738Sstever@eecs.umich.edu    uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); }
3312413SN/A    uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); }
3324468Sstever@eecs.umich.edu    uint32_t cc() const { return ntohl(opt_data.cc); }
3334468Sstever@eecs.umich.edu    uint8_t cksum() const{ return opt_data.cksum; }
3344468Sstever@eecs.umich.edu    const uint8_t *md5() const { return opt_data.md5; }
3354468Sstever@eecs.umich.edu
3364468Sstever@eecs.umich.edu    int size() const { return len(); }
3374468Sstever@eecs.umich.edu    const uint8_t *bytes() const { return (const uint8_t *)this; }
3384468Sstever@eecs.umich.edu    const uint8_t *payload() const { return bytes() + size(); }
3394467Sstever@eecs.umich.edu    uint8_t *bytes() { return (uint8_t *)this; }
3402462SN/A    uint8_t *payload() { return bytes() + size(); }
3412462SN/A};
3424467Sstever@eecs.umich.edu
3434467Sstever@eecs.umich.edu/*
3444467Sstever@eecs.umich.edu * UDP Stuff
3454467Sstever@eecs.umich.edu */
3464467Sstever@eecs.umich.edustruct UdpHdr : public udp_hdr
3474467Sstever@eecs.umich.edu{
3484467Sstever@eecs.umich.edu    uint16_t sport() const { return ntohs(uh_sport); }
3494467Sstever@eecs.umich.edu    uint16_t dport() const { return ntohs(uh_dport); }
3504467Sstever@eecs.umich.edu    uint16_t len() const { return ntohs(uh_ulen); }
3514467Sstever@eecs.umich.edu    uint16_t sum() const { return uh_sum; }
3524467Sstever@eecs.umich.edu
3534467Sstever@eecs.umich.edu    void sum(uint16_t sum) { uh_sum = sum; }
3544467Sstever@eecs.umich.edu
3554467Sstever@eecs.umich.edu    int size() const { return sizeof(udp_hdr); }
3562413SN/A    const uint8_t *bytes() const { return (const uint8_t *)this; }
3572413SN/A    const uint8_t *payload() const { return bytes() + size(); }
3584467Sstever@eecs.umich.edu    uint8_t *bytes() { return (uint8_t *)this; }
3592413SN/A    uint8_t *payload() { return bytes() + size(); }
3602413SN/A};
3612413SN/A
3622413SN/Aclass UdpPtr
3632413SN/A{
3642640Sstever@eecs.umich.edu  protected:
3652640Sstever@eecs.umich.edu    PacketPtr p;
3662914Ssaidi@eecs.umich.edu    int off;
3672413SN/A
3682413SN/A    const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); }
3692413SN/A    UdpHdr *h() { return (UdpHdr *)(p->data + off); }
3702413SN/A
3712413SN/A    void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; }
3722413SN/A    void set(const IpPtr &ptr)
3732413SN/A    {
3742413SN/A        if (ptr->proto() == IP_PROTO_UDP)
3752413SN/A            set(ptr.p, sizeof(eth_hdr) + ptr->hlen());
3762522SN/A        else
3774475Sstever@eecs.umich.edu            set(0, 0);
3782413SN/A    }
3792522SN/A
3802497SN/A  public:
3812497SN/A    UdpPtr() {}
3822497SN/A    UdpPtr(const IpPtr &ptr) { set(ptr); }
3834475Sstever@eecs.umich.edu    UdpPtr(const UdpPtr &ptr) : p(ptr.p), off(ptr.off) {}
3842497SN/A
3854475Sstever@eecs.umich.edu    UdpHdr *operator->() { return h(); }
3862522SN/A    UdpHdr &operator*() { return *h(); }
3874475Sstever@eecs.umich.edu    operator UdpHdr *() { return h(); }
3882413SN/A
3892413SN/A    const UdpHdr *operator->() const { return h(); }
3902415SN/A    const UdpHdr &operator*() const { return *h(); }
3912415SN/A    operator const UdpHdr *() const { return h(); }
3922415SN/A
3932415SN/A    const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; }
3942415SN/A    const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; }
3952413SN/A
3962413SN/A    const PacketPtr packet() const { return p; }
3973349Sbinkertn@umich.edu    PacketPtr packet() { return p; }
3982413SN/A    bool operator!() const { return !p; }
3994626Sstever@eecs.umich.edu    operator bool() const { return p; }
4002413SN/A    operator bool() { return p; }
4012413SN/A};
4022413SN/A
4033349Sbinkertn@umich.eduuint16_t cksum(const UdpPtr &ptr);
4042413SN/A
4054490Sstever@eecs.umich.edu/* namespace Net */ }
4063612Srdreslin@umich.edu
4073091Sstever@eecs.umich.edu#endif // __BASE_INET_HH__
4083091Sstever@eecs.umich.edu