From ad5f36f2acacebe15ade4d060bdcdfc628decc89 Mon Sep 17 00:00:00 2001 From: Emmanuelle Laprise Date: Fri, 27 Jul 2007 21:16:40 +0200 Subject: [PATCH] ethernet Header and Trailer classes --- src/internet-node/arp-header.cc | 2 +- src/internet-node/wscript | 1 - .../header-utils.cc => node/address-utils.cc} | 2 +- .../header-utils.h => node/address-utils.h} | 6 +- src/node/ethernet-header.cc | 173 ++++++++++++++++++ src/node/ethernet-header.h | 128 +++++++++++++ src/node/ethernet-trailer.cc | 124 +++++++++++++ src/node/ethernet-trailer.h | 104 +++++++++++ src/node/wscript | 6 + 9 files changed, 540 insertions(+), 6 deletions(-) rename src/{internet-node/header-utils.cc => node/address-utils.cc} (98%) rename src/{internet-node/header-utils.h => node/address-utils.h} (93%) create mode 100644 src/node/ethernet-header.cc create mode 100644 src/node/ethernet-header.h create mode 100644 src/node/ethernet-trailer.cc create mode 100644 src/node/ethernet-trailer.h diff --git a/src/internet-node/arp-header.cc b/src/internet-node/arp-header.cc index e340404f4..7191b0299 100644 --- a/src/internet-node/arp-header.cc +++ b/src/internet-node/arp-header.cc @@ -20,8 +20,8 @@ */ #include "ns3/assert.h" +#include "ns3/address-utils.h" #include "arp-header.h" -#include "header-utils.h" namespace ns3 { diff --git a/src/internet-node/wscript b/src/internet-node/wscript index cf412d6c8..47b81358b 100644 --- a/src/internet-node/wscript +++ b/src/internet-node/wscript @@ -24,7 +24,6 @@ def build(bld): 'arp-ipv4-interface.cc', 'arp-l3-protocol.cc', 'ipv4-loopback-interface.cc', - 'header-utils.cc', 'udp-socket.cc', 'ipv4-end-point-demux.cc', 'arp-private.cc', diff --git a/src/internet-node/header-utils.cc b/src/node/address-utils.cc similarity index 98% rename from src/internet-node/header-utils.cc rename to src/node/address-utils.cc index b3da88cfa..702db4dd5 100644 --- a/src/internet-node/header-utils.cc +++ b/src/node/address-utils.cc @@ -18,7 +18,7 @@ * * Author: Mathieu Lacage */ -#include "header-utils.h" +#include "address-utils.h" namespace ns3 { diff --git a/src/internet-node/header-utils.h b/src/node/address-utils.h similarity index 93% rename from src/internet-node/header-utils.h rename to src/node/address-utils.h index e65e7533c..9dbe8fc55 100644 --- a/src/internet-node/header-utils.h +++ b/src/node/address-utils.h @@ -18,8 +18,8 @@ * * Author: Mathieu Lacage */ -#ifndef HEADER_UTILS_H -#define HEADER_UTILS_H +#ifndef ADDRESS_UTILS_H +#define ADDRESS_UTILS_H #include "ns3/buffer.h" #include "ns3/ipv4-address.h" @@ -35,4 +35,4 @@ void ReadFrom (Buffer::Iterator &i, MacAddress &ad, uint32_t len); }; -#endif /* HEADER_UTILS_H */ +#endif /* ADDRESS_UTILS_H */ diff --git a/src/node/ethernet-header.cc b/src/node/ethernet-header.cc new file mode 100644 index 000000000..621bf0ecb --- /dev/null +++ b/src/node/ethernet-header.cc @@ -0,0 +1,173 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005 INRIA + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Emmanuelle Laprise + */ + +#include "ns3/assert.h" +#include "ns3/debug.h" +#include "ns3/header.h" +#include "ethernet-header.h" +#include "address-utils.h" + +NS_DEBUG_COMPONENT_DEFINE ("EthernetHeader"); + +namespace ns3 { + +bool EthernetHeader::m_enPreambleSfd = false; + +EthernetHeader::EthernetHeader () +{ + Init(); +} + +EthernetHeader::~EthernetHeader () +{} + +void +EthernetHeader::Init() +{ + m_preambleSfd = 0; + m_lengthType = 0x0; +} + +void +EthernetHeader::EnablePreambleSfd (bool enable) +{ + m_enPreambleSfd = enable; +} + +void +EthernetHeader::SetLengthType (uint16_t lengthType) +{ + m_lengthType = lengthType; +} +uint16_t +EthernetHeader::GetLengthType (void) const +{ + return m_lengthType; +} + +void +EthernetHeader::SetPreambleSfd (uint64_t preambleSfd) +{ + m_preambleSfd = preambleSfd; +} +uint64_t +EthernetHeader::GetPreambleSfd (void) const +{ + return m_preambleSfd; +} + +void +EthernetHeader::SetSource (MacAddress source) +{ + m_source = source; +} +MacAddress +EthernetHeader::GetSource (void) const +{ + return m_source; +} + +void +EthernetHeader::SetDestination (MacAddress dst) +{ + m_destination = dst; +} +MacAddress +EthernetHeader::GetDestination (void) const +{ + return m_destination; +} + +ethernet_header_t +EthernetHeader::GetPacketType (void) const +{ + return LENGTH; +} + +uint32_t +EthernetHeader::GetHeaderSize (void) const +{ + return GetSerializedSize(); +} + +std::string +EthernetHeader::DoGetName (void) const +{ + return "ETHERNET"; +} + +void +EthernetHeader::PrintTo (std::ostream &os) const +{ + // ethernet, right ? + os << "(ethernet)"; + if (m_enPreambleSfd) + { + os << " preamble/sfd=" << m_preambleSfd << ","; + } + os << " length/type=" << m_lengthType + << ", source=" << m_source + << ", destination=" << m_destination; +} +uint32_t +EthernetHeader::GetSerializedSize (void) const +{ + if (m_enPreambleSfd) + { + return PREAMBLE_SIZE + LENGTH_SIZE + 2*MAC_ADDR_SIZE; + } else { + return LENGTH_SIZE + 2*MAC_ADDR_SIZE; + } +} + +void +EthernetHeader::SerializeTo (Buffer::Iterator start) const +{ + Buffer::Iterator i = start; + + if (m_enPreambleSfd) + { + i.WriteU64(m_preambleSfd); + } + NS_ASSERT (m_destination.GetLength () == MAC_ADDR_SIZE); + NS_ASSERT (m_source.GetLength () == MAC_ADDR_SIZE); + WriteTo (i, m_destination); + WriteTo (i, m_source); + i.WriteU16 (m_lengthType); +} +uint32_t +EthernetHeader::DeserializeFrom (Buffer::Iterator start) +{ + Buffer::Iterator i = start; + + if (m_enPreambleSfd) + { + m_enPreambleSfd = i.ReadU64 (); + } + + ReadFrom (i, m_destination, MAC_ADDR_SIZE); + ReadFrom (i, m_source, MAC_ADDR_SIZE); + m_lengthType = i.ReadU16 (); + + return GetSerializedSize (); +} + +}; // namespace ns3 diff --git a/src/node/ethernet-header.h b/src/node/ethernet-header.h new file mode 100644 index 000000000..e9fde048a --- /dev/null +++ b/src/node/ethernet-header.h @@ -0,0 +1,128 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 Emmanuelle Laprise + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Emmanuelle Laprise + */ + +#ifndef ETHERNET_HEADER_H +#define ETHERNET_HEADER_H + +#include "ns3/header.h" +#include "ns3/mac-address.h" + +namespace ns3 { + + /** + * Types of ethernet packets. Indicates the type of the current + * header. + */ + enum ethernet_header_t { + LENGTH, /**< Basic ethernet packet, no tags, type/length field + indicates packet length or IP/ARP packet */ + VLAN, /**< Single tagged packet. Header includes VLAN tag */ + QINQ /**< Double tagged packet. Header includes two VLAN tags */ + }; +/** + * \brief Packet header for Ethernet + * + * This class can be used to add a header to an ethernet packet that + * will specify the source and destination addresses and the length of + * the packet. Eventually the class will be improved to also support + * VLAN tags in packet headers. + */ +class EthernetHeader : public Header { +public: + static const int PREAMBLE_SIZE = 8; /// size of the preamble_sfd header field + static const int LENGTH_SIZE = 2; /// size of the length_type header field + static const int MAC_ADDR_SIZE = 6; /// size of src/dest addr header fields + + /** + * \brief Construct a null ethernet header + */ + EthernetHeader (); + virtual ~EthernetHeader (); + /** + * \brief Enable or disabled the serialisation of the preamble and + * Sfd header fields + */ + static void EnablePreambleSfd (bool enable); + /** + * \param size The size of the payload in bytes + */ + void SetLengthType (uint16_t size); + /** + * \param source The source address of this packet + */ + void SetSource (MacAddress source); + /** + * \param destination The destination address of this packet. + */ + void SetDestination (MacAddress destination); + /** + * \param preambleSfd The value that the preambleSfd field should take + */ + void SetPreambleSfd (uint64_t preambleSfd); + /** + * \return The size of the payload in bytes + */ + uint16_t GetLengthType (void) const; + /** + * \return The type of packet (only basic Ethernet is currently supported) + */ + ethernet_header_t GetPacketType (void) const; + /** + * \return The source address of this packet + */ + MacAddress GetSource (void) const; + /** + * \return The destination address of this packet + */ + MacAddress GetDestination (void) const; + /** + * \return The value of the PreambleSfd field + */ + uint64_t GetPreambleSfd () const; + /** + * \return The size of the header + */ + uint32_t GetHeaderSize() const; + +private: + virtual std::string DoGetName (void) const; + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator start) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator start); + + void Init (void); + + /** + * If false, the preamble/sfd are not serialised/deserialised. + */ + static bool m_enPreambleSfd; + + uint64_t m_preambleSfd; /// Value of the Preamble/SFD fields + uint16_t m_lengthType : 16; /// Length or type of the packet + MacAddress m_source; /// Source address + MacAddress m_destination; /// Destination address +}; + +}; // namespace ns3 + + +#endif /* ETHERNET_HEADER_H */ diff --git a/src/node/ethernet-trailer.cc b/src/node/ethernet-trailer.cc new file mode 100644 index 000000000..6aa622b66 --- /dev/null +++ b/src/node/ethernet-trailer.cc @@ -0,0 +1,124 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2005 INRIA + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Emmanuelle Laprise + */ + +#include "ns3/assert.h" +#include "ns3/debug.h" +#include "ns3/trailer.h" +#include "ethernet-trailer.h" + +NS_DEBUG_COMPONENT_DEFINE ("EthernetTrailer"); + +namespace ns3 { + +bool EthernetTrailer::m_calcFcs = false; + +EthernetTrailer::EthernetTrailer () +{ + Init(); +} + +EthernetTrailer::~EthernetTrailer () +{} + +void EthernetTrailer::Init() +{ + m_fcs = 0; +} + +void +EthernetTrailer::EnableFcs (bool enable) +{ + m_calcFcs = enable; +} + +bool +EthernetTrailer::CheckFcs (const Packet& p) const +{ + if (!m_calcFcs) + { + return true; + } else { + NS_DEBUG("FCS calculation is not yet enabled" << std::endl); + return false; + } +} + +void +EthernetTrailer::CalcFcs (const Packet& p) +{ + NS_DEBUG("FCS calculation is not yet enabled" << std::endl); +} + +void +EthernetTrailer::SetFcs (uint32_t fcs) +{ + m_fcs = fcs; +} + +uint32_t +EthernetTrailer::GetFcs (void) +{ + return m_fcs; +} + +uint32_t +EthernetTrailer::GetTrailerSize (void) const +{ + return GetSerializedSize(); +} +std::string +EthernetTrailer::DoGetName (void) const +{ + return "ETHERNET"; +} + +void +EthernetTrailer::PrintTo (std::ostream &os) const +{ + os << " fcs=" << m_fcs; +} +uint32_t +EthernetTrailer::GetSerializedSize (void) const +{ + return 4; +} + +void +EthernetTrailer::SerializeTo (Buffer::Iterator end) const +{ + Buffer::Iterator i = end; + i.Prev(GetSerializedSize()); + + i.WriteU32 (m_fcs); +} +uint32_t +EthernetTrailer::DeserializeFrom (Buffer::Iterator end) +{ + Buffer::Iterator i = end; + uint32_t size = GetSerializedSize(); + i.Prev(size); + + m_fcs = i.ReadU32 (); + + return size; +} + +}; // namespace ns3 diff --git a/src/node/ethernet-trailer.h b/src/node/ethernet-trailer.h new file mode 100644 index 000000000..7ec3e162d --- /dev/null +++ b/src/node/ethernet-trailer.h @@ -0,0 +1,104 @@ +/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 Emmanuelle Laprise + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Emmanuelle Laprise + */ + +#ifndef ETHERNET_TRAILER_H +#define ETHERNET_TRAILER_H + +#include "ns3/trailer.h" +#include "ns3/packet.h" + +namespace ns3 { +/** + * \brief Packet trailer for Ethernet + * + * This class can be used to add and verify the FCS at the end of an + * ethernet packet. The actual FCS functionality is not yet coded and + * so this acts more as a placeholder. + */ +class EthernetTrailer : public Trailer { +public: + /** + * \brief Construct a null ethernet trailer + */ + EthernetTrailer (); + virtual ~EthernetTrailer (); + /** + * \brief Enable or disabled FCS checking and calculations + * \param enable If true, enables FCS calculations. + */ + static void EnableFcs (bool enable); + /** + * \brief Updates the Fcs Field to the correct FCS + * \param p Reference to a packet on which the FCS should be + * calculated. The packet should not currently contain an FCS + * trailer. + */ + void CalcFcs (const Packet& p); + /** + * \brief Sets the FCS to a new value + * \param fcs New FCS value + */ + void SetFcs (uint32_t fcs); + /** + * \return the FCS contained in this trailer + */ + uint32_t GetFcs (); + + /** + * \param p Reference to the packet on which the FCS should be + * calculated. The packet should not contain an FCS trailer. + * \return Returns true if the packet fcs is correct, false otherwise. + * + * If FCS checking is disabled, this method will always + * return true. + */ + bool CheckFcs (const Packet& p) const; + + /** + *\return Returns the size of the trailer + */ + uint32_t GetTrailerSize() const; + +private: + virtual std::string DoGetName (void) const; + virtual void PrintTo (std::ostream &os) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void SerializeTo (Buffer::Iterator end) const; + virtual uint32_t DeserializeFrom (Buffer::Iterator end); + + /** + * Initializes the trailer parameters during construction. + */ + void Init (void); + + /** + * Enabled FCS calculations. If false, fcs is set to 0 and checkFCS + * returns true. + */ + static bool m_calcFcs; + uint32_t m_fcs; /// Value of the fcs contained in the trailer + +}; + +}; // namespace ns3 + + +#endif /* ETHERNET_TRAILER_H */ diff --git a/src/node/wscript b/src/node/wscript index 0a5c64aa9..62974351a 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -10,7 +10,10 @@ def build(bld): 'ipv4-address.cc', 'net-device.cc', 'mac-address.cc', + 'address-utils.cc', 'llc-snap-header.cc', + 'ethernet-header.cc', + 'ethernet-trailer.cc', 'ipv4-route.cc', 'queue.cc', 'drop-tail-queue.cc', @@ -30,10 +33,13 @@ def build(bld): 'ipv4-address.h', 'net-device.h', 'mac-address.h', + 'address-utils.h', 'ipv4-route.h', 'queue.h', 'drop-tail-queue.h', 'llc-snap-header.h', + 'ethernet-header.h', + 'ethernet-trailer.h', 'channel.h', 'node-list.h', 'socket.h',