inet.hh revision 2665
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 * Authors: Nathan Binkert 292665Ssaidi@eecs.umich.edu * Steve Reinhardt 302SN/A */ 312SN/A 321078SN/A#ifndef __BASE_INET_HH__ 331078SN/A#define __BASE_INET_HH__ 341078SN/A 351114SN/A#include <iosfwd> 361078SN/A#include <string> 371114SN/A#include <utility> 381114SN/A#include <vector> 391114SN/A 401114SN/A#include "base/range.hh" 411114SN/A#include "dev/etherpkt.hh" 421114SN/A#include "sim/host.hh" 431078SN/A 441078SN/A#include "dnet/os.h" 451078SN/A#include "dnet/eth.h" 461078SN/A#include "dnet/ip.h" 471078SN/A#include "dnet/ip6.h" 481078SN/A#include "dnet/addr.h" 491078SN/A#include "dnet/arp.h" 501078SN/A#include "dnet/icmp.h" 511078SN/A#include "dnet/tcp.h" 521078SN/A#include "dnet/udp.h" 531078SN/A#include "dnet/intf.h" 541078SN/A#include "dnet/route.h" 551078SN/A#include "dnet/fw.h" 561078SN/A#include "dnet/blob.h" 571078SN/A#include "dnet/rand.h" 582SN/A 591114SN/Anamespace Net { 602SN/A 611114SN/A/* 621114SN/A * Ethernet Stuff 631114SN/A */ 641114SN/Astruct EthAddr : protected eth_addr 651114SN/A{ 661114SN/A protected: 671114SN/A void parse(const std::string &addr); 681078SN/A 691114SN/A public: 701114SN/A EthAddr(); 711114SN/A EthAddr(const uint8_t ea[ETH_ADDR_LEN]); 721114SN/A EthAddr(const eth_addr &ea); 731114SN/A EthAddr(const std::string &addr); 741114SN/A const EthAddr &operator=(const eth_addr &ea); 751114SN/A const EthAddr &operator=(const std::string &addr); 761079SN/A 771114SN/A int size() const { return sizeof(eth_addr); } 781114SN/A 791114SN/A const uint8_t *bytes() const { return &data[0]; } 801114SN/A uint8_t *bytes() { return &data[0]; } 811114SN/A 821114SN/A const uint8_t *addr() const { return &data[0]; } 831114SN/A bool unicast() const { return data[0] == 0x00; } 841114SN/A bool multicast() const { return data[0] == 0x01; } 851114SN/A bool broadcast() const { return data[0] == 0xff; } 861114SN/A std::string string() const; 871137SN/A 881137SN/A operator uint64_t() const 891137SN/A { 901137SN/A uint64_t reg = 0; 911137SN/A reg |= ((uint64_t)data[0]) << 40; 921137SN/A reg |= ((uint64_t)data[1]) << 32; 931137SN/A reg |= ((uint64_t)data[2]) << 24; 941137SN/A reg |= ((uint64_t)data[3]) << 16; 951137SN/A reg |= ((uint64_t)data[4]) << 8; 961137SN/A reg |= ((uint64_t)data[5]) << 0; 971137SN/A return reg; 981137SN/A } 991137SN/A 1001114SN/A}; 1011114SN/A 1021114SN/Astd::ostream &operator<<(std::ostream &stream, const EthAddr &ea); 1031114SN/Abool operator==(const EthAddr &left, const EthAddr &right); 1041114SN/A 1051114SN/Astruct EthHdr : public eth_hdr 1061078SN/A{ 1071078SN/A uint16_t type() const { return ntohs(eth_type); } 1081114SN/A const EthAddr &src() const { return *(EthAddr *)ð_src; } 1091114SN/A const EthAddr &dst() const { return *(EthAddr *)ð_dst; } 1101079SN/A 1111114SN/A int size() const { return sizeof(eth_hdr); } 1121079SN/A 1131079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 1141079SN/A const uint8_t *payload() const { return bytes() + size(); } 1151079SN/A uint8_t *bytes() { return (uint8_t *)this; } 1161079SN/A uint8_t *payload() { return bytes() + size(); } 1171078SN/A}; 1181078SN/A 1191114SN/Aclass EthPtr 1201114SN/A{ 1211114SN/A protected: 1221114SN/A friend class IpPtr; 1232566SN/A EthPacketPtr p; 1241114SN/A 1251114SN/A public: 1261114SN/A EthPtr() {} 1272566SN/A EthPtr(const EthPacketPtr &ptr) : p(ptr) { } 1281114SN/A 1291114SN/A EthHdr *operator->() { return (EthHdr *)p->data; } 1301114SN/A EthHdr &operator*() { return *(EthHdr *)p->data; } 1311114SN/A operator EthHdr *() { return (EthHdr *)p->data; } 1321114SN/A 1331114SN/A const EthHdr *operator->() const { return (const EthHdr *)p->data; } 1341114SN/A const EthHdr &operator*() const { return *(const EthHdr *)p->data; } 1351114SN/A operator const EthHdr *() const { return (const EthHdr *)p->data; } 1361114SN/A 1372566SN/A const EthPtr &operator=(const EthPacketPtr &ptr) { p = ptr; return *this; } 1381114SN/A 1392566SN/A const EthPacketPtr packet() const { return p; } 1402566SN/A EthPacketPtr packet() { return p; } 1411114SN/A bool operator!() const { return !p; } 1421114SN/A operator bool() const { return p; } 1431114SN/A}; 1441114SN/A 1451114SN/A/* 1461114SN/A * IP Stuff 1471114SN/A */ 1481114SN/Astruct IpOpt; 1491114SN/Astruct IpHdr : public ip_hdr 1501078SN/A{ 1511078SN/A uint8_t version() const { return ip_v; } 1521092SN/A uint8_t hlen() const { return ip_hl * 4; } 1531078SN/A uint8_t tos() const { return ip_tos; } 1541078SN/A uint16_t len() const { return ntohs(ip_len); } 1551078SN/A uint16_t id() const { return ntohs(ip_id); } 1561078SN/A uint16_t frag_flags() const { return ntohs(ip_off) >> 13; } 1571078SN/A uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; } 1581078SN/A uint8_t ttl() const { return ip_ttl; } 1591078SN/A uint8_t proto() const { return ip_p; } 1601092SN/A uint16_t sum() const { return ip_sum; } 1611078SN/A uint32_t src() const { return ntohl(ip_src); } 1621078SN/A uint32_t dst() const { return ntohl(ip_dst); } 1631078SN/A 1641092SN/A void sum(uint16_t sum) { ip_sum = sum; } 1651078SN/A 1661114SN/A bool options(std::vector<const IpOpt *> &vec) const; 1671079SN/A 1681079SN/A int size() const { return hlen(); } 1691079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 1701079SN/A const uint8_t *payload() const { return bytes() + size(); } 1711079SN/A uint8_t *bytes() { return (uint8_t *)this; } 1721079SN/A uint8_t *payload() { return bytes() + size(); } 1731078SN/A}; 1741078SN/A 1751114SN/Aclass IpPtr 1761114SN/A{ 1771114SN/A protected: 1781114SN/A friend class TcpPtr; 1791114SN/A friend class UdpPtr; 1802566SN/A EthPacketPtr p; 1811114SN/A 1821114SN/A const IpHdr *h() const 1831114SN/A { return (const IpHdr *)(p->data + sizeof(eth_hdr)); } 1841114SN/A IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); } 1851114SN/A 1862566SN/A void set(const EthPacketPtr &ptr) 1871114SN/A { 1881114SN/A EthHdr *eth = (EthHdr *)ptr->data; 1891114SN/A if (eth->type() == ETH_TYPE_IP) 1901114SN/A p = ptr; 1911114SN/A else 1921114SN/A p = 0; 1931114SN/A } 1941114SN/A 1951114SN/A public: 1961114SN/A IpPtr() {} 1972566SN/A IpPtr(const EthPacketPtr &ptr) { set(ptr); } 1981114SN/A IpPtr(const EthPtr &ptr) { set(ptr.p); } 1991114SN/A IpPtr(const IpPtr &ptr) : p(ptr.p) { } 2001114SN/A 2011114SN/A IpHdr *operator->() { return h(); } 2021114SN/A IpHdr &operator*() { return *h(); } 2031114SN/A operator IpHdr *() { return h(); } 2041114SN/A 2051114SN/A const IpHdr *operator->() const { return h(); } 2061114SN/A const IpHdr &operator*() const { return *h(); } 2071114SN/A operator const IpHdr *() const { return h(); } 2081114SN/A 2092566SN/A const IpPtr &operator=(const EthPacketPtr &ptr) { set(ptr); return *this; } 2101114SN/A const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; } 2111114SN/A const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; } 2121114SN/A 2132566SN/A const EthPacketPtr packet() const { return p; } 2142566SN/A EthPacketPtr packet() { return p; } 2151114SN/A bool operator!() const { return !p; } 2161114SN/A operator bool() const { return p; } 2171114SN/A operator bool() { return p; } 2181114SN/A}; 2191114SN/A 2201114SN/Auint16_t cksum(const IpPtr &ptr); 2211114SN/A 2221114SN/Astruct IpOpt : public ip_opt 2231114SN/A{ 2241114SN/A uint8_t type() const { return opt_type; } 2251114SN/A uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); } 2261114SN/A uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); } 2271114SN/A uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); } 2281114SN/A uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; } 2291114SN/A 2301114SN/A bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); } 2311114SN/A bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); } 2321114SN/A bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); } 2331114SN/A 2341114SN/A const uint8_t *data() const { return opt_data.data8; } 2351114SN/A void sec(ip_opt_data_sec &sec) const; 2361114SN/A void lsrr(ip_opt_data_rr &rr) const; 2371114SN/A void ssrr(ip_opt_data_rr &rr) const; 2381114SN/A void ts(ip_opt_data_ts &ts) const; 2391114SN/A uint16_t satid() const { return ntohs(opt_data.satid); } 2401114SN/A uint16_t mtup() const { return ntohs(opt_data.mtu); } 2411114SN/A uint16_t mtur() const { return ntohs(opt_data.mtu); } 2421114SN/A void tr(ip_opt_data_tr &tr) const; 2431114SN/A const uint32_t *addext() const { return &opt_data.addext[0]; } 2441114SN/A uint16_t rtralt() const { return ntohs(opt_data.rtralt); } 2451114SN/A void sdb(std::vector<uint32_t> &vec) const; 2461114SN/A}; 2471114SN/A 2481114SN/A/* 2491114SN/A * TCP Stuff 2501114SN/A */ 2511114SN/Astruct TcpOpt; 2521114SN/Astruct TcpHdr : public tcp_hdr 2531078SN/A{ 2541078SN/A uint16_t sport() const { return ntohs(th_sport); } 2551078SN/A uint16_t dport() const { return ntohs(th_dport); } 2561078SN/A uint32_t seq() const { return ntohl(th_seq); } 2571078SN/A uint32_t ack() const { return ntohl(th_ack); } 2581078SN/A uint8_t off() const { return th_off; } 2591078SN/A uint8_t flags() const { return th_flags & 0x3f; } 2601078SN/A uint16_t win() const { return ntohs(th_win); } 2611092SN/A uint16_t sum() const { return th_sum; } 2621078SN/A uint16_t urp() const { return ntohs(th_urp); } 2631078SN/A 2641092SN/A void sum(uint16_t sum) { th_sum = sum; } 2651078SN/A 2661114SN/A bool options(std::vector<const TcpOpt *> &vec) const; 2671114SN/A 2681079SN/A int size() const { return off(); } 2691079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 2701079SN/A const uint8_t *payload() const { return bytes() + size(); } 2711079SN/A uint8_t *bytes() { return (uint8_t *)this; } 2721079SN/A uint8_t *payload() { return bytes() + size(); } 2731078SN/A}; 2741078SN/A 2751114SN/Aclass TcpPtr 2761114SN/A{ 2771114SN/A protected: 2782566SN/A EthPacketPtr p; 2791114SN/A int off; 2801114SN/A 2811114SN/A const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); } 2821114SN/A TcpHdr *h() { return (TcpHdr *)(p->data + off); } 2831114SN/A 2842566SN/A void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; } 2851114SN/A void set(const IpPtr &ptr) 2861114SN/A { 2871114SN/A if (ptr->proto() == IP_PROTO_TCP) 2881114SN/A set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); 2891114SN/A else 2901114SN/A set(0, 0); 2911114SN/A } 2921114SN/A 2931114SN/A public: 2941114SN/A TcpPtr() {} 2951114SN/A TcpPtr(const IpPtr &ptr) { set(ptr); } 2961114SN/A TcpPtr(const TcpPtr &ptr) : p(ptr.p), off(ptr.off) {} 2971114SN/A 2981114SN/A TcpHdr *operator->() { return h(); } 2991114SN/A TcpHdr &operator*() { return *h(); } 3001114SN/A operator TcpHdr *() { return h(); } 3011114SN/A 3021114SN/A const TcpHdr *operator->() const { return h(); } 3031114SN/A const TcpHdr &operator*() const { return *h(); } 3041114SN/A operator const TcpHdr *() const { return h(); } 3051114SN/A 3061114SN/A const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; } 3071114SN/A const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; } 3081114SN/A 3092566SN/A const EthPacketPtr packet() const { return p; } 3102566SN/A EthPacketPtr packet() { return p; } 3111114SN/A bool operator!() const { return !p; } 3121114SN/A operator bool() const { return p; } 3131114SN/A operator bool() { return p; } 3141114SN/A}; 3151114SN/A 3161114SN/Auint16_t cksum(const TcpPtr &ptr); 3171114SN/A 3181114SN/Atypedef Range<uint16_t> SackRange; 3191114SN/A 3201114SN/Astruct TcpOpt : public tcp_opt 3211114SN/A{ 3221114SN/A uint8_t type() const { return opt_type; } 3231114SN/A uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; } 3241114SN/A 3251114SN/A bool isopt(int opt) const { return type() == opt; } 3261114SN/A 3271114SN/A const uint8_t *data() const { return opt_data.data8; } 3281114SN/A 3291114SN/A uint16_t mss() const { return ntohs(opt_data.mss); } 3301114SN/A uint8_t wscale() const { return opt_data.wscale; } 3311114SN/A bool sack(std::vector<SackRange> &vec) const; 3321114SN/A uint32_t echo() const { return ntohl(opt_data.echo); } 3331114SN/A uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); } 3341114SN/A uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); } 3351114SN/A uint32_t cc() const { return ntohl(opt_data.cc); } 3361114SN/A uint8_t cksum() const{ return opt_data.cksum; } 3371114SN/A const uint8_t *md5() const { return opt_data.md5; } 3381114SN/A 3391114SN/A int size() const { return len(); } 3401114SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 3411114SN/A const uint8_t *payload() const { return bytes() + size(); } 3421114SN/A uint8_t *bytes() { return (uint8_t *)this; } 3431114SN/A uint8_t *payload() { return bytes() + size(); } 3441114SN/A}; 3451114SN/A 3461114SN/A/* 3471114SN/A * UDP Stuff 3481114SN/A */ 3491114SN/Astruct UdpHdr : public udp_hdr 3501078SN/A{ 3511078SN/A uint16_t sport() const { return ntohs(uh_sport); } 3521078SN/A uint16_t dport() const { return ntohs(uh_dport); } 3531078SN/A uint16_t len() const { return ntohs(uh_ulen); } 3541171SN/A uint16_t sum() const { return uh_sum; } 3551078SN/A 3561171SN/A void sum(uint16_t sum) { uh_sum = sum; } 3571078SN/A 3581114SN/A int size() const { return sizeof(udp_hdr); } 3591079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 3601079SN/A const uint8_t *payload() const { return bytes() + size(); } 3611079SN/A uint8_t *bytes() { return (uint8_t *)this; } 3621079SN/A uint8_t *payload() { return bytes() + size(); } 3631078SN/A}; 3641078SN/A 3651114SN/Aclass UdpPtr 3661114SN/A{ 3671114SN/A protected: 3682566SN/A EthPacketPtr p; 3691114SN/A int off; 3701114SN/A 3711114SN/A const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); } 3721114SN/A UdpHdr *h() { return (UdpHdr *)(p->data + off); } 3731114SN/A 3742566SN/A void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; } 3751114SN/A void set(const IpPtr &ptr) 3761114SN/A { 3771114SN/A if (ptr->proto() == IP_PROTO_UDP) 3781114SN/A set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); 3791114SN/A else 3801114SN/A set(0, 0); 3811114SN/A } 3821114SN/A 3831114SN/A public: 3841114SN/A UdpPtr() {} 3851114SN/A UdpPtr(const IpPtr &ptr) { set(ptr); } 3861114SN/A UdpPtr(const UdpPtr &ptr) : p(ptr.p), off(ptr.off) {} 3871114SN/A 3881114SN/A UdpHdr *operator->() { return h(); } 3891114SN/A UdpHdr &operator*() { return *h(); } 3901114SN/A operator UdpHdr *() { return h(); } 3911114SN/A 3921114SN/A const UdpHdr *operator->() const { return h(); } 3931114SN/A const UdpHdr &operator*() const { return *h(); } 3941114SN/A operator const UdpHdr *() const { return h(); } 3951114SN/A 3961114SN/A const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; } 3971114SN/A const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; } 3981114SN/A 3992566SN/A const EthPacketPtr packet() const { return p; } 4002566SN/A EthPacketPtr packet() { return p; } 4011114SN/A bool operator!() const { return !p; } 4021114SN/A operator bool() const { return p; } 4031114SN/A operator bool() { return p; } 4041114SN/A}; 4051114SN/A 4061114SN/Auint16_t cksum(const UdpPtr &ptr); 4071114SN/A 4081114SN/A/* namespace Net */ } 4091114SN/A 4101078SN/A#endif // __BASE_INET_HH__ 411