--- a/RELEASE_NOTES Fri Jul 27 09:44:24 2007 +0200
+++ b/RELEASE_NOTES Mon Jul 30 10:35:03 2007 +0200
@@ -3,6 +3,13 @@
This file contains ns-3 release notes (most recent releases first).
+Release 3.0.5 (2007/08/XX)
+========================
+
+ - Add CSMA/CD model (Emmanuelle Laprise)
+ - Modularize ipv4 routing support (Gustavo Carneiro)
+ - Add mobility framework and basic mobility models
+
Release 3.0.4 (2007/07/15)
========================
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/csma-cd-one-subnet.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,171 @@
+/* -*- 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
+ */
+
+// Port of ns-2/tcl/ex/simple.tcl to ns-3
+//
+// Network topology
+//
+// n0 n1 n2 n3
+// | | | |
+// =====================
+//
+// - 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 "csma-cd-one-subnet.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#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/eui48-address.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/inet-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("CsmaCdNetDevice");
+ DebugComponentEnable("Ipv4L3Protocol");
+ DebugComponentEnable("NetDevice");
+ DebugComponentEnable("Channel");
+ DebugComponentEnable("CsmaCdChannel");
+ DebugComponentEnable("PacketSocket");
+#endif
+
+ // 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<Node> n0 = Create<InternetNode> ();
+ Ptr<Node> n1 = Create<InternetNode> ();
+ Ptr<Node> n2 = Create<InternetNode> ();
+ Ptr<Node> n3 = Create<InternetNode> ();
+
+ // We create the channels first without any IP addressing information
+ Ptr<CsmaCdChannel> channel0 =
+ CsmaCdTopology::CreateCsmaCdChannel(
+ DataRate(5000000), MilliSeconds(2));
+
+ uint32_t n0ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n0, channel0,
+ Eui48Address("10:54:23:54:23:50"));
+ uint32_t n1ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n1, channel0,
+ Eui48Address("10:54:23:54:23:51"));
+ uint32_t n2ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n2, channel0,
+ Eui48Address("10:54:23:54:23:52"));
+ uint32_t n3ifIndex = CsmaCdIpv4Topology::AddIpv4CsmaCdNode (n3, channel0,
+ Eui48Address("10:54:23:54:23:53"));
+
+ // Later, we add IP addresses.
+ CsmaCdIpv4Topology::AddIpv4Address (
+ n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
+
+ CsmaCdIpv4Topology::AddIpv4Address (
+ n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
+
+ CsmaCdIpv4Topology::AddIpv4Address (
+ n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
+
+ CsmaCdIpv4Topology::AddIpv4Address (
+ n3, n3ifIndex, 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<OnOffApplication> ooff = Create<OnOffApplication> (
+ n0,
+ InetAddress (Ipv4Address("10.1.1.2"), 80).ConvertTo (),
+ "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 n0, starting at time 1.1 seconds
+ ooff = Create<OnOffApplication> (
+ n3,
+ InetAddress (Ipv4Address("10.1.1.1"), 80).ConvertTo (),
+ "Udp",
+ ConstantVariable(1),
+ ConstantVariable(0));
+ // Start the application
+ ooff->Start(Seconds(1.1));
+ ooff->Stop (Seconds(10.0));
+
+ // Configure tracing of all enqueue, dequeue, and NetDevice receive events
+ // Trace output will be sent to the csma-cd-one-subnet.tr file
+ AsciiTrace asciitrace ("csma-cd-one-subnet.tr");
+ asciitrace.TraceAllNetDeviceRx ();
+ asciitrace.TraceAllQueues ();
+
+ // Also configure some tcpdump traces; each interface will be traced
+ // The output files will be named
+ // simple-point-to-point.pcap-<nodeId>-<interfaceId>
+ // and can be read by the "tcpdump -r" command (use "-tt" option to
+ // display timestamps correctly)
+ PcapTrace pcaptrace ("csma-cd-one-subnet.pcap");
+ pcaptrace.TraceAllIp ();
+
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/simple-point-to-point.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,191 @@
+/* -*- 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 point-to-point 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-point-to-point.tr"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <cassert>
+
+#include "ns3/command-line.h"
+#include "ns3/default-value.h"
+#include "ns3/ptr.h"
+#include "ns3/random-variable.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/point-to-point-channel.h"
+#include "ns3/point-to-point-net-device.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/inet-address.h"
+#include "ns3/ipv4.h"
+#include "ns3/socket.h"
+#include "ns3/ipv4-route.h"
+#include "ns3/point-to-point-topology.h"
+#include "ns3/onoff-application.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("Object");
+ DebugComponentEnable("Queue");
+ DebugComponentEnable("DropTailQueue");
+ DebugComponentEnable("Channel");
+ DebugComponentEnable("PointToPointChannel");
+ DebugComponentEnable("PointToPointNetDevice");
+#endif
+
+ // 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");
+
+ Bind ("OnOffApplicationPacketSize", "210");
+ Bind ("OnOffApplicationDataRate", "448kb/s");
+
+ //Bind ("DropTailQueue::m_maxPackets", 30);
+
+ // 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<Node> n0 = Create<InternetNode> ();
+ Ptr<Node> n1 = Create<InternetNode> ();
+ Ptr<Node> n2 = Create<InternetNode> ();
+ Ptr<Node> n3 = Create<InternetNode> ();
+
+ // We create the channels first without any IP addressing information
+ Ptr<PointToPointChannel> channel0 =
+ PointToPointTopology::AddPointToPointLink (
+ n0, n2, DataRate(5000000), MilliSeconds(2));
+
+ Ptr<PointToPointChannel> channel1 =
+ PointToPointTopology::AddPointToPointLink (
+ n1, n2, DataRate(5000000), MilliSeconds(2));
+
+ Ptr<PointToPointChannel> channel2 =
+ PointToPointTopology::AddPointToPointLink (
+ n2, n3, DataRate(1500000), MilliSeconds(10));
+
+ // Later, we add IP addresses.
+ PointToPointTopology::AddIpv4Addresses (
+ channel0, n0, Ipv4Address("10.1.1.1"),
+ n2, Ipv4Address("10.1.1.2"));
+
+ PointToPointTopology::AddIpv4Addresses (
+ channel1, n1, Ipv4Address("10.1.2.1"),
+ n2, Ipv4Address("10.1.2.2"));
+
+ PointToPointTopology::AddIpv4Addresses (
+ channel2, n2, Ipv4Address("10.1.3.1"),
+ n3, Ipv4Address("10.1.3.2"));
+
+ // 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
+ PointToPointTopology::AddIpv4Routes(n0, n2, channel0);
+ PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
+ PointToPointTopology::AddIpv4Routes(n2, n3, channel2);
+
+
+ // Create the OnOff application to send UDP datagrams of size
+ // 210 bytes at a rate of 448 Kb/s
+ Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
+ n0,
+ InetAddress (Ipv4Address("10.1.3.2"), 80).ConvertTo (),
+ "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<OnOffApplication> (
+ n3,
+ InetAddress (Ipv4Address("10.1.2.1"), 80).ConvertTo (),
+ "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;
+ ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
+ ipv4->SetDefaultRoute (Ipv4Address ("10.1.1.2"), 1);
+ ipv4 = n3->QueryInterface<Ipv4> (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-point-to-point.tr file
+ AsciiTrace asciitrace ("simple-point-to-point.tr");
+ asciitrace.TraceAllQueues ();
+ asciitrace.TraceAllNetDeviceRx ();
+
+ // Also configure some tcpdump traces; each interface will be traced
+ // The output files will be named
+ // simple-point-to-point.pcap-<nodeId>-<interfaceId>
+ // and can be read by the "tcpdump -r" command (use "-tt" option to
+ // display timestamps correctly)
+ PcapTrace pcaptrace ("simple-point-to-point.pcap");
+ pcaptrace.TraceAllIp ();
+
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+}
--- a/examples/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/examples/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -9,5 +9,6 @@
obj.source = source
return obj
- obj = create_ns_prog('simple-p2p', 'simple-p2p.cc', deps=['p2p', 'internet-node'])
+ obj = create_ns_prog('simple-point-to-point', 'simple-point-to-point.cc', deps=['point-to-point', 'internet-node'])
+ obj = create_ns_prog('csma-cd-one-subnet', 'csma-cd-one-subnet.cc', deps=['csma-cd', 'internet-node'])
--- a/samples/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/samples/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -18,9 +18,9 @@
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',
--- a/src/applications/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/applications/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -8,7 +8,6 @@
obj.source = [
'onoff-application.cc',
]
- obj.includes = '.'
headers = bld.create_obj('ns3header')
headers.source = [
--- a/src/common/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/common/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -24,7 +24,6 @@
'trace-root.cc',
'data-rate.cc',
]
- common.includes = '.'
headers = bld.create_obj('ns3header')
headers.source = [
--- a/src/core/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/core/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -39,7 +39,6 @@
'component-manager.cc',
'random-variable-default-value.cc',
]
- core.includes = '.'
if sys.platform == 'win32':
core.source.extend([
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/backoff.cc Mon Jul 30 10:35:03 2007 +0200
@@ -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 <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/backoff.h Mon Jul 30 10:35:03 2007 +0200
@@ -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 <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+Transmi */
+
+#ifndef BACKOFF_H
+#define BACKOFF_H
+
+#include <stdint.h>
+#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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-channel.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,371 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#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<CsmaCdNetDevice> 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<CsmaCdNetDevice> 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<CsmaCdNetDevice> device)
+{
+ NS_DEBUG("CsmaCdChannel::Reattach (" << device << ")");
+ NS_ASSERT(device != 0);
+
+ std::vector<CsmaCdDeviceRec>::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<CsmaCdNetDevice> device)
+{
+ NS_DEBUG("CsmaCdChannel::Detach (" << device << ")");
+ NS_ASSERT(device != 0);
+
+ std::vector<CsmaCdDeviceRec>::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<CsmaCdDeviceRec>::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<CsmaCdDeviceRec>::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<NetDevice>
+CsmaCdChannel::GetDevice (uint32_t i) const
+{
+ Ptr< CsmaCdNetDevice > netDevice;
+
+ netDevice = m_deviceList[i].devicePtr;
+ return netDevice;
+}
+
+int32_t
+CsmaCdChannel::GetDeviceNum (Ptr<CsmaCdNetDevice> device)
+{
+ std::vector<CsmaCdDeviceRec>::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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-channel.h Mon Jul 30 10:35:03 2007 +0200
@@ -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<emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#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<CsmaCdNetDevice> 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<CsmaCdNetDevice> 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<CsmaCdNetDevice> 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<CsmaCdNetDevice> 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<NetDevice> 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 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-ipv4-topology.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,156 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#include <algorithm>
+#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 {
+
+
+uint32_t
+CsmaCdIpv4Topology::AddIpv4CsmaCdNode(Ptr<Node> n1,
+ Ptr<CsmaCdChannel> ch,
+ Eui48Address addr)
+{
+ Ptr<Queue> q = Queue::CreateDefault ();
+
+ // assume full-duplex
+ Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
+ ns3::CsmaCdNetDevice::IP_ARP,
+ true, true);
+ nd0->AddQueue(q);
+ nd0->Attach (ch);
+ return nd0->GetIfIndex ();
+}
+
+
+void
+CsmaCdIpv4Topology::AddIpv4LlcCsmaCdNode(Ptr<Node> n1,
+ Ptr<CsmaCdChannel> ch,
+ Eui48Address addr)
+{
+ Ptr<Queue> q = Queue::CreateDefault ();
+
+ Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
+ ns3::CsmaCdNetDevice::LLC,
+ true, false);
+ nd0->AddQueue(q);
+ nd0->Attach (ch);
+
+ Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
+ ns3::CsmaCdNetDevice::LLC,
+ false, true);
+ nd1->AddQueue(q);
+ nd1->Attach (ch);
+}
+
+void
+CsmaCdIpv4Topology::AddIpv4RawCsmaCdNode(Ptr<Node> n1,
+ Ptr<CsmaCdChannel> ch,
+ Eui48Address addr)
+{
+ Ptr<Queue> q = Queue::CreateDefault ();
+
+ Ptr<CsmaCdNetDevice> nd0 = Create<CsmaCdNetDevice> (n1, addr,
+ ns3::CsmaCdNetDevice::RAW,
+ true, false);
+ nd0->AddQueue(q);
+ nd0->Attach (ch);
+
+ Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
+ ns3::CsmaCdNetDevice::RAW,
+ false, true);
+ nd1->AddQueue(q);
+ nd1->Attach (ch);
+}
+
+void
+CsmaCdIpv4Topology::AddIpv4Address(Ptr<Node> 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<NetDevice> nd1 = n1->GetDevice(ndNum);
+
+ Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
+ uint32_t index1 = ip1->AddInterface (nd1);
+
+ ip1->SetAddress (index1, addr1);
+ ip1->SetNetworkMask (index1, netmask);
+ ip1->SetUp (index1);
+
+}
+
+void
+CsmaCdIpv4Topology::AddIpv4Routes (
+ Ptr<NetDevice> nd1, Ptr<NetDevice> nd2)
+{
+ // Assert that both are Ipv4 nodes
+ Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+ Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-ipv4-topology.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,122 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca>
+//
+
+#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.
+ *
+ * \return ifIndex of the device
+ */
+ static uint32_t AddIpv4CsmaCdNode( Ptr<Node> n1,
+ Ptr<CsmaCdChannel> ch,
+ Eui48Address 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<Node> n1,
+ Ptr<CsmaCdChannel> ch,
+ Eui48Address 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<Node> n1,
+ Ptr<CsmaCdChannel> ch,
+ Eui48Address 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<Node> 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<NetDevice> nd1, Ptr<NetDevice> nd2);
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-net-device.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,494 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#include <iostream>
+#include <cassert>
+#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> node, Eui48Address addr,
+ CsmaCdEncapsulationMode encapMode)
+ : NetDevice(node, addr.ConvertTo ()),
+ m_bps (DataRate (0xffffffff))
+{
+ NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
+ m_encapMode = encapMode;
+
+ Init(true, true);
+}
+
+CsmaCdNetDevice::CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
+ CsmaCdEncapsulationMode encapMode,
+ bool sendEnable, bool receiveEnable)
+ : NetDevice(node, addr.ConvertTo ()),
+ m_bps (DataRate (0xffffffff))
+{
+ NS_DEBUG ("CsmaCdNetDevice::CsmaCdNetDevice (" << node << ")");
+ m_encapMode = encapMode;
+
+ Init(sendEnable, receiveEnable);
+}
+
+CsmaCdNetDevice::~CsmaCdNetDevice()
+{
+ NS_DEBUG ("CsmaCdNetDevice::~CsmaCdNetDevice ()");
+ m_queue = 0;
+}
+
+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 (Eui48Address ("ff:ff:ff:ff:ff:ff").ConvertTo ());
+ 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, Eui48Address dest,
+ uint16_t protocolNumber)
+{
+ if (m_encapMode == RAW)
+ {
+ return;
+ }
+ EthernetHeader header (false);
+ EthernetTrailer trailer;
+ Eui48Address source = Eui48Address::ConvertFrom (GetAddress ());
+ header.SetSource(source);
+ header.SetDestination(dest);
+
+ uint16_t lengthType = 0;
+ switch (m_encapMode)
+ {
+ case ETHERNET_V1:
+ lengthType = p.GetSize() + header.GetSize() + trailer.GetSize();
+ break;
+ case IP_ARP:
+ lengthType = protocolNumber;
+ break;
+ case LLC: {
+ LlcSnapHeader llc;
+ llc.SetType (protocolNumber);
+ p.AddHeader (llc);
+ } break;
+ case RAW:
+ NS_ASSERT (false);
+ break;
+ }
+ header.SetLengthType (lengthType);
+ p.AddHeader(header);
+ trailer.CalcFcs(p);
+ p.AddTrailer(trailer);
+}
+bool
+CsmaCdNetDevice::ProcessHeader (Packet& p, uint16_t & param)
+{
+ if (m_encapMode == RAW)
+ {
+ return true;
+ }
+ EthernetHeader header (false);
+ EthernetTrailer trailer;
+
+ p.RemoveTrailer(trailer);
+ trailer.CheckFcs(p);
+ p.RemoveHeader(header);
+
+ Eui48Address broadcast = Eui48Address::ConvertFrom (GetBroadcast ());
+ Eui48Address destination = Eui48Address::ConvertFrom (GetAddress ());
+ if ((header.GetDestination() != broadcast) &&
+ (header.GetDestination() != destination))
+ {
+ return false;
+ }
+
+ switch (m_encapMode)
+ {
+ case ETHERNET_V1:
+ case IP_ARP:
+ param = header.GetLengthType();
+ break;
+ case LLC: {
+ LlcSnapHeader llc;
+ p.RemoveHeader (llc);
+ param = llc.GetType ();
+ } break;
+ case RAW:
+ NS_ASSERT (false);
+ break;
+ }
+ return true;
+}
+
+bool
+CsmaCdNetDevice::DoNeedsArp (void) const
+{
+ if ((m_encapMode == IP_ARP) || (m_encapMode == LLC))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool
+CsmaCdNetDevice::SendTo (Packet& p, const Address& 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;
+
+ Eui48Address address = Eui48Address::ConvertFrom (dest);
+ AddHeader(p, address, 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<CsmaCdChannel> 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<Queue> 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;
+
+ uint16_t param = 0;
+ Packet packet = p;
+
+ if (ProcessHeader(packet, param))
+ {
+ m_rxTrace (packet);
+ ForwardUp (packet, param);
+ }
+ else
+ {
+ m_dropTrace (packet);
+ }
+}
+
+Ptr<Queue>
+CsmaCdNetDevice::GetQueue(void) const
+{
+ return m_queue;
+}
+
+Ptr<Channel>
+CsmaCdNetDevice::DoGetChannel(void) const
+{
+ return m_channel;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-net-device.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,410 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca
+ * Derived from the p2p net device file
+ */
+
+#ifndef CSMA_CD_NET_DEVICE_H
+#define CSMA_CD_NET_DEVICE_H
+
+#include <string.h>
+#include "ns3/node.h"
+#include "ns3/backoff.h"
+#include "ns3/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"
+#include "ns3/eui48-address.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> node, Eui48Address addr, CsmaCdEncapsulationMode pktType);
+ CsmaCdNetDevice (Ptr<Node> node, Eui48Address addr,
+ CsmaCdEncapsulationMode pktType,
+ bool sendEnable, bool receiveEnable);
+ /**
+ * Destroy a CsmaCdNetDevice
+ *
+ * This is the destructor for the CsmaCdNetDevice.
+ */
+ virtual ~CsmaCdNetDevice();
+ /**
+ * 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<CsmaCdChannel> 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> 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<Queue> 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<Channel> 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, Eui48Address 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, uint16_t & param);
+
+private:
+ // disable copy constructor and operator =
+ CsmaCdNetDevice &operator = (const CsmaCdNetDevice &o);
+ CsmaCdNetDevice (const CsmaCdNetDevice &o);
+ /**
+ * 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 Address& 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_encapMode;
+ /**
+ * 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<CsmaCdChannel> 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<Queue> m_queue;
+ /**
+ * NOT TESTED
+ * The trace source for the packet reception events that the device can
+ * fire.
+ *
+ * @see class CallBackTraceSource
+ * @see class TraceResolver
+ */
+ CallbackTraceSource<Packet &> m_rxTrace;
+ CallbackTraceSource<Packet &> m_dropTrace;
+
+};
+
+}; // namespace ns3
+
+#endif // CSMA_CD_NET_DEVICE_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-topology.cc Mon Jul 30 10:35:03 2007 +0200
@@ -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 <emmanuelle.laprise@bluekazoo.ca>
+//
+
+//
+// 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<CsmaCdChannel>
+CsmaCdTopology::CreateCsmaCdChannel(
+ const DataRate& bps,
+ const Time& delay)
+{
+ Ptr<CsmaCdChannel> channel = Create<CsmaCdChannel> (bps, delay);
+
+ return channel;
+}
+
+#if 0
+Ptr<CsmaCdNetDevice>
+CsmaCdTopology::AddCsmaCdEthernetNode(
+ Ptr<Node> n1,
+ Ptr<CsmaCdChannel> ch,
+ MacAddress addr)
+{
+ Ptr<CsmaCdNetDevice> nd1 = Create<CsmaCdNetDevice> (n1, addr,
+ ns3::CsmaCdNetDevice::ETHERNET_V1);
+
+ Ptr<Queue> q = Queue::CreateDefault ();
+ nd1->AddQueue(q);
+ nd1->Attach (ch);
+
+ return nd1;
+}
+
+Ptr<PacketSocket>
+CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaCdNetDevice> ndSrc,
+ Ptr<CsmaCdNetDevice> ndDest)
+{
+ Ptr<PacketSocket> socket = Create<PacketSocket> ();
+ socket->Bind(ndSrc);
+ socket->Connect(ndDest->GetAddress());
+ app->Connect(socket);
+
+ return socket;
+}
+
+Ptr<PacketSocket>
+CsmaCdTopology::ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaCdNetDevice> ndSrc,
+ MacAddress macAddr)
+{
+ Ptr<PacketSocket> socket = Create<PacketSocket> ();
+ socket->Bind(ndSrc);
+ socket->Connect(macAddr);
+ app->Connect(socket);
+
+ return socket;
+}
+
+Ptr<Socket>
+CsmaCdTopology::CreatePacketSocket(Ptr<Node> n1, std::string iid_name)
+{
+ InterfaceId iid = InterfaceId::LookupByName (iid_name);
+
+ Ptr<SocketFactory> socketFactory =
+ n1->QueryInterface<SocketFactory> (iid);
+
+ Ptr<Socket> socket = socketFactory->CreateSocket ();
+
+ return socket;
+}
+#endif
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/csma-cd-topology.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,123 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca>
+//
+// 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"
+#include "ns3/node.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<CsmaCdChannel> 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<CsmaCdNetDevice> AddCsmaCdEthernetNode(Ptr<Node> n1,
+ Ptr<CsmaCdChannel> 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<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaCdNetDevice> ndSrc,
+ Ptr<CsmaCdNetDevice> 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<PacketSocket> ConnectPacketSocket(Ptr<PacketSocketApp> app,
+ Ptr<CsmaCdNetDevice> 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<Socket> CreatePacketSocket(Ptr<Node> n1,
+ std::string iid_name);
+#endif
+
+};
+} // namespace ns3
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/csma-cd/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -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',
+ ]
+
--- a/src/devices/p2p/p2p-channel.cc Fri Jul 27 09:44:24 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 University of Washington
- * 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: Craig Dowell <craigdo@ee.washington.edu>
- */
-
-#include "p2p-channel.h"
-#include "p2p-net-device.h"
-#include "ns3/packet.h"
-#include "ns3/simulator.h"
-#include "ns3/debug.h"
-
-NS_DEBUG_COMPONENT_DEFINE ("PointToPointChannel");
-
-namespace ns3 {
-
-//
-// By default, you get a channel with the name "PointToPoint Channel" that
-// has an "infitely" fast transmission speed and zero delay.
-PointToPointChannel::PointToPointChannel()
-:
- Channel ("PointToPoint Channel"),
- m_bps (DataRate(0xffffffff)),
- m_delay (Seconds(0)),
- m_nDevices(0)
-{
- NS_DEBUG("PointToPointChannel::PointToPointChannel ()");
-}
-
-PointToPointChannel::PointToPointChannel(
- const DataRate& bps,
- const Time& delay)
-:
- Channel ("PointToPoint Channel"),
- m_bps (bps),
- m_delay (delay),
- m_nDevices(0)
-{
- NS_DEBUG("PointToPointChannel::PointToPointChannel (" << Channel::GetName()
- << ", " << bps.GetBitRate() << ", " << delay << ")");
-}
-
-PointToPointChannel::PointToPointChannel(
- const std::string& name,
- const DataRate& bps,
- const Time& delay)
-:
- Channel (name),
- m_bps (bps),
- m_delay (delay),
- m_nDevices(0)
-{
- NS_DEBUG("PointToPointChannel::PointToPointChannel (" << name << ", " <<
- bps.GetBitRate() << ", " << delay << ")");
-}
-
- void
-PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
-{
- NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
- NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
- NS_ASSERT(device != 0);
-
- m_link[m_nDevices++].m_src = device;
-//
-// If we have both devices connected to the channel, then finish introducing
-// the two halves and set the links to IDLE.
-//
- if (m_nDevices == N_DEVICES)
- {
- m_link[0].m_dst = m_link[1].m_src;
- m_link[1].m_dst = m_link[0].m_src;
- m_link[0].m_state = IDLE;
- m_link[1].m_state = IDLE;
- }
-}
-
-bool PointToPointChannel::TransmitStart(Packet& p,
- Ptr<PointToPointNetDevice> src,
- const Time& txTime)
-{
- NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src <<
- ")");
- NS_DEBUG ("PointToPointChannel::TransmitStart (): UID is " <<
- p.GetUid () << ")");
-
- NS_ASSERT(m_link[0].m_state != INITIALIZING);
- NS_ASSERT(m_link[1].m_state != INITIALIZING);
-
- uint32_t wire = src == m_link[0].m_src ? 0 : 1;
-
- // Here we schedule the packet receive event at the receiver,
- // which simplifies this model quite a bit. The channel just
- // adds the propagation delay time
- Simulator::Schedule (txTime + m_delay,
- &PointToPointNetDevice::Receive,
- m_link[wire].m_dst, p);
- return true;
-}
-
-uint32_t
-PointToPointChannel::GetNDevices (void) const
-{
- return m_nDevices;
-}
-
-Ptr<NetDevice>
-PointToPointChannel::GetDevice (uint32_t i) const
-{
- NS_ASSERT(i < 2);
- return m_link[i].m_src;
-}
-
-const DataRate&
-PointToPointChannel::GetDataRate (void)
-{
- return m_bps;
-}
-
-const Time&
-PointToPointChannel::GetDelay (void)
-{
- return m_delay;
-}
-
-
-} // namespace ns3
--- a/src/devices/p2p/p2p-channel.h Fri Jul 27 09:44:24 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2007 University of Washington
- *
- * 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
- */
-
-#ifndef POINT_TO_POINT_CHANNEL_H
-#define POINT_TO_POINT_CHANNEL_H
-
-#include <list>
-#include "ns3/channel.h"
-#include "ns3/ptr.h"
-#include "ns3/packet.h"
-#include "ns3/nstime.h"
-#include "ns3/data-rate.h"
-
-namespace ns3 {
-
-class PointToPointNetDevice;
-
-/**
- * \brief Simple Point To Point Channel.
- *
- * This class represents a very simple point to point channel. Think full
- * duplex RS-232 or RS-422 with null modem and no handshaking. There is no
- * multi-drop capability on this channel -- there can be a maximum of two
- * point-to-point net devices connected. Once we start talking about multi-
- * drop, or CSMA, or some other sharing mechanism, things begin getting
- * complicated quickly. Rather than invent some ad-hoc mechanism, we just
- * Keep It Simple everywhere.
- *
- * 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. Both directions use the same speed and delay time.
- *
- * There are two "wires" in the channel. The first device connected gets the
- * [0] wire to transmit on. The second device gets the [1] wire. There is a
- * state (IDLE, TRANSMITTING) associated with each wire.
- */
-class PointToPointChannel : public Channel {
-public:
-// Each point to point link has exactly two net devices
- static const int N_DEVICES = 2;
- /**
- * \brief Create a PointToPointChannel
- *
- * By default, you get a channel with the name "PointToPoint Channel" that
- * has an "infitely" fast transmission speed and zero delay.
- */
- PointToPointChannel ();
-
- /**
- * \brief Create a PointToPointChannel
- *
- * \param bps The maximum bitrate of the channel
- * \param delay Transmission delay through the channel
- */
- PointToPointChannel (const DataRate& bps, const Time& delay);
-
- /**
- * \brief Create a PointToPointChannel
- *
- * \param name the name of the channel for identification purposes
- * \param bps The maximum bitrate of the channel
- * \param delay Transmission delay through the channel
- */
- PointToPointChannel (const std::string& name,
- const DataRate& bps, const Time& delay);
-
- /**
- * \brief Attach a given netdevice to this channel
- * \param device pointer to the netdevice to attach to the channel
- */
- void Attach (Ptr<PointToPointNetDevice> device);
- bool TransmitStart (Packet& p, Ptr<PointToPointNetDevice> src,
- const Time& txTime);
- // Below two not needed
- //bool TransmitEnd (Packet &p, Ptr<PointToPointNetDevice> src);
- //void PropagationCompleteEvent(Packet p, Ptr<PointToPointNetDevice> src);
-
-
- virtual uint32_t GetNDevices (void) const;
- virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
- virtual const DataRate& GetDataRate (void);
- virtual const Time& GetDelay (void);
-
-private:
- DataRate m_bps;
- Time m_delay;
- int32_t m_nDevices;
-
- enum WireState
- {
- INITIALIZING,
- IDLE,
- TRANSMITTING,
- PROPAGATING
- };
-
- class Link
- {
- public:
- Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
- WireState m_state;
- Ptr<PointToPointNetDevice> m_src;
- Ptr<PointToPointNetDevice> m_dst;
- };
-
- Link m_link[N_DEVICES];
-};
-
-} // namespace ns3
-
-#endif /* POINT_TO_POINT_CHANNEL_H */
--- a/src/devices/p2p/p2p-topology.cc Fri Jul 27 09:44:24 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-
-//
-// Topology helper for ns3.
-// George F. Riley, Georgia Tech, Spring 2007
-
-#include <algorithm>
-#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 "p2p-channel.h"
-#include "p2p-net-device.h"
-#include "p2p-topology.h"
-
-namespace ns3 {
-
-Ptr<PointToPointChannel>
-PointToPointTopology::AddPointToPointLink(
- Ptr<Node> n1,
- Ptr<Node> n2,
- const DataRate& bps,
- const Time& delay)
-{
- Ptr<PointToPointChannel> channel = Create<PointToPointChannel> (bps, delay);
-
- Ptr<PointToPointNetDevice> net1 = Create<PointToPointNetDevice> (n1);
-
- Ptr<Queue> q = Queue::CreateDefault ();
- net1->AddQueue(q);
- net1->Attach (channel);
-
- Ptr<PointToPointNetDevice> net2 = Create<PointToPointNetDevice> (n2);
-
- q = Queue::CreateDefault ();
- net2->AddQueue(q);
- net2->Attach (channel);
-
- return channel;
-}
-
-void
-PointToPointTopology::AddIpv4Addresses(
- Ptr<const PointToPointChannel> chan,
- Ptr<Node> n1, const Ipv4Address& addr1,
- Ptr<Node> n2, const Ipv4Address& addr2)
-{
-
- // Duplex link is assumed to be subnetted as a /30
- // May run this unnumbered in the future?
- Ipv4Mask netmask("255.255.255.252");
- NS_ASSERT (netmask.IsMatch(addr1,addr2));
-
- // The PointToPoint channel is used to find the relevant NetDevices
- NS_ASSERT (chan->GetNDevices () == 2);
- Ptr<NetDevice> nd1 = chan->GetDevice (0);
- Ptr<NetDevice> nd2 = chan->GetDevice (1);
- // Make sure that nd1 belongs to n1 and nd2 to n2
- if ( (nd1->GetNode ()->GetId () == n2->GetId () ) &&
- (nd2->GetNode ()->GetId () == n1->GetId () ) )
- {
- std::swap(nd1, nd2);
- }
- NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
- NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
-
- Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
- uint32_t index1 = ip1->AddInterface (nd1);
-
- ip1->SetAddress (index1, addr1);
- ip1->SetNetworkMask (index1, netmask);
- ip1->SetUp (index1);
-
- Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
- uint32_t index2 = ip2->AddInterface (nd2);
-
- ip2->SetAddress (index2, addr2);
- ip2->SetNetworkMask (index2, netmask);
- ip2->SetUp (index2);
-
-}
-
-void
-PointToPointTopology::AddIpv4Routes (
- Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
-{
- // The PointToPoint channel is used to find the relevant NetDevices
- NS_ASSERT (chan->GetNDevices () == 2);
- Ptr<NetDevice> nd1 = chan->GetDevice (0);
- Ptr<NetDevice> nd2 = chan->GetDevice (1);
-
- // Assert that n1 is the Node owning one of the two NetDevices
- // and make sure that nd1 corresponds to it
- if (nd1->GetNode ()->GetId () == n1->GetId ())
- {
- ; // Do nothing
- }
- else if (nd2->GetNode ()->GetId () == n1->GetId ())
- {
- std::swap(nd1, nd2);
- }
- else
- {
- NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
- }
-
- // Assert that n2 is the Node owning one of the two NetDevices
- // and make sure that nd2 corresponds to it
- if (nd2->GetNode ()->GetId () != n2->GetId ())
- {
- NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
- }
-
- // Assert that both are Ipv4 nodes
- Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
- Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (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
-
--- a/src/devices/p2p/p2p-topology.h Fri Jul 27 09:44:24 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-//
-// Copyright (c) 2006 Georgia Tech Research Corporation
-//
-// 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: George F. Riley<riley@ece.gatech.edu>
-//
-// Topology helper for ns3.
-// George F. Riley, Georgia Tech, Spring 2007
-#ifndef __POINT_TO_POINT_TOPOLOGY_H__
-#define __POINT_TO_POINT_TOPOLOGY_H__
-
-#include "ns3/ptr.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 PointToPointChannel;
-class Node;
-class IPAddr;
-class DataRate;
-class Queue;
-
-/**
- * \brief A helper class to create Topologies based on the
- * ns3::PointToPointNetDevice and ns3::PointToPointChannel objects.
- */
-class PointToPointTopology {
-public:
- /**
- * \param n1 Node
- * \param n2 Node
- * \param dataRate Maximum transmission link rate
- * \param delay one-way propagation delay
- * \return Pointer to the underlying PointToPointChannel
- *
- * Add a full-duplex point-to-point link between two nodes
- * and attach PointToPointNetDevices to the resulting
- * PointToPointChannel.
- */
- static Ptr<PointToPointChannel> AddPointToPointLink(
- Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
-
- /**
- * \param chan PointToPointChannel to use
- * \param n1 Node
- * \param addr1 Ipv4 Address for n1
- * \param n2 Node
- * \param addr2 Ipv4 Address for n2
- *
- * Add Ipv4Addresses to the Ipv4 interfaces associated with the
- * two PointToPointNetDevices on the provided PointToPointChannel
- */
- static void AddIpv4Addresses(
- Ptr<const PointToPointChannel> chan,
- Ptr<Node> n1, const Ipv4Address& addr1,
- Ptr<Node> n2, const Ipv4Address& addr2);
-
- /**
- * \param channel PointToPointChannel to use
- * \param n1 Node
- * \param n2 Node
- *
- * For the given PointToPointChannel, for each Node, add an
- * IPv4 host route to the IPv4 address of the peer node.
- */
- static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
-};
-
-} // namespace ns3
-
-#endif
-
--- a/src/devices/p2p/wscript Fri Jul 27 09:44:24 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
-
-def build(bld):
- p2p = bld.create_obj('cpp', 'shlib')
- p2p.name = 'ns3-p2p'
- p2p.target = p2p.name
- p2p.uselib_local = ['ns3-node']
- p2p.source = [
- 'p2p-net-device.cc',
- 'p2p-channel.cc',
- 'p2p-topology.cc',
- ]
- p2p.includes = '.'
-
- headers = bld.create_obj('ns3header')
- headers.source = [
- 'p2p-net-device.h',
- 'p2p-channel.h',
- 'p2p-topology.h',
- ]
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-channel.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,142 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 University of Washington
+ * 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: Craig Dowell <craigdo@ee.washington.edu>
+ */
+
+#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"
+
+NS_DEBUG_COMPONENT_DEFINE ("PointToPointChannel");
+
+namespace ns3 {
+
+//
+// By default, you get a channel with the name "PointToPoint Channel" that
+// has an "infitely" fast transmission speed and zero delay.
+PointToPointChannel::PointToPointChannel()
+:
+ Channel ("PointToPoint Channel"),
+ m_bps (DataRate(0xffffffff)),
+ m_delay (Seconds(0)),
+ m_nDevices(0)
+{
+ NS_DEBUG("PointToPointChannel::PointToPointChannel ()");
+}
+
+PointToPointChannel::PointToPointChannel(
+ const DataRate& bps,
+ const Time& delay)
+:
+ Channel ("PointToPoint Channel"),
+ m_bps (bps),
+ m_delay (delay),
+ m_nDevices(0)
+{
+ NS_DEBUG("PointToPointChannel::PointToPointChannel (" << Channel::GetName()
+ << ", " << bps.GetBitRate() << ", " << delay << ")");
+}
+
+PointToPointChannel::PointToPointChannel(
+ const std::string& name,
+ const DataRate& bps,
+ const Time& delay)
+:
+ Channel (name),
+ m_bps (bps),
+ m_delay (delay),
+ m_nDevices(0)
+{
+ NS_DEBUG("PointToPointChannel::PointToPointChannel (" << name << ", " <<
+ bps.GetBitRate() << ", " << delay << ")");
+}
+
+ void
+PointToPointChannel::Attach(Ptr<PointToPointNetDevice> device)
+{
+ NS_DEBUG("PointToPointChannel::Attach (" << device << ")");
+ NS_ASSERT(m_nDevices < N_DEVICES && "Only two devices permitted");
+ NS_ASSERT(device != 0);
+
+ m_link[m_nDevices++].m_src = device;
+//
+// If we have both devices connected to the channel, then finish introducing
+// the two halves and set the links to IDLE.
+//
+ if (m_nDevices == N_DEVICES)
+ {
+ m_link[0].m_dst = m_link[1].m_src;
+ m_link[1].m_dst = m_link[0].m_src;
+ m_link[0].m_state = IDLE;
+ m_link[1].m_state = IDLE;
+ }
+}
+
+bool PointToPointChannel::TransmitStart(Packet& p,
+ Ptr<PointToPointNetDevice> src,
+ const Time& txTime)
+{
+ NS_DEBUG ("PointToPointChannel::TransmitStart (" << &p << ", " << src <<
+ ")");
+ NS_DEBUG ("PointToPointChannel::TransmitStart (): UID is " <<
+ p.GetUid () << ")");
+
+ NS_ASSERT(m_link[0].m_state != INITIALIZING);
+ NS_ASSERT(m_link[1].m_state != INITIALIZING);
+
+ uint32_t wire = src == m_link[0].m_src ? 0 : 1;
+
+ // Here we schedule the packet receive event at the receiver,
+ // which simplifies this model quite a bit. The channel just
+ // adds the propagation delay time
+ Simulator::Schedule (txTime + m_delay,
+ &PointToPointNetDevice::Receive,
+ m_link[wire].m_dst, p);
+ return true;
+}
+
+uint32_t
+PointToPointChannel::GetNDevices (void) const
+{
+ return m_nDevices;
+}
+
+Ptr<NetDevice>
+PointToPointChannel::GetDevice (uint32_t i) const
+{
+ NS_ASSERT(i < 2);
+ return m_link[i].m_src;
+}
+
+const DataRate&
+PointToPointChannel::GetDataRate (void)
+{
+ return m_bps;
+}
+
+const Time&
+PointToPointChannel::GetDelay (void)
+{
+ return m_delay;
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-channel.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 University of Washington
+ *
+ * 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
+ */
+
+#ifndef POINT_TO_POINT_CHANNEL_H
+#define POINT_TO_POINT_CHANNEL_H
+
+#include <list>
+#include "ns3/channel.h"
+#include "ns3/ptr.h"
+#include "ns3/packet.h"
+#include "ns3/nstime.h"
+#include "ns3/data-rate.h"
+
+namespace ns3 {
+
+class PointToPointNetDevice;
+
+/**
+ * \brief Simple Point To Point Channel.
+ *
+ * This class represents a very simple point to point channel. Think full
+ * duplex RS-232 or RS-422 with null modem and no handshaking. There is no
+ * multi-drop capability on this channel -- there can be a maximum of two
+ * point-to-point net devices connected. Once we start talking about multi-
+ * drop, or CSMA, or some other sharing mechanism, things begin getting
+ * complicated quickly. Rather than invent some ad-hoc mechanism, we just
+ * Keep It Simple everywhere.
+ *
+ * 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. Both directions use the same speed and delay time.
+ *
+ * There are two "wires" in the channel. The first device connected gets the
+ * [0] wire to transmit on. The second device gets the [1] wire. There is a
+ * state (IDLE, TRANSMITTING) associated with each wire.
+ */
+class PointToPointChannel : public Channel {
+public:
+// Each point to point link has exactly two net devices
+ static const int N_DEVICES = 2;
+ /**
+ * \brief Create a PointToPointChannel
+ *
+ * By default, you get a channel with the name "PointToPoint Channel" that
+ * has an "infitely" fast transmission speed and zero delay.
+ */
+ PointToPointChannel ();
+
+ /**
+ * \brief Create a PointToPointChannel
+ *
+ * \param bps The maximum bitrate of the channel
+ * \param delay Transmission delay through the channel
+ */
+ PointToPointChannel (const DataRate& bps, const Time& delay);
+
+ /**
+ * \brief Create a PointToPointChannel
+ *
+ * \param name the name of the channel for identification purposes
+ * \param bps The maximum bitrate of the channel
+ * \param delay Transmission delay through the channel
+ */
+ PointToPointChannel (const std::string& name,
+ const DataRate& bps, const Time& delay);
+
+ /**
+ * \brief Attach a given netdevice to this channel
+ * \param device pointer to the netdevice to attach to the channel
+ */
+ void Attach (Ptr<PointToPointNetDevice> device);
+ bool TransmitStart (Packet& p, Ptr<PointToPointNetDevice> src,
+ const Time& txTime);
+ // Below two not needed
+ //bool TransmitEnd (Packet &p, Ptr<PointToPointNetDevice> src);
+ //void PropagationCompleteEvent(Packet p, Ptr<PointToPointNetDevice> src);
+
+
+ virtual uint32_t GetNDevices (void) const;
+ virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+ virtual const DataRate& GetDataRate (void);
+ virtual const Time& GetDelay (void);
+
+private:
+ DataRate m_bps;
+ Time m_delay;
+ int32_t m_nDevices;
+
+ enum WireState
+ {
+ INITIALIZING,
+ IDLE,
+ TRANSMITTING,
+ PROPAGATING
+ };
+
+ class Link
+ {
+ public:
+ Link() : m_state (INITIALIZING), m_src (0), m_dst (0) {}
+ WireState m_state;
+ Ptr<PointToPointNetDevice> m_src;
+ Ptr<PointToPointNetDevice> m_dst;
+ };
+
+ Link m_link[N_DEVICES];
+};
+
+} // namespace ns3
+
+#endif /* POINT_TO_POINT_CHANNEL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-net-device.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,246 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2005,2006 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: Craig Dowell <craigdo@ee.washington.edu>
+ * Revised: George Riley <riley@ece.gatech.edu>
+ */
+
+#include <iostream>
+#include <cassert>
+#include "ns3/debug.h"
+#include "ns3/queue.h"
+#include "ns3/simulator.h"
+#include "ns3/composite-trace-resolver.h"
+#include "ns3/eui48-address.h"
+#include "ns3/llc-snap-header.h"
+#include "point-to-point-net-device.h"
+#include "point-to-point-channel.h"
+
+NS_DEBUG_COMPONENT_DEFINE ("PointToPointNetDevice");
+
+namespace ns3 {
+
+DataRateDefaultValue PointToPointNetDevice::g_defaultRate(
+ "PointToPointLinkDataRate",
+ "The default data rate for point to point links",
+ DataRate ("10Mb/s"));
+
+PointToPointNetDevice::PointToPointNetDevice (Ptr<Node> node,
+ const DataRate& rate)
+:
+ NetDevice(node, Eui48Address::Allocate ().ConvertTo ()),
+ m_txMachineState (READY),
+ m_bps (rate),
+ m_tInterframeGap (Seconds(0)),
+ m_channel (0),
+ m_queue (0),
+ m_rxTrace ()
+{
+ NS_DEBUG ("PointToPointNetDevice::PointToPointNetDevice (" << node << ")");
+
+ // BUGBUG FIXME
+ //
+ // You _must_ support broadcast to get any sort of packet from the ARP layer.
+ EnableBroadcast (Eui48Address ("ff:ff:ff:ff:ff:ff").ConvertTo ());
+ EnableMulticast();
+ EnablePointToPoint();
+}
+
+PointToPointNetDevice::~PointToPointNetDevice()
+{
+ NS_DEBUG ("PointToPointNetDevice::~PointToPointNetDevice ()");
+ m_queue = 0;
+}
+
+void
+PointToPointNetDevice::AddHeader(Packet& p, uint16_t protocolNumber)
+{
+ LlcSnapHeader llc;
+ llc.SetType (protocolNumber);
+ p.AddHeader (llc);
+}
+
+bool
+PointToPointNetDevice::ProcessHeader(Packet& p, uint16_t& 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;
+}
+
+void PointToPointNetDevice::SetInterframeGap(const Time& t)
+{
+ m_tInterframeGap = t;
+}
+
+bool PointToPointNetDevice::SendTo (Packet& p, const Address& dest,
+ uint16_t protocolNumber)
+{
+ NS_DEBUG ("PointToPointNetDevice::SendTo (" << &p << ", " << &dest << ")");
+ NS_DEBUG ("PointToPointNetDevice::SendTo (): UID is " << p.GetUid () << ")");
+
+ // GFR Comment. Why is this an assertion? Can't a link legitimately
+ // "go down" during the simulation? Shouldn't we just wait for it
+ // to come back up?
+ NS_ASSERT (IsLinkUp ());
+ AddHeader(p, protocolNumber);
+
+//
+// This class simulates a point to point device. In the case of a serial
+// link, this means that we're simulating something like a UART.
+//
+//
+// If there's a transmission in progress, we enque the packet for later
+// trnsmission; otherwise we send it now.
+ if (m_txMachineState == READY)
+ {
+ return TransmitStart (p);
+ }
+ else
+ {
+ return m_queue->Enqueue(p);
+ }
+}
+
+ bool
+PointToPointNetDevice::TransmitStart (Packet &p)
+{
+ NS_DEBUG ("PointToPointNetDevice::TransmitStart (" << &p << ")");
+ NS_DEBUG (
+ "PointToPointNetDevice::TransmitStart (): UID is " << p.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 the transmission is complete.
+//
+ NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
+ m_txMachineState = BUSY;
+ Time txTime = Seconds (m_bps.CalculateTxTime(p.GetSize()));
+ Time txCompleteTime = txTime + m_tInterframeGap;
+
+ NS_DEBUG ("PointToPointNetDevice::TransmitStart (): " <<
+ "Schedule TransmitCompleteEvent in " <<
+ txCompleteTime.GetSeconds () << "sec");
+ // Schedule the tx complete event
+ Simulator::Schedule (txCompleteTime,
+ &PointToPointNetDevice::TransmitComplete,
+ this);
+ return m_channel->TransmitStart(p, this, txTime);
+}
+
+void PointToPointNetDevice::TransmitComplete (void)
+{
+ NS_DEBUG ("PointToPointNetDevice::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
+// get the next packet from the queue. If the queue is empty, we are
+// done, otherwise transmit the next packet.
+//
+ NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
+ m_txMachineState = READY;
+ Packet p;
+ if (!m_queue->Dequeue(p)) return; // Nothing to do at this point
+ TransmitStart(p);
+}
+
+TraceResolver* PointToPointNetDevice::DoCreateTraceResolver (
+ TraceContext const &context)
+{
+ CompositeTraceResolver *resolver = new CompositeTraceResolver (context);
+ resolver->Add ("queue",
+ MakeCallback (&Queue::CreateTraceResolver, PeekPointer (m_queue)),
+ PointToPointNetDevice::QUEUE);
+ resolver->Add ("rx",
+ m_rxTrace,
+ PointToPointNetDevice::RX);
+ return resolver;
+}
+
+bool PointToPointNetDevice::Attach (Ptr<PointToPointChannel> ch)
+{
+ NS_DEBUG ("PointToPointNetDevice::Attach (" << &ch << ")");
+
+ m_channel = ch;
+
+ m_channel->Attach(this);
+ m_bps = m_channel->GetDataRate ();
+ // GFR Comment. Below is definitely wrong. Interframe gap
+ // is unrelated to channel delay.
+ //m_tInterframeGap = m_channel->GetDelay ();
+
+ /*
+ * For now, this device is up whenever a channel is attached to it.
+ * In fact, it should become up only when the second device
+ * is attached to the channel. So, there should be a way for
+ * a PointToPointChannel to notify both of its attached devices
+ * that the channel is 'complete', hence that the devices are
+ * up, hence that they can call NotifyLinkUp.
+ */
+ NotifyLinkUp ();
+ return true;
+}
+
+void PointToPointNetDevice::AddQueue (Ptr<Queue> q)
+{
+ NS_DEBUG ("PointToPointNetDevice::AddQueue (" << q << ")");
+
+ m_queue = q;
+}
+
+void PointToPointNetDevice::Receive (Packet& p)
+{
+ NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")");
+ uint16_t param = 0;
+ Packet packet = p;
+
+ ProcessHeader(packet, param);
+ m_rxTrace (packet);
+ ForwardUp (packet, param);
+}
+
+Ptr<Queue> PointToPointNetDevice::GetQueue(void) const
+{
+ return m_queue;
+}
+
+Ptr<Channel> PointToPointNetDevice::DoGetChannel(void) const
+{
+ return m_channel;
+}
+
+bool PointToPointNetDevice::DoNeedsArp (void) const
+{
+ return false;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-net-device.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,305 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 University of Washington
+ *
+ * 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: Craig Dowell <craigdo@ee.washington.edu>
+ */
+
+#ifndef POINT_TO_POINT_NET_DEVICE_H
+#define POINT_TO_POINT_NET_DEVICE_H
+
+#include <string.h>
+#include "ns3/address.h"
+#include "ns3/node.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/default-value.h"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+
+class Queue;
+class PointToPointChannel;
+
+/**
+ * \class PointToPointNetDevice
+ * \brief A Device for a Point to Point Network Link.
+ *
+ * Ns-3 takes a four-layer view of a protocol stack. This is the same model
+ * that TCP uses. In this view, layers 5-7 of the OSI reference model are
+ * grouped together into an application layer; layer four (transport / TCP) is
+ * broken out; layer three (network / IP) is broken out; and layers 1-2 are
+ * grouped together. We call this grouping of layers one and two a NetDevice
+ * and represent it as a class in the system.
+ *
+ * The NetDevice class is specialized according to the needs of the specific
+ * kind of network link. In this case, the link is a PointToPoint link. The
+ * PointToPoint link is a family of classes that includes this class, the
+ * PointToPointNetDevice, a PointToPointChannel class that represents the
+ * actual medium across which bits are sent, a PointToPointIpv4Interface class
+ * that provides the hook to tie a general purpose node to this specific
+ * link, and finally, a PointToPointTopology object that is responsible for
+ * putting all of the pieces together.
+ *
+ * This is the PointToPointNetDevice class that represents, essentially, the
+ * PC card that is used to connect to the PointToPoint network.
+ */
+class PointToPointNetDevice : 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) */
+ };
+ /**
+ * Construct a PointToPointNetDevice
+ *
+ * This is the constructor for the PointToPointNetDevice. 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 deleded.
+ *
+ * @see PointToPointTopology::AddPointToPointLink ()
+ * @param node the Node to which this device is connected.
+ */
+ PointToPointNetDevice (Ptr<Node> node,
+ const DataRate& = g_defaultRate.GetValue());
+ /**
+ * Destroy a PointToPointNetDevice
+ *
+ * This is the destructor for the PointToPointNetDevice.
+ */
+ virtual ~PointToPointNetDevice();
+ /**
+ * 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(const 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(const Time& t);
+ /**
+ * Attach the device to a channel.
+ *
+ * The PointToPointTopology object creates a PointToPointChannel and two
+ * PointtoPointNetDevices. In order to introduce these components to each
+ * other, the topology object calls Attach () on each PointToPointNetDevice.
+ * Inside this method, the Net Device calls out to the PointToPointChannel
+ * to introduce itself.
+ *
+ * @see PointToPointTopology::AddPointToPointLink ()
+ * @see SetDataRate ()
+ * @see SetInterframeGap ()
+ * @param ch a pointer to the channel to which this object is being attached.
+ */
+ bool Attach(Ptr<PointToPointChannel> ch);
+ /**
+ * Attach a queue to the PointToPointNetDevice.
+ *
+ * The PointToPointNetDevice "owns" a queue. This queue is created by the
+ * PointToPointTopology object and implements a queueing method such as
+ * DropTail or RED. The PointToPointNetDevice assumes ownership of this
+ * queue and must delete it when the device is destroyed.
+ *
+ * @see PointToPointTopology::AddPointToPointLink ()
+ * @see Queue
+ * @see DropTailQueue
+ * @param queue a pointer to the queue for which object is assuming
+ * ownership.
+ */
+ void AddQueue(Ptr<Queue> queue);
+ /**
+ * Receive a packet from a connected PointToPointChannel.
+ *
+ * The PointToPointNetDevice 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 PointToPointChannel
+ * @param p a reference to the received packet
+ */
+ void Receive (Packet& p);
+protected:
+ 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.
+ *
+ * @see PointToPointTopology
+ * @returns a pointer to the queue.
+ */
+ Ptr<Queue> 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
+ *
+ * @see PointToPointChannel
+ * @returns a pointer to the channel
+ */
+ virtual Ptr<Channel> DoGetChannel(void) const;
+ /**
+ * Set a new default data rate
+ * @param Data rate to set for new default
+ */
+ static void SetDefaultRate(const DataRate&);
+
+ /**
+ * Get the current default rate.
+ * @returns a const reference to current default
+ */
+
+ static const DataRate& GetDefaultRate();
+
+private:
+ /**
+ * 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, 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, uint16_t& param);
+ /**
+ * Send a Packet Down the Wire.
+ *
+ * The SendTo method is defined as the standard way that the level three
+ * protocol uses to tell a NetDevice to send a packet. SendTo is declared
+ * as abstract in the NetDevice class and we declare it here.
+ *
+ * @see NetDevice
+ * @param p a reference to the packet to send
+ * @param dest a reference to the Address 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 Address& dest,
+ uint16_t protocolNumber);
+ /**
+ * Start Sending a Packet Down the Wire.
+ *
+ * The TransmitStart method is the method that is used internally in the
+ * PointToPointNetDevice 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. An event is scheduled for the time at which
+ * the bits have been completely transmitted.
+ *
+ * @see PointToPointChannel::TransmitStart ()
+ * @see TransmitCompleteEvent ()
+ * @param p a reference to the packet to send
+ * @returns true if success, false on failure
+ */
+ bool TransmitStart (Packet &p);
+ /**
+ * Stop Sending a Packet Down the Wire and Begin the Interframe Gap.
+ *
+ * The TransmitComplete method is used internally to finish the process
+ * of sending a packet out on the channel.
+ *
+ */
+ void TransmitComplete(void);
+ /**
+ * Create a Trace Resolver for events in the net device.
+ *
+ * @see class TraceResolver
+ */
+ virtual TraceResolver* DoCreateTraceResolver (TraceContext const &context);
+ virtual bool DoNeedsArp (void) const;
+ /**
+ * 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 */
+ };
+ /**
+ * The state of the Net Device transmit state machine.
+ * @see TxMachineState
+ */
+ TxMachineState m_txMachineState;
+ /**
+ * 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;
+ /**
+ * The PointToPointChannel to which this PointToPointNetDevice has been
+ * attached.
+ * @see class PointToPointChannel
+ */
+ Ptr<PointToPointChannel> m_channel;
+ /**
+ * The Queue which this PointToPointNetDevice uses as a packet source.
+ * Management of this Queue has been delegated to the PointToPointNetDevice
+ * and it has the responsibility for deletion.
+ * @see class Queue
+ * @see class DropTailQueue
+ */
+ Ptr<Queue> m_queue;
+ /**
+ * The trace source for the packet reception events that the device can
+ * fire.
+ *
+ * @see class CallBackTraceSource
+ * @see class TraceResolver
+ */
+ CallbackTraceSource<Packet &> m_rxTrace;
+ /**
+ * Default data rate. Used for all newly created p2p net devices
+ */
+ static DataRateDefaultValue g_defaultRate;
+
+};
+
+}; // namespace ns3
+
+#endif // POINT_TO_POINT_NET_DEVICE_H
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-topology.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,172 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+
+//
+// Topology helper for ns3.
+// George F. Riley, Georgia Tech, Spring 2007
+
+#include <algorithm>
+#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 "point-to-point-channel.h"
+#include "point-to-point-net-device.h"
+#include "point-to-point-topology.h"
+
+namespace ns3 {
+
+Ptr<PointToPointChannel>
+PointToPointTopology::AddPointToPointLink(
+ Ptr<Node> n1,
+ Ptr<Node> n2,
+ const DataRate& bps,
+ const Time& delay)
+{
+ Ptr<PointToPointChannel> channel = Create<PointToPointChannel> (bps, delay);
+
+ Ptr<PointToPointNetDevice> net1 = Create<PointToPointNetDevice> (n1);
+
+ Ptr<Queue> q = Queue::CreateDefault ();
+ net1->AddQueue(q);
+ net1->Attach (channel);
+
+ Ptr<PointToPointNetDevice> net2 = Create<PointToPointNetDevice> (n2);
+
+ q = Queue::CreateDefault ();
+ net2->AddQueue(q);
+ net2->Attach (channel);
+
+ return channel;
+}
+
+void
+PointToPointTopology::AddIpv4Addresses(
+ Ptr<const PointToPointChannel> chan,
+ Ptr<Node> n1, const Ipv4Address& addr1,
+ Ptr<Node> n2, const Ipv4Address& addr2)
+{
+
+ // Duplex link is assumed to be subnetted as a /30
+ // May run this unnumbered in the future?
+ Ipv4Mask netmask("255.255.255.252");
+ NS_ASSERT (netmask.IsMatch(addr1,addr2));
+
+ // The PointToPoint channel is used to find the relevant NetDevices
+ NS_ASSERT (chan->GetNDevices () == 2);
+ Ptr<NetDevice> nd1 = chan->GetDevice (0);
+ Ptr<NetDevice> nd2 = chan->GetDevice (1);
+ // Make sure that nd1 belongs to n1 and nd2 to n2
+ if ( (nd1->GetNode ()->GetId () == n2->GetId () ) &&
+ (nd2->GetNode ()->GetId () == n1->GetId () ) )
+ {
+ std::swap(nd1, nd2);
+ }
+ NS_ASSERT (nd1->GetNode ()->GetId () == n1->GetId ());
+ NS_ASSERT (nd2->GetNode ()->GetId () == n2->GetId ());
+
+ Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
+ uint32_t index1 = ip1->AddInterface (nd1);
+
+ ip1->SetAddress (index1, addr1);
+ ip1->SetNetworkMask (index1, netmask);
+ ip1->SetUp (index1);
+
+ Ptr<Ipv4> ip2 = n2->QueryInterface<Ipv4> (Ipv4::iid);
+ uint32_t index2 = ip2->AddInterface (nd2);
+
+ ip2->SetAddress (index2, addr2);
+ ip2->SetNetworkMask (index2, netmask);
+ ip2->SetUp (index2);
+
+}
+
+void
+PointToPointTopology::AddIpv4Routes (
+ Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> chan)
+{
+ // The PointToPoint channel is used to find the relevant NetDevices
+ NS_ASSERT (chan->GetNDevices () == 2);
+ Ptr<NetDevice> nd1 = chan->GetDevice (0);
+ Ptr<NetDevice> nd2 = chan->GetDevice (1);
+
+ // Assert that n1 is the Node owning one of the two NetDevices
+ // and make sure that nd1 corresponds to it
+ if (nd1->GetNode ()->GetId () == n1->GetId ())
+ {
+ ; // Do nothing
+ }
+ else if (nd2->GetNode ()->GetId () == n1->GetId ())
+ {
+ std::swap(nd1, nd2);
+ }
+ else
+ {
+ NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+ }
+
+ // Assert that n2 is the Node owning one of the two NetDevices
+ // and make sure that nd2 corresponds to it
+ if (nd2->GetNode ()->GetId () != n2->GetId ())
+ {
+ NS_FATAL_ERROR("P2PTopo: Node does not contain an interface on Channel");
+ }
+
+ // Assert that both are Ipv4 nodes
+ Ptr<Ipv4> ip1 = nd1->GetNode ()->QueryInterface<Ipv4> (Ipv4::iid);
+ Ptr<Ipv4> ip2 = nd2->GetNode ()->QueryInterface<Ipv4> (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
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/point-to-point-topology.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+//
+// 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: George F. Riley<riley@ece.gatech.edu>
+//
+// Topology helper for ns3.
+// George F. Riley, Georgia Tech, Spring 2007
+#ifndef __POINT_TO_POINT_TOPOLOGY_H__
+#define __POINT_TO_POINT_TOPOLOGY_H__
+
+#include "ns3/ptr.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 PointToPointChannel;
+class Node;
+class IPAddr;
+class DataRate;
+class Queue;
+
+/**
+ * \brief A helper class to create Topologies based on the
+ * ns3::PointToPointNetDevice and ns3::PointToPointChannel objects.
+ */
+class PointToPointTopology {
+public:
+ /**
+ * \param n1 Node
+ * \param n2 Node
+ * \param dataRate Maximum transmission link rate
+ * \param delay one-way propagation delay
+ * \return Pointer to the underlying PointToPointChannel
+ *
+ * Add a full-duplex point-to-point link between two nodes
+ * and attach PointToPointNetDevices to the resulting
+ * PointToPointChannel.
+ */
+ static Ptr<PointToPointChannel> AddPointToPointLink(
+ Ptr<Node> n1, Ptr<Node> n2, const DataRate& dataRate, const Time& delay);
+
+ /**
+ * \param chan PointToPointChannel to use
+ * \param n1 Node
+ * \param addr1 Ipv4 Address for n1
+ * \param n2 Node
+ * \param addr2 Ipv4 Address for n2
+ *
+ * Add Ipv4Addresses to the Ipv4 interfaces associated with the
+ * two PointToPointNetDevices on the provided PointToPointChannel
+ */
+ static void AddIpv4Addresses(
+ Ptr<const PointToPointChannel> chan,
+ Ptr<Node> n1, const Ipv4Address& addr1,
+ Ptr<Node> n2, const Ipv4Address& addr2);
+
+ /**
+ * \param channel PointToPointChannel to use
+ * \param n1 Node
+ * \param n2 Node
+ *
+ * For the given PointToPointChannel, for each Node, add an
+ * IPv4 host route to the IPv4 address of the peer node.
+ */
+ static void AddIpv4Routes (Ptr<Node> n1, Ptr<Node> n2, Ptr<const PointToPointChannel> channel);
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/point-to-point/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,20 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+
+def build(bld):
+ 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',
+ ]
+ headers = bld.create_obj('ns3header')
+ headers.source = [
+ 'point-to-point-net-device.h',
+ 'point-to-point-channel.h',
+ 'point-to-point-topology.h',
+ ]
+
--- a/src/internet-node/arp-cache.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/arp-cache.cc Mon Jul 30 10:35:03 2007 +0200
@@ -109,6 +109,8 @@
ArpCache::Entry *
ArpCache::Add (Ipv4Address to)
{
+ NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ());
+
ArpCache::Entry *entry = new ArpCache::Entry (this);
m_arpCache[to] = entry;
return entry;
--- a/src/internet-node/arp-header.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/arp-header.cc Mon Jul 30 10:35:03 2007 +0200
@@ -20,8 +20,8 @@
*/
#include "ns3/assert.h"
+#include "ns3/address-utils.h"
#include "arp-header.h"
-#include "header-utils.h"
namespace ns3 {
--- a/src/internet-node/arp-ipv4-interface.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/arp-ipv4-interface.cc Mon Jul 30 10:35:03 2007 +0200
@@ -21,6 +21,7 @@
*/
#include "ns3/packet.h"
+#include "ns3/debug.h"
#include "ns3/composite-trace-resolver.h"
#include "ns3/node.h"
#include "ns3/net-device.h"
@@ -61,7 +62,19 @@
{
Ptr<ArpPrivate> arp = m_node->QueryInterface<ArpPrivate> (ArpPrivate::iid);
Address hardwareDestination;
- bool found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
+ bool found;
+
+ if (dest.IsBroadcast ())
+ {
+ hardwareDestination = GetDevice ()->GetBroadcast ();
+ found = true;
+ }
+ else
+ {
+ Ptr<ArpPrivate> arp = m_node->QueryInterface<ArpPrivate> (ArpPrivate::iid);
+ found = arp->Lookup (p, dest, GetDevice (), &hardwareDestination);
+ }
+
if (found)
{
GetDevice ()->Send (p, hardwareDestination, Ipv4L3Protocol::PROT_NUMBER);
--- a/src/internet-node/arp-l3-protocol.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/arp-l3-protocol.cc Mon Jul 30 10:35:03 2007 +0200
@@ -87,6 +87,13 @@
ArpCache *cache = FindCache (device);
ArpHeader arp;
packet.RemoveHeader (arp);
+
+ NS_DEBUG ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
+ " node="<<m_node->GetId ()<<", got request from " <<
+ arp.GetSourceIpv4Address () << " for address " <<
+ arp.GetDestinationIpv4Address () << "; we have address " <<
+ cache->GetInterface ()->GetAddress ());
+
if (arp.IsRequest () &&
arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ())
{
@@ -128,6 +135,12 @@
// XXX report packet as dropped.
}
}
+ else
+ {
+ NS_DEBUG ("node="<<m_node->GetId ()<<", got request from " <<
+ arp.GetSourceIpv4Address () << " for unknown address " <<
+ arp.GetDestinationIpv4Address () << " -- drop");
+ }
}
bool
ArpL3Protocol::Lookup (Packet &packet, Ipv4Address destination,
@@ -203,6 +216,11 @@
ArpL3Protocol::SendArpRequest (ArpCache const *cache, Ipv4Address to)
{
ArpHeader arp;
+ NS_DEBUG ("ARP: sending request from node "<<m_node->GetId ()<<
+ " || src: " << cache->GetDevice ()->GetAddress () <<
+ " / " << cache->GetInterface ()->GetAddress () <<
+ " || dst: " << cache->GetDevice ()->GetBroadcast () <<
+ " / " << to);
arp.SetRequest (cache->GetDevice ()->GetAddress (),
cache->GetInterface ()->GetAddress (),
cache->GetDevice ()->GetBroadcast (),
@@ -216,6 +234,10 @@
ArpL3Protocol::SendArpReply (ArpCache const *cache, Ipv4Address toIp, Address toMac)
{
ArpHeader arp;
+ NS_DEBUG ("ARP: sending reply from node "<<m_node->GetId ()<<
+ "|| src: " << cache->GetDevice ()->GetAddress () <<
+ " / " << cache->GetInterface ()->GetAddress () <<
+ " || dst: " << toMac << " / " << toIp);
arp.SetReply (cache->GetDevice ()->GetAddress (),
cache->GetInterface ()->GetAddress (),
toMac, toIp);
--- a/src/internet-node/header-utils.cc Fri Jul 27 09:44:24 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#include "header-utils.h"
-
-namespace ns3 {
-
-void WriteTo (Buffer::Iterator &i, Ipv4Address ad)
-{
- i.WriteHtonU32 (ad.GetHostOrder ());
-}
-void WriteTo (Buffer::Iterator &i, Address ad)
-{
- uint8_t mac[Address::MAX_SIZE];
- ad.CopyTo (mac);
- i.Write (mac, ad.GetLength ());
-}
-
-void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
-{
- ad.SetHostOrder (i.ReadNtohU32 ());
-}
-void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len)
-{
- uint8_t mac[Address::MAX_SIZE];
- i.Read (mac, len);
- ad.CopyFrom (mac, len);
-}
-
-
-
-}; // namespace ns3
--- a/src/internet-node/header-utils.h Fri Jul 27 09:44:24 2007 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2006 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- */
-#ifndef HEADER_UTILS_H
-#define HEADER_UTILS_H
-
-#include "ns3/buffer.h"
-#include "ns3/ipv4-address.h"
-#include "ns3/address.h"
-
-namespace ns3 {
-
-void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
-void WriteTo (Buffer::Iterator &i, Address ad);
-
-void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
-void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len);
-
-};
-
-#endif /* HEADER_UTILS_H */
--- a/src/internet-node/ipv4-end-point-demux.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/ipv4-end-point-demux.cc Mon Jul 30 10:35:03 2007 +0200
@@ -21,9 +21,12 @@
#include "ipv4-end-point-demux.h"
#include "ipv4-end-point.h"
+#include "ns3/debug.h"
namespace ns3{
+NS_DEBUG_COMPONENT_DEFINE ("Ipv4EndPointDemux");
+
Ipv4EndPointDemux::Ipv4EndPointDemux ()
: m_ephemeral (1025)
{}
@@ -68,9 +71,11 @@
Ipv4EndPoint *
Ipv4EndPointDemux::Allocate (void)
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate ()");
uint16_t port = AllocateEphemeralPort ();
if (port == 0)
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate ephemeral port allocation failed.");
return 0;
}
Ipv4EndPoint *endPoint = new Ipv4EndPoint (Ipv4Address::GetAny (), port);
@@ -80,9 +85,11 @@
Ipv4EndPoint *
Ipv4EndPointDemux::Allocate (Ipv4Address address)
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate (address=" << address << ")");
uint16_t port = AllocateEphemeralPort ();
if (port == 0)
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate ephemeral port allocation failed.");
return 0;
}
Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
@@ -97,8 +104,11 @@
Ipv4EndPoint *
Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate (address=" << address
+ << ", port=" << port << ")");
if (LookupLocal (address, port))
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate duplicate address/port; failing.");
return 0;
}
Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
@@ -110,6 +120,10 @@
Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort)
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate (localAddress=" << localAddress
+ << ", localPort=" << localPort
+ << ", peerAddress=" << peerAddress
+ << ", peerPort=" << peerPort << ")");
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
if ((*i)->GetLocalPort () == localPort &&
@@ -117,6 +131,7 @@
(*i)->GetPeerPort () == peerPort &&
(*i)->GetPeerAddress () == peerAddress)
{
+ NS_DEBUG ("Ipv4EndPointDemux::Allocate: no way we can allocate this end-point.");
/* no way we can allocate this end-point. */
return 0;
}
@@ -147,35 +162,46 @@
* Otherwise, if we find a generic match, we return it.
* Otherwise, we return 0.
*/
-Ipv4EndPoint *
+Ipv4EndPointDemux::EndPoints
Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport,
- Ipv4Address saddr, uint16_t sport)
+ Ipv4Address saddr, uint16_t sport)
{
uint32_t genericity = 3;
Ipv4EndPoint *generic = 0;
- //TRACE ("lookup " << daddr << ":" << dport << " " << saddr << ":" << sport);
+ EndPoints retval;
+
+ NS_DEBUG ("Ipv4EndPointDemux::Lookup (daddr=" << daddr << ", dport=" << dport
+ << ", saddr=" << saddr << ", sport=" << sport
+ << ")");
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
-#if 0
- TRACE ("against " <<
- (*i)->GetLocalAddress ()
- << ":" <<
- (*i)->GetLocalPort ()
- << " " <<
- (*i)->GetPeerAddress ()
- << ":"
- << (*i)->GetPeerPort ());
-#endif
+ NS_DEBUG ("Ipv4EndPointDemux::Lookup against " <<
+ (*i)->GetLocalAddress ()
+ << ":" <<
+ (*i)->GetLocalPort ()
+ << " " <<
+ (*i)->GetPeerAddress ()
+ << ":"
+ << (*i)->GetPeerPort ());
if ((*i)->GetLocalPort () != dport)
{
continue;
}
- if ((*i)->GetLocalAddress () == daddr &&
- (*i)->GetPeerPort () == sport &&
- (*i)->GetPeerAddress () == saddr)
+ NS_DEBUG ("Ipv4EndPointDemux::Lookup local address matches: "
+ << bool ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ()));
+ NS_DEBUG ("Ipv4EndPointDemux::Lookup peer port matches: "
+ << bool ((*i)->GetPeerPort () == sport || sport == 0));
+ NS_DEBUG ("Ipv4EndPointDemux::Lookup peer address matches: "
+ << bool ((*i)->GetPeerAddress () == saddr ||
+ (*i)->GetPeerAddress () == Ipv4Address::GetAny ()));
+
+ if ( ((*i)->GetLocalAddress () == daddr || daddr.IsBroadcast ())
+ && ((*i)->GetPeerPort () == sport || (*i)->GetPeerPort () == 0)
+ && ((*i)->GetPeerAddress () == saddr || (*i)->GetPeerAddress () == Ipv4Address::GetAny ()))
{
+ NS_DEBUG ("Ipv4EndPointDemux::Lookup MATCH");
/* this is an exact match. */
- return *i;
+ retval.push_back (*i);
}
uint32_t tmp = 0;
if ((*i)->GetLocalAddress () == Ipv4Address::GetAny ())
@@ -192,7 +218,11 @@
genericity = tmp;
}
}
- return generic;
+ if (retval.size () == 0 && generic != 0)
+ {
+ retval.push_back (generic);
+ }
+ return retval;
}
uint16_t
--- a/src/internet-node/ipv4-end-point-demux.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/ipv4-end-point-demux.h Mon Jul 30 10:35:03 2007 +0200
@@ -32,15 +32,18 @@
class Ipv4EndPointDemux {
public:
+ typedef std::list<Ipv4EndPoint *> EndPoints;
+ typedef std::list<Ipv4EndPoint *>::iterator EndPointsI;
+
Ipv4EndPointDemux ();
~Ipv4EndPointDemux ();
bool LookupPortLocal (uint16_t port);
bool LookupLocal (Ipv4Address addr, uint16_t port);
- Ipv4EndPoint *Lookup (Ipv4Address daddr,
- uint16_t dport,
- Ipv4Address saddr,
- uint16_t sport);
+ EndPoints Lookup (Ipv4Address daddr,
+ uint16_t dport,
+ Ipv4Address saddr,
+ uint16_t sport);
Ipv4EndPoint *Allocate (void);
Ipv4EndPoint *Allocate (Ipv4Address address);
@@ -55,8 +58,6 @@
private:
uint16_t AllocateEphemeralPort (void);
- typedef std::list<Ipv4EndPoint *> EndPoints;
- typedef std::list<Ipv4EndPoint *>::iterator EndPointsI;
uint16_t m_ephemeral;
EndPoints m_endPoints;
--- a/src/internet-node/ipv4-impl.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/ipv4-impl.cc Mon Jul 30 10:35:03 2007 +0200
@@ -39,6 +39,13 @@
m_ipv4 = 0;
}
+void
+Ipv4Impl::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+ int16_t priority)
+{
+ m_ipv4->AddRoutingProtocol (routingProtocol, priority);
+}
+
void
Ipv4Impl::AddHostRouteTo (Ipv4Address dest,
Ipv4Address nextHop,
--- a/src/internet-node/ipv4-impl.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/ipv4-impl.h Mon Jul 30 10:35:03 2007 +0200
@@ -35,6 +35,9 @@
virtual ~Ipv4Impl ();
+ virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+ int16_t priority);
+
virtual void AddHostRouteTo (Ipv4Address dest,
Ipv4Address nextHop,
uint32_t interface);
--- a/src/internet-node/ipv4-l3-protocol.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.cc Mon Jul 30 10:35:03 2007 +0200
@@ -48,9 +48,10 @@
m_nInterfaces (0),
m_defaultTtl (64),
m_identification (0),
- m_defaultRoute (0),
m_node (node)
{
+ m_staticRouting = Create<Ipv4StaticRouting> ();
+ AddRoutingProtocol (m_staticRouting, 0);
SetupLoopback ();
}
Ipv4L3Protocol::~Ipv4L3Protocol ()
@@ -64,25 +65,10 @@
delete (*i);
}
m_interfaces.clear ();
- for (HostRoutesI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i = m_hostRoutes.erase (i))
- {
- delete (*i);
- }
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j = m_networkRoutes.erase (j))
- {
- delete (*j);
- }
- if (m_defaultRoute != 0)
- {
- delete m_defaultRoute;
- m_defaultRoute = 0;
- }
m_node = 0;
L3Protocol::DoDispose ();
+ m_staticRouting->Dispose ();
+ m_staticRouting = 0;
}
void
@@ -132,17 +118,13 @@
Ipv4Address nextHop,
uint32_t interface)
{
- Ipv4Route *route = new Ipv4Route ();
- *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
- m_hostRoutes.push_back (route);
+ m_staticRouting->AddHostRouteTo (dest, nextHop, interface);
}
void
Ipv4L3Protocol::AddHostRouteTo (Ipv4Address dest,
uint32_t interface)
{
- Ipv4Route *route = new Ipv4Route ();
- *route = Ipv4Route::CreateHostRouteTo (dest, interface);
- m_hostRoutes.push_back (route);
+ m_staticRouting->AddHostRouteTo (dest, interface);
}
void
Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
@@ -150,163 +132,63 @@
Ipv4Address nextHop,
uint32_t interface)
{
- Ipv4Route *route = new Ipv4Route ();
- *route = Ipv4Route::CreateNetworkRouteTo (network,
- networkMask,
- nextHop,
- interface);
- m_networkRoutes.push_back (route);
+ m_staticRouting->AddNetworkRouteTo (network, networkMask, nextHop, interface);
}
void
Ipv4L3Protocol::AddNetworkRouteTo (Ipv4Address network,
Ipv4Mask networkMask,
uint32_t interface)
{
- Ipv4Route *route = new Ipv4Route ();
- *route = Ipv4Route::CreateNetworkRouteTo (network,
- networkMask,
- interface);
- m_networkRoutes.push_back (route);
+ m_staticRouting->AddNetworkRouteTo (network, networkMask, interface);
}
void
Ipv4L3Protocol::SetDefaultRoute (Ipv4Address nextHop,
uint32_t interface)
{
- Ipv4Route *route = new Ipv4Route ();
- *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
- delete m_defaultRoute;
- m_defaultRoute = route;
+ m_staticRouting->SetDefaultRoute (nextHop, interface);
}
-Ipv4Route *
-Ipv4L3Protocol::Lookup (Ipv4Address dest)
+
+void
+Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader,
+ Packet packet,
+ Ipv4RoutingProtocol::RouteReplyCallback routeReply)
{
- for (HostRoutesCI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i++)
+ for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();
+ rprotoIter != m_routingProtocols.end (); rprotoIter++)
{
- NS_ASSERT ((*i)->IsHost ());
- if ((*i)->GetDest ().IsEqual (dest))
- {
- return (*i);
- }
+ if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply))
+ return;
}
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- NS_ASSERT ((*j)->IsNetwork ());
- Ipv4Mask mask = (*j)->GetDestNetworkMask ();
- Ipv4Address entry = (*j)->GetDestNetwork ();
- if (mask.IsMatch (dest, entry))
- {
- return (*j);
- }
- }
- if (m_defaultRoute != 0)
- {
- NS_ASSERT (m_defaultRoute->IsDefault ());
- return m_defaultRoute;
- }
- return 0;
+ // No route found
+ routeReply (false, Ipv4Route (), packet, ipHeader);
+}
+
+void
+Ipv4L3Protocol::AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+ int priority)
+{
+ m_routingProtocols.push_back
+ (std::pair<int, Ptr<Ipv4RoutingProtocol> > (-priority, routingProtocol));
+ m_routingProtocols.sort ();
}
uint32_t
Ipv4L3Protocol::GetNRoutes (void)
{
- uint32_t n = 0;
- if (m_defaultRoute != 0)
- {
- n++;
- }
- n += m_hostRoutes.size ();
- n += m_networkRoutes.size ();
- return n;
+ return m_staticRouting->GetNRoutes ();
}
+
Ipv4Route *
Ipv4L3Protocol::GetRoute (uint32_t index)
{
- if (index == 0 && m_defaultRoute != 0)
- {
- return m_defaultRoute;
- }
- if (index > 0 && m_defaultRoute != 0)
- {
- index--;
- }
- if (index < m_hostRoutes.size ())
- {
- uint32_t tmp = 0;
- for (HostRoutesCI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i++)
- {
- if (tmp == index)
- {
- return *i;
- }
- tmp++;
- }
- }
- index -= m_hostRoutes.size ();
- uint32_t tmp = 0;
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- if (tmp == index)
- {
- return *j;
- }
- tmp++;
- }
- NS_ASSERT (false);
- // quiet compiler.
- return 0;
+ return m_staticRouting->GetRoute (index);
}
+
void
Ipv4L3Protocol::RemoveRoute (uint32_t index)
{
- if (index == 0 && m_defaultRoute != 0)
- {
- delete m_defaultRoute;
- m_defaultRoute = 0;
- }
- if (index > 0 && m_defaultRoute != 0)
- {
- index--;
- }
- if (index < m_hostRoutes.size ())
- {
- uint32_t tmp = 0;
- for (HostRoutesI i = m_hostRoutes.begin ();
- i != m_hostRoutes.end ();
- i++)
- {
- if (tmp == index)
- {
- delete *i;
- m_hostRoutes.erase (i);
- return;
- }
- tmp++;
- }
- }
- index -= m_hostRoutes.size ();
- uint32_t tmp = 0;
- for (NetworkRoutesI j = m_networkRoutes.begin ();
- j != m_networkRoutes.end ();
- j++)
- {
- if (tmp == index)
- {
- delete *j;
- m_networkRoutes.erase (j);
- return;
- }
- tmp++;
- }
- NS_ASSERT (false);
+ m_staticRouting->RemoveRoute (index);
}
@@ -386,6 +268,7 @@
ForwardUp (packet, ipHeader);
}
+
void
Ipv4L3Protocol::Send (Packet const &packet,
Ipv4Address source,
@@ -404,30 +287,49 @@
m_identification ++;
- // XXX Note here that in most ipv4 stacks in the world,
- // the route calculation for an outgoing packet is not
- // done in the ip layer. It is done within the application
- // socket when the first packet is sent to avoid this
- // costly lookup on a per-packet basis.
- // That would require us to get the route from the packet,
- // most likely with a packet tag. The higher layers do not
- // do this yet for us.
- Ipv4Route *route = Lookup (ipHeader.GetDestination ());
- if (route == 0)
+ if (destination.IsBroadcast ())
+ {
+ uint32_t ifaceIndex = 0;
+ for (Ipv4InterfaceList::iterator ifaceIter = m_interfaces.begin ();
+ ifaceIter != m_interfaces.end (); ifaceIter++, ifaceIndex++)
+ {
+ Ipv4Interface *outInterface = *ifaceIter;
+ Packet packetCopy = packet;
+
+ NS_ASSERT (packetCopy.GetSize () <= outInterface->GetMtu ());
+ packetCopy.AddHeader (ipHeader);
+ m_txTrace (packetCopy, ifaceIndex);
+ outInterface->Send (packetCopy, destination);
+ }
+ }
+ else
{
- NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
+ // XXX Note here that in most ipv4 stacks in the world,
+ // the route calculation for an outgoing packet is not
+ // done in the ip layer. It is done within the application
+ // socket when the first packet is sent to avoid this
+ // costly lookup on a per-packet basis.
+ // That would require us to get the route from the packet,
+ // most likely with a packet tag. The higher layers do not
+ // do this yet for us.
+ Lookup (ipHeader, packet,
+ MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
+ }
+}
+
+void
+Ipv4L3Protocol::SendRealOut (bool found,
+ Ipv4Route const &route,
+ Packet packet,
+ Ipv4Header const &ipHeader)
+{
+ if (!found)
+ {
+ NS_DEBUG ("no route to host. drop.");
m_dropTrace (packet);
return;
}
-
- SendRealOut (packet, ipHeader, *route);
-}
-
-void
-Ipv4L3Protocol::SendRealOut (Packet const &p, Ipv4Header const &ip, Ipv4Route const &route)
-{
- Packet packet = p;
- packet.AddHeader (ip);
+ packet.AddHeader (ipHeader);
Ipv4Interface *outInterface = GetInterface (route.GetInterface ());
NS_ASSERT (packet.GetSize () <= outInterface->GetMtu ());
m_txTrace (packet, route.GetInterface ());
@@ -437,7 +339,7 @@
}
else
{
- outInterface->Send (packet, ip.GetDestination ());
+ outInterface->Send (packet, ipHeader.GetDestination ());
}
}
@@ -470,7 +372,7 @@
}
}
- if (ipHeader.GetDestination ().IsEqual (Ipv4Address::GetBroadcast ()))
+ if (ipHeader.GetDestination ().IsBroadcast ())
{
NS_DEBUG ("for me 3");
return false;
@@ -489,15 +391,10 @@
return true;
}
ipHeader.SetTtl (ipHeader.GetTtl () - 1);
- Ipv4Route *route = Lookup (ipHeader.GetDestination ());
- if (route == 0)
- {
- NS_DEBUG ("not for me -- forwarding but no route to host. drop.");
- m_dropTrace (packet);
- return true;
- }
+
NS_DEBUG ("not for me -- forwarding.");
- SendRealOut (packet, ipHeader, *route);
+ Lookup (ipHeader, packet,
+ MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
return true;
}
@@ -551,12 +448,39 @@
{
Ipv4Interface *interface = GetInterface (i);
interface->SetUp ();
+
+ // If interface address and network mask have been set, add a route
+ // to the network of the interface (like e.g. ifconfig does on a
+ // Linux box)
+ if ((interface->GetAddress ()) != (Ipv4Address ())
+ && (interface->GetNetworkMask ()) != (Ipv4Mask ()))
+ {
+ AddNetworkRouteTo (interface->GetAddress ().CombineMask (interface->GetNetworkMask ()),
+ interface->GetNetworkMask (), i);
+ }
}
void
-Ipv4L3Protocol::SetDown (uint32_t i)
+Ipv4L3Protocol::SetDown (uint32_t ifaceIndex)
{
- Ipv4Interface *interface = GetInterface (i);
+ Ipv4Interface *interface = GetInterface (ifaceIndex);
interface->SetDown ();
+
+ // Remove all routes that are going through this interface
+ bool modified = true;
+ while (modified)
+ {
+ modified = false;
+ for (uint32_t i = 0; i < GetNRoutes (); i++)
+ {
+ Ipv4Route *route = GetRoute (i);
+ if (route->GetInterface () == ifaceIndex)
+ {
+ RemoveRoute (i);
+ modified = true;
+ break;
+ }
+ }
+ }
}
--- a/src/internet-node/ipv4-l3-protocol.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/ipv4-l3-protocol.h Mon Jul 30 10:35:03 2007 +0200
@@ -27,8 +27,11 @@
#include "ns3/callback-trace-source.h"
#include "ns3/array-trace-resolver.h"
#include "ns3/ipv4-address.h"
+#include "ipv4-header.h"
#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
#include "l3-protocol.h"
+#include "ipv4-static-routing.h"
namespace ns3 {
@@ -124,7 +127,10 @@
void SetDefaultRoute (Ipv4Address nextHop,
uint32_t interface);
- Ipv4Route *Lookup (Ipv4Address dest);
+ void Lookup (Ipv4Header const &ipHeader,
+ Packet packet,
+ Ipv4RoutingProtocol::RouteReplyCallback routeReply);
+
uint32_t GetNRoutes (void);
Ipv4Route *GetRoute (uint32_t i);
void RemoveRoute (uint32_t i);
@@ -143,11 +149,19 @@
void SetUp (uint32_t i);
void SetDown (uint32_t i);
+ void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+ int priority);
protected:
+
virtual void DoDispose (void);
+
private:
- void SendRealOut (Packet const &packet, Ipv4Header const &ip, Ipv4Route const &route);
+
+ void SendRealOut (bool found,
+ Ipv4Route const &route,
+ Packet packet,
+ Ipv4Header const &ipHeader);
bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
void ForwardUp (Packet p, Ipv4Header const&ip);
uint32_t AddIpv4Interface (Ipv4Interface *interface);
@@ -155,26 +169,22 @@
TraceResolver *InterfacesCreateTraceResolver (TraceContext const &context) const;
typedef std::list<Ipv4Interface*> Ipv4InterfaceList;
- typedef std::list<Ipv4Route *> HostRoutes;
- typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
- typedef std::list<Ipv4Route *>::iterator HostRoutesI;
- typedef std::list<Ipv4Route *> NetworkRoutes;
- typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
- typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
+ typedef std::list< std::pair< int, Ptr<Ipv4RoutingProtocol> > > Ipv4RoutingProtocolList;
Ipv4InterfaceList m_interfaces;
uint32_t m_nInterfaces;
uint8_t m_defaultTtl;
uint16_t m_identification;
- HostRoutes m_hostRoutes;
- NetworkRoutes m_networkRoutes;
- Ipv4Route *m_defaultRoute;
Ptr<Node> m_node;
CallbackTraceSource<Packet const &, uint32_t> m_txTrace;
CallbackTraceSource<Packet const &, uint32_t> m_rxTrace;
CallbackTraceSource<Packet const &> m_dropTrace;
+
+ Ipv4RoutingProtocolList m_routingProtocols;
+
+ Ptr<Ipv4StaticRouting> m_staticRouting;
};
} // Namespace ns3
-#endif /* IPV$_L3_PROTOCOL_H */
+#endif /* IPV4_L3_PROTOCOL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-static-routing.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,253 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+// Gustavo Carneiro <gjc@inescporto.pt>
+
+#include "ipv4-static-routing.h"
+#include "ns3/packet.h"
+
+
+namespace ns3 {
+
+
+void
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateHostRouteTo (dest, nextHop, interface);
+ m_hostRoutes.push_back (route);
+}
+void
+Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateHostRouteTo (dest, interface);
+ m_hostRoutes.push_back (route);
+}
+void
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateNetworkRouteTo (network,
+ networkMask,
+ nextHop,
+ interface);
+ m_networkRoutes.push_back (route);
+}
+void
+Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateNetworkRouteTo (network,
+ networkMask,
+ interface);
+ m_networkRoutes.push_back (route);
+}
+void
+Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface)
+{
+ Ipv4Route *route = new Ipv4Route ();
+ *route = Ipv4Route::CreateDefaultRoute (nextHop, interface);
+ delete m_defaultRoute;
+ m_defaultRoute = route;
+}
+
+Ipv4Route *
+Ipv4StaticRouting::LookupStatic (Ipv4Address dest)
+{
+ for (HostRoutesCI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ NS_ASSERT ((*i)->IsHost ());
+ if ((*i)->GetDest ().IsEqual (dest))
+ {
+ return (*i);
+ }
+ }
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ NS_ASSERT ((*j)->IsNetwork ());
+ Ipv4Mask mask = (*j)->GetDestNetworkMask ();
+ Ipv4Address entry = (*j)->GetDestNetwork ();
+ if (mask.IsMatch (dest, entry))
+ {
+ return (*j);
+ }
+ }
+ if (m_defaultRoute != 0)
+ {
+ NS_ASSERT (m_defaultRoute->IsDefault ());
+ return m_defaultRoute;
+ }
+ return 0;
+}
+
+uint32_t
+Ipv4StaticRouting::GetNRoutes (void)
+{
+ uint32_t n = 0;
+ if (m_defaultRoute != 0)
+ {
+ n++;
+ }
+ n += m_hostRoutes.size ();
+ n += m_networkRoutes.size ();
+ return n;
+}
+Ipv4Route *
+Ipv4StaticRouting::GetRoute (uint32_t index)
+{
+ if (index == 0 && m_defaultRoute != 0)
+ {
+ return m_defaultRoute;
+ }
+ if (index > 0 && m_defaultRoute != 0)
+ {
+ index--;
+ }
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesCI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ return *i;
+ }
+ tmp++;
+ }
+ }
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ return *j;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+ // quiet compiler.
+ return 0;
+}
+void
+Ipv4StaticRouting::RemoveRoute (uint32_t index)
+{
+ if (index == 0 && m_defaultRoute != 0)
+ {
+ delete m_defaultRoute;
+ m_defaultRoute = 0;
+ }
+ if (index > 0 && m_defaultRoute != 0)
+ {
+ index--;
+ }
+ if (index < m_hostRoutes.size ())
+ {
+ uint32_t tmp = 0;
+ for (HostRoutesI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i++)
+ {
+ if (tmp == index)
+ {
+ delete *i;
+ m_hostRoutes.erase (i);
+ return;
+ }
+ tmp++;
+ }
+ }
+ index -= m_hostRoutes.size ();
+ uint32_t tmp = 0;
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j++)
+ {
+ if (tmp == index)
+ {
+ delete *j;
+ m_networkRoutes.erase (j);
+ return;
+ }
+ tmp++;
+ }
+ NS_ASSERT (false);
+}
+
+bool
+Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
+ Packet packet,
+ RouteReplyCallback routeReply)
+{
+ Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
+ if (route != 0)
+ {
+ routeReply (true, *route, packet, ipHeader);
+ return true;
+ }
+ else
+ {
+ return false; // Let other routing protocols try to handle this
+ // route request.
+ }
+}
+
+void
+Ipv4StaticRouting::DoDispose (void)
+{
+ for (HostRoutesI i = m_hostRoutes.begin ();
+ i != m_hostRoutes.end ();
+ i = m_hostRoutes.erase (i))
+ {
+ delete (*i);
+ }
+ for (NetworkRoutesI j = m_networkRoutes.begin ();
+ j != m_networkRoutes.end ();
+ j = m_networkRoutes.erase (j))
+ {
+ delete (*j);
+ }
+ if (m_defaultRoute != 0)
+ {
+ delete m_defaultRoute;
+ m_defaultRoute = 0;
+ }
+ Ipv4RoutingProtocol::DoDispose ();
+}
+
+
+}//namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-node/ipv4-static-routing.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,101 @@
+// -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2006 Georgia Tech Research Corporation
+// 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: George F. Riley<riley@ece.gatech.edu>
+// Gustavo Carneiro <gjc@inescporto.pt>
+//
+
+#ifndef IPV4_STATIC_ROUTING_H
+#define IPV4_STATIC_ROUTING_H
+
+#include <list>
+#include <stdint.h>
+#include "ns3/callback-trace-source.h"
+#include "ns3/array-trace-resolver.h"
+#include "ns3/ipv4-address.h"
+#include "ipv4-header.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4.h"
+#include "l3-protocol.h"
+
+namespace ns3 {
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4Route;
+class Node;
+class TraceResolver;
+class TraceContext;
+
+
+class Ipv4StaticRouting : public Ipv4RoutingProtocol
+{
+
+public:
+ Ipv4StaticRouting () : m_defaultRoute (0) {}
+
+ virtual bool RequestRoute (Ipv4Header const &ipHeader,
+ Packet packet,
+ RouteReplyCallback routeReply);
+
+
+ void AddHostRouteTo (Ipv4Address dest,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ void AddHostRouteTo (Ipv4Address dest,
+ uint32_t interface);
+
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ Ipv4Address nextHop,
+ uint32_t interface);
+ void AddNetworkRouteTo (Ipv4Address network,
+ Ipv4Mask networkMask,
+ uint32_t interface);
+ void SetDefaultRoute (Ipv4Address nextHop,
+ uint32_t interface);
+ uint32_t GetNRoutes (void);
+ Ipv4Route *GetRoute (uint32_t i);
+ void RemoveRoute (uint32_t i);
+
+protected:
+ void DoDispose (void);
+
+private:
+ typedef std::list<Ipv4Route *> HostRoutes;
+ typedef std::list<Ipv4Route *>::const_iterator HostRoutesCI;
+ typedef std::list<Ipv4Route *>::iterator HostRoutesI;
+ typedef std::list<Ipv4Route *> NetworkRoutes;
+ typedef std::list<Ipv4Route *>::const_iterator NetworkRoutesCI;
+ typedef std::list<Ipv4Route *>::iterator NetworkRoutesI;
+
+ Ipv4Route *LookupStatic (Ipv4Address dest);
+
+ HostRoutes m_hostRoutes;
+ NetworkRoutes m_networkRoutes;
+ Ipv4Route *m_defaultRoute;
+};
+
+
+
+} // Namespace ns3
+
+#endif /* IPV4_STATIC_ROUTING_H */
--- a/src/internet-node/udp-l4-protocol.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/udp-l4-protocol.cc Mon Jul 30 10:35:03 2007 +0200
@@ -113,13 +113,14 @@
{
UdpHeader udpHeader;
packet.RemoveHeader (udpHeader);
- Ipv4EndPoint *endPoint = m_endPoints->Lookup (destination, udpHeader.GetDestination (),
- source, udpHeader.GetSource ());
- if (endPoint == 0)
+ Ipv4EndPointDemux::EndPoints endPoints =
+ m_endPoints->Lookup (destination, udpHeader.GetDestination (),
+ source, udpHeader.GetSource ());
+ for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
+ endPoint != endPoints.end (); endPoint++)
{
- return;
+ (*endPoint)->ForwardUp (packet, source, udpHeader.GetSource ());
}
- endPoint->ForwardUp (packet, source, udpHeader.GetSource ());
}
void
--- a/src/internet-node/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/internet-node/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -17,6 +17,7 @@
'ipv4-checksum.cc',
'ipv4-interface.cc',
'ipv4-l3-protocol.cc',
+ 'ipv4-static-routing.cc',
'ipv4-end-point.cc',
'udp-l4-protocol.cc',
'arp-header.cc',
@@ -24,7 +25,6 @@
'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',
@@ -34,11 +34,11 @@
'pcap-trace.cc',
'udp-impl.cc',
]
- obj.includes = '.'
headers = bld.create_obj('ns3header')
headers.source = [
'internet-node.h',
'ascii-trace.h',
'pcap-trace.h',
+ 'ipv4-header.h',
]
--- a/src/mobility/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/mobility/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -20,7 +20,6 @@
'static-speed-helper.cc',
'static-speed-mobility-model.cc',
]
- mobility.includes = '.'
headers = bld.create_obj('ns3header')
headers.source = [
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/address-utils.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#include "address-utils.h"
+
+namespace ns3 {
+
+void WriteTo (Buffer::Iterator &i, Ipv4Address ad)
+{
+ i.WriteHtonU32 (ad.GetHostOrder ());
+}
+void WriteTo (Buffer::Iterator &i, const Address &ad)
+{
+ uint8_t mac[Address::MAX_SIZE];
+ ad.CopyTo (mac);
+ i.Write (mac, ad.GetLength ());
+}
+void WriteTo (Buffer::Iterator &i, Eui48Address ad)
+{
+ uint8_t mac[6];
+ ad.CopyTo (mac);
+ i.Write (mac, 6);
+}
+
+void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad)
+{
+ ad.SetHostOrder (i.ReadNtohU32 ());
+}
+void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len)
+{
+ uint8_t mac[Address::MAX_SIZE];
+ i.Read (mac, len);
+ ad.CopyFrom (mac, len);
+}
+void ReadFrom (Buffer::Iterator &i, Eui48Address &ad)
+{
+ uint8_t mac[6];
+ i.Read (mac, 6);
+ ad.CopyFrom (mac);
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/address-utils.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2006 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+#ifndef ADDRESS_UTILS_H
+#define ADDRESS_UTILS_H
+
+#include "ns3/buffer.h"
+#include "ipv4-address.h"
+#include "address.h"
+#include "eui48-address.h"
+
+namespace ns3 {
+
+void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
+void WriteTo (Buffer::Iterator &i, const Address &ad);
+void WriteTo (Buffer::Iterator &i, Eui48Address ad);
+
+void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
+void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len);
+void ReadFrom (Buffer::Iterator &i, Eui48Address &ad);
+
+};
+
+#endif /* ADDRESS_UTILS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-header.cc Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,163 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#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 {
+
+EthernetHeader::EthernetHeader (bool hasPreamble)
+ : m_enPreambleSfd (hasPreamble),
+ m_lengthType (0)
+{}
+
+EthernetHeader::EthernetHeader ()
+ : m_enPreambleSfd (false),
+ m_lengthType (0)
+{}
+
+EthernetHeader::~EthernetHeader ()
+{}
+
+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 (Eui48Address source)
+{
+ m_source = source;
+}
+Eui48Address
+EthernetHeader::GetSource (void) const
+{
+ return m_source;
+}
+
+void
+EthernetHeader::SetDestination (Eui48Address dst)
+{
+ m_destination = dst;
+}
+Eui48Address
+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);
+ }
+ 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);
+ ReadFrom (i, m_source);
+ m_lengthType = i.ReadU16 ();
+
+ return GetSerializedSize ();
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-header.h Mon Jul 30 10:35:03 2007 +0200
@@ -0,0 +1,127 @@
+/* -*- 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 <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#ifndef ETHERNET_HEADER_H
+#define ETHERNET_HEADER_H
+
+#include "ns3/header.h"
+#include "ns3/eui48-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
+ * \param hasPreamble if true, insert and remove an ethernet preamble from the
+ * packet, if false, does not insert and remove it.
+ */
+ EthernetHeader (bool hasPreamble);
+ /**
+ * \brief Construct a null ethernet header
+ * By default, does not add or remove an ethernet preamble
+ */
+ EthernetHeader ();
+ virtual ~EthernetHeader ();
+ /**
+ * \param size The size of the payload in bytes
+ */
+ void SetLengthType (uint16_t size);
+ /**
+ * \param source The source address of this packet
+ */
+ void SetSource (Eui48Address source);
+ /**
+ * \param destination The destination address of this packet.
+ */
+ void SetDestination (Eui48Address 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
+ */
+ Eui48Address GetSource (void) const;
+ /**
+ * \return The destination address of this packet
+ */
+ Eui48Address 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);
+
+ /**
+ * If false, the preamble/sfd are not serialised/deserialised.
+ */
+ bool m_enPreambleSfd;
+ uint64_t m_preambleSfd; /// Value of the Preamble/SFD fields
+ uint16_t m_lengthType; /// Length or type of the packet
+ Eui48Address m_source; /// Source address
+ Eui48Address m_destination; /// Destination address
+};
+
+}; // namespace ns3
+
+
+#endif /* ETHERNET_HEADER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-trailer.cc Mon Jul 30 10:35:03 2007 +0200
@@ -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 <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/node/ethernet-trailer.h Mon Jul 30 10:35:03 2007 +0200
@@ -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 <emmanuelle.laprise@bluekazoo.ca>
+ */
+
+#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 */
--- a/src/node/eui48-address.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/eui48-address.cc Mon Jul 30 10:35:03 2007 +0200
@@ -1,6 +1,7 @@
#include "eui48-address.h"
#include "address.h"
#include "ns3/assert.h"
+#include <iomanip>
namespace ns3 {
@@ -58,6 +59,17 @@
}
NS_ASSERT (i == 6);
}
+void
+Eui48Address::CopyFrom (const uint8_t buffer[6])
+{
+ memcpy (m_address, buffer, 6);
+}
+void
+Eui48Address::CopyTo (uint8_t buffer[6]) const
+{
+ memcpy (buffer, m_address, 6);
+}
+
Address
Eui48Address::ConvertTo (void) const
{
@@ -92,5 +104,36 @@
return type;
}
+bool operator == (const Eui48Address &a, const Eui48Address &b)
+{
+ uint8_t ada[6];
+ uint8_t adb[6];
+ a.CopyTo (ada);
+ b.CopyTo (adb);
+ return memcmp (ada, adb, 6) == 0;
+}
+bool operator != (const Eui48Address &a, const Eui48Address &b)
+{
+ return ! (a == b);
+}
+
+std::ostream& operator<< (std::ostream& os, const Eui48Address & address)
+{
+ uint8_t ad[6];
+ address.CopyTo (ad);
+
+ os.setf (std::ios::hex, std::ios::basefield);
+ std::cout.fill('0');
+ for (uint8_t i=0; i < 5; i++)
+ {
+ os << std::setw(2) << (uint32_t)ad[i] << ":";
+ }
+ // Final byte not suffixed by ":"
+ os << std::setw(2) << (uint32_t)ad[5];
+ os.setf (std::ios::dec, std::ios::basefield);
+ std::cout.fill(' ');
+ return os;
+}
+
} // namespace ns3
--- a/src/node/eui48-address.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/eui48-address.h Mon Jul 30 10:35:03 2007 +0200
@@ -2,6 +2,7 @@
#define EUI48_ADDRESS_H
#include <stdint.h>
+#include <ostream>
namespace ns3 {
@@ -22,6 +23,19 @@
* The format of the string is "xx:xx:xx:xx:xx:xx"
*/
Eui48Address (const char *str);
+
+ /**
+ * \param buffer address in network order
+ *
+ * Copy the input address to our internal buffer.
+ */
+ void CopyFrom (const uint8_t buffer[6]);
+ /**
+ * \param buffer address in network order
+ *
+ * Copy the internal address to the input buffer.
+ */
+ void CopyTo (uint8_t buffer[6]) const;
/**
* \returns a new Address instance
*
@@ -42,8 +56,11 @@
private:
static uint8_t GetType (void);
uint8_t m_address[6];
+};
-};
+bool operator == (const Eui48Address &a, const Eui48Address &b);
+bool operator != (const Eui48Address &a, const Eui48Address &b);
+std::ostream& operator<< (std::ostream& os, const Eui48Address & address);
} // namespace ns3
--- a/src/node/ipv4-address.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/ipv4-address.cc Mon Jul 30 10:35:03 2007 +0200
@@ -145,8 +145,20 @@
}
}
+Ipv4Address
+Ipv4Address::CombineMask (Ipv4Mask const &mask) const
+{
+ return Ipv4Address (GetHostOrder () & mask.GetHostOrder ());
+}
+
+bool
+Ipv4Address::IsBroadcast (void) const
+{
+ return (m_address == 0xffffffffU);
+}
+
bool
-Ipv4Address::IsMulticast (void)
+Ipv4Address::IsMulticast (void) const
{
// XXX
return false;
--- a/src/node/ipv4-address.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/ipv4-address.h Mon Jul 30 10:35:03 2007 +0200
@@ -28,6 +28,8 @@
namespace ns3 {
+class Ipv4Mask;
+
/** Ipv4 addresses are stored in host order in
* this class.
*/
@@ -89,8 +91,18 @@
*/
void Print (std::ostream &os) const;
- bool IsBroadcast (void);
- bool IsMulticast (void);
+ bool IsBroadcast (void) const;
+ bool IsMulticast (void) const;
+ /**
+ * \brief Combine this address with a network mask
+ *
+ * This method returns an IPv4 address that is this address combined
+ * (bitwise and) with a network mask, yielding an IPv4 network
+ * address.
+ *
+ * \param a network mask
+ */
+ Ipv4Address CombineMask (Ipv4Mask const &mask) const;
Address ConvertTo (void) const;
static Ipv4Address ConvertFrom (const Address &address);
--- a/src/node/ipv4.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/ipv4.h Mon Jul 30 10:35:03 2007 +0200
@@ -24,6 +24,7 @@
#include <stdint.h>
#include "ns3/ipv4-address.h"
#include "ns3/object.h"
+#include "ns3/callback.h"
#include "ipv4-route.h"
namespace ns3 {
@@ -31,6 +32,78 @@
class NetDevice;
class Packet;
class Ipv4Route;
+class Ipv4Header; // FIXME: ipv4-header.h needs to move from module
+ // "internet-node" to module "node"
+
+/**
+ * \brief Base class for IPv4 routing protocols.
+ *
+ * This class represents the interface between the IPv4 routing core
+ * and a specific IPv4 routing protocol. The interface is
+ * asynchronous (callback based) in order to support reactive routing
+ * protocols (e.g. AODV).
+ */
+class Ipv4RoutingProtocol : public Object
+{
+public:
+ // void (*RouteReply) (bool found, Ipv4Route route, Packet packet, Ipv4Header const &ipHeader);
+
+
+ /**
+ * \brief Callback to be invoked when route discovery is completed
+ *
+ * \param bool flag indicating whether a route was actually found;
+ * when this is false, the Ipv4Route parameter is ignored
+ *
+ * \param Ipv4Route the route found
+ *
+ * \param Packet the packet for which a route was requested; can be
+ * modified by the routing protocol
+ *
+ * \param Ipv4Header the IP header supplied to the route request
+ * method (possibly modified in case a new routing header is
+ * inserted and consequently the protocol type has to change).
+ *
+ */
+ typedef Callback<void, bool, const Ipv4Route&, Packet, const Ipv4Header&> RouteReplyCallback;
+
+ /**
+ * \brief Asynchronously requests a route for a given packet and IP header
+ *
+ * \param ipHeader IP header of the packet
+ * \param packet packet that is being sent or forwarded
+ * \param routeReply callback that will receive the route reply
+ *
+ * \returns true if the routing protocol should be able to get the
+ * route, false otherwise.
+ *
+ * This method is called whenever a node's IPv4 forwarding engine
+ * needs to lookup a route for a given packet and IP header.
+ *
+ * The routing protocol implementation may determine immediately it
+ * should not be handling this particular the route request. For
+ * instance, a routing protocol may decline to search for routes for
+ * certain classes of addresses, like link-local. In this case,
+ * RequestRoute() should return false and the routeReply callback
+ * must not be invoked.
+ *
+ * If the routing protocol implementations assumes it can provide
+ * the requested route, then it should return true, and the
+ * routeReply callback must be invoked, either immediately before
+ * returning true (synchronously), or in the future (asynchronous).
+ * The routing protocol may use any information available in the IP
+ * header and packet as routing key, although most routing protocols
+ * use only the destination address (as given by
+ * ipHeader.GetDestination ()). The routing protocol is also
+ * allowed to add a new header to the packet, which will appear
+ * immediately after the IP header, although most routing do not
+ * insert any extra header.
+ */
+ virtual bool RequestRoute (const Ipv4Header &ipHeader,
+ Packet packet,
+ RouteReplyCallback routeReply) = 0;
+};
+
/**
* \brief Access to the Ipv4 forwarding table and to the ipv4 interfaces
*
@@ -47,7 +120,20 @@
static const InterfaceId iid;
Ipv4 ();
virtual ~Ipv4 ();
-
+
+ /**
+ * \brief Register a new routing protocol to be used in this IPv4 stack
+ *
+ * \param routingProtocol new routing protocol implementation object
+ * \param priority priority to give to this routing protocol.
+ * Values may range between -32768 and +32767. The priority 0
+ * corresponds to static routing table lookups, higher values have
+ * more priority. The order by which routing protocols with the
+ * same priority value are consulted is undefined.
+ */
+ virtual void AddRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol,
+ int16_t priority) = 0;
+
/**
* \param dest destination address
* \param nextHop address of next hop.
--- a/src/node/net-device.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/net-device.cc Mon Jul 30 10:35:03 2007 +0200
@@ -22,12 +22,15 @@
#include <iostream>
#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 @@
{
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 @@
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
--- a/src/node/net-device.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/net-device.h Mon Jul 30 10:35:03 2007 +0200
@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Modified by Emmanuelle Laprise to remove dependance on LLC headers
*/
#ifndef NET_DEVICE_H
#define NET_DEVICE_H
@@ -227,6 +228,8 @@
/**
* \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 @@
* 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 @@
*/
virtual void DoDispose (void);
+ Callback<bool,Ptr<NetDevice>,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 @@
* 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 Address& dest) = 0;
+ virtual bool SendTo (Packet& p, const Address &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 @@
*/
virtual Ptr<Channel> DoGetChannel (void) const = 0;
- Ptr<Node> m_node;
+ Ptr<Node> m_node;
std::string m_name;
uint16_t m_ifIndex;
Address m_address;
@@ -290,7 +297,6 @@
bool m_isMulticast;
bool m_isPointToPoint;
Callback<void> m_linkChangeCallback;
- Callback<bool,Ptr<NetDevice>,const Packet &,uint16_t> m_receiveCallback;
};
}; // namespace ns3
--- a/src/node/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/node/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -12,7 +12,10 @@
'node.cc',
'ipv4-address.cc',
'net-device.cc',
+ 'address-utils.cc',
'llc-snap-header.cc',
+ 'ethernet-header.cc',
+ 'ethernet-trailer.cc',
'ipv4-route.cc',
'queue.cc',
'drop-tail-queue.cc',
@@ -24,7 +27,6 @@
'ipv4.cc',
'application.cc',
]
- node.includes = '.'
headers = bld.create_obj('ns3header')
headers.source = [
@@ -34,10 +36,13 @@
'node.h',
'ipv4-address.h',
'net-device.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',
--- a/src/simulator/event-id.cc Fri Jul 27 09:44:24 2007 +0200
+++ b/src/simulator/event-id.cc Mon Jul 30 10:35:03 2007 +0200
@@ -45,12 +45,12 @@
}
}
bool
-EventId::IsExpired (void)
+EventId::IsExpired (void) const
{
return Simulator::IsExpired (*this);
}
bool
-EventId::IsRunning (void)
+EventId::IsRunning (void) const
{
return !IsExpired ();
}
--- a/src/simulator/event-id.h Fri Jul 27 09:44:24 2007 +0200
+++ b/src/simulator/event-id.h Mon Jul 30 10:35:03 2007 +0200
@@ -44,8 +44,8 @@
* method.
* \returns true if the event has expired, false otherwise.
*/
- bool IsExpired (void);
- bool IsRunning (void);
+ bool IsExpired (void) const;
+ bool IsRunning (void) const;
public:
/* The following methods are semi-private
* they are supposed to be invoked only by
--- a/src/simulator/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/simulator/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -65,7 +65,6 @@
'simulator.cc',
'time-default-value.cc',
]
- sim.includes = '.'
headers = bld.create_obj('ns3header')
headers.source = [
--- a/src/wscript Fri Jul 27 09:44:24 2007 +0200
+++ b/src/wscript Mon Jul 30 10:35:03 2007 +0200
@@ -15,7 +15,8 @@
'simulator',
'node',
'internet-node',
- 'devices/p2p',
+ 'devices/point-to-point',
+ 'devices/csma-cd',
'applications',
'mobility',
)