A Discrete-Event Network Simulator
API
virtual-net-device-example.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * Based on simple-global-routing.cc
16  * The Tunnel class adds two tunnels, n0<=>n3 and n1<=>n3
17  */
18 
19 // Network topology
20 //
21 // n0
22 // \ 5 Mb/s, 2ms
23 // \ 1.5Mb/s, 10ms
24 // n2 -------------------------n3
25 // /
26 // / 5 Mb/s, 2ms
27 // n1
28 //
29 // - all links are point-to-point links with indicated one-way BW/delay
30 // - Tracing of queues and packet receptions to file "virtual-net-device.tr"
31 
32 // Tunneling changes (relative to the simple-global-routing example):
33 // - n0 will receive an extra virtual interface with hardcoded inner-tunnel address 11.0.0.1
34 // - n1 will also receive an extra virtual interface with the same inner-tunnel address 11.0.0.1
35 // - n3 will receive an extra virtual interface with inner-tunnel address 11.0.0.254
36 // - The flows will be between 11.0.0.x (inner-tunnel) addresses instead of 10.1.x.y ones
37 // - n3 will decide, on a per-packet basis, via random number, whether to
38 // send the packet to n0 or to n1.
39 //
40 // Note: here we create a tunnel where IP packets are tunneled over
41 // UDP/IP, but tunneling directly IP-over-IP would also be possible;
42 // see src/node/ipv4-raw-socket-factory.h.
43 
44 #include "ns3/applications-module.h"
45 #include "ns3/core-module.h"
46 #include "ns3/internet-module.h"
47 #include "ns3/network-module.h"
48 #include "ns3/point-to-point-module.h"
49 #include "ns3/virtual-net-device.h"
50 
51 #include <cassert>
52 #include <fstream>
53 #include <iostream>
54 #include <string>
55 
56 using namespace ns3;
57 
58 NS_LOG_COMPONENT_DEFINE("VirtualNetDeviceExample");
59 
65 class Tunnel
66 {
77 
87  const Address& source,
88  const Address& dest,
89  uint16_t protocolNumber)
90  {
91  NS_LOG_DEBUG("Send to " << m_n3Address << ": " << *packet);
92  m_n0Socket->SendTo(packet, 0, InetSocketAddress(m_n3Address, 667));
93  return true;
94  }
95 
105  const Address& source,
106  const Address& dest,
107  uint16_t protocolNumber)
108  {
109  NS_LOG_DEBUG("Send to " << m_n3Address << ": " << *packet);
110  m_n1Socket->SendTo(packet, 0, InetSocketAddress(m_n3Address, 667));
111  return true;
112  }
113 
123  const Address& source,
124  const Address& dest,
125  uint16_t protocolNumber)
126  {
127  if (m_rng->GetValue() < 0.25)
128  {
129  NS_LOG_DEBUG("Send to " << m_n0Address << ": " << *packet);
130  m_n3Socket->SendTo(packet, 0, InetSocketAddress(m_n0Address, 667));
131  }
132  else
133  {
134  NS_LOG_DEBUG("Send to " << m_n1Address << ": " << *packet);
135  m_n3Socket->SendTo(packet, 0, InetSocketAddress(m_n1Address, 667));
136  }
137  return true;
138  }
139 
145  {
146  Ptr<Packet> packet = socket->Recv(65535, 0);
147  NS_LOG_DEBUG("N3SocketRecv: " << *packet);
148  m_n3Tap->Receive(packet,
149  0x0800,
150  m_n3Tap->GetAddress(),
151  m_n3Tap->GetAddress(),
153  }
154 
160  {
161  Ptr<Packet> packet = socket->Recv(65535, 0);
162  NS_LOG_DEBUG("N0SocketRecv: " << *packet);
163  m_n0Tap->Receive(packet,
164  0x0800,
165  m_n0Tap->GetAddress(),
166  m_n0Tap->GetAddress(),
168  }
169 
175  {
176  Ptr<Packet> packet = socket->Recv(65535, 0);
177  NS_LOG_DEBUG("N1SocketRecv: " << *packet);
178  m_n1Tap->Receive(packet,
179  0x0800,
180  m_n1Tap->GetAddress(),
181  m_n1Tap->GetAddress(),
183  }
184 
185  public:
196  Ptr<Node> n0,
197  Ptr<Node> n1,
198  Ipv4Address n3Addr,
199  Ipv4Address n0Addr,
200  Ipv4Address n1Addr)
201  : m_n3Address(n3Addr),
202  m_n0Address(n0Addr),
203  m_n1Address(n1Addr)
204  {
205  m_rng = CreateObject<UniformRandomVariable>();
206  m_n3Socket = Socket::CreateSocket(n3, TypeId::LookupByName("ns3::UdpSocketFactory"));
207  m_n3Socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 667));
209 
210  m_n0Socket = Socket::CreateSocket(n0, TypeId::LookupByName("ns3::UdpSocketFactory"));
211  m_n0Socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 667));
213 
214  m_n1Socket = Socket::CreateSocket(n1, TypeId::LookupByName("ns3::UdpSocketFactory"));
215  m_n1Socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 667));
217 
218  // n0 tap device
219  m_n0Tap = CreateObject<VirtualNetDevice>();
220  m_n0Tap->SetAddress(Mac48Address("11:00:01:02:03:01"));
222  n0->AddDevice(m_n0Tap);
223  Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4>();
224  uint32_t i = ipv4->AddInterface(m_n0Tap);
225  ipv4->AddAddress(i,
226  Ipv4InterfaceAddress(Ipv4Address("11.0.0.1"), Ipv4Mask("255.255.255.0")));
227  ipv4->SetUp(i);
228 
229  // n1 tap device
230  m_n1Tap = CreateObject<VirtualNetDevice>();
231  m_n1Tap->SetAddress(Mac48Address("11:00:01:02:03:02"));
233  n1->AddDevice(m_n1Tap);
234  ipv4 = n1->GetObject<Ipv4>();
235  i = ipv4->AddInterface(m_n1Tap);
236  ipv4->AddAddress(i,
237  Ipv4InterfaceAddress(Ipv4Address("11.0.0.1"), Ipv4Mask("255.255.255.0")));
238  ipv4->SetUp(i);
239 
240  // n3 tap device
241  m_n3Tap = CreateObject<VirtualNetDevice>();
242  m_n3Tap->SetAddress(Mac48Address("11:00:01:02:03:04"));
244  n3->AddDevice(m_n3Tap);
245  ipv4 = n3->GetObject<Ipv4>();
246  i = ipv4->AddInterface(m_n3Tap);
247  ipv4->AddAddress(
248  i,
249  Ipv4InterfaceAddress(Ipv4Address("11.0.0.254"), Ipv4Mask("255.255.255.0")));
250  ipv4->SetUp(i);
251  }
252 };
253 
254 int
255 main(int argc, char* argv[])
256 {
257  // Users may find it convenient to turn on explicit logging
258  // for selected modules; the below lines suggest how to do this
259 #if 0
260  LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
261 #endif
263 
264  // Set up some default values for the simulation. Use the
265  Config::SetDefault("ns3::OnOffApplication::PacketSize", UintegerValue(210));
266  Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue("448kb/s"));
267 
268  // Allow the user to override any of the defaults and the above
269  // Config::SetDefault ()s at run-time, via command-line arguments
270  CommandLine cmd(__FILE__);
271  cmd.Parse(argc, argv);
272 
273  NS_LOG_INFO("Create nodes.");
274  NodeContainer c;
275  c.Create(4);
276  NodeContainer n0n2 = NodeContainer(c.Get(0), c.Get(2));
277  NodeContainer n1n2 = NodeContainer(c.Get(1), c.Get(2));
278  NodeContainer n3n2 = NodeContainer(c.Get(3), c.Get(2));
279 
281  internet.Install(c);
282 
283  // We create the channels first without any IP addressing information
284  NS_LOG_INFO("Create channels.");
286  p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
287  p2p.SetChannelAttribute("Delay", StringValue("2ms"));
288  NetDeviceContainer d0d2 = p2p.Install(n0n2);
289 
290  NetDeviceContainer d1d2 = p2p.Install(n1n2);
291 
292  p2p.SetDeviceAttribute("DataRate", StringValue("1500kbps"));
293  p2p.SetChannelAttribute("Delay", StringValue("10ms"));
294  NetDeviceContainer d3d2 = p2p.Install(n3n2);
295 
296  // Later, we add IP addresses.
297  NS_LOG_INFO("Assign IP Addresses.");
299  ipv4.SetBase("10.1.1.0", "255.255.255.0");
300  Ipv4InterfaceContainer i0i2 = ipv4.Assign(d0d2);
301 
302  ipv4.SetBase("10.1.2.0", "255.255.255.0");
303  Ipv4InterfaceContainer i1i2 = ipv4.Assign(d1d2);
304 
305  ipv4.SetBase("10.1.3.0", "255.255.255.0");
306  Ipv4InterfaceContainer i3i2 = ipv4.Assign(d3d2);
307 
308  // Create router nodes, initialize routing database and set up the routing
309  // tables in the nodes.
311 
312  // Add the tunnels n0<=>n3 and n1<=>n3
313  Tunnel tunnel(c.Get(3),
314  c.Get(0),
315  c.Get(1),
316  i3i2.GetAddress(0),
317  i0i2.GetAddress(0),
318  i1i2.GetAddress(0));
319 
320  // Create the OnOff application to send UDP datagrams of size
321  // 210 bytes at a rate of 448 Kb/s
322  NS_LOG_INFO("Create Applications.");
323  uint16_t port = 9; // Discard port (RFC 863)
324  OnOffHelper onoff("ns3::UdpSocketFactory",
325  Address(InetSocketAddress(Ipv4Address("11.0.0.254"), port)));
326  onoff.SetConstantRate(DataRate("448kb/s"));
327  ApplicationContainer apps = onoff.Install(c.Get(0));
328  apps.Start(Seconds(1.0));
329  apps.Stop(Seconds(10.0));
330 
331  // Create a packet sink to receive these packets
332  PacketSinkHelper sink("ns3::UdpSocketFactory",
334  apps = sink.Install(c.Get(3));
335  apps.Start(Seconds(1.0));
336  // apps.Stop (Seconds (10.0));
337 
338  // Create a similar flow from n3 to n1, starting at time 1.1 seconds
339  onoff.SetAttribute("Remote", AddressValue(InetSocketAddress(Ipv4Address("11.0.0.1"), port)));
340  apps = onoff.Install(c.Get(3));
341  apps.Start(Seconds(1.1));
342  apps.Stop(Seconds(10.0));
343 
344  // Create a packet sink to receive these packets
345  apps = sink.Install(c.Get(1));
346  apps.Start(Seconds(1.1));
347  // apps.Stop (Seconds (10.0));
348 
349  AsciiTraceHelper ascii;
350  p2p.EnableAsciiAll(ascii.CreateFileStream("virtual-net-device.tr"));
351  p2p.EnablePcapAll("virtual-net-device");
352 
353  NS_LOG_INFO("Run Simulation.");
354  Simulator::Run();
356  NS_LOG_INFO("Done.");
357 
358  return 0;
359 }
Ipv4InterfaceContainer i0i2
IPv4 interface container i0 + i2.
NodeContainer n1n2
Nodecontainer n1 + n2.
Ipv4InterfaceContainer i1i2
IPv4 interface container i1 + i2.
NodeContainer n0n2
Nodecontainer n0 + n2.
Tunnel class - its goal is to create and manage the tunnels between endpoints.
void N0SocketRecv(Ptr< Socket > socket)
Receive a packet on the N0 VirtualNetDevice.
bool N0VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Send a packet through the N0 VirtualNetDevice.
Ptr< Socket > m_n3Socket
Socket on the N3 node.
void N3SocketRecv(Ptr< Socket > socket)
Receive a packet on the N3 VirtualNetDevice.
Ptr< Socket > m_n1Socket
Socket on the N1 node.
Ipv4Address m_n1Address
Address of the N1 node.
Ipv4Address m_n3Address
Address of the N3 node.
Ipv4Address m_n0Address
Address of the N0 node.
bool N3VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Send a packet through the N3 VirtualNetDevice.
Ptr< UniformRandomVariable > m_rng
Random number generator.
void N1SocketRecv(Ptr< Socket > socket)
Receive a packet on the N1 VirtualNetDevice.
Ptr< VirtualNetDevice > m_n0Tap
VirtualNetDevice on the N0 node.
Ptr< VirtualNetDevice > m_n3Tap
VirtualNetDevice on the N3 node.
bool N1VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Send a packet through the N1 VirtualNetDevice.
Ptr< Socket > m_n0Socket
Socket on the N0 node.
Ptr< VirtualNetDevice > m_n1Tap
VirtualNetDevice on the N1 node.
Tunnel(Ptr< Node > n3, Ptr< Node > n0, Ptr< Node > n1, Ipv4Address n3Addr, Ipv4Address n0Addr, Ipv4Address n1Addr)
Constructor.
a polymophic address class
Definition: address.h:101
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Manage ASCII trace files for device models.
Definition: trace-helper.h:174
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
Parse command-line arguments.
Definition: command-line.h:232
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
static Ipv4Address GetAny()
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
a class to store IPv4 address information on an interface
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
an EUI-48 address
Definition: mac48-address.h:46
holds a vector of ns3::NetDevice pointers
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
static void EnablePrinting()
Enable printing packets metadata.
Definition: packet.cc:596
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Build a set of PointToPointNetDevice objects.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
Hold variables of type string.
Definition: string.h:56
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:835
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
Address GetAddress() const override
void SetAddress(Address address) override
Set the address of this interface.
bool Receive(Ptr< Packet > packet, uint16_t protocol, const Address &source, const Address &destination, PacketType packetType)
void SetSendCallback(SendCallback transmitCb)
Set the user callback to be called when a L2 packet is to be transmitted.
uint16_t port
Definition: dsdv-manet.cc:44
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:302
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition: log.h:104
cmd
Definition: second.py:40
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55