A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
virtual-net-device.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Based on simple-global-routing.cc
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 // - CBR/UDP flows from n0 to n3, and from n3 to n1
31 // - FTP/TCP flow from n0 to n3, starting at time 1.2 to time 1.35 sec.
32 // - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
33 // (i.e., DataRate of 448,000 bps)
34 // - DropTail queues
35 // - Tracing of queues and packet receptions to file "virtual-net-device.tr"
36 
37 // Tunneling changes (relative to the simple-global-routing example):
38 // n0 will receive an extra virtual interface with address 11.0.0.1
39 // n1 will also receive an extra virtual interface with the same address 11.0.0.1
40 // n3 will receive an extra virtual interface with address 11.0.0.254
41 // The flows will be between 11.0.0.x (tunnel) addresses instead of 10.1.x.y ones
42 // n3 will decide, on a per-packet basis, via random number, whether to
43 // send the packet to n0 or to n1.
44 //
45 // Note: here we create a tunnel where IP packets are tunneled over
46 // UDP/IP, but tunneling directly IP-over-IP would also be possible;
47 // see src/node/ipv4-raw-socket-factory.h.
48 
49 #include <iostream>
50 #include <fstream>
51 #include <string>
52 #include <cassert>
53 
54 #include "ns3/core-module.h"
55 #include "ns3/network-module.h"
56 #include "ns3/internet-module.h"
57 #include "ns3/point-to-point-module.h"
58 #include "ns3/applications-module.h"
59 #include "ns3/virtual-net-device.h"
60 #include "ns3/ipv4-global-routing-helper.h"
61 
62 using namespace ns3;
63 
64 NS_LOG_COMPONENT_DEFINE ("VirtualNetDeviceExample");
65 
66 class Tunnel
67 {
78 
79 
80  bool
81  N0VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
82  {
83  NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
84  m_n0Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
85  return true;
86  }
87 
88  bool
89  N1VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
90  {
91  NS_LOG_DEBUG ("Send to " << m_n3Address << ": " << *packet);
92  m_n1Socket->SendTo (packet, 0, InetSocketAddress (m_n3Address, 667));
93  return true;
94  }
95 
96  bool
97  N3VirtualSend (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber)
98  {
99  if (m_rng->GetValue () < 0.25)
100  {
101  NS_LOG_DEBUG ("Send to " << m_n0Address << ": " << *packet);
102  m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n0Address, 667));
103  }
104  else
105  {
106  NS_LOG_DEBUG ("Send to " << m_n1Address << ": " << *packet);
107  m_n3Socket->SendTo (packet, 0, InetSocketAddress (m_n1Address, 667));
108  }
109  return true;
110  }
111 
112  void N3SocketRecv (Ptr<Socket> socket)
113  {
114  Ptr<Packet> packet = socket->Recv (65535, 0);
115  NS_LOG_DEBUG ("N3SocketRecv: " << *packet);
116  SocketAddressTag socketAddressTag;
117  packet->RemovePacketTag (socketAddressTag);
118  m_n3Tap->Receive (packet, 0x0800, m_n3Tap->GetAddress (), m_n3Tap->GetAddress (), NetDevice::PACKET_HOST);
119  }
120 
121  void N0SocketRecv (Ptr<Socket> socket)
122  {
123  Ptr<Packet> packet = socket->Recv (65535, 0);
124  NS_LOG_DEBUG ("N0SocketRecv: " << *packet);
125  SocketAddressTag socketAddressTag;
126  packet->RemovePacketTag (socketAddressTag);
127  m_n0Tap->Receive (packet, 0x0800, m_n0Tap->GetAddress (), m_n0Tap->GetAddress (), NetDevice::PACKET_HOST);
128  }
129 
130  void N1SocketRecv (Ptr<Socket> socket)
131  {
132  Ptr<Packet> packet = socket->Recv (65535, 0);
133  NS_LOG_DEBUG ("N1SocketRecv: " << *packet);
134  SocketAddressTag socketAddressTag;
135  packet->RemovePacketTag (socketAddressTag);
136  m_n1Tap->Receive (packet, 0x0800, m_n1Tap->GetAddress (), m_n1Tap->GetAddress (), NetDevice::PACKET_HOST);
137  }
138 
139 public:
140 
142  Ipv4Address n3Addr, Ipv4Address n0Addr, Ipv4Address n1Addr)
143  : m_n3Address (n3Addr), m_n0Address (n0Addr), m_n1Address (n1Addr)
144  {
145  m_rng = CreateObject<UniformRandomVariable> ();
146  m_n3Socket = Socket::CreateSocket (n3, TypeId::LookupByName ("ns3::UdpSocketFactory"));
147  m_n3Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
148  m_n3Socket->SetRecvCallback (MakeCallback (&Tunnel::N3SocketRecv, this));
149 
150  m_n0Socket = Socket::CreateSocket (n0, TypeId::LookupByName ("ns3::UdpSocketFactory"));
151  m_n0Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
152  m_n0Socket->SetRecvCallback (MakeCallback (&Tunnel::N0SocketRecv, this));
153 
154  m_n1Socket = Socket::CreateSocket (n1, TypeId::LookupByName ("ns3::UdpSocketFactory"));
155  m_n1Socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 667));
156  m_n1Socket->SetRecvCallback (MakeCallback (&Tunnel::N1SocketRecv, this));
157 
158  // n0 tap device
159  m_n0Tap = CreateObject<VirtualNetDevice> ();
160  m_n0Tap->SetAddress (Mac48Address ("11:00:01:02:03:01"));
161  m_n0Tap->SetSendCallback (MakeCallback (&Tunnel::N0VirtualSend, this));
162  n0->AddDevice (m_n0Tap);
163  Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4> ();
164  uint32_t i = ipv4->AddInterface (m_n0Tap);
165  ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.1"), Ipv4Mask ("255.255.255.0")));
166  ipv4->SetUp (i);
167 
168  // n1 tap device
169  m_n1Tap = CreateObject<VirtualNetDevice> ();
170  m_n1Tap->SetAddress (Mac48Address ("11:00:01:02:03:02"));
171  m_n1Tap->SetSendCallback (MakeCallback (&Tunnel::N1VirtualSend, this));
172  n1->AddDevice (m_n1Tap);
173  ipv4 = n1->GetObject<Ipv4> ();
174  i = ipv4->AddInterface (m_n1Tap);
175  ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.1"), Ipv4Mask ("255.255.255.0")));
176  ipv4->SetUp (i);
177 
178  // n3 tap device
179  m_n3Tap = CreateObject<VirtualNetDevice> ();
180  m_n3Tap->SetAddress (Mac48Address ("11:00:01:02:03:04"));
181  m_n3Tap->SetSendCallback (MakeCallback (&Tunnel::N3VirtualSend, this));
182  n3->AddDevice (m_n3Tap);
183  ipv4 = n3->GetObject<Ipv4> ();
184  i = ipv4->AddInterface (m_n3Tap);
185  ipv4->AddAddress (i, Ipv4InterfaceAddress (Ipv4Address ("11.0.0.254"), Ipv4Mask ("255.255.255.0")));
186  ipv4->SetUp (i);
187 
188  }
189 
190 
191 };
192 
193 
194 
195 int
196 main (int argc, char *argv[])
197 {
198  // Users may find it convenient to turn on explicit debugging
199  // for selected modules; the below lines suggest how to do this
200 #if 0
201  LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
202 #endif
204 
205 
206  // Set up some default values for the simulation. Use the
207  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
208  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
209 
210  //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);
211 
212  // Allow the user to override any of the defaults and the above
213  // DefaultValue::Bind ()s at run-time, via command-line arguments
214  CommandLine cmd;
215  cmd.Parse (argc, argv);
216 
217  // Here, we will explicitly create four nodes. In more sophisticated
218  // topologies, we could configure a node factory.
219  NS_LOG_INFO ("Create nodes.");
220  NodeContainer c;
221  c.Create (4);
222  NodeContainer n0n2 = NodeContainer (c.Get (0), c.Get (2));
223  NodeContainer n1n2 = NodeContainer (c.Get (1), c.Get (2));
224  NodeContainer n3n2 = NodeContainer (c.Get (3), c.Get (2));
225 
226  InternetStackHelper internet;
227  internet.Install (c);
228 
229  // We create the channels first without any IP addressing information
230  NS_LOG_INFO ("Create channels.");
231  PointToPointHelper p2p;
232  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
233  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
234  NetDeviceContainer d0d2 = p2p.Install (n0n2);
235 
236  NetDeviceContainer d1d2 = p2p.Install (n1n2);
237 
238  p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps"));
239  p2p.SetChannelAttribute ("Delay", StringValue ("10ms"));
240  NetDeviceContainer d3d2 = p2p.Install (n3n2);
241 
242  // Later, we add IP addresses.
243  NS_LOG_INFO ("Assign IP Addresses.");
244  Ipv4AddressHelper ipv4;
245  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
246  Ipv4InterfaceContainer i0i2 = ipv4.Assign (d0d2);
247 
248  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
249  Ipv4InterfaceContainer i1i2 = ipv4.Assign (d1d2);
250 
251  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
252  Ipv4InterfaceContainer i3i2 = ipv4.Assign (d3d2);
253 
254  // Create router nodes, initialize routing database and set up the routing
255  // tables in the nodes.
257 
258  // Add the tunnels
259  Tunnel tunnel (c.Get (3), c.Get (0), c.Get (1),
260  i3i2.GetAddress (0), i0i2.GetAddress (0), i1i2.GetAddress (0));
261 
262  // Create the OnOff application to send UDP datagrams of size
263  // 210 bytes at a rate of 448 Kb/s
264  NS_LOG_INFO ("Create Applications.");
265  uint16_t port = 9; // Discard port (RFC 863)
266  OnOffHelper onoff ("ns3::UdpSocketFactory",
267  Address (InetSocketAddress (Ipv4Address ("11.0.0.254"), port)));
268  onoff.SetConstantRate (DataRate ("448kb/s"));
269  ApplicationContainer apps = onoff.Install (c.Get (0));
270  apps.Start (Seconds (1.0));
271  apps.Stop (Seconds (10.0));
272 
273  // Create a packet sink to receive these packets
274  PacketSinkHelper sink ("ns3::UdpSocketFactory",
276  apps = sink.Install (c.Get (3));
277  apps.Start (Seconds (1.0));
278  //apps.Stop (Seconds (10.0));
279 
280  // Create a similar flow from n3 to n1, starting at time 1.1 seconds
281  onoff.SetAttribute ("Remote",
282  AddressValue (InetSocketAddress (Ipv4Address ("11.0.0.1"), port)));
283  apps = onoff.Install (c.Get (3));
284  apps.Start (Seconds (1.1));
285  apps.Stop (Seconds (10.0));
286 
287  // Create a packet sink to receive these packets
288  apps = sink.Install (c.Get (1));
289  apps.Start (Seconds (1.1));
290  //apps.Stop (Seconds (10.0));
291 
292  AsciiTraceHelper ascii;
293  p2p.EnableAsciiAll (ascii.CreateFileStream ("virtual-net-device.tr"));
294  p2p.EnablePcapAll ("virtual-net-device");
295 
296  NS_LOG_INFO ("Run Simulation.");
297  Simulator::Run ();
299  NS_LOG_INFO ("Done.");
300 
301  return 0;
302 }
holds a vector of ns3::Application pointers.
virtual uint32_t AddInterface(Ptr< NetDevice > device)=0
Manage ASCII trace files for device models.
Definition: trace-helper.h:128
an Inet address class
static Ipv4Address GetAny(void)
Ipv4Address m_n1Address
NodeContainer n1n2
Definition: red-tests.cc:63
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
holds a vector of std::pair of Ptr and interface index.
static void PopulateRoutingTables(void)
Build a routing database and initialize the routing tables of the nodes in the simulation.
Ptr< UniformRandomVariable > m_rng
hold variables of type string
Definition: string.h:19
NetDeviceContainer Install(NodeContainer c)
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
Ptr< VirtualNetDevice > m_n0Tap
void N3SocketRecv(Ptr< Socket > socket)
static void Run(void)
Run the simulation until one of:
Definition: simulator.cc:157
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Definition: log.h:298
Ipv4Address m_n3Address
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
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. ...
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:42
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:86
Ptr< Socket > m_n1Socket
Class for representing data rates.
Definition: data-rate.h:71
Ptr< Socket > m_n3Socket
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
static void EnablePrinting(void)
By default, packets do not keep around enough metadata to perform the operations requested by the Pri...
Definition: packet.cc:552
virtual void SetUp(uint32_t interface)=0
Hold an unsigned integer type.
Definition: uinteger.h:46
holds a vector of ns3::NetDevice pointers
Ptr< VirtualNetDevice > m_n1Tap
Ipv4InterfaceContainer i0i2
Definition: red-tests.cc:68
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:948
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
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:71
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
Parse command-line arguments.
Definition: command-line.h:152
static void Destroy(void)
Every event scheduled by the Simulator::insertAtDestroy method is invoked.
Definition: simulator.cc:121
bool N0VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:667
void SetConstantRate(DataRate dataRate, uint32_t packetSize=512)
Helper function to set a constant rate source.
keep track of a set of node pointers.
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
an EUI-48 address
Definition: mac48-address.h:41
NodeContainer n0n2
Definition: red-tests.cc:62
bool N3VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
Ptr< VirtualNetDevice > m_n3Tap
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
hold objects of type ns3::Address
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
uint32_t AddDevice(Ptr< NetDevice > device)
Definition: node.cc:118
a class to store IPv4 address information on an interface
Packet addressed oo us.
Definition: net-device.h:272
Ipv4InterfaceContainer i1i2
Definition: red-tests.cc:69
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
Ptr< Socket > m_n0Socket
virtual bool AddAddress(uint32_t interface, Ipv4InterfaceAddress address)=0
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
void Parse(int argc, char *argv[])
Parse the program arguments.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void EnableAsciiAll(std::string prefix)
Enable ascii trace output on each device (which is of the appropriate type) in the set of all nodes c...
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Tunnel(Ptr< Node > n3, Ptr< Node > n0, Ptr< Node > n1, Ipv4Address n3Addr, Ipv4Address n0Addr, Ipv4Address n1Addr)
Ipv4Address m_n0Address
void N0SocketRecv(Ptr< Socket > socket)
int main(int argc, char *argv[])
Ptr< T > GetObject(void) const
Definition: object.h:361
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
void N1SocketRecv(Ptr< Socket > socket)
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
void LogComponentEnable(char const *name, enum LogLevel level)
Definition: log.cc:311
static TypeId LookupByName(std::string name)
Definition: type-id.cc:536
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
bool N1VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)