A Discrete-Event Network Simulator
API
virtual-net-device.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/virtual-net-device.h"
45
46#include "ns3/applications-module.h"
47#include "ns3/core-module.h"
48#include "ns3/internet-module.h"
49#include "ns3/network-module.h"
50#include "ns3/point-to-point-module.h"
51
52#include <cassert>
53#include <fstream>
54#include <iostream>
55#include <string>
56
57using namespace ns3;
58
59NS_LOG_COMPONENT_DEFINE("VirtualNetDeviceExample");
60
66class Tunnel
67{
78
88 const Address& source,
89 const Address& dest,
90 uint16_t protocolNumber)
91 {
92 NS_LOG_DEBUG("Send to " << m_n3Address << ": " << *packet);
94 return true;
95 }
96
106 const Address& source,
107 const Address& dest,
108 uint16_t protocolNumber)
109 {
110 NS_LOG_DEBUG("Send to " << m_n3Address << ": " << *packet);
112 return true;
113 }
114
124 const Address& source,
125 const Address& dest,
126 uint16_t protocolNumber)
127 {
128 if (m_rng->GetValue() < 0.25)
129 {
130 NS_LOG_DEBUG("Send to " << m_n0Address << ": " << *packet);
132 }
133 else
134 {
135 NS_LOG_DEBUG("Send to " << m_n1Address << ": " << *packet);
137 }
138 return true;
139 }
140
146 {
147 Ptr<Packet> packet = socket->Recv(65535, 0);
148 NS_LOG_DEBUG("N3SocketRecv: " << *packet);
149 m_n3Tap->Receive(packet,
150 0x0800,
153 NetDevice::PACKET_HOST);
154 }
155
161 {
162 Ptr<Packet> packet = socket->Recv(65535, 0);
163 NS_LOG_DEBUG("N0SocketRecv: " << *packet);
164 m_n0Tap->Receive(packet,
165 0x0800,
168 NetDevice::PACKET_HOST);
169 }
170
176 {
177 Ptr<Packet> packet = socket->Recv(65535, 0);
178 NS_LOG_DEBUG("N1SocketRecv: " << *packet);
179 m_n1Tap->Receive(packet,
180 0x0800,
183 NetDevice::PACKET_HOST);
184 }
185
186 public:
197 Ptr<Node> n0,
198 Ptr<Node> n1,
199 Ipv4Address n3Addr,
200 Ipv4Address n0Addr,
201 Ipv4Address n1Addr)
202 : m_n3Address(n3Addr),
203 m_n0Address(n0Addr),
204 m_n1Address(n1Addr)
205 {
206 m_rng = CreateObject<UniformRandomVariable>();
207 m_n3Socket = Socket::CreateSocket(n3, TypeId::LookupByName("ns3::UdpSocketFactory"));
208 m_n3Socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 667));
210
211 m_n0Socket = Socket::CreateSocket(n0, TypeId::LookupByName("ns3::UdpSocketFactory"));
212 m_n0Socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 667));
214
215 m_n1Socket = Socket::CreateSocket(n1, TypeId::LookupByName("ns3::UdpSocketFactory"));
216 m_n1Socket->Bind(InetSocketAddress(Ipv4Address::GetAny(), 667));
218
219 // n0 tap device
220 m_n0Tap = CreateObject<VirtualNetDevice>();
221 m_n0Tap->SetAddress(Mac48Address("11:00:01:02:03:01"));
223 n0->AddDevice(m_n0Tap);
224 Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4>();
225 uint32_t i = ipv4->AddInterface(m_n0Tap);
226 ipv4->AddAddress(i,
227 Ipv4InterfaceAddress(Ipv4Address("11.0.0.1"), Ipv4Mask("255.255.255.0")));
228 ipv4->SetUp(i);
229
230 // n1 tap device
231 m_n1Tap = CreateObject<VirtualNetDevice>();
232 m_n1Tap->SetAddress(Mac48Address("11:00:01:02:03:02"));
234 n1->AddDevice(m_n1Tap);
235 ipv4 = n1->GetObject<Ipv4>();
236 i = ipv4->AddInterface(m_n1Tap);
237 ipv4->AddAddress(i,
238 Ipv4InterfaceAddress(Ipv4Address("11.0.0.1"), Ipv4Mask("255.255.255.0")));
239 ipv4->SetUp(i);
240
241 // n3 tap device
242 m_n3Tap = CreateObject<VirtualNetDevice>();
243 m_n3Tap->SetAddress(Mac48Address("11:00:01:02:03:04"));
245 n3->AddDevice(m_n3Tap);
246 ipv4 = n3->GetObject<Ipv4>();
247 i = ipv4->AddInterface(m_n3Tap);
248 ipv4->AddAddress(
249 i,
250 Ipv4InterfaceAddress(Ipv4Address("11.0.0.254"), Ipv4Mask("255.255.255.0")));
251 ipv4->SetUp(i);
252 }
253};
254
255int
256main(int argc, char* argv[])
257{
258 // Users may find it convenient to turn on explicit logging
259 // for selected modules; the below lines suggest how to do this
260#if 0
261 LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
262#endif
263 Packet::EnablePrinting();
264
265 // Set up some default values for the simulation. Use the
266 Config::SetDefault("ns3::OnOffApplication::PacketSize", UintegerValue(210));
267 Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue("448kb/s"));
268
269 // Allow the user to override any of the defaults and the above
270 // Config::SetDefault ()s at run-time, via command-line arguments
271 CommandLine cmd(__FILE__);
272 cmd.Parse(argc, argv);
273
274 NS_LOG_INFO("Create nodes.");
276 c.Create(4);
277 NodeContainer n0n2 = NodeContainer(c.Get(0), c.Get(2));
278 NodeContainer n1n2 = NodeContainer(c.Get(1), c.Get(2));
279 NodeContainer n3n2 = NodeContainer(c.Get(3), c.Get(2));
280
281 InternetStackHelper internet;
282 internet.Install(c);
283
284 // We create the channels first without any IP addressing information
285 NS_LOG_INFO("Create channels.");
287 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
288 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
289 NetDeviceContainer d0d2 = p2p.Install(n0n2);
290
291 NetDeviceContainer d1d2 = p2p.Install(n1n2);
292
293 p2p.SetDeviceAttribute("DataRate", StringValue("1500kbps"));
294 p2p.SetChannelAttribute("Delay", StringValue("10ms"));
295 NetDeviceContainer d3d2 = p2p.Install(n3n2);
296
297 // Later, we add IP addresses.
298 NS_LOG_INFO("Assign IP Addresses.");
300 ipv4.SetBase("10.1.1.0", "255.255.255.0");
302
303 ipv4.SetBase("10.1.2.0", "255.255.255.0");
305
306 ipv4.SetBase("10.1.3.0", "255.255.255.0");
307 Ipv4InterfaceContainer i3i2 = ipv4.Assign(d3d2);
308
309 // Create router nodes, initialize routing database and set up the routing
310 // tables in the nodes.
311 Ipv4GlobalRoutingHelper::PopulateRoutingTables();
312
313 // Add the tunnels n0<=>n3 and n1<=>n3
314 Tunnel tunnel(c.Get(3),
315 c.Get(0),
316 c.Get(1),
317 i3i2.GetAddress(0),
318 i0i2.GetAddress(0),
319 i1i2.GetAddress(0));
320
321 // Create the OnOff application to send UDP datagrams of size
322 // 210 bytes at a rate of 448 Kb/s
323 NS_LOG_INFO("Create Applications.");
324 uint16_t port = 9; // Discard port (RFC 863)
325 OnOffHelper onoff("ns3::UdpSocketFactory",
326 Address(InetSocketAddress(Ipv4Address("11.0.0.254"), port)));
327 onoff.SetConstantRate(DataRate("448kb/s"));
328 ApplicationContainer apps = onoff.Install(c.Get(0));
329 apps.Start(Seconds(1.0));
330 apps.Stop(Seconds(10.0));
331
332 // Create a packet sink to receive these packets
333 PacketSinkHelper sink("ns3::UdpSocketFactory",
334 Address(InetSocketAddress(Ipv4Address::GetAny(), port)));
335 apps = sink.Install(c.Get(3));
336 apps.Start(Seconds(1.0));
337 // apps.Stop (Seconds (10.0));
338
339 // Create a similar flow from n3 to n1, starting at time 1.1 seconds
340 onoff.SetAttribute("Remote", AddressValue(InetSocketAddress(Ipv4Address("11.0.0.1"), port)));
341 apps = onoff.Install(c.Get(3));
342 apps.Start(Seconds(1.1));
343 apps.Stop(Seconds(10.0));
344
345 // Create a packet sink to receive these packets
346 apps = sink.Install(c.Get(1));
347 apps.Start(Seconds(1.1));
348 // apps.Stop (Seconds (10.0));
349
350 AsciiTraceHelper ascii;
351 p2p.EnableAsciiAll(ascii.CreateFileStream("virtual-net-device.tr"));
352 p2p.EnablePcapAll("virtual-net-device");
353
354 NS_LOG_INFO("Run Simulation.");
355 Simulator::Run();
356 Simulator::Destroy();
357 NS_LOG_INFO("Done.");
358
359 return 0;
360}
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:92
AttributeValue implementation for Address.
holds a vector of ns3::Application pointers.
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter.
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
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...
Manage ASCII trace files for device models.
Definition: trace-helper.h:173
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.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
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:258
an EUI-48 address
Definition: mac48-address.h:46
holds a vector of ns3::NetDevice pointers
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
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
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 ...
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.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:126
virtual Ptr< Packet > Recv(uint32_t maxSize, uint32_t flags)=0
Read data from the socket.
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:42
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
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:45
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
#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:328
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:691
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition: log.h:107
void LogComponentEnable(const char *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:358
cmd
Definition: second.py:33
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition: wifi-tcp.cc:55