From a58b834c8e333385f9be37eb4d343d70f8177613 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 20 Sep 2004 10:43:53 -0400 Subject: Clean up network header stuff and make it more generic. Use libdnet when we can instead of our own home grown stuff. SConscript: separate the crc code into its own file base/inet.cc: move the crc stuff to crc.cc add generic code for calculating ip/tcp/udp checksums base/inet.hh: - move crc stuff to crc.hh - #include all of the libdnet stuff. (this makes base/inet.hh the only file you need to include if you want to use this kind of stuff.) - Wrap some of the libdnet structs to get easier access to structure members. These wrappers will automatically deal with masking/shifting/ byte-swapping. base/refcnt.hh: If one derives from RefCountingPtr, they should have access to the internal data pointer. build/SConstruct: make #include of dnet stuff work dev/etherlink.cc: dev/ethertap.cc: dev/ethertap.hh: EtherPacket -> PacketData dev/etherpkt.cc: EtherPacket -> PacketData add a function for populating extra info about a packet. Basically just gives pointers to ethernet/ip/tcp/udp headers if they exist. dev/etherpkt.hh: EtherPacket -> PacketData remove most of the packet header stuff from teh PacketData class and just add a few generic functions for grabbing various headers that may exist in the packet. The old functionality is contained in the headers. dev/ns_gige.cc: - IP -> Ip, UDP -> Udp, TCP ->Tcp when used in variable names - get rid of our own byte swapping functions. - whack checksum code and use libdnet version. - Get pointers to the various packet headers and grab info from those headers. (The byte swapping in the headers now.) - Add stats for Udp Checksums dev/ns_gige.hh: use libdnet for checksum code. IP -> Ip, TCP -> Tcp in variable names add stats for UDP checksums --HG-- extra : convert_revision : 96c4160e1967b7c0090acd456df4a76e1f3aab53 --- base/crc.cc | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ base/crc.hh | 37 +++++++++++++++++ base/inet.cc | 124 ++++++--------------------------------------------------- base/inet.hh | 94 ++++++++++++++++++++++++++++++++++++++++--- base/refcnt.hh | 2 +- 5 files changed, 256 insertions(+), 118 deletions(-) create mode 100644 base/crc.cc create mode 100644 base/crc.hh (limited to 'base') diff --git a/base/crc.cc b/base/crc.cc new file mode 100644 index 000000000..8bff4b868 --- /dev/null +++ b/base/crc.cc @@ -0,0 +1,117 @@ +/* $Id$ */ + +/* + * Copyright (c) 1988, 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "sim/host.hh" +#include "base/crc.hh" + +#define ETHER_CRC_POLY_LE 0xedb88320 +#define ETHER_CRC_POLY_BE 0x04c11db6 + +#if 0 +/* + * This is for reference. We have a table-driven version + * of the little-endian crc32 generator, which is faster + * than the double-loop. + */ +uint32_t +crc32le(const uint8_t *buf, size_t len) +{ + uint32_t c, crc, carry; + size_t i, j; + + crc = 0xffffffffU; /* initial value */ + + for (i = 0; i < len; i++) { + c = buf[i]; + for (j = 0; j < 8; j++) { + carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01); + crc >>= 1; + c >>= 1; + if (carry) + crc = (crc ^ ETHER_CRC_POLY_LE); + } + } + + return (crc); +} +#else +uint32_t +crc32le(const uint8_t *buf, size_t len) +{ + static const uint32_t crctab[] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + uint32_t crc; + int i; + + crc = 0xffffffffU; /* initial value */ + + for (i = 0; i < len; i++) { + crc ^= buf[i]; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + crc = (crc >> 4) ^ crctab[crc & 0xf]; + } + + return (crc); +} +#endif + +uint32_t +crc32be(const uint8_t *buf, size_t len) +{ + uint32_t c, crc, carry; + size_t i, j; + + crc = 0xffffffffU; /* initial value */ + + for (i = 0; i < len; i++) { + c = buf[i]; + for (j = 0; j < 8; j++) { + carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); + crc <<= 1; + c >>= 1; + if (carry) + crc = (crc ^ ETHER_CRC_POLY_BE) | carry; + } + } + + return (crc); +} diff --git a/base/crc.hh b/base/crc.hh new file mode 100644 index 000000000..bd6719b98 --- /dev/null +++ b/base/crc.hh @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2002-2003 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __BASE_CRC_HH__ +#define __BASE_CRC_HH__ + +#include "sim/host.hh" + +uint32_t crc32be(const uint8_t *buf, size_t len); +uint32_t crc32le(const uint8_t *buf, size_t len); + +#endif // __BASE_CRC_HH__ diff --git a/base/inet.cc b/base/inet.cc index e2bdd19ff..ac0758c1f 100644 --- a/base/inet.cc +++ b/base/inet.cc @@ -33,7 +33,7 @@ #include "sim/host.hh" #include "base/inet.hh" -using namespace::std; +using namespace std; string eaddr_string(const uint8_t a[6]) { @@ -43,119 +43,19 @@ eaddr_string(const uint8_t a[6]) return stream.str(); } -/* - * Copyright (c) 1988, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/*********************************************************************** - This section of code taken from NetBSD -***********************************************************************/ - -#define ETHER_CRC_POLY_LE 0xedb88320 -#define ETHER_CRC_POLY_BE 0x04c11db6 - -#if 0 -/* - * This is for reference. We have a table-driven version - * of the little-endian crc32 generator, which is faster - * than the double-loop. - */ -uint32_t -crc32le(const uint8_t *buf, size_t len) +uint16_t +IpHdr::ip_cksum() const { - uint32_t c, crc, carry; - size_t i, j; - - crc = 0xffffffffU; /* initial value */ - - for (i = 0; i < len; i++) { - c = buf[i]; - for (j = 0; j < 8; j++) { - carry = ((crc & 0x01) ? 1 : 0) ^ (c & 0x01); - crc >>= 1; - c >>= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_LE); - } - } - - return (crc); -} -#else -uint32_t -crc32le(const uint8_t *buf, size_t len) -{ - static const uint32_t crctab[] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - uint32_t crc; - int i; - - crc = 0xffffffffU; /* initial value */ - - for (i = 0; i < len; i++) { - crc ^= buf[i]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - } - - return (crc); + uint16_t sum = ip_cksum_add(this, hlen(), 0); + return ip_cksum_carry(sum); } -#endif -uint32_t -crc32be(const uint8_t *buf, size_t len) +uint16_t +IpHdr::tu_cksum() const { - uint32_t c, crc, carry; - size_t i, j; - - crc = 0xffffffffU; /* initial value */ - - for (i = 0; i < len; i++) { - c = buf[i]; - for (j = 0; j < 8; j++) { - carry = ((crc & 0x80000000U) ? 1 : 0) ^ (c & 0x01); - crc <<= 1; - c >>= 1; - if (carry) - crc = (crc ^ ETHER_CRC_POLY_BE) | carry; - } - } - - return (crc); + uint16_t sum = ip_cksum_add(payload(), len() - hlen(), 0); + sum = ip_cksum_add(&ip_src, 4, sum); + sum = ip_cksum_add(&ip_dst, 4, sum); + sum += htons(ip_p + ip_len); + return ip_cksum_carry(sum); } - -/*********************************************************************** - This is the end of the NetBSD code -***********************************************************************/ diff --git a/base/inet.hh b/base/inet.hh index 67ac5a504..86a04aae4 100644 --- a/base/inet.hh +++ b/base/inet.hh @@ -26,12 +26,96 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __INET_HH__ -#define __INET_HH__ +#ifndef __BASE_INET_HH__ +#define __BASE_INET_HH__ + +#include + +#include "dnet/os.h" + +#include "dnet/eth.h" +#include "dnet/ip.h" +#include "dnet/ip6.h" +#include "dnet/addr.h" +#include "dnet/arp.h" +#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" -uint32_t crc32be(const uint8_t *buf, size_t len); -uint32_t crc32le(const uint8_t *buf, size_t len); std::string eaddr_string(const uint8_t a[6]); -#endif // __INET_HH__ + +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); } + + bool unicast() { return eth_dst.data[0] == 0x00; } + bool multicast() { return eth_dst.data[0] == 0x01; } + bool broadcast() { return eth_dst.data[0] == 0xff; } +}; + +struct IpHdr : protected ip_hdr +{ + uint8_t version() const { return ip_v; } + uint8_t hlen() const { return ip_hl; } + uint8_t tos() const { return ip_tos; } + uint16_t len() const { return ntohs(ip_len); } + uint16_t id() const { return ntohs(ip_id); } + uint16_t frag_flags() const { return ntohs(ip_off) >> 13; } + uint16_t frag_off() const { return ntohs(ip_off) & 0x1fff; } + uint8_t ttl() const { return ip_ttl; } + uint8_t proto() const { return ip_p; } + uint16_t sum() const { return ntohs(ip_sum); } + uint32_t src() const { return ntohl(ip_src); } + uint32_t dst() const { return ntohl(ip_dst); } + + void sum(uint16_t sum) { ip_sum = htons(sum); } + + 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(); } +}; + +struct TcpHdr : protected tcp_hdr +{ + uint16_t sport() const { return ntohs(th_sport); } + uint16_t dport() const { return ntohs(th_dport); } + uint32_t seq() const { return ntohl(th_seq); } + uint32_t ack() const { return ntohl(th_ack); } + uint8_t off() const { return th_off; } + uint8_t flags() const { return th_flags & 0x3f; } + uint16_t win() const { return ntohs(th_win); } + uint16_t sum() const { return ntohs(th_sum); } + uint16_t urp() const { return ntohs(th_urp); } + + 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(); } +}; + +struct UdpHdr : protected udp_hdr +{ + uint16_t sport() const { return ntohs(uh_sport); } + uint16_t dport() const { return ntohs(uh_dport); } + uint16_t len() const { return ntohs(uh_ulen); } + uint16_t sum() const { return ntohs(uh_sum); } + + 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); } +}; + +#endif // __BASE_INET_HH__ diff --git a/base/refcnt.hh b/base/refcnt.hh index d308dd0cf..251dc905b 100644 --- a/base/refcnt.hh +++ b/base/refcnt.hh @@ -48,7 +48,7 @@ class RefCounted template class RefCountingPtr { - private: + protected: T *data; void copy(T *d) { -- cgit v1.2.3