diff options
Diffstat (limited to 'base/inet.hh')
-rw-r--r-- | base/inet.hh | 311 |
1 files changed, 274 insertions, 37 deletions
diff --git a/base/inet.hh b/base/inet.hh index 8a49790a7..7ea4de6bb 100644 --- a/base/inet.hh +++ b/base/inet.hh @@ -29,10 +29,16 @@ #ifndef __BASE_INET_HH__ #define __BASE_INET_HH__ +#include <iosfwd> #include <string> +#include <utility> +#include <vector> -#include "dnet/os.h" +#include "base/range.hh" +#include "dev/etherpkt.hh" +#include "sim/host.hh" +#include "dnet/os.h" #include "dnet/eth.h" #include "dnet/ip.h" #include "dnet/ip6.h" @@ -41,45 +47,90 @@ #include "dnet/icmp.h" #include "dnet/tcp.h" #include "dnet/udp.h" - #include "dnet/intf.h" #include "dnet/route.h" #include "dnet/fw.h" - #include "dnet/blob.h" #include "dnet/rand.h" -#include "sim/host.hh" +namespace Net { -std::string eaddr_string(const uint8_t a[6]); +/* + * Ethernet Stuff + */ +struct EthAddr : protected eth_addr +{ + protected: + void parse(const std::string &addr); -struct EthHdr; -struct IpHdr; -struct TcpHdr; -struct UdpHdr; + public: + EthAddr(); + EthAddr(const uint8_t ea[ETH_ADDR_LEN]); + EthAddr(const eth_addr &ea); + EthAddr(const std::string &addr); + const EthAddr &operator=(const eth_addr &ea); + const EthAddr &operator=(const std::string &addr); -struct EthHdr : protected eth_hdr -{ - uint16_t type() const { return ntohs(eth_type); } + int size() const { return sizeof(eth_addr); } - const IpHdr *ip() const - { return type() == ETH_TYPE_IP ? (const IpHdr *)payload() : 0; } + const uint8_t *bytes() const { return &data[0]; } + uint8_t *bytes() { return &data[0]; } - IpHdr *ip() - { return type() == ETH_TYPE_IP ? (IpHdr *)payload() : 0; } + const uint8_t *addr() const { return &data[0]; } + bool unicast() const { return data[0] == 0x00; } + bool multicast() const { return data[0] == 0x01; } + bool broadcast() const { return data[0] == 0xff; } + std::string string() const; +}; + +std::ostream &operator<<(std::ostream &stream, const EthAddr &ea); +bool operator==(const EthAddr &left, const EthAddr &right); + +struct EthHdr : public eth_hdr +{ + uint16_t type() const { return ntohs(eth_type); } + const EthAddr &src() const { return *(EthAddr *)ð_src; } + const EthAddr &dst() const { return *(EthAddr *)ð_dst; } - bool unicast() { return eth_dst.data[0] == 0x00; } - bool multicast() { return eth_dst.data[0] == 0x01; } - bool broadcast() { return eth_dst.data[0] == 0xff; } + int size() const { return sizeof(eth_hdr); } - int size() const { return sizeof(EthHdr); } const uint8_t *bytes() const { return (const uint8_t *)this; } const uint8_t *payload() const { return bytes() + size(); } uint8_t *bytes() { return (uint8_t *)this; } uint8_t *payload() { return bytes() + size(); } }; -struct IpHdr : protected ip_hdr +class EthPtr +{ + protected: + friend class IpPtr; + PacketPtr p; + + public: + EthPtr() {} + EthPtr(const PacketPtr &ptr) : p(ptr) { } + + EthHdr *operator->() { return (EthHdr *)p->data; } + EthHdr &operator*() { return *(EthHdr *)p->data; } + operator EthHdr *() { return (EthHdr *)p->data; } + + const EthHdr *operator->() const { return (const EthHdr *)p->data; } + const EthHdr &operator*() const { return *(const EthHdr *)p->data; } + operator const EthHdr *() const { return (const EthHdr *)p->data; } + + const EthPtr &operator=(const PacketPtr &ptr) { p = ptr; return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } +}; + +/* + * IP Stuff + */ +struct IpOpt; +struct IpHdr : public ip_hdr { uint8_t version() const { return ip_v; } uint8_t hlen() const { return ip_hl * 4; } @@ -96,19 +147,7 @@ struct IpHdr : protected ip_hdr void sum(uint16_t sum) { ip_sum = sum; } - uint16_t ip_cksum() const; - uint16_t tu_cksum() const; - - const TcpHdr *tcp() const - { return proto() == IP_PROTO_TCP ? (const TcpHdr *)payload() : 0; } - const UdpHdr *udp() const - { return proto() == IP_PROTO_UDP ? (const UdpHdr *)payload() : 0; } - - TcpHdr *tcp() - { return proto() == IP_PROTO_TCP ? (TcpHdr *)payload() : 0; } - UdpHdr *udp() - { return proto() == IP_PROTO_UDP ? (UdpHdr *)payload() : 0; } - + bool options(std::vector<const IpOpt *> &vec) const; int size() const { return hlen(); } const uint8_t *bytes() const { return (const uint8_t *)this; } @@ -117,7 +156,84 @@ struct IpHdr : protected ip_hdr uint8_t *payload() { return bytes() + size(); } }; -struct TcpHdr : protected tcp_hdr +class IpPtr +{ + protected: + friend class TcpPtr; + friend class UdpPtr; + PacketPtr p; + + const IpHdr *h() const + { return (const IpHdr *)(p->data + sizeof(eth_hdr)); } + IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); } + + void set(const PacketPtr &ptr) + { + EthHdr *eth = (EthHdr *)ptr->data; + if (eth->type() == ETH_TYPE_IP) + p = ptr; + else + p = 0; + } + + public: + IpPtr() {} + IpPtr(const PacketPtr &ptr) { set(ptr); } + IpPtr(const EthPtr &ptr) { set(ptr.p); } + IpPtr(const IpPtr &ptr) : p(ptr.p) { } + + IpHdr *operator->() { return h(); } + IpHdr &operator*() { return *h(); } + operator IpHdr *() { return h(); } + + const IpHdr *operator->() const { return h(); } + const IpHdr &operator*() const { return *h(); } + operator const IpHdr *() const { return h(); } + + const IpPtr &operator=(const PacketPtr &ptr) { set(ptr); return *this; } + const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; } + const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } + operator bool() { return p; } +}; + +uint16_t cksum(const IpPtr &ptr); + +struct IpOpt : public ip_opt +{ + uint8_t type() const { return opt_type; } + uint8_t typeNumber() const { return IP_OPT_NUMBER(opt_type); } + uint8_t typeClass() const { return IP_OPT_CLASS(opt_type); } + uint8_t typeCopied() const { return IP_OPT_COPIED(opt_type); } + uint8_t len() const { return IP_OPT_TYPEONLY(type()) ? 1 : opt_len; } + + bool isNumber(int num) const { return typeNumber() == IP_OPT_NUMBER(num); } + bool isClass(int cls) const { return typeClass() == IP_OPT_CLASS(cls); } + bool isCopied(int cpy) const { return typeCopied() == IP_OPT_COPIED(cpy); } + + const uint8_t *data() const { return opt_data.data8; } + void sec(ip_opt_data_sec &sec) const; + void lsrr(ip_opt_data_rr &rr) const; + void ssrr(ip_opt_data_rr &rr) const; + void ts(ip_opt_data_ts &ts) const; + uint16_t satid() const { return ntohs(opt_data.satid); } + uint16_t mtup() const { return ntohs(opt_data.mtu); } + uint16_t mtur() const { return ntohs(opt_data.mtu); } + void tr(ip_opt_data_tr &tr) const; + const uint32_t *addext() const { return &opt_data.addext[0]; } + uint16_t rtralt() const { return ntohs(opt_data.rtralt); } + void sdb(std::vector<uint32_t> &vec) const; +}; + +/* + * TCP Stuff + */ +struct TcpOpt; +struct TcpHdr : public tcp_hdr { uint16_t sport() const { return ntohs(th_sport); } uint16_t dport() const { return ntohs(th_dport); } @@ -131,6 +247,8 @@ struct TcpHdr : protected tcp_hdr void sum(uint16_t sum) { th_sum = sum; } + bool options(std::vector<const TcpOpt *> &vec) const; + int size() const { return off(); } const uint8_t *bytes() const { return (const uint8_t *)this; } const uint8_t *payload() const { return bytes() + size(); } @@ -138,7 +256,81 @@ struct TcpHdr : protected tcp_hdr uint8_t *payload() { return bytes() + size(); } }; -struct UdpHdr : protected udp_hdr +class TcpPtr +{ + protected: + PacketPtr p; + int off; + + const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); } + TcpHdr *h() { return (TcpHdr *)(p->data + off); } + + void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } + void set(const IpPtr &ptr) + { + if (ptr->proto() == IP_PROTO_TCP) + set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); + else + set(0, 0); + } + + public: + TcpPtr() {} + TcpPtr(const IpPtr &ptr) { set(ptr); } + TcpPtr(const TcpPtr &ptr) : p(ptr.p), off(ptr.off) {} + + TcpHdr *operator->() { return h(); } + TcpHdr &operator*() { return *h(); } + operator TcpHdr *() { return h(); } + + const TcpHdr *operator->() const { return h(); } + const TcpHdr &operator*() const { return *h(); } + operator const TcpHdr *() const { return h(); } + + const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; } + const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } + operator bool() { return p; } +}; + +uint16_t cksum(const TcpPtr &ptr); + +typedef Range<uint16_t> SackRange; + +struct TcpOpt : public tcp_opt +{ + uint8_t type() const { return opt_type; } + uint8_t len() const { return TCP_OPT_TYPEONLY(type()) ? 1 : opt_len; } + + bool isopt(int opt) const { return type() == opt; } + + const uint8_t *data() const { return opt_data.data8; } + + uint16_t mss() const { return ntohs(opt_data.mss); } + uint8_t wscale() const { return opt_data.wscale; } + bool sack(std::vector<SackRange> &vec) const; + uint32_t echo() const { return ntohl(opt_data.echo); } + uint32_t tsval() const { return ntohl(opt_data.timestamp[0]); } + uint32_t tsecr() const { return ntohl(opt_data.timestamp[1]); } + uint32_t cc() const { return ntohl(opt_data.cc); } + uint8_t cksum() const{ return opt_data.cksum; } + const uint8_t *md5() const { return opt_data.md5; } + + int size() const { return len(); } + const uint8_t *bytes() const { return (const uint8_t *)this; } + const uint8_t *payload() const { return bytes() + size(); } + uint8_t *bytes() { return (uint8_t *)this; } + uint8_t *payload() { return bytes() + size(); } +}; + +/* + * UDP Stuff + */ +struct UdpHdr : public udp_hdr { uint16_t sport() const { return ntohs(uh_sport); } uint16_t dport() const { return ntohs(uh_dport); } @@ -147,11 +339,56 @@ struct UdpHdr : protected udp_hdr void sum(uint16_t sum) { uh_sum = htons(sum); } - int size() const { return sizeof(UdpHdr); } + int size() const { return sizeof(udp_hdr); } const uint8_t *bytes() const { return (const uint8_t *)this; } const uint8_t *payload() const { return bytes() + size(); } uint8_t *bytes() { return (uint8_t *)this; } uint8_t *payload() { return bytes() + size(); } }; +class UdpPtr +{ + protected: + PacketPtr p; + int off; + + const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); } + UdpHdr *h() { return (UdpHdr *)(p->data + off); } + + void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } + void set(const IpPtr &ptr) + { + if (ptr->proto() == IP_PROTO_UDP) + set(ptr.p, sizeof(eth_hdr) + ptr->hlen()); + else + set(0, 0); + } + + public: + UdpPtr() {} + UdpPtr(const IpPtr &ptr) { set(ptr); } + UdpPtr(const UdpPtr &ptr) : p(ptr.p), off(ptr.off) {} + + UdpHdr *operator->() { return h(); } + UdpHdr &operator*() { return *h(); } + operator UdpHdr *() { return h(); } + + const UdpHdr *operator->() const { return h(); } + const UdpHdr &operator*() const { return *h(); } + operator const UdpHdr *() const { return h(); } + + const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; } + const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; } + + const PacketPtr packet() const { return p; } + PacketPtr packet() { return p; } + bool operator!() const { return !p; } + operator bool() const { return p; } + operator bool() { return p; } +}; + +uint16_t cksum(const UdpPtr &ptr); + +/* namespace Net */ } + #endif // __BASE_INET_HH__ |