From 54af49fe405fd98b48a8fdd7f667cce6ea8d696a Mon Sep 17 00:00:00 2001 From: Emmanuelle Laprise Date: Fri, 27 Jul 2007 20:17:23 +0200 Subject: [PATCH 1/7] src/devices/p2p -> src/devices/point-to-point --- src/devices/{p2p => point-to-point}/p2p-channel.cc | 0 src/devices/{p2p => point-to-point}/p2p-channel.h | 0 src/devices/{p2p => point-to-point}/p2p-net-device.cc | 0 src/devices/{p2p => point-to-point}/p2p-net-device.h | 0 src/devices/{p2p => point-to-point}/p2p-topology.cc | 0 src/devices/{p2p => point-to-point}/p2p-topology.h | 0 src/devices/{p2p => point-to-point}/wscript | 0 src/wscript | 2 +- 8 files changed, 1 insertion(+), 1 deletion(-) rename src/devices/{p2p => point-to-point}/p2p-channel.cc (100%) rename src/devices/{p2p => point-to-point}/p2p-channel.h (100%) rename src/devices/{p2p => point-to-point}/p2p-net-device.cc (100%) rename src/devices/{p2p => point-to-point}/p2p-net-device.h (100%) rename src/devices/{p2p => point-to-point}/p2p-topology.cc (100%) rename src/devices/{p2p => point-to-point}/p2p-topology.h (100%) rename src/devices/{p2p => point-to-point}/wscript (100%) diff --git a/src/devices/p2p/p2p-channel.cc b/src/devices/point-to-point/p2p-channel.cc similarity index 100% rename from src/devices/p2p/p2p-channel.cc rename to src/devices/point-to-point/p2p-channel.cc diff --git a/src/devices/p2p/p2p-channel.h b/src/devices/point-to-point/p2p-channel.h similarity index 100% rename from src/devices/p2p/p2p-channel.h rename to src/devices/point-to-point/p2p-channel.h diff --git a/src/devices/p2p/p2p-net-device.cc b/src/devices/point-to-point/p2p-net-device.cc similarity index 100% rename from src/devices/p2p/p2p-net-device.cc rename to src/devices/point-to-point/p2p-net-device.cc diff --git a/src/devices/p2p/p2p-net-device.h b/src/devices/point-to-point/p2p-net-device.h similarity index 100% rename from src/devices/p2p/p2p-net-device.h rename to src/devices/point-to-point/p2p-net-device.h diff --git a/src/devices/p2p/p2p-topology.cc b/src/devices/point-to-point/p2p-topology.cc similarity index 100% rename from src/devices/p2p/p2p-topology.cc rename to src/devices/point-to-point/p2p-topology.cc diff --git a/src/devices/p2p/p2p-topology.h b/src/devices/point-to-point/p2p-topology.h similarity index 100% rename from src/devices/p2p/p2p-topology.h rename to src/devices/point-to-point/p2p-topology.h diff --git a/src/devices/p2p/wscript b/src/devices/point-to-point/wscript similarity index 100% rename from src/devices/p2p/wscript rename to src/devices/point-to-point/wscript diff --git a/src/wscript b/src/wscript index 4b34a9156..1d20c24e4 100644 --- a/src/wscript +++ b/src/wscript @@ -15,7 +15,7 @@ all_modules = ( 'simulator', 'node', 'internet-node', - 'devices/p2p', + 'devices/point-to-point', 'applications', 'mobility', ) From 0e21d85be1091655f2555e577d85e5108fb2f275 Mon Sep 17 00:00:00 2001 From: Emmanuelle Laprise Date: Fri, 27 Jul 2007 20:26:36 +0200 Subject: [PATCH 2/7] src/devices/point-to-point/p2p-* -> src/devices/point-to-point/point-to-point-* --- examples/simple-p2p.cc | 6 +++--- .../{p2p-channel.cc => point-to-point-channel.cc} | 4 ++-- .../{p2p-channel.h => point-to-point-channel.h} | 0 ...2p-net-device.cc => point-to-point-net-device.cc} | 4 ++-- ...{p2p-net-device.h => point-to-point-net-device.h} | 0 .../{p2p-topology.cc => point-to-point-topology.cc} | 6 +++--- .../{p2p-topology.h => point-to-point-topology.h} | 0 src/devices/point-to-point/wscript | 12 ++++++------ 8 files changed, 16 insertions(+), 16 deletions(-) rename src/devices/point-to-point/{p2p-channel.cc => point-to-point-channel.cc} (98%) rename src/devices/point-to-point/{p2p-channel.h => point-to-point-channel.h} (100%) rename src/devices/point-to-point/{p2p-net-device.cc => point-to-point-net-device.cc} (98%) rename src/devices/point-to-point/{p2p-net-device.h => point-to-point-net-device.h} (100%) rename src/devices/point-to-point/{p2p-topology.cc => point-to-point-topology.cc} (97%) rename src/devices/point-to-point/{p2p-topology.h => point-to-point-topology.h} (100%) diff --git a/examples/simple-p2p.cc b/examples/simple-p2p.cc index 9ad235b5e..412edcaa1 100644 --- a/examples/simple-p2p.cc +++ b/examples/simple-p2p.cc @@ -54,14 +54,14 @@ #include "ns3/ascii-trace.h" #include "ns3/pcap-trace.h" #include "ns3/internet-node.h" -#include "ns3/p2p-channel.h" -#include "ns3/p2p-net-device.h" +#include "ns3/point-to-point-channel.h" +#include "ns3/point-to-point-net-device.h" #include "ns3/mac-address.h" #include "ns3/ipv4-address.h" #include "ns3/ipv4.h" #include "ns3/socket.h" #include "ns3/ipv4-route.h" -#include "ns3/p2p-topology.h" +#include "ns3/point-to-point-topology.h" #include "ns3/onoff-application.h" using namespace ns3; diff --git a/src/devices/point-to-point/p2p-channel.cc b/src/devices/point-to-point/point-to-point-channel.cc similarity index 98% rename from src/devices/point-to-point/p2p-channel.cc rename to src/devices/point-to-point/point-to-point-channel.cc index adceda3f4..ae78010cf 100644 --- a/src/devices/point-to-point/p2p-channel.cc +++ b/src/devices/point-to-point/point-to-point-channel.cc @@ -19,8 +19,8 @@ * Author: Craig Dowell */ -#include "p2p-channel.h" -#include "p2p-net-device.h" +#include "point-to-point-channel.h" +#include "point-to-point-net-device.h" #include "ns3/packet.h" #include "ns3/simulator.h" #include "ns3/debug.h" diff --git a/src/devices/point-to-point/p2p-channel.h b/src/devices/point-to-point/point-to-point-channel.h similarity index 100% rename from src/devices/point-to-point/p2p-channel.h rename to src/devices/point-to-point/point-to-point-channel.h diff --git a/src/devices/point-to-point/p2p-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc similarity index 98% rename from src/devices/point-to-point/p2p-net-device.cc rename to src/devices/point-to-point/point-to-point-net-device.cc index 13d352889..8f474edde 100644 --- a/src/devices/point-to-point/p2p-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -26,8 +26,8 @@ #include "ns3/queue.h" #include "ns3/simulator.h" #include "ns3/composite-trace-resolver.h" -#include "p2p-net-device.h" -#include "p2p-channel.h" +#include "point-to-point-net-device.h" +#include "point-to-point-channel.h" NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice"); diff --git a/src/devices/point-to-point/p2p-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h similarity index 100% rename from src/devices/point-to-point/p2p-net-device.h rename to src/devices/point-to-point/point-to-point-net-device.h diff --git a/src/devices/point-to-point/p2p-topology.cc b/src/devices/point-to-point/point-to-point-topology.cc similarity index 97% rename from src/devices/point-to-point/p2p-topology.cc rename to src/devices/point-to-point/point-to-point-topology.cc index 0b0ee003b..5a9558419 100644 --- a/src/devices/point-to-point/p2p-topology.cc +++ b/src/devices/point-to-point/point-to-point-topology.cc @@ -32,9 +32,9 @@ #include "ns3/ipv4.h" #include "ns3/queue.h" -#include "p2p-channel.h" -#include "p2p-net-device.h" -#include "p2p-topology.h" +#include "point-to-point-channel.h" +#include "point-to-point-net-device.h" +#include "point-to-point-topology.h" namespace ns3 { diff --git a/src/devices/point-to-point/p2p-topology.h b/src/devices/point-to-point/point-to-point-topology.h similarity index 100% rename from src/devices/point-to-point/p2p-topology.h rename to src/devices/point-to-point/point-to-point-topology.h diff --git a/src/devices/point-to-point/wscript b/src/devices/point-to-point/wscript index 639420dc7..e09cb71b4 100644 --- a/src/devices/point-to-point/wscript +++ b/src/devices/point-to-point/wscript @@ -7,16 +7,16 @@ def build(bld): p2p.target = p2p.name p2p.uselib_local = ['ns3-node'] p2p.source = [ - 'p2p-net-device.cc', - 'p2p-channel.cc', - 'p2p-topology.cc', + 'point-to-point-net-device.cc', + 'point-to-point-channel.cc', + 'point-to-point-topology.cc', ] p2p.includes = '.' headers = bld.create_obj('ns3header') headers.source = [ - 'p2p-net-device.h', - 'p2p-channel.h', - 'p2p-topology.h', + 'point-to-point-net-device.h', + 'point-to-point-channel.h', + 'point-to-point-topology.h', ] From b078d918945993974043cc5999504d6722d30473 Mon Sep 17 00:00:00 2001 From: Emmanuelle Laprise Date: Fri, 27 Jul 2007 20:45:07 +0200 Subject: [PATCH 3/7] cleanup the wscripts --- examples/wscript | 2 +- samples/wscript | 4 ++-- src/devices/point-to-point/wscript | 13 ++++++------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/examples/wscript b/examples/wscript index f535ea93f..c5b5ed69f 100644 --- a/examples/wscript +++ b/examples/wscript @@ -9,5 +9,5 @@ def build(bld): obj.source = source return obj - obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node']) + obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['point-to-point', 'internet-node']) diff --git a/samples/wscript b/samples/wscript index 9883cd24d..30c825555 100644 --- a/samples/wscript +++ b/samples/wscript @@ -18,9 +18,9 @@ def build(bld): obj = create_ns_prog('main-test', 'main-test.cc') obj = create_ns_prog('main-simple', 'main-simple.cc', deps=['node', 'internet-node', 'applications']) - #obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'p2p']) + #obj = create_ns_prog('main-simple-p2p', 'main-simple-p2p.cc', deps=['node', 'point-to-point']) obj = create_ns_prog('main-default-value', 'main-default-value.cc', - deps=['core', 'simulator', 'node', 'p2p']) + deps=['core', 'simulator', 'node', 'point-to-point']) obj = create_ns_prog('main-grid-topology', 'main-grid-topology.cc', deps=['core', 'simulator', 'mobility', 'internet-node']) obj = create_ns_prog('main-random-topology', 'main-random-topology.cc', diff --git a/src/devices/point-to-point/wscript b/src/devices/point-to-point/wscript index e09cb71b4..59d6ba3f8 100644 --- a/src/devices/point-to-point/wscript +++ b/src/devices/point-to-point/wscript @@ -2,21 +2,20 @@ def build(bld): - p2p = bld.create_obj('cpp', 'shlib') - p2p.name = 'ns3-p2p' - p2p.target = p2p.name - p2p.uselib_local = ['ns3-node'] - p2p.source = [ + module = bld.create_obj('cpp', 'shlib') + module.name = 'ns3-point-to-point' + module.target = module.name + module.uselib_local = ['ns3-node'] + module.source = [ 'point-to-point-net-device.cc', 'point-to-point-channel.cc', 'point-to-point-topology.cc', ] - p2p.includes = '.' - headers = bld.create_obj('ns3header') headers.source = [ 'point-to-point-net-device.h', 'point-to-point-channel.h', 'point-to-point-topology.h', ] + module.includes = '.' From 718ec6459308a607dfbc155743a09681306c9aa8 Mon Sep 17 00:00:00 2001 From: Emmanuelle Laprise Date: Fri, 27 Jul 2007 20:45:18 +0200 Subject: [PATCH 4/7] Move LLC encapsulation from NetDevice to subclasses. --- .../point-to-point-net-device.cc | 31 ++++++++++++++++--- .../point-to-point-net-device.h | 21 +++++++++---- src/node/net-device.cc | 28 ++++++++++------- src/node/net-device.h | 14 ++++++--- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index 8f474edde..565557df6 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -28,6 +28,7 @@ #include "ns3/composite-trace-resolver.h" #include "point-to-point-net-device.h" #include "point-to-point-channel.h" +#include "ns3/llc-snap-header.h" NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice"); @@ -65,13 +66,30 @@ PointToPointNetDevice::~PointToPointNetDevice() m_queue = 0; } +void PointToPointNetDevice::AddHeader(Packet& p, const MacAddress& dest, + uint16_t protocolNumber) +{ + LlcSnapHeader llc; + llc.SetType (protocolNumber); + p.AddHeader (llc); +} + +bool PointToPointNetDevice::ProcessHeader(Packet& p, int& param) +{ + LlcSnapHeader llc; + p.RemoveHeader (llc); + + param = llc.GetType (); + + return true; +} + void PointToPointNetDevice::DoDispose() { m_channel = 0; NetDevice::DoDispose (); } - void PointToPointNetDevice::SetDataRate(const DataRate& bps) { m_bps = bps; @@ -82,7 +100,8 @@ void PointToPointNetDevice::SetInterframeGap(const Time& t) m_tInterframeGap = t; } -bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest) +bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest, + uint16_t protocolNumber) { NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")"); NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")"); @@ -91,6 +110,7 @@ bool PointToPointNetDevice::SendTo (Packet& p, const MacAddress& dest) // "go down" during the simulation? Shouldn't we just wait for it // to come back up? NS_ASSERT (IsLinkUp ()); + AddHeader(p, dest, protocolNumber); // // This class simulates a point to point device. In the case of a serial @@ -198,9 +218,12 @@ void PointToPointNetDevice::AddQueue (Ptr q) void PointToPointNetDevice::Receive (Packet& p) { NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")"); + int param = 0; + Packet packet = p; - m_rxTrace (p); - ForwardUp (p); + ProcessHeader(packet, param); + m_rxTrace (packet); + ForwardUp (packet, param); } Ptr PointToPointNetDevice::GetQueue(void) const diff --git a/src/devices/point-to-point/point-to-point-net-device.h b/src/devices/point-to-point/point-to-point-net-device.h index a4bc3be00..6e8f3f0ae 100644 --- a/src/devices/point-to-point/point-to-point-net-device.h +++ b/src/devices/point-to-point/point-to-point-net-device.h @@ -187,11 +187,18 @@ protected: static const DataRate& GetDefaultRate(); private: - // unimplemented methods to make it impossible - // to copy these objects. - PointToPointNetDevice (const PointToPointNetDevice& nd); - PointToPointNetDevice& operator = (const PointToPointNetDevice&o); - + /** + * Adds the necessary headers and trailers to a packet of data in order to + * respect the protocol implemented by the agent. + */ + void AddHeader(Packet& p, const MacAddress& dest, uint16_t protocolNumber); + /** + * Removes, from a packet of data, all headers and trailers that + * relate to the protocol implemented by the agent + * \return Returns true if the packet should be forwarded up the + * protocol stack. + */ + bool ProcessHeader(Packet& p, int& param); /** * Send a Packet Down the Wire. * @@ -202,9 +209,11 @@ private: * @see NetDevice * @param p a reference to the packet to send * @param dest a reference to the MacAddress of the destination device + * @param protocolNumber Protocol Number used to find protocol touse * @returns true if success, false on failure */ - virtual bool SendTo (Packet& p, const MacAddress& dest); + virtual bool SendTo (Packet& p, const MacAddress& dest, + uint16_t protocolNumber); /** * Start Sending a Packet Down the Wire. * diff --git a/src/node/net-device.cc b/src/node/net-device.cc index 5774abeac..7bc61dc9b 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -22,12 +22,15 @@ #include #include "ns3/assert.h" #include "ns3/object.h" +#include "ns3/debug.h" + #include "channel.h" #include "net-device.h" -#include "llc-snap-header.h" #include "node.h" +NS_DEBUG_COMPONENT_DEFINE ("NetDevice"); + namespace ns3 { const InterfaceId NetDevice::iid = MakeInterfaceId ("NetDevice", Object::iid); @@ -172,10 +175,7 @@ NetDevice::Send(Packet& p, const MacAddress& dest, uint16_t protocolNumber) { if (m_isUp) { - LlcSnapHeader llc; - llc.SetType (protocolNumber); - p.AddHeader (llc); - return SendTo(p, dest); + return SendTo(p, dest, protocolNumber); } else { @@ -195,18 +195,24 @@ NetDevice::GetChannel (void) const return DoGetChannel (); } -// Receive packet from below +// Receive packets from below bool -NetDevice::ForwardUp (Packet& packet) +NetDevice::ForwardUp(Packet& p, uint32_t param) { bool retval = false; - LlcSnapHeader llc; - packet.RemoveHeader (llc); + Packet packet = p; + + NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid() + << " device is: " << GetName()); + if (!m_receiveCallback.IsNull ()) { - retval = m_receiveCallback (this, packet, llc.GetType ()); + retval = m_receiveCallback (this, packet, param); + } else { + NS_DEBUG ("NetDevice::Receive call back is NULL"); } - return retval; + + return retval; } void diff --git a/src/node/net-device.h b/src/node/net-device.h index 522b1ed41..b5de34fc8 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mathieu Lacage + * Modified by Emmanuelle Laprise to remove dependance on LLC headers */ #ifndef NET_DEVICE_H #define NET_DEVICE_H @@ -227,6 +228,8 @@ public: /** * \param p packet sent from below up to Network Device + * \param param Extra parameter extracted from header and needed by + * some protocols * \returns true if the packet was forwarded successfully, * false otherwise. * @@ -234,7 +237,8 @@ public: * forwards it to the higher layers by calling this method * which is responsible for passing it up to the Rx callback. */ - bool ForwardUp (Packet& p); + bool ForwardUp (Packet& p, uint32_t param); + /** * The dispose method for this NetDevice class. @@ -244,10 +248,13 @@ public: */ virtual void DoDispose (void); + Callback,const Packet &,uint16_t> m_receiveCallback; + private: /** * \param p packet to send * \param dest address of destination to which packet must be sent + * \param protocolNumber Number of the protocol (used with some protocols) * \returns true if the packet could be sent successfully, false * otherwise. * @@ -255,7 +262,7 @@ public: * method. When the link is Up, this method is invoked to ask * subclasses to forward packets. Subclasses MUST override this method. */ - virtual bool SendTo (Packet& p, const MacAddress& dest) = 0; + virtual bool SendTo (Packet& p, const MacAddress &dest, uint16_t protocolNumber) = 0; /** * \returns true if this NetDevice needs the higher-layers * to perform ARP over it, false otherwise. @@ -279,7 +286,7 @@ public: */ virtual Ptr DoGetChannel (void) const = 0; - Ptr m_node; + Ptr m_node; std::string m_name; uint16_t m_ifIndex; MacAddress m_address; @@ -290,7 +297,6 @@ public: bool m_isMulticast; bool m_isPointToPoint; Callback m_linkChangeCallback; - Callback,const Packet &,uint16_t> m_receiveCallback; }; }; // namespace ns3 From ad5f36f2acacebe15ade4d060bdcdfc628decc89 Mon Sep 17 00:00:00 2001 From: Emmanuelle Laprise Date: Fri, 27 Jul 2007 21:16:40 +0200 Subject: [PATCH 5/7] 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', From 31530c731173b63e06c891c9ada1431552b69419 Mon Sep 17 00:00:00 2001 From: Emmanuelle Laprise Date: Fri, 27 Jul 2007 21:17:14 +0200 Subject: [PATCH 6/7] a csma/cd NetDevice subclass and a test script --- examples/simple-csma-cd.cc | 209 ++++++++ examples/wscript | 1 + src/devices/csma-cd/backoff.cc | 83 +++ src/devices/csma-cd/backoff.h | 87 ++++ src/devices/csma-cd/csma-cd-channel.cc | 359 +++++++++++++ src/devices/csma-cd/csma-cd-channel.h | 307 +++++++++++ src/devices/csma-cd/csma-cd-ipv4-topology.cc | 162 ++++++ src/devices/csma-cd/csma-cd-ipv4-topology.h | 120 +++++ src/devices/csma-cd/csma-cd-net-device.cc | 504 +++++++++++++++++++ src/devices/csma-cd/csma-cd-net-device.h | 424 ++++++++++++++++ src/devices/csma-cd/csma-cd-topology.cc | 103 ++++ src/devices/csma-cd/csma-cd-topology.h | 128 +++++ src/devices/csma-cd/wscript | 24 + src/wscript | 1 + 14 files changed, 2512 insertions(+) create mode 100644 examples/simple-csma-cd.cc create mode 100644 src/devices/csma-cd/backoff.cc create mode 100644 src/devices/csma-cd/backoff.h create mode 100644 src/devices/csma-cd/csma-cd-channel.cc create mode 100644 src/devices/csma-cd/csma-cd-channel.h create mode 100644 src/devices/csma-cd/csma-cd-ipv4-topology.cc create mode 100644 src/devices/csma-cd/csma-cd-ipv4-topology.h create mode 100644 src/devices/csma-cd/csma-cd-net-device.cc create mode 100644 src/devices/csma-cd/csma-cd-net-device.h create mode 100644 src/devices/csma-cd/csma-cd-topology.cc create mode 100644 src/devices/csma-cd/csma-cd-topology.h create mode 100644 src/devices/csma-cd/wscript diff --git a/examples/simple-csma-cd.cc b/examples/simple-csma-cd.cc new file mode 100644 index 000000000..d5549af5b --- /dev/null +++ b/examples/simple-csma-cd.cc @@ -0,0 +1,209 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * 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 + * + * ns-2 simple.tcl script (ported from ns-2) + * Originally authored by Steve McCanne, 12/19/1996 + */ + +// Port of ns-2/tcl/ex/simple.tcl to ns-3 +// +// Network topology +// +// n0 +// \ 5 Mb/s, 2ms +// \ 1.5Mb/s, 10ms +// n2 -------------------------n3 +// / +// / 5 Mb/s, 2ms +// n1 +// +// - all links are p2p links with indicated one-way BW/delay +// - CBR/UDP flows from n0 to n3, and from n3 to n1 +// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. +// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. +// (i.e., DataRate of 448,000 bps) +// - DropTail queues +// - Tracing of queues and packet receptions to file "simple-p2p.tr" + +#include +#include +#include +#include + +#include "ns3/command-line.h" +#include "ns3/default-value.h" +#include "ns3/ptr.h" +#include "ns3/random-variable.h" +#include "ns3/debug.h" + +#include "ns3/simulator.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" + +#include "ns3/ascii-trace.h" +#include "ns3/pcap-trace.h" +#include "ns3/internet-node.h" +#include "ns3/csma-cd-channel.h" +#include "ns3/csma-cd-net-device.h" +#include "ns3/csma-cd-topology.h" +#include "ns3/csma-cd-ipv4-topology.h" +#include "ns3/mac-address.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/socket.h" +#include "ns3/ipv4-route.h" +#include "ns3/onoff-application.h" + +#include "ns3/ascii-trace.h" + +#include "ns3/trace-context.h" +#include "ns3/trace-root.h" + + +using namespace ns3; + + +int main (int argc, char *argv[]) +{ + + // Users may find it convenient to turn on explicit debugging + // for selected modules; the below lines suggest how to do this +#if 0 + DebugComponentEnable("Channel"); + DebugComponentEnable("CsmaCdChannel"); + DebugComponentEnable("CsmaCdNetDevice"); + DebugComponentEnable("NetDevice"); + DebugComponentEnable("PacketSocket"); +#endif + + Packet::EnableMetadata(); + + // Set up some default values for the simulation. Use the Bind() + // technique to tell the system what subclass of Queue to use, + // and what the queue limit is + + // The below Bind command tells the queue factory which class to + // instantiate, when the queue factory is invoked in the topology code + Bind ("Queue", "DropTailQueue"); + + // Allow the user to override any of the defaults and the above + // Bind()s at run-time, via command-line arguments + CommandLine::Parse (argc, argv); + + // Here, we will explicitly create four nodes. In more sophisticated + // topologies, we could configure a node factory. + Ptr n0 = Create (); + Ptr n1 = Create (); + Ptr n2 = Create (); + Ptr n3 = Create (); + + // We create the channels first without any IP addressing information + Ptr channel0 = + CsmaCdTopology::CreateCsmaCdChannel( + DataRate(5000000), MilliSeconds(2)); + + CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0, + MacAddress("10:54:23:54:23:50")); + CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0, + MacAddress("10:54:23:54:23:51")); + CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0, + MacAddress("10:54:23:54:23:52")); + CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0, + MacAddress("10:54:23:54:23:53")); + + // Later, we add IP addresses. + CsmaCdIpv4Topology::AddIpv4Address ( + n0, 0, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); + + CsmaCdIpv4Topology::AddIpv4Address ( + n0, 1, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); + + CsmaCdIpv4Topology::AddIpv4Address ( + n1, 0, Ipv4Address("10.1.2.1"), Ipv4Mask("255.255.255.0")); + + CsmaCdIpv4Topology::AddIpv4Address ( + n1, 1, Ipv4Address("10.1.2.2"), Ipv4Mask("255.255.255.0")); + + CsmaCdIpv4Topology::AddIpv4Address ( + n2, 0, Ipv4Address("10.1.3.1"), Ipv4Mask("255.255.255.0")); + + CsmaCdIpv4Topology::AddIpv4Address ( + n2, 1, Ipv4Address("10.1.3.2"), Ipv4Mask("255.255.255.0")); + + CsmaCdIpv4Topology::AddIpv4Address ( + n3, 0, Ipv4Address("10.1.4.1"), Ipv4Mask("255.255.255.0")); + + CsmaCdIpv4Topology::AddIpv4Address ( + n3, 1, Ipv4Address("10.1.4.2"), Ipv4Mask("255.255.255.0")); + + // Finally, we add static routes. These three steps (Channel and + // NetDevice creation, IP Address assignment, and routing) are + // separated because there may be a need to postpone IP Address + // assignment (emulation) or modify to use dynamic routing + CsmaCdIpv4Topology::AddIpv4Routes(n0->GetDevice(0), n2->GetDevice(1)); + CsmaCdIpv4Topology::AddIpv4Routes(n1->GetDevice(0), n2->GetDevice(1)); + CsmaCdIpv4Topology::AddIpv4Routes(n2->GetDevice(0), n3->GetDevice(1)); + + + // Create the OnOff application to send UDP datagrams of size + // 210 bytes at a rate of 448 Kb/s + Ptr ooff = Create ( + n0, + Ipv4Address("10.1.3.2"), + 80, + "Udp", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.0)); + ooff->Stop (Seconds(10.0)); + + // Create a similar flow from n3 to n1, starting at time 1.1 seconds + ooff = Create ( + n3, + Ipv4Address("10.1.2.1"), + 80, + "Udp", + ConstantVariable(1), + ConstantVariable(0)); + // Start the application + ooff->Start(Seconds(1.1)); + ooff->Stop (Seconds(10.0)); + + // Here, finish off packet routing configuration + // This will likely set by some global StaticRouting object in the future + Ptr ipv4; + ipv4 = n0->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); + ipv4 = n3->QueryInterface (Ipv4::iid); + ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1); + + // Configure tracing of all enqueue, dequeue, and NetDevice receive events + // Trace output will be sent to the simple-p2p.tr file + AsciiTrace asciitrace ("simple-csma-cd.tr"); + asciitrace.TraceAllNetDeviceRx (); + // asciitrace.TraceAllQueues (); + + // Also configure some tcpdump traces; each interface will be traced + // The output files will be named simple-p2p.pcap-- + // and can be read by the "tcpdump -r" command (use "-tt" option to + // display timestamps correctly) + // PcapTrace pcaptrace ("simple-p2p.pcap"); + // pcaptrace.TraceAllIp (); + + Simulator::Run (); + + Simulator::Destroy (); +} diff --git a/examples/wscript b/examples/wscript index c5b5ed69f..dcdf4ef67 100644 --- a/examples/wscript +++ b/examples/wscript @@ -10,4 +10,5 @@ def build(bld): return obj obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['point-to-point', 'internet-node']) + obj = create_ns_prog('simple-csma-cd', 'simple-csma-cd.cc', deps=['csma-cd', 'internet-node']) diff --git a/src/devices/csma-cd/backoff.cc b/src/devices/csma-cd/backoff.cc new file mode 100644 index 000000000..8f6dd1ee0 --- /dev/null +++ b/src/devices/csma-cd/backoff.cc @@ -0,0 +1,83 @@ +/* -*- 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 + */ + +#include "backoff.h" + +namespace ns3 { + +Backoff::Backoff() +{ + m_slotTime = MicroSeconds(1); + m_minSlots = 1; + m_maxSlots = 1000; + m_ceiling = 10; + m_maxRetries = 1000; + + ResetBackoffTime(); +} + +Backoff::Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, + uint32_t ceiling, uint32_t maxRetries) +{ + m_slotTime = slotTime; + m_minSlots = minSlots; + m_maxSlots = maxSlots; + m_ceiling = ceiling; + m_maxRetries = maxRetries; +} + +Time +Backoff::GetBackoffTime (void) +{ + Time backoff; + uint32_t ceiling; + + if ((m_ceiling > 0) &&(m_numBackoffRetries > m_ceiling)) + ceiling = m_ceiling; + else + ceiling = m_numBackoffRetries; + + uint32_t minSlot = m_minSlots; + uint32_t maxSlot = (uint32_t)pow(2, ceiling) - 1; + if (maxSlot > m_maxSlots) + maxSlot = m_maxSlots; + + uint32_t backoffSlots = + (uint32_t)UniformVariable::GetSingleValue(minSlot, maxSlot); + + backoff = Scalar(backoffSlots) * m_slotTime; + return (backoff); +} + +void Backoff::ResetBackoffTime (void) +{ + m_numBackoffRetries = 0; +} + +bool Backoff::MaxRetriesReached(void) { + return (m_numBackoffRetries >= m_maxRetries); +} + +void Backoff::IncrNumRetries(void) { + m_numBackoffRetries++; +} + +} // namespace ns3 diff --git a/src/devices/csma-cd/backoff.h b/src/devices/csma-cd/backoff.h new file mode 100644 index 000000000..adf270076 --- /dev/null +++ b/src/devices/csma-cd/backoff.h @@ -0,0 +1,87 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 Emmanuelle Laprise + * + * 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/nstime.h" +#include "ns3/random-variable.h" + +namespace ns3 { + + /** + * \brief The backoff class is used for calculating backoff times + * when many net devices can write to the same channel + * + */ + +class Backoff { +public: + uint32_t m_minSlots; // Minimum number of backoff slots (when + // multiplied by m_slotTime, determines minimum + // backoff time) + uint32_t m_maxSlots; // Maximim number of backoff slots (when + // multiplied by m_slotTime, determines + // maximum backoff time) + uint32_t m_ceiling; // Caps the exponential function when the + // number of retries reaches m_ceiling + uint32_t m_maxRetries; // Maximum number of transmission retries + // before the packet is dropped. + Time m_slotTime; // Length of one slot. A slot time, it usually + // the packet transmission time, if the packet + // size is fixed. + + Backoff(); + Backoff(Time slotTime, uint32_t minSlots, uint32_t maxSlots, + uint32_t ceiling, uint32_t maxRetries); + + /** + * \return The amount of time that the net device should wait before + * trying to retransmit the packet + */ + Time GetBackoffTime(); + /** + * Indicates to the backoff object that the last packet was + * successfully transmitted and that the number of retries should be + * reset to 0. + */ + void ResetBackoffTime(); + /** + * \return True if the maximum number of retries has been reached + */ + bool MaxRetriesReached(); + /** + * Increments the number of retries by 1. + */ + void IncrNumRetries(); + +private: + uint32_t m_numBackoffRetries; // Number of times that the + // transmitter has tried to + // unsuccessfully transmit the current + // packet +}; + +}; // namespace ns3 + +#endif // BACKOFF_H + diff --git a/src/devices/csma-cd/csma-cd-channel.cc b/src/devices/csma-cd/csma-cd-channel.cc new file mode 100644 index 000000000..004ddbd33 --- /dev/null +++ b/src/devices/csma-cd/csma-cd-channel.cc @@ -0,0 +1,359 @@ +/* -*- 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 + */ + +#include "csma-cd-channel.h" +#include "csma-cd-net-device.h" +#include "ns3/packet.h" +#include "ns3/simulator.h" +#include "ns3/debug.h" + +NS_DEBUG_COMPONENT_DEFINE ("CsmaCdChannel"); + +namespace ns3 { + +CsmaCdDeviceRec::CsmaCdDeviceRec() +{ + active = false; +} + +CsmaCdDeviceRec::CsmaCdDeviceRec(Ptr device) +{ + devicePtr = device; + active = true; +} + +bool +CsmaCdDeviceRec::IsActive() { + return active; +} + + +// +// By default, you get a channel with the name "CsmaCd Channel" that +// has an "infitely" fast transmission speed and zero delay. +CsmaCdChannel::CsmaCdChannel() +: + Channel ("CsmaCd Channel"), + m_bps (DataRate(0xffffffff)), + m_delay (Seconds(0)) +{ + NS_DEBUG("CsmaCdChannel::CsmaCdChannel ()"); + Init(); +} + +CsmaCdChannel::CsmaCdChannel( + const DataRate& bps, + const Time& delay) +: + Channel ("CsmaCd Channel"), + m_bps (bps), + m_delay (delay) +{ + NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << Channel::GetName() + << ", " << bps.GetBitRate() << ", " << delay << ")"); + Init(); +} + +CsmaCdChannel::CsmaCdChannel( + const std::string& name, + const DataRate& bps, + const Time& delay) +: + Channel (name), + m_bps (bps), + m_delay (delay) +{ + NS_DEBUG("CsmaCdChannel::CsmaCdChannel (" << name << ", " << + bps.GetBitRate() << ", " << delay << ")"); + Init(); +} + +void CsmaCdChannel::Init() { + m_state = IDLE; + m_deviceList.clear(); +} + +int32_t +CsmaCdChannel::Attach(Ptr device) +{ + NS_DEBUG("CsmaCdChannel::Attach (" << device << ")"); + NS_ASSERT(device != 0); + + CsmaCdDeviceRec rec(device); + + m_deviceList.push_back(rec); + return (m_deviceList.size() - 1); +} + +bool +CsmaCdChannel::Reattach(Ptr device) +{ + NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")"); + NS_ASSERT(device != 0); + + std::vector::iterator it; + for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + { + if (it->devicePtr == device) + { + if (!it->active) { + it->active = true; + return true; + } else { + return false; + } + } + } + return false; +} + +bool +CsmaCdChannel::Reattach(uint32_t deviceId) +{ + NS_DEBUG("CsmaCdChannel::Reattach (" << deviceId << ")"); + if (deviceId < m_deviceList.size()) + { + return false; + } + + if (m_deviceList[deviceId].active) + { + return false; + } else { + m_deviceList[deviceId].active = true; + return true; + } +} + +bool +CsmaCdChannel::Detach(uint32_t deviceId) +{ + NS_DEBUG("CsmaCdChannel::Detach (" << deviceId << ")"); + + if (deviceId < m_deviceList.size()) + { + if (!m_deviceList[deviceId].active) + { + NS_DEBUG("CsmaCdChannel::Detach Device is already detached (" + << deviceId << ")"); + return false; + } + + m_deviceList[deviceId].active = false; + if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId)) + { + NS_DEBUG("CsmaCdChannel::Detach Device is currently" + << "transmitting (" << deviceId << ")"); + // Here we will need to place a warning in the packet + } + + return true; + } else { + return false; + } +} + +bool +CsmaCdChannel::Detach(Ptr device) +{ + NS_DEBUG("CsmaCdChannel::Detach (" << device << ")"); + NS_ASSERT(device != 0); + + std::vector::iterator it; + for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + { + if ((it->devicePtr == device) && (it->active)) + { + it->active = false; + return true; + } + } + return false; +} + +bool +CsmaCdChannel::TransmitStart(Packet& p, uint32_t srcId) +{ + NS_DEBUG ("CsmaCdChannel::TransmitStart (" << &p << ", " << srcId + << ")"); + NS_DEBUG ("CsmaCdChannel::TransmitStart (): UID is " << + p.GetUid () << ")"); + + if (m_state != IDLE) + { + NS_DEBUG("CsmaCdChannel::TransmitStart (): state is not IDLE"); + return false; + } + + if (!IsActive(srcId)) + { + NS_DEBUG("CsmaCdChannel::TransmitStart (): ERROR: Seclected " + << "source is not currently attached to network"); + return false; + } + + NS_DEBUG("CsmaCdChannel::TransmitStart (): switch to TRANSMITTING"); + m_currentPkt = p; + m_currentSrc = srcId; + m_state = TRANSMITTING; + return true; +} + +bool +CsmaCdChannel::IsActive(uint32_t deviceId) { + return (m_deviceList[deviceId].active); +} + +bool +CsmaCdChannel::TransmitEnd() +{ + NS_DEBUG("CsmaCdChannel::TransmitEnd (" << &m_currentPkt << ", " + << m_currentSrc << ")"); + NS_DEBUG("CsmaCdChannel::TransmitEnd (): UID is " << + m_currentPkt.GetUid () << ")"); + + NS_ASSERT(m_state == TRANSMITTING); + m_state = PROPAGATING; + + bool retVal = true; + + if (!IsActive(m_currentSrc)) { + NS_DEBUG("CsmaCdChannel::TransmitEnd (): ERROR: Seclected source " + << "was detached before the end of the transmission"); + retVal = false; + } + + NS_DEBUG ("CsmaCdChannel::TransmitEnd (): Schedule event in " << + m_delay.GetSeconds () << "sec"); + + Simulator::Schedule (m_delay, + &CsmaCdChannel::PropagationCompleteEvent, + this); + return retVal; +} + +void +CsmaCdChannel::PropagationCompleteEvent() +{ + NS_DEBUG("CsmaCdChannel::PropagationCompleteEvent (" + << &m_currentPkt << ")"); + NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): UID is " << + m_currentPkt.GetUid () << ")"); + + NS_ASSERT(m_state == PROPAGATING); + m_state = IDLE; + + NS_DEBUG ("CsmaCdChannel::PropagationCompleteEvent (): Receive"); + + std::vector::iterator it; + for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + { + if (it->IsActive()) + { + it->devicePtr->Receive (m_currentPkt); + } + } +} + + +uint32_t +CsmaCdChannel::GetNumActDevices (void) +{ + int numActDevices = 0; + std::vector::iterator it; + for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + { + if (it->active) + { + numActDevices++; + } + } + return numActDevices; +} + +// This is not the number of active devices. This is the total number +// of devices even if some were detached after. +uint32_t +CsmaCdChannel::GetNDevices (void) const +{ + return (m_deviceList.size()); +} + +Ptr +CsmaCdChannel::GetDevice (uint32_t i) const +{ + Ptr< CsmaCdNetDevice > netDevice; + + netDevice = m_deviceList[i].devicePtr; + return netDevice; +} + +int32_t +CsmaCdChannel::GetDeviceNum (Ptr device) +{ + std::vector::iterator it; + int i = 0; + for (it = m_deviceList.begin(); it < m_deviceList.end(); it++) + { + if (it->devicePtr == device) + { + if (it->active) + { + return i; + } else { + return -2; + } + } + i++; + } + return -1; +} + +bool +CsmaCdChannel::IsBusy (void) +{ + if (m_state == IDLE) + { + return false; + } else { + return true; + } +} + +DataRate +CsmaCdChannel::GetDataRate (void) +{ + return m_bps; +} + +Time +CsmaCdChannel::GetDelay (void) +{ + return m_delay; +} + +WireState +CsmaCdChannel::GetState(void) +{ + return m_state; +} + +} // namespace ns3 diff --git a/src/devices/csma-cd/csma-cd-channel.h b/src/devices/csma-cd/csma-cd-channel.h new file mode 100644 index 000000000..fafb5b6ad --- /dev/null +++ b/src/devices/csma-cd/csma-cd-channel.h @@ -0,0 +1,307 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 Emmanuelle Laprise + * + * 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 CSMA_CD_CHANNEL_H +#define CSMA_CD_CHANNEL_H + +#include "ns3/channel.h" +#include "ns3/ptr.h" +#include "ns3/packet.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" + +namespace ns3 { + +class CsmaCdNetDevice; + + /** + * \brief CsmaCdNetDevice Record + * + * Stores the information related to each net device that is + * connected to the channel. + */ + class CsmaCdDeviceRec { + public: + Ptr< CsmaCdNetDevice > devicePtr; /// Pointer to the net device + bool active; /// Is net device enabled to TX/RX + + CsmaCdDeviceRec(); + CsmaCdDeviceRec(Ptr< CsmaCdNetDevice > device); + /* + * \return If the net device pointed to by the devicePtr is active + * and ready to RX/TX. + */ + bool IsActive(); + }; + + /** + * Current state of the channel + */ + enum WireState + { + IDLE, /**< Channel is IDLE, no packet is being + transmitted */ + TRANSMITTING, /**< Channel is BUSY, a packet is being written + by a net device */ + PROPAGATING /**< Channel is BUSY, packet is propagating to + all attached net devices */ + }; + +/** + * \brief CsmaCd Channel. + * + * This class represents a simple Csma/Cd channel that can be used + * when many nodes are connected to one wire. It uses a single busy + * flag to indicate if the channel is currently in use. It does not + * take into account the distances between stations or the speed of + * light to determine collisions. + * + * Each net device must query the state of the channel and make sure + * that it is IDLE before writing a packet to the channel. + * + * When the channel is instaniated, the constructor takes parameters + * for a single speed, in bits per second, and a speed-of-light delay + * time as a Time object. When a net device is attached to a channel, + * it is assigned a device ID, this is in order to facilitate the + * check that makes sure that a net device that is trying to send a + * packet to the channel is really connected to this channel + * + */ +class CsmaCdChannel : public Channel { +public: + /** + * \brief Create a CsmaCdChannel + * + * By default, you get a channel with the name "CsmaCd Channel" that + * has an "infitely" fast transmission speed and zero delay. + */ + CsmaCdChannel (); + + /** + * \brief Create a CsmaCdChannel + * + * \param bps The bitrate of the channel + * \param delay Transmission delay through the channel + */ + CsmaCdChannel (const DataRate& bps, const Time& delay); + + /** + * \brief Create a CsmaCdChannel + * + * \param name the name of the channel for identification purposes + * \param bps The bitrate of the channel + * \param delay Transmission delay through the channel + */ + CsmaCdChannel (const std::string& name, + const DataRate& bps, const Time& delay); + + /** + * \brief Attach a given netdevice to this channel + * + * \param device Device pointer to the netdevice to attach to the channel + * \return The assigned device number + */ + int32_t Attach (Ptr device); + /** + * \brief Detach a given netdevice from this channel + * + * The net device is marked as inactive and it is not allowed to + * receive or transmit packets + * + * \param device Device pointer to the netdevice to detach from the channel + * \return True if the device is found and attached to the channel, + * false if the device is not currently connected to the channel or + * can't be found. + */ + bool Detach (Ptr device); + /** + * \brief Detach a given netdevice from this channel + * + * The net device is marked as inactive and it is not allowed to + * receive or transmit packets + * + * \param deviceId The deviceID assigned to the net device when it + * was connected to the channel + * \return True if the device is found and attached to the channel, + * false if the device is not currently connected to the channel or + * can't be found. + */ + bool Detach (uint32_t deviceId); + /** + * \brief Reattach a previously detached net device to the channel + * + * The net device is marked as active. It is now allowed to receive + * or transmit packets. The net device must have been previously + * attached to the channel using the attach function. + * + * \param deviceId The device ID assigned to the net device when it + * was connected to the channel + * \return True if the device is found and is not attached to the + * channel, false if the device is currently connected to the + * channel or can't be found. + */ + bool Reattach(uint32_t deviceId); + /** + * \brief Reattach a previously detached net device to the channel + * + * The net device is marked as active. It is now allowed to receive + * or transmit packets. The net device must have been previously + * attached to the channel using the attach function. + * + * \param device Device pointer to the netdevice to detach from the channel + * \return True if the device is found and is not attached to the + * channel, false if the device is currently connected to the + * channel or can't be found. + */ + bool Reattach(Ptr device); + /** + * \brief Start transmitting a packet over the channel + * + * If the srcId belongs to a net device that is connected to the + * channel, packet transmission begins, and the channel becomes busy + * until the packet has completely reached all destinations. + * + * \param p A reference to the packet that will be transmitted over + * the channel + * \param srcId The device Id of the net device that wants to + * transmit on the channel. + * \return True if the channel is not busy and the transmitting net + * device is currently active. + */ + bool TransmitStart (Packet& p, uint32_t srcId); + /** + * \brief Indicates that the net device has finished transmitting + * the packet over the channel + * + * The channel will stay busy until the packet has completely + * propagated to all net devices attached to the channel. The + * TransmitEnd function schedules the PropagationCompleteEvent which + * will free the channel for further transmissions. Stores the + * packet p as the m_currentPkt, the packet being currently + * transmitting. + * + * \return Returns true unless the source was detached before it + * completed its transmission. + */ + bool TransmitEnd (); + /** + * \brief Indicates that the channel has finished propagating the + * current packet. The channel is released and becomes free. + * + * Calls the receive function of every active net device that is + * attached to the channel. + */ + void PropagationCompleteEvent(); + /** + * \return Returns the device number assigned to a net device by the + * channel + * + * \param device Device pointer to the netdevice for which the device + * number is needed + */ + int32_t GetDeviceNum (Ptr device); + /** + * \return Returns the state of the channel (IDLE -- free, + * TRANSMITTING -- busy, PROPAGATING - busy ) + */ + WireState GetState(); + + /** + * \brief Indicates if the channel is busy. The channel will only + * accept new packets for transmission if it is not busy. + * + * \return Returns true if the channel is busy and false if it is + * free. + */ + bool IsBusy(); + + /** + * \brief Indicates if a net device is currently attached or + * detached from the channel. + * + * \param deviceId The ID that was assigned to the net device when + * it was attached to the channel. + * \return Returns true if the net device is attached to the + * channel, false otherwise. + */ + bool IsActive(uint32_t deviceId); + /** + * \return Returns the number of net devices that are currently + * attached to the channel. + */ + uint32_t GetNumActDevices (void); + /** + * \return Returns the total number of devices including devices + * that have been detached from the channel. + */ + virtual uint32_t GetNDevices (void) const; + /** + * \param i The deviceId of the net device for which we want the + * pointer. + * \return Returns the pointer to the net device that is associated + * with deviceId i. + */ + virtual Ptr GetDevice (uint32_t i) const; + + virtual DataRate GetDataRate (void); + virtual Time GetDelay (void); + +private: + DataRate m_bps; /// Data rate of the channel + Time m_delay; /// Delay of the channel. + + /** + * List of the net devices that have been or are currently connected + * to the channel. + * + * Devices are nor removed from this list, they are marked as + * inactive. Otherwise the assigned device IDs will not refer to the + * correct NetDevice. The DeviceIds are used so that it is possible + * to have a number to refer to an entry in the list so that the + * whole list does not have to be searched when making sure that a + * source is attached to a channel when it is transmitting data. + */ + std::vector< CsmaCdDeviceRec > m_deviceList; + /** + * Packet that is currently being transmitted on the channel (or last + * packet to have been transmitted on the channel if the channel is + * free.) + */ + Packet m_currentPkt; + /** + * Device Id of the source that is currently transmitting on the + * channel. Or last source to have transmitted a packet on the + * channel, if the channel is currently not busy. + */ + uint32_t m_currentSrc; + /** + * Current state of the channel + */ + WireState m_state; + /** + * Initializes the channel when it is constructed. Resets the + * deviceList and sets the channel state to IDLE. + */ + void Init (void); +}; + +} // namespace ns3 + +#endif /* CSMA_CD_CHANNEL_H */ diff --git a/src/devices/csma-cd/csma-cd-ipv4-topology.cc b/src/devices/csma-cd/csma-cd-ipv4-topology.cc new file mode 100644 index 000000000..64ddc036c --- /dev/null +++ b/src/devices/csma-cd/csma-cd-ipv4-topology.cc @@ -0,0 +1,162 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +// +// Copyright (c) 2007 Emmanuelle Laprise +// +// 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 +#include "ns3/assert.h" +#include "ns3/debug.h" +#include "ns3/fatal-error.h" +#include "ns3/nstime.h" +#include "ns3/internet-node.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/queue.h" + +#include "csma-cd-channel.h" +#include "csma-cd-net-device.h" +#include "csma-cd-ipv4-topology.h" + +namespace ns3 { + + +void +CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr n1, + Ptr ch, + MacAddress addr) +{ + Ptr q = Queue::CreateDefault (); + + // Use the first net device in the node to transmit + Ptr nd0 = Create (n1, addr, + ns3::CsmaCdNetDevice::IP_ARP, + true, false); + nd0->AddQueue(q); + nd0->Attach (ch); + + // Use the second net device in the node to transmit + Ptr nd1 = Create (n1, addr, + ns3::CsmaCdNetDevice::IP_ARP, + false, true); + nd1->AddQueue(q); + nd1->Attach (ch); +} + + +void +CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr n1, + Ptr ch, + MacAddress addr) +{ + Ptr q = Queue::CreateDefault (); + + Ptr nd0 = Create (n1, addr, + ns3::CsmaCdNetDevice::LLC, + true, false); + nd0->AddQueue(q); + nd0->Attach (ch); + + Ptr nd1 = Create (n1, addr, + ns3::CsmaCdNetDevice::LLC, + false, true); + nd1->AddQueue(q); + nd1->Attach (ch); +} + +void +CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr n1, + Ptr ch, + MacAddress addr) +{ + Ptr q = Queue::CreateDefault (); + + Ptr nd0 = Create (n1, addr, + ns3::CsmaCdNetDevice::RAW, + true, false); + nd0->AddQueue(q); + nd0->Attach (ch); + + Ptr nd1 = Create (n1, addr, + ns3::CsmaCdNetDevice::RAW, + false, true); + nd1->AddQueue(q); + nd1->Attach (ch); +} + +void +CsmaCdIpv4Topology::AddIpv4Address(Ptr n1, + int ndNum, + const Ipv4Address& addr1, + const Ipv4Mask& netmask1) +{ + + // Duplex link is assumed to be subnetted as a /30 + // May run this unnumbered in the future? + Ipv4Mask netmask(netmask1); + + Ptr nd1 = n1->GetDevice(ndNum); + + Ptr ip1 = n1->QueryInterface (Ipv4::iid); + uint32_t index1 = ip1->AddInterface (nd1); + + ip1->SetAddress (index1, addr1); + ip1->SetNetworkMask (index1, netmask); + ip1->SetUp (index1); + +} + +void +CsmaCdIpv4Topology::AddIpv4Routes ( + Ptr nd1, Ptr nd2) +{ + // Assert that both are Ipv4 nodes + Ptr ip1 = nd1->GetNode ()->QueryInterface (Ipv4::iid); + Ptr ip2 = nd2->GetNode ()->QueryInterface (Ipv4::iid); + NS_ASSERT(ip1 != 0 && ip2 != 0); + + // Get interface indexes for both nodes corresponding to the right channel + uint32_t index1 = 0; + bool found = false; + for (uint32_t i = 0; i < ip1->GetNInterfaces (); i++) + { + if (ip1 ->GetNetDevice (i) == nd1) + { + index1 = i; + found = true; + } + } + NS_ASSERT(found); + + uint32_t index2 = 0; + found = false; + for (uint32_t i = 0; i < ip2->GetNInterfaces (); i++) + { + if (ip2 ->GetNetDevice (i) == nd2) + { + index2 = i; + found = true; + } + } + NS_ASSERT(found); + + ip1->AddHostRouteTo (ip2-> GetAddress (index2), index1); + ip2->AddHostRouteTo (ip1-> GetAddress (index1), index2); +} + +} // namespace ns3 + diff --git a/src/devices/csma-cd/csma-cd-ipv4-topology.h b/src/devices/csma-cd/csma-cd-ipv4-topology.h new file mode 100644 index 000000000..fe821cee6 --- /dev/null +++ b/src/devices/csma-cd/csma-cd-ipv4-topology.h @@ -0,0 +1,120 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +// +// Copyright (c) 2007 Emmanuelle Laprise +// +// 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 __CSMA_CD_IPV4_TOPOLOGY_H__ +#define __CSMA_CD_IPV4_TOPOLOGY_H__ + +#include "ns3/ptr.h" +#include "ns3/ipv4-address.h" +#include "ns3/ipv4.h" +#include "ns3/ipv4-route.h" +#include "ns3/internet-node.h" +#include "ns3/csma-cd-net-device.h" + +// The topology class consists of only static methods thar are used to +// create the topology and data flows for an ns3 simulation + +namespace ns3 { + +class CsmaCdIpv4Channel; +class Node; +class IPAddr; +class DataRate; +class Queue; + +/** + * \brief A helper class to create Topologies based on the + * InternetNodes and CsmaCdChannels. Either the + * SimpleCsmaCdNetDevice or the LLCCsmaCdNetDevice can be used + * when constructing these topologies. + */ +class CsmaCdIpv4Topology { +public: + + /** + * \param n1 Node to be attached to the Csma/Cd channel + * \param ch CsmaCdChannel to which node n1 should be attached + * \param addr Mac address of the node + * + * Add a Csma/Cd node to a Csma/Cd channel. This function adds + * a EthernetCsmaCdNetDevice to the nodes so that they can + * connect to a CsmaCdChannel. This means that Ethernet headers + * and trailers will be added to the packet before sending out on + * the net device. + */ + static void AddIpv4CsmaCdNode( Ptr n1, + Ptr ch, + MacAddress addr); + + /** + * \param n1 Node to be attached to the Csma/Cd channel + * \param ch CsmaCdChannel to which node n1 should be attached + * \param addr Mac address of the node + * + * Add a Csma/Cd node to a Csma/Cd channel. This function adds + * a RawCsmaCdNetDevice to the nodes so that they can connect + * to a CsmaCdChannel. + */ + static void AddIpv4RawCsmaCdNode( Ptr n1, + Ptr ch, + MacAddress addr); + + /** + * \param n1 Node to be attached to the Csma/Cd channel + * \param ch CsmaCdChannel to which node n1 should be attached + * \param addr Mac address of the node + * + * Add a Csma/Cd node to a Csma/Cd channel. This function adds + * a LlcCsmaCdNetDevice to the nodes so that they can connect + * to a CsmaCdChannel. + */ + static void AddIpv4LlcCsmaCdNode( Ptr n1, + Ptr ch, + MacAddress addr); + + + + /** + * \param n1 Node + * \param ndNum NetDevice number with which to associate address + * \param addr1 Ipv4 Address for ndNum of n1 + * \param network network mask for ndNum of node n1 + * + * Add an Ipv4Address to the Ipv4 interface associated with the + * ndNum CsmaCdIpv4NetDevices on the provided + * CsmaCdIpv4Channel + */ + static void AddIpv4Address(Ptr n1, int ndNum, + const Ipv4Address& addr1, + const Ipv4Mask& netmask1); + + /** + * \param nd1 Node + * \param nd2 Node + * + * Add an IPV4 host route between the two specified net devices + */ + static void AddIpv4Routes (Ptr nd1, Ptr nd2); +}; + +} // namespace ns3 + +#endif + diff --git a/src/devices/csma-cd/csma-cd-net-device.cc b/src/devices/csma-cd/csma-cd-net-device.cc new file mode 100644 index 000000000..61b162420 --- /dev/null +++ b/src/devices/csma-cd/csma-cd-net-device.cc @@ -0,0 +1,504 @@ +/* -*- 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 + */ + +#include +#include +#include "ns3/debug.h" +#include "ns3/queue.h" +#include "ns3/simulator.h" +#include "ns3/composite-trace-resolver.h" +#include "csma-cd-net-device.h" +#include "csma-cd-channel.h" +#include "ns3/ethernet-header.h" +#include "ns3/ethernet-trailer.h" +#include "ns3/llc-snap-header.h" + +NS_DEBUG_COMPONENT_DEFINE ("CsmaCdNetDevice"); + +namespace ns3 { + +CsmaCdNetDevice::CsmaCdNetDevice (Ptr node, MacAddress addr, + CsmaCdEncapsulationMode pktType) + : NetDevice(node, addr), m_bps (DataRate (0xffffffff)) +{ + NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")"); + m_pktType = pktType; + + Init(true, true); +} + +CsmaCdNetDevice::CsmaCdNetDevice (Ptr node, MacAddress addr, + CsmaCdEncapsulationMode pktType, + bool sendEnable, bool receiveEnable) + : NetDevice(node, addr), m_bps (DataRate (0xffffffff)) +{ + NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")"); + m_pktType = pktType; + + Init(sendEnable, receiveEnable); +} + +CsmaCdNetDevice::~CsmaCdNetDevice() +{ + NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()"); + m_queue = 0; +} + +// +// Copy constructor for CsmaCdNetDevice. +// +// We use the underlying NetDevice copy constructor to get the base class +// copied. These just remain as is (e.g. you get the same name, the same +// MAC address). If you need to fix them up, YOU, the copier need to do +// that. +// +// The things we need to be careful of are the channel, the queue and the +// trace callback. If the channel pointer is non-zero, we copy the pointer +// and add a reference. If the queue is non-zero, we copy it using the queue +// assignment operator. We don't mess with the trace -- we just reset it. +// We're assuming that the tracing will be set up after the topology creation +// phase and this won't actually matter. +// + +CsmaCdNetDevice::CsmaCdNetDevice (const CsmaCdNetDevice& nd) + : NetDevice(nd), m_bps (nd.m_bps) +{ + NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << &nd << ")"); + + m_txMachineState = READY; + m_tInterframeGap = nd.m_tInterframeGap; + m_backoff = nd.m_backoff; + m_channel = nd.m_channel; + m_queue = 0; + m_pktType = nd.m_pktType; + m_sendEnable = nd.m_sendEnable; + m_receiveEnable = nd.m_receiveEnable; + + if (nd.m_queue) + { + m_queue = nd.m_queue; + } + +} + +void +CsmaCdNetDevice::DoDispose () +{ + m_channel = 0; + NetDevice::DoDispose (); +} + +// +// Assignment operator for CsmaCdNetDevice. +// +// This uses the non-obvious trick of taking the source net device passed by +// value instead of by reference. This causes the copy constructor to be +// invoked (where the real work is done -- see above). All we have to do +// here is to return the newly constructed net device. +// +/* +CsmaCdNetDevice& +CsmaCdNetDevice::operator= (const CsmaCdNetDevice nd) +{ + NS_DEBUG ("CsmaCdNetDevice::operator= (" << &nd << ")"); + return *this; +} +*/ + +void +CsmaCdNetDevice::Init(bool sendEnable, bool receiveEnable) +{ + m_txMachineState = READY; + m_tInterframeGap = Seconds(0); + m_channel = 0; + m_queue = 0; + + EnableBroadcast (MacAddress ("ff:ff:ff:ff:ff:ff")); + EnableMulticast(); + EnablePointToPoint(); + + SetSendEnable (sendEnable); + SetReceiveEnable (receiveEnable); +} + +void +CsmaCdNetDevice::SetSendEnable (bool sendEnable) +{ + m_sendEnable = sendEnable; +} + +void +CsmaCdNetDevice::SetReceiveEnable (bool receiveEnable) +{ + m_receiveEnable = receiveEnable; +} +bool +CsmaCdNetDevice::IsSendEnabled (void) +{ + return (m_sendEnable); +} + +bool +CsmaCdNetDevice::IsReceiveEnabled (void) +{ + return (m_receiveEnable); +} + +void +CsmaCdNetDevice::SetDataRate (DataRate bps) +{ + m_bps = bps; +} + +void +CsmaCdNetDevice::SetInterframeGap (Time t) +{ + m_tInterframeGap = t; +} + +void +CsmaCdNetDevice::SetBackoffParams (Time slotTime, uint32_t minSlots, + uint32_t maxSlots, uint32_t ceiling, + uint32_t maxRetries) +{ + m_backoff.m_slotTime = slotTime; + m_backoff.m_minSlots = minSlots; + m_backoff.m_maxSlots = maxSlots; + m_backoff.m_ceiling = ceiling; + m_backoff.m_maxRetries = maxRetries; +} +void +CsmaCdNetDevice::AddHeader (Packet& p, const MacAddress& dest, + uint16_t protocolNumber) +{ + if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP)) + { + EthernetHeader header; + EthernetTrailer trailer; + + header.SetSource(this->GetAddress()); + header.SetDestination(dest); + switch (m_pktType) + { + case IP_ARP: + header.SetLengthType(protocolNumber); + break; + default: + header.SetLengthType(p.GetSize() + header.GetSize() + trailer.GetSize()); + break; + } + p.AddHeader(header); + trailer.CalcFcs(p); + p.AddTrailer(trailer); + } + else if (m_pktType == LLC) + { + LlcSnapHeader llc; + llc.SetType (protocolNumber); + p.AddHeader (llc); + } +} +bool +CsmaCdNetDevice::ProcessHeader(Packet& p, int& param) +{ + bool retVal = true; + + if ((m_pktType == ETHERNET_V1) || (m_pktType == IP_ARP)) + { + EthernetHeader header; + EthernetTrailer trailer; + + p.RemoveTrailer(trailer); + trailer.CheckFcs(p); + p.RemoveHeader(header); + + param = header.GetLengthType(); + if ((header.GetDestination() != this->GetBroadcast()) && + (header.GetDestination() != this->GetAddress())) + { + retVal = false; + } + } + else if (m_pktType == LLC) + { + LlcSnapHeader llc; + p.RemoveHeader (llc); + + param = llc.GetType (); + } + + return retVal; +} + +bool +CsmaCdNetDevice::DoNeedsArp (void) const +{ + if ((m_pktType == IP_ARP) || (m_pktType == LLC)) + { + return true; + } else { + return false; + } +} + +bool +CsmaCdNetDevice::SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber) +{ + NS_DEBUG ("CsmaCdNetDevice::SendTo (" << &p << ")"); + NS_DEBUG ("CsmaCdNetDevice::SendTo (): UID is " << p.GetUid () << ")"); + + NS_ASSERT (IsLinkUp ()); + + // Only transmit if send side of net device is enabled + if (!IsSendEnabled()) + return false; + + AddHeader(p, dest, protocolNumber); + + // Place the packet to be sent on the send queue + if (m_queue->Enqueue(p) == false ) + { + return false; + } + // If the device is idle, we need to start a transmission. Otherwise, + // the transmission will be started when the current packet finished + // transmission (see TransmitCompleteEvent) + if (m_txMachineState == READY) + { + // Store the next packet to be transmitted + if (m_queue->Dequeue (m_currentPkt)) + { + TransmitStart(); + } + } + return true; +} + +void +CsmaCdNetDevice::TransmitStart () +{ + NS_DEBUG ("CsmaCdNetDevice::TransmitStart (" << &m_currentPkt << ")"); + NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): UID is " + << m_currentPkt.GetUid () << ")"); +// +// This function is called to start the process of transmitting a packet. +// We need to tell the channel that we've started wiggling the wire and +// schedule an event that will be executed when it's time to tell the +// channel that we're done wiggling the wire. +// + NS_ASSERT_MSG((m_txMachineState == READY) || (m_txMachineState == BACKOFF), + "Must be READY to transmit. Tx state is: " + << m_txMachineState); + + // Only transmit if send side of net device is enabled + if (!IsSendEnabled()) + return; + + if (m_channel->GetState() != IDLE) + { // Channel busy, backoff and rechedule TransmitStart() + m_txMachineState = BACKOFF; + if (m_backoff.MaxRetriesReached()) + { // Too many retries reached, abort transmission of packet + TransmitAbort(); + } else { + m_backoff.IncrNumRetries(); + Time backoffTime = m_backoff.GetBackoffTime(); + + NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " + << "Channel busy, backing off for " + << backoffTime.GetSeconds () << "sec"); + + Simulator::Schedule (backoffTime, + &CsmaCdNetDevice::TransmitStart, + this); + } + } else { + // Channel is free, transmit packet + m_txMachineState = BUSY; + Time tEvent = Seconds (m_bps.CalculateTxTime(m_currentPkt.GetSize())); + + NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " << + "Schedule TransmitCompleteEvent in " << + tEvent.GetSeconds () << "sec"); + + Simulator::Schedule (tEvent, + &CsmaCdNetDevice::TransmitCompleteEvent, + this); + if (!m_channel->TransmitStart (m_currentPkt, m_deviceId)) + { + NS_DEBUG ("CsmaCdNetDevice::TransmitStart (): " << + "Channel transmit start did not work at " << + tEvent.GetSeconds () << "sec"); + m_txMachineState = READY; + } else { + // Transmission success, reset backoff time parameters. + m_backoff.ResetBackoffTime(); + } + } +} + + +void +CsmaCdNetDevice::TransmitAbort (void) +{ + NS_DEBUG ("CsmaCdNetDevice::TransmitAbort ()"); + + NS_DEBUG ("CsmaCdNetDevice::TransmitAbort (): Pkt UID is " << + m_currentPkt.GetUid () << ")"); + + // Try to transmit a new packet + bool found; + found = m_queue->Dequeue (m_currentPkt); + NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?"); + m_backoff.ResetBackoffTime(); + m_txMachineState = READY; + TransmitStart (); +} + +void +CsmaCdNetDevice::TransmitCompleteEvent (void) +{ + NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent ()"); +// +// This function is called to finish the process of transmitting a packet. +// We need to tell the channel that we've stopped wiggling the wire and +// schedule an event that will be executed when it's time to re-enable +// the transmitter after the interframe gap. +// + NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting"); + // Channel should be transmitting + NS_ASSERT(m_channel->GetState() == TRANSMITTING); + m_txMachineState = GAP; + + NS_DEBUG ("CsmaCdNetDevice::TransmitCompleteEvent (): Pkt UID is " << + m_currentPkt.GetUid () << ")"); + m_channel->TransmitEnd (); + + NS_DEBUG ( + "CsmaCdNetDevice::TransmitCompleteEvent (): " << + "Schedule TransmitReadyEvent in " + << m_tInterframeGap.GetSeconds () << "sec"); + + Simulator::Schedule (m_tInterframeGap, + &CsmaCdNetDevice::TransmitReadyEvent, + this); +} + +void +CsmaCdNetDevice::TransmitReadyEvent (void) +{ + NS_DEBUG ("CsmaCdNetDevice::TransmitReadyEvent ()"); +// +// This function is called to enable the transmitter after the interframe +// gap has passed. If there are pending transmissions, we use this opportunity +// to start the next transmit. +// + NS_ASSERT_MSG(m_txMachineState == GAP, "Must be in interframe gap"); + m_txMachineState = READY; + + // Get the next packet from the queue for transmitting + if (m_queue->IsEmpty()) + { + return; + } + else + { + bool found; + found = m_queue->Dequeue (m_currentPkt); + NS_ASSERT_MSG(found, "IsEmpty false but no Packet on queue?"); + TransmitStart (); + } +} + +TraceResolver * +CsmaCdNetDevice::DoCreateTraceResolver (TraceContext const &context) +{ + CompositeTraceResolver *resolver = new CompositeTraceResolver (context); + resolver->Add ("queue", + MakeCallback (&Queue::CreateTraceResolver, + PeekPointer (m_queue)), + CsmaCdNetDevice::QUEUE); + resolver->Add ("rx", + m_rxTrace, + CsmaCdNetDevice::RX); + return resolver; +} + +bool +CsmaCdNetDevice::Attach (Ptr ch) +{ + NS_DEBUG ("CsmaCdNetDevice::Attach (" << &ch << ")"); + + m_channel = ch; + + m_deviceId = m_channel->Attach(this); + m_bps = m_channel->GetDataRate (); + m_tInterframeGap = m_channel->GetDelay (); + + /* + * For now, this device is up whenever a channel is attached to it. + */ + NotifyLinkUp (); + return true; +} + +void +CsmaCdNetDevice::AddQueue (Ptr q) +{ + NS_DEBUG ("CsmaCdNetDevice::AddQueue (" << q << ")"); + + m_queue = q; +} + +void +CsmaCdNetDevice::Receive (Packet& p) +{ + NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")"); + + // Only receive if send side of net device is enabled + if (!IsReceiveEnabled()) + return; + + int param = 0; + Packet packet = p; + + if (ProcessHeader(packet, param)) + { + m_rxTrace (packet); + ForwardUp (packet, param); + } else { + m_dropTrace (packet); + } +} + +Ptr +CsmaCdNetDevice::GetQueue(void) const +{ + return m_queue; +} + +Ptr +CsmaCdNetDevice::DoGetChannel(void) const +{ + return m_channel; +} + +} // namespace ns3 diff --git a/src/devices/csma-cd/csma-cd-net-device.h b/src/devices/csma-cd/csma-cd-net-device.h new file mode 100644 index 000000000..d2972feb2 --- /dev/null +++ b/src/devices/csma-cd/csma-cd-net-device.h @@ -0,0 +1,424 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2007 Emmanuelle Laprise + * + * 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/node.h" +#include "ns3/backoff.h" +#include "ns3/mac-address.h" +#include "ns3/net-device.h" +#include "ns3/callback.h" +#include "ns3/packet.h" +#include "ns3/callback-trace-source.h" +#include "ns3/nstime.h" +#include "ns3/data-rate.h" +#include "ns3/ptr.h" +#include "ns3/random-variable.h" + +namespace ns3 { + +class Queue; +class CsmaCdChannel; + +/** + * \class CsmaCdNetDevice + * \brief A Device for a CsmaCd Network Link. + * + * The Csma/Cd net device class is analogous to layer 1 and 2 of the + * TCP stack. The NetDevice takes a raw packet of bytes and creates a + * protocol specific packet from them. The Csma/Cd net device class + * takes this packet and adds and processes the headers/trailers that + * are associated with EthernetV1, EthernetV2, RAW or LLC + * protocols. The EthernetV1 packet type adds and removes Ethernet + * destination and source addresses. The LLC packet type adds and + * removes LLC snap headers. The raw packet type does not add or + * remove any headers. Each Csma/Cd net device will receive all + * packets written to the Csma/Cd link. The ProcessHeader function can + * be used to filter out the packets such that higher level layers + * only receive packets that are addressed to their associated net + * devices + * + */ +class CsmaCdNetDevice : public NetDevice { +public: + /** + * Enumeration of the types of traces supported in the class. + * + */ + enum TraceType { + QUEUE, /**< Trace queue events on the attached queue */ + RX, /**< Trace packet reception events (from the channel) */ + DROP /**< Trace packet drop events (from the channel) */ + }; + + /** + * Enumeration of the types of packets supported in the class. + * + */ +enum CsmaCdEncapsulationMode { + ETHERNET_V1, /**< Version one ethernet packet, length field */ + IP_ARP, /**< Ethernet packet encapsulates IP/ARP packet */ + RAW, /**< Packet that contains no headers */ + LLC, /**< LLC packet encapsulation */ +}; + + /** + * Construct a CsmaCdNetDevice + * + * This is the constructor for the CsmaCdNetDevice. It takes as a + * parameter the Node to which this device is connected. Ownership of the + * Node pointer is not implied and the node must not be deleted. + * + * \param node the Node to which this device is connected. + * \param addr The source MAC address of the net device. + */ + CsmaCdNetDevice (Ptr node, MacAddress addr, CsmaCdEncapsulationMode pktType); + CsmaCdNetDevice (Ptr node, MacAddress addr, + CsmaCdEncapsulationMode pktType, + bool sendEnable, bool receiveEnable); + /** + * Copy Construct a CsmaCdNetDevice + * + * This is the copy constructor for the CsmaCdNetDevice. This is + * primarily used in topology creation. + * + * \param nd the object to be copied + */ + CsmaCdNetDevice (const CsmaCdNetDevice& nd); + /** + * Destroy a CsmaCdNetDevice + * + * This is the destructor for the CsmaCdNetDevice. + */ + virtual ~CsmaCdNetDevice(); + /** + * Assignment Operator for a CsmaCdNetDevice + * + * This is the assignment operator for the CsmaCdNetDevice. This is + * to allow + * + * \param nd the object to be copied + */ + // CsmaCdNetDevice& operator= (CsmaCdNetDevice nd); + /** + * Set the Data Rate used for transmission of packets. The data rate is + * set in the Attach () method from the corresponding field in the channel + * to which the device is attached. It can be overridden using this method. + * + * @see Attach () + * \param bps the data rate at which this object operates + */ + void SetDataRate (DataRate bps); + /** + * Set the inteframe gap used to separate packets. The interframe gap + * defines the minimum space required between packets sent by this device. + * It is usually set in the Attach () method based on the speed of light + * delay of the channel to which the device is attached. It can be + * overridden using this method if desired. + * + * @see Attach () + * \param t the interframe gap time + */ + void SetInterframeGap (Time t); + /** + * Set the backoff parameters used to determine the wait to retry + * transmitting a packet when the channel is busy. + * + * @see Attach () + * \param slotTime Length of a packet slot (or average packet time) + * \param minSlots Minimum number of slots to wait + * \param maxSlots Maximum number of slots to wait + * \param maxRetries Maximum number of retries before packet is discard + * \param ceiling Cap on the exponential function when calculating max slots + */ + void SetBackoffParams (Time slotTime, uint32_t minSlots, uint32_t maxSlots, + uint32_t maxRetries, uint32_t ceiling); + /** + * Attach the device to a channel. + * + * The function Attach is used to add a CsmaCdNetDevice to a + * CsmaCdChannel. + * + * @see SetDataRate () + * @see SetInterframeGap () + * \param ch a pointer to the channel to which this object is being attached. + */ + bool Attach (Ptr ch); + /** + * Attach a queue to the CsmaCdNetDevice. + * + * The CsmaCdNetDevice "owns" a queue. This queue is created by the + * CsmaCdTopology object and implements a queueing method such as + * DropTail or RED. The CsmaCdNetDevice assumes ownership of this + * queue and must delete it when the device is destroyed. + * + * @see CsmaCdTopology::AddCsmaCdLink () + * @see Queue + * @see DropTailQueue + * \param queue a pointer to the queue for which object is assuming + * ownership. + */ + void AddQueue (Ptr queue); + /** + * Receive a packet from a connected CsmaCdChannel. + * + * The CsmaCdNetDevice receives packets from its connected channel + * and forwards them up the protocol stack. This is the public method + * used by the channel to indicate that the last bit of a packet has + * arrived at the device. + * + * @see CsmaCdChannel + * \param p a reference to the received packet + */ + void Receive (Packet& p); + + bool IsSendEnabled (void); + bool IsReceiveEnabled (void); + + void SetSendEnable (bool); + void SetReceiveEnable (bool); + +protected: + virtual bool DoNeedsArp (void) const; + virtual void DoDispose (void); + /** + * Get a copy of the attached Queue. + * + * This method is provided for any derived class that may need to get + * direct access to the underlying queue. + * + * \return a pointer to the queue. + */ + Ptr GetQueue (void) const; + /** + * Get a copy of the attached Channel + * + * This method is provided for any derived class that may need to get + * direct access to the connected channel + * + * \return a pointer to the channel + */ + virtual Ptr DoGetChannel (void) const; + /** + * Adds the necessary headers and trailers to a packet of data in order to + * respect the packet type + * + * \param p Packet to which header should be added + * \param dest MAC destination address to which packet should be sent + * \param protocolNumber In some protocols, identifies the type of + * payload contained in this packet. + */ + void AddHeader (Packet& p, const MacAddress& dest, + uint16_t protocolNumber); + /** + * Removes, from a packet of data, all headers and trailers that + * relate to the packet type + * + * \param p Packet whose headers need to be processed + * \param param An integer parameter that can be set by the function + * to return information gathered in the header + * \return Returns true if the packet should be forwarded up the + * protocol stack. + */ + bool ProcessHeader (Packet& p, int& param); + +private: + /** + * Initializes variablea when construction object. + */ + void Init (bool sendEnable, bool receiveEnable); + /** + * Send a Packet on the Csma/Cd network + * + * This method does not use a destination address since all packets + * are broadcast to all NetDevices attached to the channel. Packet + * should contain all needed headers at this time. + * + * If the device is ready to transmit, the next packet is read off + * of the queue and stored locally until it has been transmitted. + * + * \param p a reference to the packet to send + * \param dest destination address + * \param protocolNumber -- this parameter is not used here + * \return true if success, false on failure + */ + virtual bool SendTo (Packet& p, const MacAddress& dest, uint16_t protocolNumber); + + /** + * Start Sending a Packet Down the Wire. + * + * The TransmitStart method is the method that is used internally in + * the CsmaCdNetDevice to begin the process of sending a packet + * out on the channel. The corresponding method is called on the + * channel to let it know that the physical device this class + * represents has virually started sending signals, this causes the + * channel to become busy. An event is scheduled for the time at + * which the bits have been completely transmitted. If the channel + * is busy, the method reschedules itself for a later time (within + * the backoff period) + * + * @see CsmaCdChannel::TransmitStart () + * @see TransmitCompleteEvent () + */ + void TransmitStart (); + /** + * Stop Sending a Packet Down the Wire and Begin the Interframe Gap. + * + * The TransmitCompleteEvent method is used internally to finish the process + * of sending a packet out on the channel. During execution of this method + * the TransmitEnd method is called on the channel to let it know that the + * physical device this class represents has virually finished sending + * signals. The channel uses this event to begin its speed of light delay + * timer after which it notifies the Net Device at the other end of the + * link that the bits have arrived. During this method, the net device + * also schedules the TransmitReadyEvent at which time the transmitter + * becomes ready to send the next packet. + * + * @see CsmaCdChannel::TransmitEnd () + * @see TransmitReadyEvent () + */ + void TransmitCompleteEvent (void); + /** + * Cause the Transmitter to Become Ready to Send Another Packet. + * + * The TransmitReadyEvent method is used internally to re-enable the + * transmit machine of the net device. It is scheduled after a suitable + * interframe gap after the completion of the previous transmission. + * The queue is checked at this time, and if there is a packet waiting on + * the queue, the transmission process is begun. + * + * If a packet is in the queue, it is extracted for the queue as the + * next packet to be transmitted by the net device. + * + * @see TransmitStart () + */ + void TransmitReadyEvent (void); + /** + * Create a Trace Resolver for events in the net device. + * (NOT TESTED) + * @see class TraceResolver + */ + virtual TraceResolver *DoCreateTraceResolver (TraceContext const &context); + + /** + * Aborts the transmission of the current packet + * + * If the net device has tried to transmit a packet for more times + * than the maximum allowed number of retries (channel always busy) + * then the packet is dropped. + * + */ + void TransmitAbort (void); + + /** + * Device ID returned by the attached functions. It is used by the + * mp-channel to identify each net device to make sure that only + * active net devices are writing to the channel + */ + uint32_t m_deviceId; + + /** + * Enable net device to send packets. True by default + */ + bool m_sendEnable; + /** + * Enable net device to receive packets. True by default + */ + bool m_receiveEnable; + /** + * Enumeration of the states of the transmit machine of the net device. + */ + enum TxMachineState + { + READY, /**< The transmitter is ready to begin transmission of a packet */ + BUSY, /**< The transmitter is busy transmitting a packet */ + GAP, /**< The transmitter is in the interframe gap time */ + BACKOFF /**< The transmitter is waiting for the channel to be free */ + }; + /** + * The state of the Net Device transmit state machine. + * @see TxMachineState + */ + TxMachineState m_txMachineState; + + /** + * The type of packet that should be created by the AddHeader + * function and that should be processed by the ProcessHeader + * function. + */ + CsmaCdEncapsulationMode m_pktType; + /** + * The data rate that the Net Device uses to simulate packet transmission + * timing. + * @see class DataRate + */ + DataRate m_bps; + /** + * The interframe gap that the Net Device uses to throttle packet + * transmission + * @see class Time + */ + Time m_tInterframeGap; + /** + * Holds the backoff parameters and is used to calculate the next + * backoff time to use when the channel is busy and the net device + * is ready to transmit + */ + Backoff m_backoff; + /** + * Next packet that will be transmitted (if transmitter is not + * currently transmitting) or packet that is currently being + * transmitted. + */ + Packet m_currentPkt; + /** + * The CsmaCdChannel to which this CsmaCdNetDevice has been + * attached. + * @see class CsmaCdChannel + */ + Ptr m_channel; + /** + * The Queue which this CsmaCdNetDevice uses as a packet source. + * Management of this Queue has been delegated to the CsmaCdNetDevice + * and it has the responsibility for deletion. + * @see class Queue + * @see class DropTailQueue + */ + Ptr m_queue; + /** + * NOT TESTED + * The trace source for the packet reception events that the device can + * fire. + * + * @see class CallBackTraceSource + * @see class TraceResolver + */ + CallbackTraceSource m_rxTrace; + CallbackTraceSource m_dropTrace; + +}; + +}; // namespace ns3 + +#endif // CSMA_CD_NET_DEVICE_H + diff --git a/src/devices/csma-cd/csma-cd-topology.cc b/src/devices/csma-cd/csma-cd-topology.cc new file mode 100644 index 000000000..e4af1a309 --- /dev/null +++ b/src/devices/csma-cd/csma-cd-topology.cc @@ -0,0 +1,103 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +// +// Copyright (c) 2007 Emmanuelle Laprise +// +// 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 +// + +// +// Topology helper for CsmaCd channels in ns3. + +#include "ns3/assert.h" +#include "ns3/debug.h" +#include "ns3/queue.h" + +#include "csma-cd-channel.h" +#include "csma-cd-net-device.h" +#include "csma-cd-topology.h" +#include "ns3/socket-factory.h" + +namespace ns3 { + +Ptr +CsmaCdTopology::CreateCsmaCdChannel( + const DataRate& bps, + const Time& delay) +{ + Ptr channel = Create (bps, delay); + + return channel; +} + +#if 0 +Ptr +CsmaCdTopology::AddCsmaCdEthernetNode( + Ptr n1, + Ptr ch, + MacAddress addr) +{ + Ptr nd1 = Create (n1, addr, + ns3::CsmaCdNetDevice::ETHERNET_V1); + + Ptr q = Queue::CreateDefault (); + nd1->AddQueue(q); + nd1->Attach (ch); + + return nd1; +} + +Ptr +CsmaCdTopology::ConnectPacketSocket(Ptr app, + Ptr ndSrc, + Ptr ndDest) +{ + Ptr socket = Create (); + socket->Bind(ndSrc); + socket->Connect(ndDest->GetAddress()); + app->Connect(socket); + + return socket; +} + +Ptr +CsmaCdTopology::ConnectPacketSocket(Ptr app, + Ptr ndSrc, + MacAddress macAddr) +{ + Ptr socket = Create (); + socket->Bind(ndSrc); + socket->Connect(macAddr); + app->Connect(socket); + + return socket; +} + +Ptr +CsmaCdTopology::CreatePacketSocket(Ptr n1, std::string iid_name) +{ + InterfaceId iid = InterfaceId::LookupByName (iid_name); + + Ptr socketFactory = + n1->QueryInterface (iid); + + Ptr socket = socketFactory->CreateSocket (); + + return socket; +} +#endif + +} // namespace ns3 + diff --git a/src/devices/csma-cd/csma-cd-topology.h b/src/devices/csma-cd/csma-cd-topology.h new file mode 100644 index 000000000..b89e0b522 --- /dev/null +++ b/src/devices/csma-cd/csma-cd-topology.h @@ -0,0 +1,128 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +// +// Copyright (c) 2007 Emmanuelle Laprise +// +// 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 +// +// Topology helper for multipoint channels in ns3. +// +#ifndef CSMA_CD_TOPOLOGY_H +#define CSMA_CD_TOPOLOGY_H + +#include "ns3/ptr.h" +#include "ns3/csma-cd-net-device.h" +#if 0 +#include "ns3/packet-socket.h" +#include "ns3/packet-socket-app.h" +#endif +#include "ns3/node.h" +#include "ns3/mac-address.h" + +// The topology class consists of only static methods thar are used to +// create the topology and data flows for an ns3 simulation + +namespace ns3 { + +class CsmaCdChannel; +class Node; +class DataRate; +class Queue; + +/** + * \brief A helper class to create CsmaCd Topologies + * + * CsmaCd topologies are created based on the + * ns3::CsmaCdNetDevice subclasses and ns3::CsmaCdChannel + * objects. This class uses the EthernetNetDevice and + * PacketSocket classes in order to create logical connections between + * net devices. The PacketSocket class generates the data and the + * EthernetNetDevice class creates ethernet packets from the + * data, filling in source and destination addresses. The + * EthernetNetDevice class filters received data packets + * according to its destination Mac addresses. + */ +class CsmaCdTopology { +public: + /** + * \param dataRate Maximum transmission link rate + * \param delay propagation delay between any two nodes + * \return Pointer to the created CsmaCdChannel + * + * Create a CsmaCdChannel. All nodes connected to a multipoint + * channels will receive all packets written to that channel + */ + static Ptr CreateCsmaCdChannel( + const DataRate& dataRate, const Time& delay); + +#if 0 + /** + * \param n1 Node to be attached to the multipoint channel + * \param ch CsmaCdChannel to which node n1 should be attached + * \param addr MacAddress that should be assigned to the + * EthernetNetDevice that will be added to the node. + * + * Add a multipoint node to a multipoint channel + */ + static Ptr AddCsmaCdEthernetNode(Ptr n1, + Ptr ch, + MacAddress addr); + + /** + * \param app Application that will be sending data to the agent + * \param ndSrc Net Device that will be sending the packets onto the + * network + * \param ndDest Net Device to which ndSrc will be sending the packets + * \return A pointer to the PacketSocket + * + * Creates an PacketSocket and configure it to send packets between + * two net devices + */ +static Ptr ConnectPacketSocket(Ptr app, + Ptr ndSrc, + Ptr ndDest); + + /** + * \param app Application that will be sending data to the agent + * \param ndSrc Net Device that will be sending the packets onto the + * network + * \param macAddr Mac destination address for the packets send by + * the ndSrc net device \return a Pointer to the created + * PacketSocket + * + * Creates an PacketSocket and configure it to send packets from a + * net device to a destination MacAddress + */ +static Ptr ConnectPacketSocket(Ptr app, + Ptr ndSrc, + MacAddress macAddr); + + /** + * \param n1 Node from which socketfactory should be tested. + * \param iid_name Interface identifier ("Packet", in this case) + * + * This is a test function to make sure that a socket can be created + * by using the socketfactory interface provided in the + * netdevicenode. + */ +static Ptr CreatePacketSocket(Ptr n1, + std::string iid_name); +#endif + +}; +} // namespace ns3 + +#endif + diff --git a/src/devices/csma-cd/wscript b/src/devices/csma-cd/wscript new file mode 100644 index 000000000..31497fd51 --- /dev/null +++ b/src/devices/csma-cd/wscript @@ -0,0 +1,24 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + + +def build(bld): + obj = bld.create_obj('cpp', 'shlib') + obj.name = 'ns3-csma-cd' + obj.target = obj.name + obj.uselib_local = ['ns3-node'] + obj.source = [ + 'backoff.cc', + 'csma-cd-net-device.cc', + 'csma-cd-channel.cc', + 'csma-cd-topology.cc', + 'csma-cd-ipv4-topology.cc', + ] + headers = bld.create_obj('ns3header') + headers.source = [ + 'backoff.h', + 'csma-cd-net-device.h', + 'csma-cd-channel.h', + 'csma-cd-topology.h', + 'csma-cd-ipv4-topology.h', + ] + diff --git a/src/wscript b/src/wscript index 1d20c24e4..32c7bdde0 100644 --- a/src/wscript +++ b/src/wscript @@ -16,6 +16,7 @@ all_modules = ( 'node', 'internet-node', 'devices/point-to-point', + 'devices/csma-cd', 'applications', 'mobility', ) From 230b3840ad8c352ca46abeecd002b1f23a5d4a76 Mon Sep 17 00:00:00 2001 From: Mathieu Lacage Date: Fri, 27 Jul 2007 21:39:58 +0200 Subject: [PATCH 7/7] cleanup simple example --- examples/simple-csma-cd.cc | 85 ++++++++++---------------------------- 1 file changed, 22 insertions(+), 63 deletions(-) diff --git a/examples/simple-csma-cd.cc b/examples/simple-csma-cd.cc index d5549af5b..d24f7c54b 100644 --- a/examples/simple-csma-cd.cc +++ b/examples/simple-csma-cd.cc @@ -12,30 +12,25 @@ * 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 - * - * ns-2 simple.tcl script (ported from ns-2) - * Originally authored by Steve McCanne, 12/19/1996 */ // Port of ns-2/tcl/ex/simple.tcl to ns-3 // // Network topology // -// n0 -// \ 5 Mb/s, 2ms -// \ 1.5Mb/s, 10ms -// n2 -------------------------n3 -// / -// / 5 Mb/s, 2ms -// n1 +// n0 +// | +// | +// n2---+----n3 +// | +// | +// n1 // -// - all links are p2p links with indicated one-way BW/delay -// - CBR/UDP flows from n0 to n3, and from n3 to n1 -// - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec. +// - CBR/UDP flows from n0 to n1, and from n3 to n0 // - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec. // (i.e., DataRate of 448,000 bps) // - DropTail queues -// - Tracing of queues and packet receptions to file "simple-p2p.tr" +// - Tracing of queues and packet receptions to file "simple-csma-cd.tr" #include #include @@ -88,8 +83,6 @@ int main (int argc, char *argv[]) DebugComponentEnable("PacketSocket"); #endif - Packet::EnableMetadata(); - // Set up some default values for the simulation. Use the Bind() // technique to tell the system what subclass of Queue to use, // and what the queue limit is @@ -115,53 +108,34 @@ int main (int argc, char *argv[]) DataRate(5000000), MilliSeconds(2)); CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0, - MacAddress("10:54:23:54:23:50")); + MacAddress("10:54:23:54:23:50")); CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0, - MacAddress("10:54:23:54:23:51")); + MacAddress("10:54:23:54:23:51")); CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0, - MacAddress("10:54:23:54:23:52")); + MacAddress("10:54:23:54:23:52")); CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0, - MacAddress("10:54:23:54:23:53")); + MacAddress("10:54:23:54:23:53")); // Later, we add IP addresses. CsmaCdIpv4Topology::AddIpv4Address ( - n0, 0, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); + n0, 1, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0")); CsmaCdIpv4Topology::AddIpv4Address ( - n0, 1, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); + n1, 1, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0")); CsmaCdIpv4Topology::AddIpv4Address ( - n1, 0, Ipv4Address("10.1.2.1"), Ipv4Mask("255.255.255.0")); - - CsmaCdIpv4Topology::AddIpv4Address ( - n1, 1, Ipv4Address("10.1.2.2"), Ipv4Mask("255.255.255.0")); - - CsmaCdIpv4Topology::AddIpv4Address ( - n2, 0, Ipv4Address("10.1.3.1"), Ipv4Mask("255.255.255.0")); + n2, 1, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0")); CsmaCdIpv4Topology::AddIpv4Address ( - n2, 1, Ipv4Address("10.1.3.2"), Ipv4Mask("255.255.255.0")); - - CsmaCdIpv4Topology::AddIpv4Address ( - n3, 0, Ipv4Address("10.1.4.1"), Ipv4Mask("255.255.255.0")); - - CsmaCdIpv4Topology::AddIpv4Address ( - n3, 1, Ipv4Address("10.1.4.2"), Ipv4Mask("255.255.255.0")); - - // Finally, we add static routes. These three steps (Channel and - // NetDevice creation, IP Address assignment, and routing) are - // separated because there may be a need to postpone IP Address - // assignment (emulation) or modify to use dynamic routing - CsmaCdIpv4Topology::AddIpv4Routes(n0->GetDevice(0), n2->GetDevice(1)); - CsmaCdIpv4Topology::AddIpv4Routes(n1->GetDevice(0), n2->GetDevice(1)); - CsmaCdIpv4Topology::AddIpv4Routes(n2->GetDevice(0), n3->GetDevice(1)); + n3, 1, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0")); // Create the OnOff application to send UDP datagrams of size // 210 bytes at a rate of 448 Kb/s + // from n0 to n1 Ptr ooff = Create ( n0, - Ipv4Address("10.1.3.2"), + Ipv4Address("10.1.1.2"), 80, "Udp", ConstantVariable(1), @@ -170,10 +144,10 @@ int main (int argc, char *argv[]) ooff->Start(Seconds(1.0)); ooff->Stop (Seconds(10.0)); - // Create a similar flow from n3 to n1, starting at time 1.1 seconds + // Create a similar flow from n3 to n0, starting at time 1.1 seconds ooff = Create ( n3, - Ipv4Address("10.1.2.1"), + Ipv4Address("10.1.1.1"), 80, "Udp", ConstantVariable(1), @@ -181,28 +155,13 @@ int main (int argc, char *argv[]) // Start the application ooff->Start(Seconds(1.1)); ooff->Stop (Seconds(10.0)); - - // Here, finish off packet routing configuration - // This will likely set by some global StaticRouting object in the future - Ptr ipv4; - ipv4 = n0->QueryInterface (Ipv4::iid); - ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1); - ipv4 = n3->QueryInterface (Ipv4::iid); - ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.1"), 1); - + // Configure tracing of all enqueue, dequeue, and NetDevice receive events // Trace output will be sent to the simple-p2p.tr file AsciiTrace asciitrace ("simple-csma-cd.tr"); asciitrace.TraceAllNetDeviceRx (); // asciitrace.TraceAllQueues (); - // Also configure some tcpdump traces; each interface will be traced - // The output files will be named simple-p2p.pcap-- - // and can be read by the "tcpdump -r" command (use "-tt" option to - // display timestamps correctly) - // PcapTrace pcaptrace ("simple-p2p.pcap"); - // pcaptrace.TraceAllIp (); - Simulator::Run (); Simulator::Destroy ();