inet.hh revision 1762
12SN/A/* 21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/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__ 302SN/A#define __BASE_INET_HH__ 312SN/A 321388SN/A#include <iosfwd> 332SN/A#include <string> 342SN/A#include <utility> 352SN/A#include <vector> 361191SN/A 371191SN/A#include "base/range.hh" 381191SN/A#include "dev/etherpkt.hh" 391388SN/A#include "sim/host.hh" 405529Snate@binkert.org 411717SN/A#include "dnet/os.h" 422651Ssaidi@eecs.umich.edu#include "dnet/eth.h" 432680Sktlim@umich.edu#include "dnet/ip.h" 441977SN/A#include "dnet/ip6.h" 455529Snate@binkert.org#include "dnet/addr.h" 463144Shsul@eecs.umich.edu#include "dnet/arp.h" 472190SN/A#include "dnet/icmp.h" 4856SN/A#include "dnet/tcp.h" 492190SN/A#include "dnet/udp.h" 502SN/A#include "dnet/intf.h" 512359SN/A#include "dnet/route.h" 522359SN/A#include "dnet/fw.h" 532359SN/A#include "dnet/blob.h" 542SN/A#include "dnet/rand.h" 552SN/A 562SN/Anamespace Net { 572SN/A 582SN/A/* 592SN/A * Ethernet Stuff 602SN/A */ 612SN/Astruct EthAddr : protected eth_addr 622SN/A{ 635606Snate@binkert.org protected: 645606Snate@binkert.org void parse(const std::string &addr); 655606Snate@binkert.org 663126Sktlim@umich.edu public: 673126Sktlim@umich.edu EthAddr(); 685606Snate@binkert.org EthAddr(const uint8_t ea[ETH_ADDR_LEN]); 693126Sktlim@umich.edu EthAddr(const eth_addr &ea); 703126Sktlim@umich.edu EthAddr(const std::string &addr); 712356SN/A const EthAddr &operator=(const eth_addr &ea); 722356SN/A const EthAddr &operator=(const std::string &addr); 732356SN/A 742367SN/A int size() const { return sizeof(eth_addr); } 752356SN/A 765100Ssaidi@eecs.umich.edu const uint8_t *bytes() const { return &data[0]; } 772367SN/A uint8_t *bytes() { return &data[0]; } 782356SN/A 792356SN/A const uint8_t *addr() const { return &data[0]; } 802356SN/A bool unicast() const { return data[0] == 0x00; } 812367SN/A bool multicast() const { return data[0] == 0x01; } 822367SN/A bool broadcast() const { return data[0] == 0xff; } 832367SN/A std::string string() const; 842367SN/A 852356SN/A operator uint64_t() const 865606Snate@binkert.org { 872356SN/A uint64_t reg = 0; 882356SN/A reg |= ((uint64_t)data[0]) << 40; 892356SN/A reg |= ((uint64_t)data[1]) << 32; 905336Shines@cs.fsu.edu reg |= ((uint64_t)data[2]) << 24; 912356SN/A reg |= ((uint64_t)data[3]) << 16; 924873Sstever@eecs.umich.edu reg |= ((uint64_t)data[4]) << 8; 932356SN/A reg |= ((uint64_t)data[5]) << 0; 942356SN/A return reg; 951858SN/A } 961400SN/A 975712Shsul@eecs.umich.edu}; 985712Shsul@eecs.umich.edu 995529Snate@binkert.orgstd::ostream &operator<<(std::ostream &stream, const EthAddr &ea); 1003661Srdreslin@umich.edubool operator==(const EthAddr &left, const EthAddr &right); 1012SN/A 1021400SN/Astruct EthHdr : public eth_hdr 1035712Shsul@eecs.umich.edu{ 1045529Snate@binkert.org uint16_t type() const { return ntohs(eth_type); } 1053661Srdreslin@umich.edu const EthAddr &src() const { return *(EthAddr *)ð_src; } 1062SN/A const EthAddr &dst() const { return *(EthAddr *)ð_dst; } 1072SN/A 1082359SN/A int size() const { return sizeof(eth_hdr); } 1091062SN/A 1105712Shsul@eecs.umich.edu const uint8_t *bytes() const { return (const uint8_t *)this; } 1115712Shsul@eecs.umich.edu const uint8_t *payload() const { return bytes() + size(); } 1125712Shsul@eecs.umich.edu uint8_t *bytes() { return (uint8_t *)this; } 1135712Shsul@eecs.umich.edu uint8_t *payload() { return bytes() + size(); } 1145712Shsul@eecs.umich.edu}; 1152SN/A 1162SN/Aclass EthPtr 1172SN/A{ 1185712Shsul@eecs.umich.edu protected: 1195712Shsul@eecs.umich.edu friend class IpPtr; 1202SN/A PacketPtr p; 1212SN/A 1222SN/A public: 1232SN/A EthPtr() {} 1241354SN/A EthPtr(const PacketPtr &ptr) : p(ptr) { } 1252SN/A 126503SN/A EthHdr *operator->() { return (EthHdr *)p->data; } 1272SN/A EthHdr &operator*() { return *(EthHdr *)p->data; } 1282SN/A operator EthHdr *() { return (EthHdr *)p->data; } 1292SN/A 1302SN/A const EthHdr *operator->() const { return (const EthHdr *)p->data; } 1315606Snate@binkert.org const EthHdr &operator*() const { return *(const EthHdr *)p->data; } 1325606Snate@binkert.org operator const EthHdr *() const { return (const EthHdr *)p->data; } 1335606Snate@binkert.org 1345606Snate@binkert.org const EthPtr &operator=(const PacketPtr &ptr) { p = ptr; return *this; } 1355606Snate@binkert.org 1365606Snate@binkert.org const PacketPtr packet() const { return p; } 1375606Snate@binkert.org PacketPtr packet() { return p; } 1382SN/A bool operator!() const { return !p; } 1391400SN/A operator bool() const { return p; } 1405606Snate@binkert.org}; 1415606Snate@binkert.org 1422SN/A/* 1432SN/A * IP Stuff 1442SN/A */ 1452SN/Astruct IpOpt; 1462SN/Astruct IpHdr : public ip_hdr 1475606Snate@binkert.org{ 1485606Snate@binkert.org uint8_t version() const { return ip_v; } 1495606Snate@binkert.org uint8_t hlen() const { return ip_hl * 4; } 1505606Snate@binkert.org uint8_t tos() const { return ip_tos; } 1512SN/A uint16_t len() const { return ntohs(ip_len); } 1522SN/A uint16_t id() const { return ntohs(ip_id); } 153124SN/A uint16_t frag_flags() const { return ntohs(ip_off) >> 13; } 1541354SN/A uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; } 155124SN/A uint8_t ttl() const { return ip_ttl; } 156124SN/A uint8_t proto() const { return ip_p; } 157124SN/A uint16_t sum() const { return ip_sum; } 158124SN/A uint32_t src() const { return ntohl(ip_src); } 159124SN/A uint32_t dst() const { return ntohl(ip_dst); } 160124SN/A 1615606Snate@binkert.org void sum(uint16_t sum) { ip_sum = sum; } 1625606Snate@binkert.org 1635606Snate@binkert.org bool options(std::vector<const IpOpt *> &vec) const; 1645606Snate@binkert.org 1655606Snate@binkert.org int size() const { return hlen(); } 1665606Snate@binkert.org const uint8_t *bytes() const { return (const uint8_t *)this; } 1675606Snate@binkert.org const uint8_t *payload() const { return bytes() + size(); } 168124SN/A uint8_t *bytes() { return (uint8_t *)this; } 1691400SN/A uint8_t *payload() { return bytes() + size(); } 1705606Snate@binkert.org}; 171124SN/A 172124SN/Aclass IpPtr 173124SN/A{ 174124SN/A protected: 175124SN/A friend class TcpPtr; 1765606Snate@binkert.org friend class UdpPtr; 1775606Snate@binkert.org PacketPtr p; 1785606Snate@binkert.org 1795606Snate@binkert.org const IpHdr *h() const 180124SN/A { return (const IpHdr *)(p->data + sizeof(eth_hdr)); } 181124SN/A IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); } 1821191SN/A 1835529Snate@binkert.org void set(const PacketPtr &ptr) 1841388SN/A { 1851191SN/A EthHdr *eth = (EthHdr *)ptr->data; 1865529Snate@binkert.org if (eth->type() == ETH_TYPE_IP) 1871191SN/A p = ptr; 1885529Snate@binkert.org else 1891191SN/A p = 0; 1901191SN/A } 1915606Snate@binkert.org 1925606Snate@binkert.org public: 1935606Snate@binkert.org IpPtr() {} 1941191SN/A IpPtr(const PacketPtr &ptr) { set(ptr); } 1951191SN/A IpPtr(const EthPtr &ptr) { set(ptr.p); } 1961917SN/A IpPtr(const IpPtr &ptr) : p(ptr.p) { } 1971917SN/A 1985529Snate@binkert.org IpHdr *operator->() { return h(); } 1995529Snate@binkert.org IpHdr &operator*() { return *h(); } 2001917SN/A operator IpHdr *() { return h(); } 2015529Snate@binkert.org 2021917SN/A const IpHdr *operator->() const { return h(); } 2031191SN/A const IpHdr &operator*() const { return *h(); } 2041191SN/A operator const IpHdr *() const { return h(); } 2051191SN/A 2061191SN/A const IpPtr &operator=(const PacketPtr &ptr) { set(ptr); return *this; } 2071191SN/A const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; } 2081191SN/A const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; } 2091191SN/A 2101191SN/A const PacketPtr packet() const { return p; } 2111191SN/A PacketPtr packet() { return p; } 2121191SN/A bool operator!() const { return !p; } 2131191SN/A operator bool() const { return p; } 2141129SN/A operator bool() { return p; } 2151129SN/A}; 2161129SN/A 2175529Snate@binkert.orguint16_t cksum(const IpPtr &ptr); 2182680Sktlim@umich.edu 2191129SN/Astruct IpOpt : public ip_opt 220180SN/A{ 2212SN/A uint8_t type() const { return opt_type; } 2221917SN/A uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); } 2231917SN/A uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); } 2241917SN/A uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); } 2255529Snate@binkert.org uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; } 2265606Snate@binkert.org 2271917SN/A bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); } 2282356SN/A bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); } 2295529Snate@binkert.org bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); } 2305606Snate@binkert.org 2315606Snate@binkert.org const uint8_t *data() const { return opt_data.data8; } 2325606Snate@binkert.org void sec(ip_opt_data_sec &sec) const; 2332356SN/A void lsrr(ip_opt_data_rr &rr) const; 2341917SN/A void ssrr(ip_opt_data_rr &rr) const; 2351917SN/A void ts(ip_opt_data_ts &ts) const; 2361917SN/A uint16_t satid() const { return ntohs(opt_data.satid); } 2371917SN/A uint16_t mtup() const { return ntohs(opt_data.mtu); } 2382SN/A uint16_t mtur() const { return ntohs(opt_data.mtu); } 2392SN/A void tr(ip_opt_data_tr &tr) const; 240729SN/A const uint32_t *addext() const { return &opt_data.addext[0]; } 241707SN/A uint16_t rtralt() const { return ntohs(opt_data.rtralt); } 242707SN/A void sdb(std::vector<uint32_t> &vec) const; 243707SN/A}; 244707SN/A 245707SN/A/* 246707SN/A * TCP Stuff 2472680Sktlim@umich.edu */ 2482SN/Astruct TcpOpt; 2492SN/Astruct TcpHdr : public tcp_hdr 2502SN/A{ 2512SN/A uint16_t sport() const { return ntohs(th_sport); } 2522680Sktlim@umich.edu uint16_t dport() const { return ntohs(th_dport); } 2532SN/A uint32_t seq() const { return ntohl(th_seq); } 2542SN/A uint32_t ack() const { return ntohl(th_ack); } 2552680Sktlim@umich.edu uint8_t off() const { return th_off; } 2562190SN/A uint8_t flags() const { return th_flags & 0x3f; } 2572190SN/A uint16_t win() const { return ntohs(th_win); } 2582190SN/A uint16_t sum() const { return th_sum; } 2592SN/A uint16_t urp() const { return ntohs(th_urp); } 2602SN/A 2613495Sktlim@umich.edu void sum(uint16_t sum) { th_sum = sum; } 2623495Sktlim@umich.edu 2633495Sktlim@umich.edu bool options(std::vector<const TcpOpt *> &vec) const; 2643661Srdreslin@umich.edu 2653495Sktlim@umich.edu int size() const { return off(); } 2663661Srdreslin@umich.edu const uint8_t *bytes() const { return (const uint8_t *)this; } 2673495Sktlim@umich.edu const uint8_t *payload() const { return bytes() + size(); } 2683495Sktlim@umich.edu uint8_t *bytes() { return (uint8_t *)this; } 2693495Sktlim@umich.edu uint8_t *payload() { return bytes() + size(); } 2703495Sktlim@umich.edu}; 2713495Sktlim@umich.edu 2723495Sktlim@umich.educlass TcpPtr 2733495Sktlim@umich.edu{ 2744599Sacolyte@umich.edu protected: 2754599Sacolyte@umich.edu PacketPtr p; 2763661Srdreslin@umich.edu int off; 2773495Sktlim@umich.edu 2783495Sktlim@umich.edu const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); } 2793495Sktlim@umich.edu TcpHdr *h() { return (TcpHdr *)(p->data + off); } 2803495Sktlim@umich.edu 281180SN/A void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } 282180SN/A void set(const IpPtr &ptr) 2832680Sktlim@umich.edu { 284180SN/A if (ptr->proto() == IP_PROTO_TCP) 2852680Sktlim@umich.edu set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); 2862680Sktlim@umich.edu else 2872378SN/A set(0, 0); 2885714Shsul@eecs.umich.edu } 2895713Shsul@eecs.umich.edu 2905714Shsul@eecs.umich.edu public: 291180SN/A TcpPtr() {} 292180SN/A TcpPtr(const IpPtr &ptr) { set(ptr); } 293180SN/A TcpPtr(const TcpPtr &ptr) : p(ptr.p), off(ptr.off) {} 294180SN/A 295180SN/A TcpHdr *operator->() { return h(); } 2964000Ssaidi@eecs.umich.edu TcpHdr &operator*() { return *h(); } 2974000Ssaidi@eecs.umich.edu operator TcpHdr *() { return h(); } 2984000Ssaidi@eecs.umich.edu 2994000Ssaidi@eecs.umich.edu const TcpHdr *operator->() const { return h(); } 3004000Ssaidi@eecs.umich.edu const TcpHdr &operator*() const { return *h(); } 3014000Ssaidi@eecs.umich.edu operator const TcpHdr *() const { return h(); } 3024000Ssaidi@eecs.umich.edu 3034000Ssaidi@eecs.umich.edu const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; } 3044000Ssaidi@eecs.umich.edu const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; } 3054000Ssaidi@eecs.umich.edu 306180SN/A const PacketPtr packet() const { return p; } 3072798Sktlim@umich.edu PacketPtr packet() { return p; } 308180SN/A bool operator!() const { return !p; } 3092359SN/A operator bool() const { return p; } 3102359SN/A operator bool() { return p; } 3112359SN/A}; 3125606Snate@binkert.org 3132359SN/Auint16_t cksum(const TcpPtr &ptr); 314180SN/A 315180SN/Atypedef Range<uint16_t> SackRange; 316180SN/A 3174192Sktlim@umich.edustruct TcpOpt : public tcp_opt 318180SN/A{ 3192680Sktlim@umich.edu uint8_t type() const { return opt_type; } 320180SN/A uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; } 3215712Shsul@eecs.umich.edu 3225712Shsul@eecs.umich.edu bool isopt(int opt) const { return type() == opt; } 3232680Sktlim@umich.edu 3242680Sktlim@umich.edu const uint8_t *data() const { return opt_data.data8; } 3252680Sktlim@umich.edu 326180SN/A uint16_t mss() const { return ntohs(opt_data.mss); } 3272680Sktlim@umich.edu uint8_t wscale() const { return opt_data.wscale; } 3282651Ssaidi@eecs.umich.edu bool sack(std::vector<SackRange> &vec) const; 3292680Sktlim@umich.edu uint32_t echo() const { return ntohl(opt_data.echo); } 3302651Ssaidi@eecs.umich.edu uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); } 3315714Shsul@eecs.umich.edu uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); } 3325714Shsul@eecs.umich.edu uint32_t cc() const { return ntohl(opt_data.cc); } 3332359SN/A uint8_t cksum() const{ return opt_data.cksum; } 3345217Ssaidi@eecs.umich.edu const uint8_t *md5() const { return opt_data.md5; } 3355217Ssaidi@eecs.umich.edu 336180SN/A int size() const { return len(); } 337605SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 3381858SN/A const uint8_t *payload() const { return bytes() + size(); } 3393520Sgblack@eecs.umich.edu uint8_t *bytes() { return (uint8_t *)this; } 3402254SN/A uint8_t *payload() { return bytes() + size(); } 3412680Sktlim@umich.edu}; 3422680Sktlim@umich.edu 3432254SN/A/* 3444947Snate@binkert.org * UDP Stuff 3455606Snate@binkert.org */ 346612SN/Astruct UdpHdr : public udp_hdr 3474192Sktlim@umich.edu{ 3484192Sktlim@umich.edu uint16_t sport() const { return ntohs(uh_sport); } 3494192Sktlim@umich.edu uint16_t dport() const { return ntohs(uh_dport); } 3504192Sktlim@umich.edu uint16_t len() const { return ntohs(uh_ulen); } 3515476Snate@binkert.org uint16_t sum() const { return uh_sum; } 3525476Snate@binkert.org 3534192Sktlim@umich.edu void sum(uint16_t sum) { uh_sum = sum; } 3545476Snate@binkert.org 3554192Sktlim@umich.edu int size() const { return sizeof(udp_hdr); } 3564192Sktlim@umich.edu const uint8_t *bytes() const { return (const uint8_t *)this; } 3575476Snate@binkert.org const uint8_t *payload() const { return bytes() + size(); } 3585476Snate@binkert.org uint8_t *bytes() { return (uint8_t *)this; } 3594192Sktlim@umich.edu uint8_t *payload() { return bytes() + size(); } 3605476Snate@binkert.org}; 3614192Sktlim@umich.edu 362180SN/Aclass UdpPtr 363180SN/A{ 364180SN/A protected: 3651858SN/A PacketPtr p; 3665536Srstrong@hp.com int off; 3675606Snate@binkert.org 3681917SN/A const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); } 3691917SN/A UdpHdr *h() { return (UdpHdr *)(p->data + off); } 3701917SN/A 3711917SN/A void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } 3721917SN/A void set(const IpPtr &ptr) 3732680Sktlim@umich.edu { 3742680Sktlim@umich.edu if (ptr->proto() == IP_PROTO_UDP) 3752680Sktlim@umich.edu set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); 3761917SN/A else 3772254SN/A set(0, 0); 3785606Snate@binkert.org } 3791917SN/A 3801917SN/A public: 3812SN/A UdpPtr() {} 3825704Snate@binkert.org UdpPtr(const IpPtr &ptr) { set(ptr); } 3832SN/A UdpPtr(const UdpPtr &ptr) : p(ptr.p), off(ptr.off) {} 3845647Sgblack@eecs.umich.edu 3852SN/A UdpHdr *operator->() { return h(); } 3862SN/A UdpHdr &operator*() { return *h(); } 3872SN/A operator UdpHdr *() { return h(); } 3885704Snate@binkert.org 3892SN/A const UdpHdr *operator->() const { return h(); } 3905647Sgblack@eecs.umich.edu const UdpHdr &operator*() const { return *h(); } 3912SN/A operator const UdpHdr *() const { return h(); } 3922SN/A 3932SN/A const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; } 3945704Snate@binkert.org const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; } 3952SN/A 3965704Snate@binkert.org const PacketPtr packet() const { return p; } 3972SN/A PacketPtr packet() { return p; } 3982SN/A bool operator!() const { return !p; } 399921SN/A operator bool() const { return p; } 400921SN/A operator bool() { return p; } 401921SN/A}; 4024000Ssaidi@eecs.umich.edu 4035647Sgblack@eecs.umich.eduuint16_t cksum(const UdpPtr &ptr); 404921SN/A 405921SN/A/* namespace Net */ } 406921SN/A 407921SN/A#endif // __BASE_INET_HH__ 408921SN/A