a bit more cleaning of the network header wrappers.
authorNathan Binkert <binkertn@umich.edu>
Tue, 21 Sep 2004 05:41:55 +0000 (01:41 -0400)
committerNathan Binkert <binkertn@umich.edu>
Tue, 21 Sep 2004 05:41:55 +0000 (01:41 -0400)
base/inet.hh:
    add functions to the various headers to grab the most common
    encapsulated protocols.  This could easily get out of hand, but
    we're just worrying about tcp, udp, and ip for now.

    add common functions size(), bytes(), and payload() to all wrappers.
    size() gets the header size
    bytes() returns a uint8_t * to the beginning of the header
    payload() returns a uint8_t * to the beginning of the payload.
dev/etherpkt.cc:
dev/etherpkt.hh:
    don't cache pointers to headers.  It's probably not worth the
    hassle.

--HG--
extra : convert_revision : ba9df85ac019b8a48233042dde79fb9da9546410

base/inet.hh
dev/etherpkt.cc
dev/etherpkt.hh

index 86a04aae47d5d9eff9876ae3a04fd3eb05ef9785..b20c90bebf9b6e7e6689c0ea30d7701d170491f7 100644 (file)
 
 std::string eaddr_string(const uint8_t a[6]);
 
+struct EthHdr;
+struct IpHdr;
+struct TcpHdr;
+struct UdpHdr;
+
 struct EthHdr : protected eth_hdr
 {
     uint16_t type() const { return ntohs(eth_type); }
-    const uint8_t *payload() const { return (const uint8_t *)this + sizeof(*this); }
-    uint8_t *payload() { return (uint8_t *)this + sizeof(*this); }
+
+    const IpHdr *ip() const
+    { return type() == ETH_TYPE_IP ? (const IpHdr *)payload() : 0; }
+
+    IpHdr *ip()
+    { return type() == ETH_TYPE_IP ? (IpHdr *)payload() : 0; }
 
     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(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
@@ -83,8 +98,23 @@ struct IpHdr : protected ip_hdr
 
     uint16_t ip_cksum() const;
     uint16_t tu_cksum() const;
-    const uint8_t  *payload() const { return (const uint8_t *)this + hlen(); }
-    uint8_t  *payload() { return (uint8_t *)this + hlen(); }
+
+    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; }
+
+
+    int size() const { return hlen(); }
+    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 TcpHdr : protected tcp_hdr
@@ -101,8 +131,11 @@ struct TcpHdr : protected tcp_hdr
 
     void sum(uint16_t sum) { th_sum = htons(sum); }
 
-    const uint8_t *payload() const { return (const uint8_t *)this + off(); }
-    uint8_t *payload() { return (uint8_t *)this + off(); }
+    int size() const { return off(); }
+    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 UdpHdr : protected udp_hdr
@@ -114,8 +147,11 @@ struct UdpHdr : protected udp_hdr
 
     void sum(uint16_t sum) { uh_sum = htons(sum); }
 
-    const uint8_t *payload() const { return (const uint8_t *)this + sizeof(*this); }
-    uint8_t *payload() { return (uint8_t *)this + sizeof(*this); }
+    int size() const { return sizeof(UdpHdr); }
+    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(); }
 };
 
 #endif // __BASE_INET_HH__
index 292fe7faf26eb2d59a4449903594baeb446e631d..273b8ee646ddc91de159b48148adda49bb98df80 100644 (file)
 
 using namespace std;
 
-void
-PacketData::doext()
-{
-    _eth = 0;
-    _ip = 0;
-    _tcp = 0;
-    _udp = 0;
-
-    if (!data)
-        return;
-
-    _eth = data;
-    if (eth()->type() == ETH_TYPE_IP) {
-        _ip = eth()->payload();
-
-        if (ip()->proto() == IP_PROTO_TCP)
-            _tcp = ip()->payload();
-
-        if (ip()->proto() == IP_PROTO_UDP)
-            _udp = ip()->payload();
-    }
-}
-
 void
 PacketData::serialize(ostream &os)
 {
index 53612b830e745c811bf7e5ff63cdfd6c3f0f3b09..9c5f004910d00cb441fbfd7a4a48619a5e6b9a9b 100644 (file)
@@ -51,30 +51,22 @@ class PacketData : public RefCounted
     uint8_t *data;
     int length;
 
-  protected:
-    uint8_t *_eth;
-    uint8_t *_ip;
-    uint8_t *_tcp;
-    uint8_t *_udp;
-
-    void doext();
-    void ext()
-    {
-        if (_eth != data)
-            doext();
-    }
-
   public:
-    PacketData() : data(NULL), length(0) { doext(); }
+    PacketData() : data(NULL), length(0) { }
     PacketData(std::auto_ptr<uint8_t> d, int l)
-        : data(d.release()), length(l) { doext(); }
+        : data(d.release()), length(l) { }
     ~PacketData() { if (data) delete [] data; }
 
   public:
-    EthHdr *eth() { ext(); return (EthHdr *)_eth; }
-    IpHdr *ip() { ext(); return (IpHdr *)_ip; }
-    TcpHdr *tcp() { ext(); return (TcpHdr *)_tcp; }
-    UdpHdr *udp() { ext(); return (UdpHdr *)_udp; }
+    const EthHdr *eth() const { return (const EthHdr *)data; }
+    const IpHdr *ip() const {const EthHdr *h = eth(); return h ? h->ip() : 0;}
+    const TcpHdr *tcp() const {const IpHdr *h = ip(); return h ? h->tcp() : 0;}
+    const UdpHdr *udp() const {const IpHdr *h = ip(); return h ? h->udp() : 0;}
+
+    EthHdr *eth() { return (EthHdr *)data; }
+    IpHdr *ip()   { EthHdr *h = eth(); return h ? h->ip() : 0; }
+    TcpHdr *tcp() { IpHdr *h = ip(); return h ? h->tcp() : 0; }
+    UdpHdr *udp() { IpHdr *h = ip(); return h ? h->udp() : 0; }
 
   public:
     void serialize(std::ostream &os);