A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
radvd-two-prefix.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 Strasbourg University
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: David Gross <gdavid.devel@gmail.com>
19  * Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
20  */
21 
22 // Network topology
23 // //
24 // // n0 R n1
25 // // | _ |
26 // // ====|_|====
27 // // router
28 // // - R sends RA to n0's subnet (2001:1::/64 and 2001:ABCD::/64);
29 // // - R interface to n0 has two addresses with following prefixes 2001:1::/64 and 2001:ABCD::/64;
30 // // - R sends RA to n1's subnet (2001:2::/64);
31 // // - n0 ping6 n1.
32 // //
33 // // - Tracing of queues and packet receptions to file "radvd-two-prefix.tr"
34 
35 #include <fstream>
36 #include "ns3/core-module.h"
37 #include "ns3/internet-module.h"
38 #include "ns3/csma-module.h"
39 #include "ns3/applications-module.h"
40 
41 #include "ns3/ipv6-routing-table-entry.h"
42 #include "ns3/radvd.h"
43 #include "ns3/radvd-interface.h"
44 #include "ns3/radvd-prefix.h"
45 #include "ns3/ipv6-static-routing-helper.h"
46 
47 using namespace ns3;
48 
49 NS_LOG_COMPONENT_DEFINE ("RadvdTwoPrefixExample");
50 
56 {
57 public:
62  inline void PrintIpAddresses (Ptr<Node>& n)
63  {
64  Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
65  uint32_t nInterfaces = ipv6->GetNInterfaces();
66 
67  std::cout << "Node: " << ipv6->GetObject<Node> ()->GetId ()
68  << " Time: " << Simulator::Now ().GetSeconds () << "s "
69  << "IPv6 addresses" << std::endl;
70  std::cout << "(Interface index, Address index)\t" << "IPv6 Address" << std::endl;
71 
72  for (uint32_t i = 0; i < nInterfaces; i++)
73  {
74  for (uint32_t j = 0; j < ipv6->GetNAddresses(i); j++)
75  {
76  std::cout << "(" << int(i) << "," << int(j) << ")\t" << ipv6->GetAddress(i,j) << std::endl;
77  }
78  }
79  std::cout << std::endl;
80  }
81 };
82 
83 int main (int argc, char** argv)
84 {
85  bool verbose = false;
86 
87  CommandLine cmd;
88  cmd.AddValue ("verbose", "turn on log components", verbose);
89  cmd.Parse (argc, argv);
90 
91  if (verbose)
92  {
93  LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
94  LogComponentEnable ("Ipv6RawSocketImpl", LOG_LEVEL_ALL);
95  LogComponentEnable ("Icmpv6L4Protocol", LOG_LEVEL_ALL);
96  LogComponentEnable ("Ipv6StaticRouting", LOG_LEVEL_ALL);
97  LogComponentEnable ("Ipv6Interface", LOG_LEVEL_ALL);
98  LogComponentEnable ("RadvdApplication", LOG_LEVEL_ALL);
99  LogComponentEnable ("Ping6Application", LOG_LEVEL_ALL);
100  }
101 
102  NS_LOG_INFO ("Create nodes.");
103  Ptr<Node> n0 = CreateObject<Node> ();
104  Ptr<Node> r = CreateObject<Node> ();
105  Ptr<Node> n1 = CreateObject<Node> ();
106 
107  NodeContainer net1 (n0, r);
108  NodeContainer net2 (r, n1);
109  NodeContainer all (n0, r, n1);
110 
111  NS_LOG_INFO ("Create IPv6 Internet Stack");
112  InternetStackHelper internetv6;
113  internetv6.Install (all);
114 
115  NS_LOG_INFO ("Create channels.");
116  CsmaHelper csma;
117  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
118  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
119  NetDeviceContainer d1 = csma.Install (net1); /* n0 - R */
120  NetDeviceContainer d2 = csma.Install (net2); /* R - n1 */
121 
122  NS_LOG_INFO ("Create networks and assign IPv6 Addresses.");
123  Ipv6AddressHelper ipv6;
124 
125  /* first subnet */
126  ipv6.SetBase (Ipv6Address ("2001:1::"), Ipv6Prefix (64));
127  NetDeviceContainer tmp;
128  tmp.Add (d1.Get (0)); /* n0 */
129  Ipv6InterfaceContainer iic1 = ipv6.AssignWithoutAddress (tmp); /* n0 interface */
130 
131  NetDeviceContainer tmp2;
132  tmp2.Add (d1.Get (1)); /* R */
133  Ipv6InterfaceContainer iicr1 = ipv6.Assign (tmp2); /* R interface to the first subnet is just statically assigned */
134  iicr1.SetForwarding (0, true);
135  iicr1.SetDefaultRouteInAllNodes (0);
136  iic1.Add (iicr1);
137 
138  /* add another IPv6 address for second prefix advertised on first subnet */
139  ipv6.SetBase (Ipv6Address ("2001:ABCD::2"), Ipv6Prefix (64));
140  ipv6.Assign (tmp2);
141 
142  /* second subnet R - n1 */
143  ipv6.SetBase (Ipv6Address ("2001:2::"), Ipv6Prefix (64));
144  NetDeviceContainer tmp3;
145  tmp3.Add (d2.Get (0)); /* R */
146  Ipv6InterfaceContainer iicr2 = ipv6.Assign (tmp3); /* R interface */
147  iicr2.SetForwarding (0, true);
148  iicr2.SetDefaultRouteInAllNodes (0);
149 
150  NetDeviceContainer tmp4;
151  tmp4.Add (d2.Get (1)); /* n1 */
152  Ipv6InterfaceContainer iic2 = ipv6.AssignWithoutAddress (tmp4);
153  iic2.Add (iicr2);
154 
155  /* radvd configuration */
156  RadvdHelper radvdHelper;
157  /* R interface (n0 - R) */
158  radvdHelper.AddAnnouncedPrefix(iic1.GetInterfaceIndex (1), Ipv6Address("2001:ABCD::0"), 64);
159  radvdHelper.AddAnnouncedPrefix(iic1.GetInterfaceIndex (1), Ipv6Address("2001:1::0"), 64);
160 
161  // Set some non-standard timers so the simulation is not taking ages
162  Ptr<RadvdInterface> routerInterface = radvdHelper.GetRadvdInterface(iic1.GetInterfaceIndex (1));
163  routerInterface->SetMaxRtrAdvInterval (2000);
164  routerInterface->SetMinRtrAdvInterval (1000);
165  RadvdInterface::RadvdPrefixList prefixList = routerInterface->GetPrefixes ();
166  for (RadvdInterface::RadvdPrefixListI iter = prefixList.begin(); iter != prefixList.end(); iter++)
167  {
168  (*iter)->SetPreferredLifeTime (3);
169  (*iter)->SetValidLifeTime (5);
170  }
171 
172  /* R interface (R - n1) */
173  radvdHelper.AddAnnouncedPrefix(iic2.GetInterfaceIndex (1), Ipv6Address("2001:2::0"), 64);
174 
175  // Set some non-standard timers so the simulation is not taking ages
176  routerInterface = radvdHelper.GetRadvdInterface(iic2.GetInterfaceIndex (1));
177  routerInterface->SetMaxRtrAdvInterval (2000);
178  routerInterface->SetMinRtrAdvInterval (1000);
179  prefixList = routerInterface->GetPrefixes ();
180  for (RadvdInterface::RadvdPrefixListI iter = prefixList.begin(); iter != prefixList.end(); iter++)
181  {
182  (*iter)->SetPreferredLifeTime (3);
183  (*iter)->SetValidLifeTime (5);
184  }
185 
186  ApplicationContainer radvdApps = radvdHelper.Install(r);
187  radvdApps.Start (Seconds (1.0));
188  radvdApps.Stop (Seconds (2.0));
189 
190  /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via R */
191  uint32_t packetSize = 1024;
192  uint32_t maxPacketCount = 8;
193  Time interPacketInterval = Seconds (1.);
194  Ping6Helper ping6;
195 
196  /* ping6.SetLocal (iic1.GetAddress (0, 1)); */
197  ping6.SetRemote (Ipv6Address ("2001:2::200:ff:fe00:4")); /* should be n1 address after autoconfiguration */
198  ping6.SetIfIndex (iic1.GetInterfaceIndex (0));
199 
200  ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
201  ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
202  ping6.SetAttribute ("PacketSize", UintegerValue (packetSize));
203  ApplicationContainer apps = ping6.Install (net1.Get (0));
204  apps.Start (Seconds (2.0));
205  apps.Stop (Seconds (9.0));
206 
207  Ipv6StaticRoutingHelper routingHelper;
208  Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> (&std::cout);
209  routingHelper.PrintRoutingTableAt (Seconds (2.0), n0, routingStream);
210  routingHelper.PrintRoutingTableAt (Seconds (10.0), n0, routingStream);
211 
212  IpAddressHelper ipAddressHelper;
213  /* RA should be received, two prefixes + routes + default route should be present */
214  Simulator::Schedule (Seconds (2.0), &IpAddressHelper::PrintIpAddresses, &ipAddressHelper, n0);
215  /* at the end, RA addresses and routes should be cleared */
216  Simulator::Schedule (Seconds (10.0), &IpAddressHelper::PrintIpAddresses, &ipAddressHelper, n0);
217 
218  AsciiTraceHelper ascii;
219  csma.EnableAsciiAll (ascii.CreateFileStream ("radvd-two-prefix.tr"));
220  csma.EnablePcapAll (std::string ("radvd-two-prefix"), true);
221 
222  NS_LOG_INFO ("Run Simulation.");
223  Simulator::Run ();
225  NS_LOG_INFO ("Done.");
226 }
227