inet.hh revision 10251
12SN/A/* 29955SGeoffrey.Blake@arm.com * Copyright (c) 2013 ARM Limited 39955SGeoffrey.Blake@arm.com * All rights reserved 49955SGeoffrey.Blake@arm.com * 59955SGeoffrey.Blake@arm.com * The license below extends only to copyright in the software and shall 69955SGeoffrey.Blake@arm.com * not be construed as granting a license to any other intellectual 79955SGeoffrey.Blake@arm.com * property including but not limited to intellectual property relating 89955SGeoffrey.Blake@arm.com * to a hardware implementation of the functionality of the software 99955SGeoffrey.Blake@arm.com * licensed hereunder. You may use the software subject to the license 109955SGeoffrey.Blake@arm.com * terms below provided that you ensure that this notice is replicated 119955SGeoffrey.Blake@arm.com * unmodified and in its entirety in all distributions of the software, 129955SGeoffrey.Blake@arm.com * modified or unmodified, in source code or in binary form. 139955SGeoffrey.Blake@arm.com * 141762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 157778Sgblack@eecs.umich.edu * Copyright (c) 2010 Advanced Micro Devices, Inc. 162SN/A * All rights reserved. 172SN/A * 182SN/A * Redistribution and use in source and binary forms, with or without 192SN/A * modification, are permitted provided that the following conditions are 202SN/A * met: redistributions of source code must retain the above copyright 212SN/A * notice, this list of conditions and the following disclaimer; 222SN/A * redistributions in binary form must reproduce the above copyright 232SN/A * notice, this list of conditions and the following disclaimer in the 242SN/A * documentation and/or other materials provided with the distribution; 252SN/A * neither the name of the copyright holders nor the names of its 262SN/A * contributors may be used to endorse or promote products derived from 272SN/A * this software without specific prior written permission. 282SN/A * 292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 342SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 352SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 392SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 402665Ssaidi@eecs.umich.edu * 412665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 422665Ssaidi@eecs.umich.edu * Steve Reinhardt 437778Sgblack@eecs.umich.edu * Gabe Black 449955SGeoffrey.Blake@arm.com * Geoffrey Blake 452SN/A */ 462SN/A 471078SN/A#ifndef __BASE_INET_HH__ 481078SN/A#define __BASE_INET_HH__ 491078SN/A 501114SN/A#include <iosfwd> 511078SN/A#include <string> 521114SN/A#include <utility> 531114SN/A#include <vector> 541114SN/A 556216Snate@binkert.org#include "base/types.hh" 561114SN/A#include "dev/etherpkt.hh" 571078SN/A#include "dnet/os.h" 581078SN/A#include "dnet/eth.h" 591078SN/A#include "dnet/ip.h" 601078SN/A#include "dnet/ip6.h" 611078SN/A#include "dnet/addr.h" 621078SN/A#include "dnet/arp.h" 631078SN/A#include "dnet/icmp.h" 641078SN/A#include "dnet/tcp.h" 651078SN/A#include "dnet/udp.h" 661078SN/A#include "dnet/intf.h" 671078SN/A#include "dnet/route.h" 681078SN/A#include "dnet/fw.h" 691078SN/A#include "dnet/blob.h" 701078SN/A#include "dnet/rand.h" 712SN/A 721114SN/Anamespace Net { 732SN/A 741114SN/A/* 751114SN/A * Ethernet Stuff 761114SN/A */ 771114SN/Astruct EthAddr : protected eth_addr 781114SN/A{ 791114SN/A protected: 801114SN/A void parse(const std::string &addr); 811078SN/A 821114SN/A public: 831114SN/A EthAddr(); 841114SN/A EthAddr(const uint8_t ea[ETH_ADDR_LEN]); 851114SN/A EthAddr(const eth_addr &ea); 861114SN/A EthAddr(const std::string &addr); 871114SN/A const EthAddr &operator=(const eth_addr &ea); 881114SN/A const EthAddr &operator=(const std::string &addr); 891079SN/A 901114SN/A int size() const { return sizeof(eth_addr); } 911114SN/A 921114SN/A const uint8_t *bytes() const { return &data[0]; } 931114SN/A uint8_t *bytes() { return &data[0]; } 941114SN/A 951114SN/A const uint8_t *addr() const { return &data[0]; } 9610251Satgutier@umich.edu bool unicast() const { return !(data[0] & 0x01); } 9710251Satgutier@umich.edu bool multicast() const { return !unicast() && !broadcast(); } 9810251Satgutier@umich.edu bool broadcast() const 9910251Satgutier@umich.edu { 10010251Satgutier@umich.edu bool isBroadcast = true; 10110251Satgutier@umich.edu for (int i = 0; i < ETH_ADDR_LEN; ++i) { 10210251Satgutier@umich.edu isBroadcast = isBroadcast && data[i] == 0xff; 10310251Satgutier@umich.edu } 10410251Satgutier@umich.edu 10510251Satgutier@umich.edu return isBroadcast; 10610251Satgutier@umich.edu } 10710251Satgutier@umich.edu 1081114SN/A std::string string() const; 1091137SN/A 1101137SN/A operator uint64_t() const 1111137SN/A { 1121137SN/A uint64_t reg = 0; 1131137SN/A reg |= ((uint64_t)data[0]) << 40; 1141137SN/A reg |= ((uint64_t)data[1]) << 32; 1151137SN/A reg |= ((uint64_t)data[2]) << 24; 1161137SN/A reg |= ((uint64_t)data[3]) << 16; 1171137SN/A reg |= ((uint64_t)data[4]) << 8; 1181137SN/A reg |= ((uint64_t)data[5]) << 0; 1191137SN/A return reg; 1201137SN/A } 1211137SN/A 1221114SN/A}; 1231114SN/A 1241114SN/Astd::ostream &operator<<(std::ostream &stream, const EthAddr &ea); 1251114SN/Abool operator==(const EthAddr &left, const EthAddr &right); 1261114SN/A 1271114SN/Astruct EthHdr : public eth_hdr 1281078SN/A{ 1299955SGeoffrey.Blake@arm.com bool isVlan() const { return (ntohs(eth_type) == ETH_TYPE_8021Q); } 1309955SGeoffrey.Blake@arm.com uint16_t type() const { 1319955SGeoffrey.Blake@arm.com if (!isVlan()) 1329955SGeoffrey.Blake@arm.com return ntohs(eth_type); 1339955SGeoffrey.Blake@arm.com else 1349955SGeoffrey.Blake@arm.com // L3 type is now 16 bytes into the hdr with 802.1Q 1359955SGeoffrey.Blake@arm.com // instead of 12. dnet/eth.h only supports 802.1 1369955SGeoffrey.Blake@arm.com return ntohs(*((uint16_t*)(((uint8_t *)this) + 16))); 1379955SGeoffrey.Blake@arm.com } 1389955SGeoffrey.Blake@arm.com uint16_t vlanId() const { 1399955SGeoffrey.Blake@arm.com if (isVlan()) 1409955SGeoffrey.Blake@arm.com return ntohs(*((uint16_t*)(((uint8_t *)this) + 14))); 1419955SGeoffrey.Blake@arm.com else 1429955SGeoffrey.Blake@arm.com return 0x0000; 1439955SGeoffrey.Blake@arm.com } 1449955SGeoffrey.Blake@arm.com 1451114SN/A const EthAddr &src() const { return *(EthAddr *)ð_src; } 1461114SN/A const EthAddr &dst() const { return *(EthAddr *)ð_dst; } 1471079SN/A 1489955SGeoffrey.Blake@arm.com int size() const { 1499955SGeoffrey.Blake@arm.com if (!isVlan()) 1509955SGeoffrey.Blake@arm.com return sizeof(eth_hdr); 1519955SGeoffrey.Blake@arm.com else 1529955SGeoffrey.Blake@arm.com return (sizeof(eth_hdr)+4); 1539955SGeoffrey.Blake@arm.com } 1541079SN/A 1551079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 1561079SN/A const uint8_t *payload() const { return bytes() + size(); } 1571079SN/A uint8_t *bytes() { return (uint8_t *)this; } 1581079SN/A uint8_t *payload() { return bytes() + size(); } 1591078SN/A}; 1601078SN/A 1611114SN/Aclass EthPtr 1621114SN/A{ 1631114SN/A protected: 1641114SN/A friend class IpPtr; 1659955SGeoffrey.Blake@arm.com friend class Ip6Ptr; 1662566SN/A EthPacketPtr p; 1671114SN/A 1681114SN/A public: 1691114SN/A EthPtr() {} 1702566SN/A EthPtr(const EthPacketPtr &ptr) : p(ptr) { } 1711114SN/A 1721114SN/A EthHdr *operator->() { return (EthHdr *)p->data; } 1731114SN/A EthHdr &operator*() { return *(EthHdr *)p->data; } 1741114SN/A operator EthHdr *() { return (EthHdr *)p->data; } 1751114SN/A 1761114SN/A const EthHdr *operator->() const { return (const EthHdr *)p->data; } 1771114SN/A const EthHdr &operator*() const { return *(const EthHdr *)p->data; } 1781114SN/A operator const EthHdr *() const { return (const EthHdr *)p->data; } 1791114SN/A 1802566SN/A const EthPtr &operator=(const EthPacketPtr &ptr) { p = ptr; return *this; } 1811114SN/A 1822566SN/A const EthPacketPtr packet() const { return p; } 1832566SN/A EthPacketPtr packet() { return p; } 1841114SN/A bool operator!() const { return !p; } 1851114SN/A operator bool() const { return p; } 1865782Ssaidi@eecs.umich.edu int off() const { return 0; } 1875782Ssaidi@eecs.umich.edu int pstart() const { return off() + ((const EthHdr*)p->data)->size(); } 1881114SN/A}; 1891114SN/A 1901114SN/A/* 1911114SN/A * IP Stuff 1921114SN/A */ 1937777Sgblack@eecs.umich.edustruct IpAddress 1947777Sgblack@eecs.umich.edu{ 1957777Sgblack@eecs.umich.edu protected: 1967777Sgblack@eecs.umich.edu uint32_t _ip; 1977777Sgblack@eecs.umich.edu 1987777Sgblack@eecs.umich.edu public: 1997777Sgblack@eecs.umich.edu IpAddress() : _ip(0) 2007777Sgblack@eecs.umich.edu {} 2017777Sgblack@eecs.umich.edu IpAddress(const uint32_t __ip) : _ip(__ip) 2027777Sgblack@eecs.umich.edu {} 2037777Sgblack@eecs.umich.edu 2047777Sgblack@eecs.umich.edu uint32_t ip() const { return _ip; } 2057777Sgblack@eecs.umich.edu 2067777Sgblack@eecs.umich.edu std::string string() const; 2077777Sgblack@eecs.umich.edu}; 2087777Sgblack@eecs.umich.edu 2097777Sgblack@eecs.umich.edustd::ostream &operator<<(std::ostream &stream, const IpAddress &ia); 2107777Sgblack@eecs.umich.edubool operator==(const IpAddress &left, const IpAddress &right); 2117777Sgblack@eecs.umich.edu 2127777Sgblack@eecs.umich.edustruct IpNetmask : public IpAddress 2137777Sgblack@eecs.umich.edu{ 2147777Sgblack@eecs.umich.edu protected: 2157777Sgblack@eecs.umich.edu uint8_t _netmask; 2167777Sgblack@eecs.umich.edu 2177777Sgblack@eecs.umich.edu public: 2187777Sgblack@eecs.umich.edu IpNetmask() : IpAddress(), _netmask(0) 2197777Sgblack@eecs.umich.edu {} 2207777Sgblack@eecs.umich.edu IpNetmask(const uint32_t __ip, const uint8_t __netmask) : 2217777Sgblack@eecs.umich.edu IpAddress(__ip), _netmask(__netmask) 2227777Sgblack@eecs.umich.edu {} 2237777Sgblack@eecs.umich.edu 2247777Sgblack@eecs.umich.edu uint8_t netmask() const { return _netmask; } 2257777Sgblack@eecs.umich.edu 2267777Sgblack@eecs.umich.edu std::string string() const; 2277777Sgblack@eecs.umich.edu}; 2287777Sgblack@eecs.umich.edu 2297777Sgblack@eecs.umich.edustd::ostream &operator<<(std::ostream &stream, const IpNetmask &in); 2307777Sgblack@eecs.umich.edubool operator==(const IpNetmask &left, const IpNetmask &right); 2317777Sgblack@eecs.umich.edu 2327777Sgblack@eecs.umich.edustruct IpWithPort : public IpAddress 2337777Sgblack@eecs.umich.edu{ 2347777Sgblack@eecs.umich.edu protected: 2357777Sgblack@eecs.umich.edu uint16_t _port; 2367777Sgblack@eecs.umich.edu 2377777Sgblack@eecs.umich.edu public: 2387777Sgblack@eecs.umich.edu IpWithPort() : IpAddress(), _port(0) 2397777Sgblack@eecs.umich.edu {} 2407777Sgblack@eecs.umich.edu IpWithPort(const uint32_t __ip, const uint16_t __port) : 2417777Sgblack@eecs.umich.edu IpAddress(__ip), _port(__port) 2427777Sgblack@eecs.umich.edu {} 2437777Sgblack@eecs.umich.edu 2447777Sgblack@eecs.umich.edu uint8_t port() const { return _port; } 2457777Sgblack@eecs.umich.edu 2467777Sgblack@eecs.umich.edu std::string string() const; 2477777Sgblack@eecs.umich.edu}; 2487777Sgblack@eecs.umich.edu 2497777Sgblack@eecs.umich.edustd::ostream &operator<<(std::ostream &stream, const IpWithPort &iwp); 2507777Sgblack@eecs.umich.edubool operator==(const IpWithPort &left, const IpWithPort &right); 2517777Sgblack@eecs.umich.edu 2521114SN/Astruct IpOpt; 2531114SN/Astruct IpHdr : public ip_hdr 2541078SN/A{ 2551078SN/A uint8_t version() const { return ip_v; } 2561092SN/A uint8_t hlen() const { return ip_hl * 4; } 2571078SN/A uint8_t tos() const { return ip_tos; } 2581078SN/A uint16_t len() const { return ntohs(ip_len); } 2591078SN/A uint16_t id() const { return ntohs(ip_id); } 2601078SN/A uint16_t frag_flags() const { return ntohs(ip_off) >> 13; } 2611078SN/A uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; } 2621078SN/A uint8_t ttl() const { return ip_ttl; } 2631078SN/A uint8_t proto() const { return ip_p; } 2641092SN/A uint16_t sum() const { return ip_sum; } 2651078SN/A uint32_t src() const { return ntohl(ip_src); } 2661078SN/A uint32_t dst() const { return ntohl(ip_dst); } 2671078SN/A 2681092SN/A void sum(uint16_t sum) { ip_sum = sum; } 2695761Ssaidi@eecs.umich.edu void id(uint16_t _id) { ip_id = htons(_id); } 2705761Ssaidi@eecs.umich.edu void len(uint16_t _len) { ip_len = htons(_len); } 2715761Ssaidi@eecs.umich.edu 2721114SN/A bool options(std::vector<const IpOpt *> &vec) const; 2731079SN/A 2741079SN/A int size() const { return hlen(); } 2751079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 2761079SN/A const uint8_t *payload() const { return bytes() + size(); } 2771079SN/A uint8_t *bytes() { return (uint8_t *)this; } 2781079SN/A uint8_t *payload() { return bytes() + size(); } 2791078SN/A}; 2801078SN/A 2811114SN/Aclass IpPtr 2821114SN/A{ 2831114SN/A protected: 2841114SN/A friend class TcpPtr; 2851114SN/A friend class UdpPtr; 2862566SN/A EthPacketPtr p; 2879955SGeoffrey.Blake@arm.com bool eth_hdr_vlan; 2881114SN/A 2892566SN/A void set(const EthPacketPtr &ptr) 2901114SN/A { 2915484Snate@binkert.org p = 0; 2929955SGeoffrey.Blake@arm.com eth_hdr_vlan = false; 2935484Snate@binkert.org 2945484Snate@binkert.org if (ptr) { 2955484Snate@binkert.org EthHdr *eth = (EthHdr *)ptr->data; 2965484Snate@binkert.org if (eth->type() == ETH_TYPE_IP) 2975484Snate@binkert.org p = ptr; 2989955SGeoffrey.Blake@arm.com if (eth->isVlan()) 2999955SGeoffrey.Blake@arm.com eth_hdr_vlan = true; 3005484Snate@binkert.org } 3011114SN/A } 3021114SN/A 3031114SN/A public: 3049955SGeoffrey.Blake@arm.com IpPtr() : p(0), eth_hdr_vlan(false) {} 3059955SGeoffrey.Blake@arm.com IpPtr(const EthPacketPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr); } 3069955SGeoffrey.Blake@arm.com IpPtr(const EthPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr.p); } 3079955SGeoffrey.Blake@arm.com IpPtr(const IpPtr &ptr) : p(ptr.p), eth_hdr_vlan(ptr.eth_hdr_vlan) { } 3081114SN/A 3099955SGeoffrey.Blake@arm.com IpHdr *get() { return (IpHdr *)(p->data + sizeof(eth_hdr) + 3109955SGeoffrey.Blake@arm.com ((eth_hdr_vlan) ? 4 : 0)); } 3115484Snate@binkert.org IpHdr *operator->() { return get(); } 3125484Snate@binkert.org IpHdr &operator*() { return *get(); } 3131114SN/A 3145484Snate@binkert.org const IpHdr *get() const 3159955SGeoffrey.Blake@arm.com { return (const IpHdr *)(p->data + sizeof(eth_hdr) + 3169955SGeoffrey.Blake@arm.com ((eth_hdr_vlan) ? 4 : 0)); } 3175484Snate@binkert.org const IpHdr *operator->() const { return get(); } 3185484Snate@binkert.org const IpHdr &operator*() const { return *get(); } 3191114SN/A 3202566SN/A const IpPtr &operator=(const EthPacketPtr &ptr) { set(ptr); return *this; } 3211114SN/A const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; } 3221114SN/A const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; } 3231114SN/A 3242566SN/A const EthPacketPtr packet() const { return p; } 3252566SN/A EthPacketPtr packet() { return p; } 3261114SN/A bool operator!() const { return !p; } 3271114SN/A operator bool() const { return p; } 3289955SGeoffrey.Blake@arm.com int off() const { return (sizeof(eth_hdr) + ((eth_hdr_vlan) ? 4 : 0)); } 3299955SGeoffrey.Blake@arm.com int pstart() const { return (off() + get()->size()); } 3301114SN/A}; 3311114SN/A 3321114SN/Auint16_t cksum(const IpPtr &ptr); 3331114SN/A 3341114SN/Astruct IpOpt : public ip_opt 3351114SN/A{ 3361114SN/A uint8_t type() const { return opt_type; } 3371114SN/A uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); } 3381114SN/A uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); } 3391114SN/A uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); } 3401114SN/A uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; } 3411114SN/A 3421114SN/A bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); } 3431114SN/A bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); } 3441114SN/A bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); } 3451114SN/A 3461114SN/A const uint8_t *data() const { return opt_data.data8; } 3471114SN/A void sec(ip_opt_data_sec &sec) const; 3481114SN/A void lsrr(ip_opt_data_rr &rr) const; 3491114SN/A void ssrr(ip_opt_data_rr &rr) const; 3501114SN/A void ts(ip_opt_data_ts &ts) const; 3511114SN/A uint16_t satid() const { return ntohs(opt_data.satid); } 3521114SN/A uint16_t mtup() const { return ntohs(opt_data.mtu); } 3531114SN/A uint16_t mtur() const { return ntohs(opt_data.mtu); } 3541114SN/A void tr(ip_opt_data_tr &tr) const; 3551114SN/A const uint32_t *addext() const { return &opt_data.addext[0]; } 3561114SN/A uint16_t rtralt() const { return ntohs(opt_data.rtralt); } 3571114SN/A void sdb(std::vector<uint32_t> &vec) const; 3581114SN/A}; 3591114SN/A 3601114SN/A/* 3619955SGeoffrey.Blake@arm.com * Ip6 Classes 3629955SGeoffrey.Blake@arm.com */ 3639955SGeoffrey.Blake@arm.comstruct Ip6Opt; 3649955SGeoffrey.Blake@arm.comstruct Ip6Hdr : public ip6_hdr 3659955SGeoffrey.Blake@arm.com{ 3669955SGeoffrey.Blake@arm.com uint8_t version() const { return ip6_vfc; } 3679955SGeoffrey.Blake@arm.com uint32_t flow() const { return ntohl(ip6_flow); } 3689955SGeoffrey.Blake@arm.com uint16_t plen() const { return ntohs(ip6_plen); } 3699955SGeoffrey.Blake@arm.com uint16_t hlen() const { return IP6_HDR_LEN; } 3709955SGeoffrey.Blake@arm.com uint8_t nxt() const { return ip6_nxt; } 3719955SGeoffrey.Blake@arm.com uint8_t hlim() const { return ip6_hlim; } 3729955SGeoffrey.Blake@arm.com 3739955SGeoffrey.Blake@arm.com const uint8_t* src() const { return ip6_src.data; } 3749955SGeoffrey.Blake@arm.com const uint8_t* dst() const { return ip6_dst.data; } 3759955SGeoffrey.Blake@arm.com 3769955SGeoffrey.Blake@arm.com int extensionLength() const; 3779955SGeoffrey.Blake@arm.com const Ip6Opt* getExt(uint8_t ext) const; 3789955SGeoffrey.Blake@arm.com const Ip6Opt* fragmentExt() const { return getExt(IP_PROTO_FRAGMENT); } 3799955SGeoffrey.Blake@arm.com const Ip6Opt* rtTypeExt() const { return getExt(IP_PROTO_ROUTING); } 3809955SGeoffrey.Blake@arm.com const Ip6Opt* dstOptExt() const { return getExt(IP_PROTO_DSTOPTS); } 3819955SGeoffrey.Blake@arm.com uint8_t proto() const; 3829955SGeoffrey.Blake@arm.com 3839955SGeoffrey.Blake@arm.com void plen(uint16_t _plen) { ip6_plen = htons(_plen); } 3849955SGeoffrey.Blake@arm.com 3859955SGeoffrey.Blake@arm.com int size() const { return IP6_HDR_LEN + extensionLength(); } 3869955SGeoffrey.Blake@arm.com const uint8_t *bytes() const { return (const uint8_t *)this; } 3879955SGeoffrey.Blake@arm.com const uint8_t *payload() const { return bytes() + IP6_HDR_LEN 3889955SGeoffrey.Blake@arm.com + extensionLength(); } 3899955SGeoffrey.Blake@arm.com uint8_t *bytes() { return (uint8_t *)this; } 3909955SGeoffrey.Blake@arm.com uint8_t *payload() { return bytes() + IP6_HDR_LEN 3919955SGeoffrey.Blake@arm.com + extensionLength(); } 3929955SGeoffrey.Blake@arm.com}; 3939955SGeoffrey.Blake@arm.com 3949955SGeoffrey.Blake@arm.comclass Ip6Ptr 3959955SGeoffrey.Blake@arm.com{ 3969955SGeoffrey.Blake@arm.com protected: 3979955SGeoffrey.Blake@arm.com friend class TcpPtr; 3989955SGeoffrey.Blake@arm.com friend class UdpPtr; 3999955SGeoffrey.Blake@arm.com EthPacketPtr p; 4009955SGeoffrey.Blake@arm.com bool eth_hdr_vlan; 4019955SGeoffrey.Blake@arm.com 4029955SGeoffrey.Blake@arm.com void set(const EthPacketPtr &ptr) 4039955SGeoffrey.Blake@arm.com { 4049955SGeoffrey.Blake@arm.com p = 0; 4059955SGeoffrey.Blake@arm.com eth_hdr_vlan = false; 4069955SGeoffrey.Blake@arm.com 4079955SGeoffrey.Blake@arm.com if (ptr) { 4089955SGeoffrey.Blake@arm.com EthHdr *eth = (EthHdr *)ptr->data; 4099955SGeoffrey.Blake@arm.com if (eth->type() == ETH_TYPE_IPV6) 4109955SGeoffrey.Blake@arm.com p = ptr; 4119955SGeoffrey.Blake@arm.com if (eth->isVlan()) 4129955SGeoffrey.Blake@arm.com eth_hdr_vlan = true; 4139955SGeoffrey.Blake@arm.com } 4149955SGeoffrey.Blake@arm.com } 4159955SGeoffrey.Blake@arm.com 4169955SGeoffrey.Blake@arm.com public: 4179955SGeoffrey.Blake@arm.com Ip6Ptr() : p(0), eth_hdr_vlan(false) {} 4189955SGeoffrey.Blake@arm.com Ip6Ptr(const EthPacketPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr); } 4199955SGeoffrey.Blake@arm.com Ip6Ptr(const EthPtr &ptr) : p(0), eth_hdr_vlan(false) { set(ptr.p); } 4209955SGeoffrey.Blake@arm.com Ip6Ptr(const Ip6Ptr &ptr) : p(ptr.p), eth_hdr_vlan(ptr.eth_hdr_vlan) { } 4219955SGeoffrey.Blake@arm.com 4229955SGeoffrey.Blake@arm.com Ip6Hdr *get() { return (Ip6Hdr *)(p->data + sizeof(eth_hdr) 4239955SGeoffrey.Blake@arm.com + ((eth_hdr_vlan) ? 4 : 0)); } 4249955SGeoffrey.Blake@arm.com Ip6Hdr *operator->() { return get(); } 4259955SGeoffrey.Blake@arm.com Ip6Hdr &operator*() { return *get(); } 4269955SGeoffrey.Blake@arm.com 4279955SGeoffrey.Blake@arm.com const Ip6Hdr *get() const 4289955SGeoffrey.Blake@arm.com { return (const Ip6Hdr *)(p->data + sizeof(eth_hdr) 4299955SGeoffrey.Blake@arm.com + ((eth_hdr_vlan) ? 4 : 0)); } 4309955SGeoffrey.Blake@arm.com const Ip6Hdr *operator->() const { return get(); } 4319955SGeoffrey.Blake@arm.com const Ip6Hdr &operator*() const { return *get(); } 4329955SGeoffrey.Blake@arm.com 4339955SGeoffrey.Blake@arm.com const Ip6Ptr &operator=(const EthPacketPtr &ptr) 4349955SGeoffrey.Blake@arm.com { set(ptr); return *this; } 4359955SGeoffrey.Blake@arm.com const Ip6Ptr &operator=(const EthPtr &ptr) 4369955SGeoffrey.Blake@arm.com { set(ptr.p); return *this; } 4379955SGeoffrey.Blake@arm.com const Ip6Ptr &operator=(const Ip6Ptr &ptr) 4389955SGeoffrey.Blake@arm.com { p = ptr.p; return *this; } 4399955SGeoffrey.Blake@arm.com 4409955SGeoffrey.Blake@arm.com const EthPacketPtr packet() const { return p; } 4419955SGeoffrey.Blake@arm.com EthPacketPtr packet() { return p; } 4429955SGeoffrey.Blake@arm.com bool operator!() const { return !p; } 4439955SGeoffrey.Blake@arm.com operator bool() const { return p; } 4449955SGeoffrey.Blake@arm.com int off() const { return sizeof(eth_hdr) + ((eth_hdr_vlan) ? 4 : 0); } 4459955SGeoffrey.Blake@arm.com int pstart() const { return off() + get()->size(); } 4469955SGeoffrey.Blake@arm.com}; 4479955SGeoffrey.Blake@arm.com 4489955SGeoffrey.Blake@arm.com// Dnet supplied ipv6 opt header is incomplete and 4499955SGeoffrey.Blake@arm.com// newer NIC card filters expect a more robust 4509955SGeoffrey.Blake@arm.com// ipv6 header option declaration. 4519955SGeoffrey.Blake@arm.comstruct ip6_opt_fragment { 4529955SGeoffrey.Blake@arm.com uint16_t offlg; 4539955SGeoffrey.Blake@arm.com uint32_t ident; 4549955SGeoffrey.Blake@arm.com}; 4559955SGeoffrey.Blake@arm.com 4569955SGeoffrey.Blake@arm.comstruct ip6_opt_routing_type2 { 4579955SGeoffrey.Blake@arm.com uint8_t type; 4589955SGeoffrey.Blake@arm.com uint8_t segleft; 4599955SGeoffrey.Blake@arm.com uint32_t reserved; 4609955SGeoffrey.Blake@arm.com ip6_addr_t addr; 4619955SGeoffrey.Blake@arm.com}; 4629955SGeoffrey.Blake@arm.com 4639955SGeoffrey.Blake@arm.com#define HOME_ADDRESS_OPTION 0xC9 4649955SGeoffrey.Blake@arm.comstruct ip6_opt_dstopts { 4659955SGeoffrey.Blake@arm.com uint8_t type; 4669955SGeoffrey.Blake@arm.com uint8_t length; 4679955SGeoffrey.Blake@arm.com ip6_addr_t addr; 4689955SGeoffrey.Blake@arm.com} __attribute__((packed)); 4699955SGeoffrey.Blake@arm.com 4709955SGeoffrey.Blake@arm.comstruct ip6_opt_hdr 4719955SGeoffrey.Blake@arm.com{ 4729955SGeoffrey.Blake@arm.com uint8_t ext_nxt; 4739955SGeoffrey.Blake@arm.com uint8_t ext_len; 4749955SGeoffrey.Blake@arm.com union { 4759955SGeoffrey.Blake@arm.com struct ip6_opt_fragment fragment; 4769955SGeoffrey.Blake@arm.com struct ip6_opt_routing_type2 rtType2; 4779955SGeoffrey.Blake@arm.com struct ip6_opt_dstopts dstOpts; 4789955SGeoffrey.Blake@arm.com } ext_data; 4799955SGeoffrey.Blake@arm.com} __attribute__((packed)); 4809955SGeoffrey.Blake@arm.com 4819955SGeoffrey.Blake@arm.comstruct Ip6Opt : public ip6_opt_hdr 4829955SGeoffrey.Blake@arm.com{ 4839955SGeoffrey.Blake@arm.com uint8_t nxt() const { return ext_nxt; } 4849955SGeoffrey.Blake@arm.com uint8_t extlen() const { return ext_len; } 4859955SGeoffrey.Blake@arm.com uint8_t len() const { return extlen() + 8; } 4869955SGeoffrey.Blake@arm.com 4879955SGeoffrey.Blake@arm.com // Supporting the types of header extensions likely to be encountered: 4889955SGeoffrey.Blake@arm.com // fragment, routing type 2 and dstopts. 4899955SGeoffrey.Blake@arm.com 4909955SGeoffrey.Blake@arm.com // Routing type 2 4919955SGeoffrey.Blake@arm.com uint8_t rtType2Type() const { return ext_data.rtType2.type; } 4929955SGeoffrey.Blake@arm.com uint8_t rtType2SegLft() const { return ext_data.rtType2.segleft; } 4939955SGeoffrey.Blake@arm.com const uint8_t* rtType2Addr() const { return ext_data.rtType2.addr.data; } 4949955SGeoffrey.Blake@arm.com 4959955SGeoffrey.Blake@arm.com // Fragment 4969955SGeoffrey.Blake@arm.com uint16_t fragmentOfflg() const { return ntohs(ext_data.fragment.offlg); } 4979955SGeoffrey.Blake@arm.com uint32_t fragmentIdent() const { return ntohl(ext_data.fragment.ident); } 4989955SGeoffrey.Blake@arm.com 4999955SGeoffrey.Blake@arm.com // Dst Options/Home Address Option 5009955SGeoffrey.Blake@arm.com uint8_t dstOptType() const { return ext_data.dstOpts.type; } 5019955SGeoffrey.Blake@arm.com uint8_t dstOptLength() const { return ext_data.dstOpts.length; } 5029955SGeoffrey.Blake@arm.com const uint8_t* dstOptAddr() const { return ext_data.dstOpts.addr.data; } 5039955SGeoffrey.Blake@arm.com}; 5049955SGeoffrey.Blake@arm.com 5059955SGeoffrey.Blake@arm.com 5069955SGeoffrey.Blake@arm.com/* 5071114SN/A * TCP Stuff 5081114SN/A */ 5091114SN/Astruct TcpOpt; 5101114SN/Astruct TcpHdr : public tcp_hdr 5111078SN/A{ 5121078SN/A uint16_t sport() const { return ntohs(th_sport); } 5131078SN/A uint16_t dport() const { return ntohs(th_dport); } 5141078SN/A uint32_t seq() const { return ntohl(th_seq); } 5151078SN/A uint32_t ack() const { return ntohl(th_ack); } 5169955SGeoffrey.Blake@arm.com uint8_t off() const { return th_off*4; } 5171078SN/A uint8_t flags() const { return th_flags & 0x3f; } 5181078SN/A uint16_t win() const { return ntohs(th_win); } 5191092SN/A uint16_t sum() const { return th_sum; } 5201078SN/A uint16_t urp() const { return ntohs(th_urp); } 5211078SN/A 5221092SN/A void sum(uint16_t sum) { th_sum = sum; } 5235761Ssaidi@eecs.umich.edu void seq(uint32_t _seq) { th_seq = htonl(_seq); } 5245761Ssaidi@eecs.umich.edu void flags(uint8_t _flags) { th_flags = _flags; } 5251078SN/A 5261114SN/A bool options(std::vector<const TcpOpt *> &vec) const; 5271114SN/A 5281079SN/A int size() const { return off(); } 5291079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 5301079SN/A const uint8_t *payload() const { return bytes() + size(); } 5311079SN/A uint8_t *bytes() { return (uint8_t *)this; } 5321079SN/A uint8_t *payload() { return bytes() + size(); } 5331078SN/A}; 5341078SN/A 5351114SN/Aclass TcpPtr 5361114SN/A{ 5371114SN/A protected: 5382566SN/A EthPacketPtr p; 5395782Ssaidi@eecs.umich.edu int _off; 5401114SN/A 5415782Ssaidi@eecs.umich.edu void set(const EthPacketPtr &ptr, int offset) { p = ptr; _off = offset; } 5421114SN/A void set(const IpPtr &ptr) 5431114SN/A { 5445484Snate@binkert.org if (ptr && ptr->proto() == IP_PROTO_TCP) 5459955SGeoffrey.Blake@arm.com set(ptr.p, ptr.pstart()); 5469955SGeoffrey.Blake@arm.com else 5479955SGeoffrey.Blake@arm.com set(0, 0); 5489955SGeoffrey.Blake@arm.com } 5499955SGeoffrey.Blake@arm.com void set(const Ip6Ptr &ptr) 5509955SGeoffrey.Blake@arm.com { 5519955SGeoffrey.Blake@arm.com if (ptr && ptr->proto() == IP_PROTO_TCP) 5529955SGeoffrey.Blake@arm.com set(ptr.p, ptr.pstart()); 5531114SN/A else 5541114SN/A set(0, 0); 5551114SN/A } 5561114SN/A 5571114SN/A public: 5585782Ssaidi@eecs.umich.edu TcpPtr() : p(0), _off(0) {} 5595782Ssaidi@eecs.umich.edu TcpPtr(const IpPtr &ptr) : p(0), _off(0) { set(ptr); } 5609955SGeoffrey.Blake@arm.com TcpPtr(const Ip6Ptr &ptr) : p(0), _off(0) { set(ptr); } 5615782Ssaidi@eecs.umich.edu TcpPtr(const TcpPtr &ptr) : p(ptr.p), _off(ptr._off) {} 5621114SN/A 5635782Ssaidi@eecs.umich.edu TcpHdr *get() { return (TcpHdr *)(p->data + _off); } 5645484Snate@binkert.org TcpHdr *operator->() { return get(); } 5655484Snate@binkert.org TcpHdr &operator*() { return *get(); } 5661114SN/A 5675782Ssaidi@eecs.umich.edu const TcpHdr *get() const { return (const TcpHdr *)(p->data + _off); } 5685484Snate@binkert.org const TcpHdr *operator->() const { return get(); } 5695484Snate@binkert.org const TcpHdr &operator*() const { return *get(); } 5701114SN/A 5719955SGeoffrey.Blake@arm.com const TcpPtr &operator=(const IpPtr &i) 5729955SGeoffrey.Blake@arm.com { set(i); return *this; } 5739955SGeoffrey.Blake@arm.com const TcpPtr &operator=(const TcpPtr &t) 5749955SGeoffrey.Blake@arm.com { set(t.p, t._off); return *this; } 5751114SN/A 5762566SN/A const EthPacketPtr packet() const { return p; } 5772566SN/A EthPacketPtr packet() { return p; } 5781114SN/A bool operator!() const { return !p; } 5791114SN/A operator bool() const { return p; } 5805782Ssaidi@eecs.umich.edu int off() const { return _off; } 5815782Ssaidi@eecs.umich.edu int pstart() const { return off() + get()->size(); } 5821114SN/A}; 5831114SN/A 5841114SN/Auint16_t cksum(const TcpPtr &ptr); 5851114SN/A 5861114SN/Astruct TcpOpt : public tcp_opt 5871114SN/A{ 5881114SN/A uint8_t type() const { return opt_type; } 5891114SN/A uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; } 5901114SN/A 5911114SN/A bool isopt(int opt) const { return type() == opt; } 5921114SN/A 5931114SN/A const uint8_t *data() const { return opt_data.data8; } 5941114SN/A 5951114SN/A uint16_t mss() const { return ntohs(opt_data.mss); } 5961114SN/A uint8_t wscale() const { return opt_data.wscale; } 5971114SN/A uint32_t echo() const { return ntohl(opt_data.echo); } 5981114SN/A uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); } 5991114SN/A uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); } 6001114SN/A uint32_t cc() const { return ntohl(opt_data.cc); } 6011114SN/A uint8_t cksum() const{ return opt_data.cksum; } 6021114SN/A const uint8_t *md5() const { return opt_data.md5; } 6031114SN/A 6041114SN/A int size() const { return len(); } 6051114SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 6061114SN/A const uint8_t *payload() const { return bytes() + size(); } 6071114SN/A uint8_t *bytes() { return (uint8_t *)this; } 6081114SN/A uint8_t *payload() { return bytes() + size(); } 6091114SN/A}; 6101114SN/A 6111114SN/A/* 6121114SN/A * UDP Stuff 6131114SN/A */ 6141114SN/Astruct UdpHdr : public udp_hdr 6151078SN/A{ 6161078SN/A uint16_t sport() const { return ntohs(uh_sport); } 6171078SN/A uint16_t dport() const { return ntohs(uh_dport); } 6181078SN/A uint16_t len() const { return ntohs(uh_ulen); } 6191171SN/A uint16_t sum() const { return uh_sum; } 6201078SN/A 6211171SN/A void sum(uint16_t sum) { uh_sum = sum; } 6225761Ssaidi@eecs.umich.edu void len(uint16_t _len) { uh_ulen = htons(_len); } 6231078SN/A 6241114SN/A int size() const { return sizeof(udp_hdr); } 6251079SN/A const uint8_t *bytes() const { return (const uint8_t *)this; } 6261079SN/A const uint8_t *payload() const { return bytes() + size(); } 6271079SN/A uint8_t *bytes() { return (uint8_t *)this; } 6281079SN/A uint8_t *payload() { return bytes() + size(); } 6291078SN/A}; 6301078SN/A 6311114SN/Aclass UdpPtr 6321114SN/A{ 6331114SN/A protected: 6342566SN/A EthPacketPtr p; 6355782Ssaidi@eecs.umich.edu int _off; 6361114SN/A 6375782Ssaidi@eecs.umich.edu void set(const EthPacketPtr &ptr, int offset) { p = ptr; _off = offset; } 6381114SN/A void set(const IpPtr &ptr) 6391114SN/A { 6405484Snate@binkert.org if (ptr && ptr->proto() == IP_PROTO_UDP) 6419955SGeoffrey.Blake@arm.com set(ptr.p, ptr.pstart()); 6429955SGeoffrey.Blake@arm.com else 6439955SGeoffrey.Blake@arm.com set(0, 0); 6449955SGeoffrey.Blake@arm.com } 6459955SGeoffrey.Blake@arm.com void set(const Ip6Ptr &ptr) 6469955SGeoffrey.Blake@arm.com { 6479955SGeoffrey.Blake@arm.com if (ptr && ptr->proto() == IP_PROTO_UDP) 6489955SGeoffrey.Blake@arm.com set(ptr.p, ptr.pstart()); 6491114SN/A else 6501114SN/A set(0, 0); 6511114SN/A } 6521114SN/A 6531114SN/A public: 6545782Ssaidi@eecs.umich.edu UdpPtr() : p(0), _off(0) {} 6555782Ssaidi@eecs.umich.edu UdpPtr(const IpPtr &ptr) : p(0), _off(0) { set(ptr); } 6569955SGeoffrey.Blake@arm.com UdpPtr(const Ip6Ptr &ptr) : p(0), _off(0) { set(ptr); } 6575782Ssaidi@eecs.umich.edu UdpPtr(const UdpPtr &ptr) : p(ptr.p), _off(ptr._off) {} 6581114SN/A 6595782Ssaidi@eecs.umich.edu UdpHdr *get() { return (UdpHdr *)(p->data + _off); } 6605484Snate@binkert.org UdpHdr *operator->() { return get(); } 6615484Snate@binkert.org UdpHdr &operator*() { return *get(); } 6621114SN/A 6635782Ssaidi@eecs.umich.edu const UdpHdr *get() const { return (const UdpHdr *)(p->data + _off); } 6645484Snate@binkert.org const UdpHdr *operator->() const { return get(); } 6655484Snate@binkert.org const UdpHdr &operator*() const { return *get(); } 6661114SN/A 6671114SN/A const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; } 6689955SGeoffrey.Blake@arm.com const UdpPtr &operator=(const UdpPtr &t) 6699955SGeoffrey.Blake@arm.com { set(t.p, t._off); return *this; } 6701114SN/A 6712566SN/A const EthPacketPtr packet() const { return p; } 6722566SN/A EthPacketPtr packet() { return p; } 6731114SN/A bool operator!() const { return !p; } 6741114SN/A operator bool() const { return p; } 6755782Ssaidi@eecs.umich.edu int off() const { return _off; } 6765782Ssaidi@eecs.umich.edu int pstart() const { return off() + get()->size(); } 6771114SN/A}; 6781114SN/A 6799955SGeoffrey.Blake@arm.comuint16_t __tu_cksum6(const Ip6Ptr &ip6); 6809554Sandreas.hansson@arm.comuint16_t __tu_cksum(const IpPtr &ip); 6811114SN/Auint16_t cksum(const UdpPtr &ptr); 6821114SN/A 6835782Ssaidi@eecs.umich.eduint hsplit(const EthPacketPtr &ptr); 6845782Ssaidi@eecs.umich.edu 6857811Ssteve.reinhardt@amd.com} // namespace Net 6861114SN/A 6871078SN/A#endif // __BASE_INET_HH__ 688