A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
rip-simple-network.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016 Universita' di Firenze, Italy
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
7 */
8
9// Network topology
10//
11// SRC
12// |<=== source network
13// A-----B
14// \ / \ all networks have cost 1, except
15// \ / | for the direct link from C to D, which
16// C / has cost 10
17// | /
18// |/
19// D
20// |<=== target network
21// DST
22//
23//
24// A, B, C and D are RIPng routers.
25// A and D are configured with static addresses.
26// SRC and DST will exchange packets.
27//
28// After about 3 seconds, the topology is built, and Echo Reply will be received.
29// After 40 seconds, the link between B and D will break, causing a route failure.
30// After 44 seconds from the failure, the routers will recovery from the failure.
31// Split Horizoning should affect the recovery time, but it is not. See the manual
32// for an explanation of this effect.
33//
34// If "showPings" is enabled, the user will see:
35// 1) if the ping has been acknowledged
36// 2) if a Destination Unreachable has been received by the sender
37// 3) nothing, when the Echo Request has been received by the destination but
38// the Echo Reply is unable to reach the sender.
39// Examining the .pcap files with Wireshark can confirm this effect.
40
41#include "ns3/core-module.h"
42#include "ns3/csma-module.h"
43#include "ns3/internet-apps-module.h"
44#include "ns3/internet-module.h"
45#include "ns3/ipv4-routing-table-entry.h"
46#include "ns3/ipv4-static-routing-helper.h"
47
48#include <fstream>
49
50using namespace ns3;
51
52NS_LOG_COMPONENT_DEFINE("RipSimpleRouting");
53
54void
55TearDownLink(Ptr<Node> nodeA, Ptr<Node> nodeB, uint32_t interfaceA, uint32_t interfaceB)
56{
57 nodeA->GetObject<Ipv4>()->SetDown(interfaceA);
58 nodeB->GetObject<Ipv4>()->SetDown(interfaceB);
59}
60
61int
62main(int argc, char** argv)
63{
64 bool verbose = false;
65 bool printRoutingTables = false;
66 bool showPings = false;
67 std::string SplitHorizon("PoisonReverse");
68
69 CommandLine cmd(__FILE__);
70 cmd.AddValue("verbose", "turn on log components", verbose);
71 cmd.AddValue("printRoutingTables",
72 "Print routing tables at 30, 60 and 90 seconds",
73 printRoutingTables);
74 cmd.AddValue("showPings", "Show Ping reception", showPings);
75 cmd.AddValue("splitHorizonStrategy",
76 "Split Horizon strategy to use (NoSplitHorizon, SplitHorizon, PoisonReverse)",
77 SplitHorizon);
78 cmd.Parse(argc, argv);
79
80 if (verbose)
81 {
83 LogComponentEnable("RipSimpleRouting", LOG_LEVEL_INFO);
85 LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL);
86 LogComponentEnable("Icmpv4L4Protocol", LOG_LEVEL_ALL);
87 LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL);
90 }
91
92 if (SplitHorizon == "NoSplitHorizon")
93 {
94 Config::SetDefault("ns3::Rip::SplitHorizon", EnumValue(Rip::NO_SPLIT_HORIZON));
95 }
96 else if (SplitHorizon == "SplitHorizon")
97 {
98 Config::SetDefault("ns3::Rip::SplitHorizon", EnumValue(Rip::SPLIT_HORIZON));
99 }
100 else
101 {
102 Config::SetDefault("ns3::Rip::SplitHorizon", EnumValue(Rip::POISON_REVERSE));
103 }
104
105 NS_LOG_INFO("Create nodes.");
107 Names::Add("SrcNode", src);
109 Names::Add("DstNode", dst);
111 Names::Add("RouterA", a);
113 Names::Add("RouterB", b);
115 Names::Add("RouterC", c);
117 Names::Add("RouterD", d);
118 NodeContainer net1(src, a);
119 NodeContainer net2(a, b);
120 NodeContainer net3(a, c);
121 NodeContainer net4(b, c);
122 NodeContainer net5(c, d);
123 NodeContainer net6(b, d);
124 NodeContainer net7(d, dst);
125 NodeContainer routers(a, b, c, d);
126 NodeContainer nodes(src, dst);
127
128 NS_LOG_INFO("Create channels.");
130 csma.SetChannelAttribute("DataRate", DataRateValue(5000000));
131 csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
132 NetDeviceContainer ndc1 = csma.Install(net1);
133 NetDeviceContainer ndc2 = csma.Install(net2);
134 NetDeviceContainer ndc3 = csma.Install(net3);
135 NetDeviceContainer ndc4 = csma.Install(net4);
136 NetDeviceContainer ndc5 = csma.Install(net5);
137 NetDeviceContainer ndc6 = csma.Install(net6);
138 NetDeviceContainer ndc7 = csma.Install(net7);
139
140 NS_LOG_INFO("Create IPv4 and routing");
141 RipHelper ripRouting;
142
143 // Rule of thumb:
144 // Interfaces are added sequentially, starting from 0
145 // However, interface 0 is always the loopback...
146 ripRouting.ExcludeInterface(a, 1);
147 ripRouting.ExcludeInterface(d, 3);
148
149 ripRouting.SetInterfaceMetric(c, 3, 10);
150 ripRouting.SetInterfaceMetric(d, 1, 10);
151
153 listRH.Add(ripRouting, 0);
154 // Ipv4StaticRoutingHelper staticRh;
155 // listRH.Add (staticRh, 5);
156
158 internet.SetIpv6StackInstall(false);
159 internet.SetRoutingHelper(listRH);
160 internet.Install(routers);
161
162 InternetStackHelper internetNodes;
163 internetNodes.SetIpv6StackInstall(false);
164 internetNodes.Install(nodes);
165
166 // Assign addresses.
167 // The source and destination networks have global addresses
168 // The "core" network just needs link-local addresses for routing.
169 // We assign global addresses to the routers as well to receive
170 // ICMPv6 errors.
171 NS_LOG_INFO("Assign IPv4 Addresses.");
173
174 ipv4.SetBase(Ipv4Address("10.0.0.0"), Ipv4Mask("255.255.255.0"));
175 Ipv4InterfaceContainer iic1 = ipv4.Assign(ndc1);
176
177 ipv4.SetBase(Ipv4Address("10.0.1.0"), Ipv4Mask("255.255.255.0"));
178 Ipv4InterfaceContainer iic2 = ipv4.Assign(ndc2);
179
180 ipv4.SetBase(Ipv4Address("10.0.2.0"), Ipv4Mask("255.255.255.0"));
181 Ipv4InterfaceContainer iic3 = ipv4.Assign(ndc3);
182
183 ipv4.SetBase(Ipv4Address("10.0.3.0"), Ipv4Mask("255.255.255.0"));
184 Ipv4InterfaceContainer iic4 = ipv4.Assign(ndc4);
185
186 ipv4.SetBase(Ipv4Address("10.0.4.0"), Ipv4Mask("255.255.255.0"));
187 Ipv4InterfaceContainer iic5 = ipv4.Assign(ndc5);
188
189 ipv4.SetBase(Ipv4Address("10.0.5.0"), Ipv4Mask("255.255.255.0"));
190 Ipv4InterfaceContainer iic6 = ipv4.Assign(ndc6);
191
192 ipv4.SetBase(Ipv4Address("10.0.6.0"), Ipv4Mask("255.255.255.0"));
193 Ipv4InterfaceContainer iic7 = ipv4.Assign(ndc7);
194
195 Ptr<Ipv4StaticRouting> staticRouting;
197 src->GetObject<Ipv4>()->GetRoutingProtocol());
198 staticRouting->SetDefaultRoute("10.0.0.2", 1);
200 dst->GetObject<Ipv4>()->GetRoutingProtocol());
201 staticRouting->SetDefaultRoute("10.0.6.1", 1);
202
203 if (printRoutingTables)
204 {
205 Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper>(&std::cout);
206
207 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(30.0), a, routingStream);
208 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(30.0), b, routingStream);
209 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(30.0), c, routingStream);
210 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(30.0), d, routingStream);
211
212 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(60.0), a, routingStream);
213 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(60.0), b, routingStream);
214 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(60.0), c, routingStream);
215 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(60.0), d, routingStream);
216
217 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(90.0), a, routingStream);
218 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(90.0), b, routingStream);
219 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(90.0), c, routingStream);
220 Ipv4RoutingHelper::PrintRoutingTableAt(Seconds(90.0), d, routingStream);
221 }
222
223 NS_LOG_INFO("Create Applications.");
224 uint32_t packetSize = 1024;
225 Time interPacketInterval = Seconds(1.0);
226 PingHelper ping(Ipv4Address("10.0.6.2"));
227
228 ping.SetAttribute("Interval", TimeValue(interPacketInterval));
229 ping.SetAttribute("Size", UintegerValue(packetSize));
230 if (showPings)
231 {
232 ping.SetAttribute("VerboseMode", EnumValue(Ping::VerboseMode::VERBOSE));
233 }
234 ApplicationContainer apps = ping.Install(src);
235 apps.Start(Seconds(1.0));
236 apps.Stop(Seconds(110.0));
237
238 AsciiTraceHelper ascii;
239 csma.EnableAsciiAll(ascii.CreateFileStream("rip-simple-routing.tr"));
240 csma.EnablePcapAll("rip-simple-routing", true);
241
242 Simulator::Schedule(Seconds(40), &TearDownLink, b, d, 3, 2);
243
244 /* Now, do the actual simulation. */
245 NS_LOG_INFO("Run Simulation.");
246 Simulator::Stop(Seconds(131.0));
249 NS_LOG_INFO("Done.");
250
251 return 0;
252}
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.
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.
build a set of CsmaNetDevice objects
Definition csma-helper.h:37
Hold variables of type enum.
Definition enum.h:52
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...
void SetIpv6StackInstall(bool enable)
Enable/disable IPv6 stack install.
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.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition ipv4.h:69
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol() const =0
Get the routing protocol to be used by this Ipv4 stack.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Helper class that adds ns3::Ipv4ListRouting objects.
void Add(const Ipv4RoutingHelper &routing, int16_t priority)
a class to represent an Ipv4 address mask
static void PrintRoutingTableAt(Time printTime, Ptr< Node > node, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
prints the routing tables of a node at a particular time.
static Ptr< T > GetRouting(Ptr< Ipv4RoutingProtocol > protocol)
Request a specified routing protocol <T> from Ipv4RoutingProtocol protocol.
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition names.cc:764
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
Create a ping application and associate it to a node.
Definition ping-helper.h:31
Smart pointer class similar to boost::intrusive_ptr.
Helper class that adds RIP routing to nodes.
Definition rip-helper.h:31
void ExcludeInterface(Ptr< Node > node, uint32_t interface)
Exclude an interface from RIP protocol.
void SetInterfaceMetric(Ptr< Node > node, uint32_t interface, uint8_t metric)
Set a metric for an interface.
@ SPLIT_HORIZON
Split Horizon.
Definition rip.h:203
@ NO_SPLIT_HORIZON
No Split Horizon.
Definition rip.h:202
@ POISON_REVERSE
Poison Reverse Split Horizon.
Definition rip.h:204
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
Hold an unsigned integer type.
Definition uinteger.h:34
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
NodeContainer nodes
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:291
LogLevel
Logging severity classes and levels.
Definition log.h:83
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:105
@ LOG_PREFIX_TIME
Prefix all trace prints with simulation time.
Definition log.h:108
@ LOG_PREFIX_NODE
Prefix all trace prints with simulation node.
Definition log.h:109
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition log.h:93
void LogComponentEnableAll(LogLevel level)
Enable the logging output for all registered log components.
Definition log.cc:309
bool verbose
void TearDownLink(Ptr< Node > nodeA, Ptr< Node > nodeB, uint32_t interfaceA, uint32_t interfaceB)
static const uint32_t packetSize
Packet size generated at the AP.