A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
csma-star.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  */
17 
18 #include "ns3/core-module.h"
19 #include "ns3/network-module.h"
20 #include "ns3/csma-module.h"
21 #include "ns3/csma-star-helper.h"
22 #include "ns3/applications-module.h"
23 #include "ns3/csma-module.h"
24 #include "ns3/internet-module.h"
25 #include "ns3/ipv6-address-generator.h"
26 
27 // Network topology (default)
28 //
29 // n2 + + n3 .
30 // | ... |\ /| ... | .
31 // ======= \ / ======= .
32 // CSMA \ / CSMA .
33 // \ / .
34 // n1 +--- n0 ---+ n4 .
35 // | ... | / \ | ... | .
36 // ======= / \ ======= .
37 // CSMA / \ CSMA .
38 // / \ .
39 // n6 + + n5 .
40 // | ... | | ... | .
41 // ======= ======= .
42 // CSMA CSMA .
43 //
44 
45 using namespace ns3;
46 
47 NS_LOG_COMPONENT_DEFINE ("CsmaStar");
48 
49 int
50 main (int argc, char *argv[])
51 {
52 
53  //
54  // Set up some default values for the simulation.
55  //
56  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (137));
57 
58  // ??? try and stick 15kb/s into the data rate
59  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("14kb/s"));
60 
61  //
62  // Default number of nodes in the star. Overridable by command line argument.
63  //
64  uint32_t nSpokes = 7;
65  uint32_t useIpv6 = 0;
66  Ipv6Address ipv6AddressBase = Ipv6Address("2001::");
67  Ipv6Prefix ipv6AddressPrefix = Ipv6Prefix(64);
68 
69  CommandLine cmd;
70  cmd.AddValue ("nSpokes", "Number of spoke nodes to place in the star", nSpokes);
71  cmd.AddValue ("useIpv6", "Use Ipv6", useIpv6);
72  cmd.Parse (argc, argv);
73 
74  NS_LOG_INFO ("Build star topology.");
75  CsmaHelper csma;
76  csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
77  csma.SetChannelAttribute ("Delay", StringValue ("1ms"));
78  CsmaStarHelper star (nSpokes, csma);
79 
80  NodeContainer fillNodes;
81 
82  //
83  // Just to be nasy, hang some more nodes off of the CSMA channel for each
84  // spoke, so that there are a total of 16 nodes on each channel. Stash
85  // all of these new devices into a container.
86  //
87  NetDeviceContainer fillDevices;
88 
89  uint32_t nFill = 14;
90  for (uint32_t i = 0; i < star.GetSpokeDevices ().GetN (); ++i)
91  {
92  Ptr<Channel> channel = star.GetSpokeDevices ().Get (i)->GetChannel ();
93  Ptr<CsmaChannel> csmaChannel = channel->GetObject<CsmaChannel> ();
94  NodeContainer newNodes;
95  newNodes.Create (nFill);
96  fillNodes.Add (newNodes);
97  fillDevices.Add (csma.Install (newNodes, csmaChannel));
98  }
99 
100  NS_LOG_INFO ("Install internet stack on all nodes.");
101  InternetStackHelper internet;
102  star.InstallStack (internet);
103  internet.Install (fillNodes);
104 
105  NS_LOG_INFO ("Assign IP Addresses.");
106  if (useIpv6 == 0)
107  {
108  star.AssignIpv4Addresses (Ipv4AddressHelper ("10.1.0.0", "255.255.255.0"));
109  }
110  else
111  {
112  star.AssignIpv6Addresses (ipv6AddressBase, ipv6AddressPrefix);
113  }
114 
115  //
116  // We assigned addresses to the logical hub and the first "drop" of the
117  // CSMA network that acts as the spoke, but we also have a number of fill
118  // devices (nFill) also hanging off the CSMA network. We have got to
119  // assign addresses to them as well. We put all of the fill devices into
120  // a single device container, so the first nFill devices are associated
121  // with the channel connected to spokeDevices.Get (0), the second nFill
122  // devices afe associated with the channel connected to spokeDevices.Get (1)
123  // etc.
124  //
125  Ipv4AddressHelper address;
126  Ipv6AddressHelper address6;
127  for(uint32_t i = 0; i < star.SpokeCount (); ++i)
128  {
129  if (useIpv6 == 0)
130  {
131  std::ostringstream subnet;
132  subnet << "10.1." << i << ".0";
133  NS_LOG_INFO ("Assign IP Addresses for CSMA subnet " << subnet.str ());
134  address.SetBase (subnet.str ().c_str (), "255.255.255.0", "0.0.0.3");
135 
136  for (uint32_t j = 0; j < nFill; ++j)
137  {
138  address.Assign (fillDevices.Get (i * nFill + j));
139  }
140  }
141  else
142  {
143  Ipv6AddressGenerator::Init (ipv6AddressBase, ipv6AddressPrefix);
144  Ipv6Address v6network = Ipv6AddressGenerator::GetNetwork (ipv6AddressPrefix);
145  address6.SetBase (v6network, ipv6AddressPrefix);
146 
147  for (uint32_t j = 0; j < nFill; ++j)
148  {
149  address6.Assign(fillDevices.Get (i * nFill + j));
150  }
151  }
152  }
153 
154  NS_LOG_INFO ("Create applications.");
155  //
156  // Create a packet sink on the star "hub" to receive packets.
157  //
158  uint16_t port = 50000;
159 
160  if (useIpv6 == 0)
161  {
162  Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
163  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
164  ApplicationContainer hubApp = packetSinkHelper.Install (star.GetHub ());
165  hubApp.Start (Seconds (1.0));
166  hubApp.Stop (Seconds (10.0));
167  }
168  else
169  {
170  Address hubLocalAddress6 (Inet6SocketAddress (Ipv6Address::GetAny (), port));
171  PacketSinkHelper packetSinkHelper6 ("ns3::TcpSocketFactory", hubLocalAddress6);
172  ApplicationContainer hubApp6 = packetSinkHelper6.Install (star.GetHub ());
173  hubApp6.Start (Seconds (1.0));
174  hubApp6.Stop (Seconds (10.0));
175  }
176 
177  //
178  // Create OnOff applications to send TCP to the hub, one on each spoke node.
179  //
180  OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
181  onOffHelper.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
182  onOffHelper.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
183 
184  ApplicationContainer spokeApps;
185 
186  for (uint32_t i = 0; i < star.SpokeCount (); ++i)
187  {
188  if (useIpv6 == 0)
189  {
190  AddressValue remoteAddress (InetSocketAddress (star.GetHubIpv4Address (i), port));
191  onOffHelper.SetAttribute ("Remote", remoteAddress);
192  }
193  else
194  {
195  AddressValue remoteAddress (Inet6SocketAddress (star.GetHubIpv6Address (i), port));
196  onOffHelper.SetAttribute ("Remote", remoteAddress);
197  }
198  spokeApps.Add (onOffHelper.Install (star.GetSpokeNode (i)));
199  }
200 
201  spokeApps.Start (Seconds (1.0));
202  spokeApps.Stop (Seconds (10.0));
203 
204  //
205  // Because we are evil, we also add OnOff applications to send TCP to the hub
206  // from the fill devices on each CSMA link. The first nFill nodes in the
207  // fillNodes container are on the CSMA network talking to the zeroth device
208  // on the hub node. The next nFill nodes are on the CSMA network talking to
209  // the first device on the hub node, etc. So the ith fillNode is associated
210  // with the hub address found on the (i / nFill)th device on the hub node.
211  //
212  ApplicationContainer fillApps;
213 
214  for (uint32_t i = 0; i < fillNodes.GetN (); ++i)
215  {
216  AddressValue remoteAddress;
217  if (useIpv6 == 0)
218  {
219  remoteAddress = AddressValue(InetSocketAddress (star.GetHubIpv4Address (i / nFill), port));
220  }
221  else
222  {
223  remoteAddress = AddressValue(Inet6SocketAddress (star.GetHubIpv6Address (i / nFill), port));
224  }
225  onOffHelper.SetAttribute ("Remote", remoteAddress);
226  fillApps.Add (onOffHelper.Install (fillNodes.Get (i)));
227  }
228 
229  fillApps.Start (Seconds (1.0));
230  fillApps.Stop (Seconds (10.0));
231 
232  NS_LOG_INFO ("Enable static global routing.");
233  //
234  // Turn on global static routing so we can actually be routed across the star.
235  //
236  if (useIpv6 == 0)
237  {
239  }
240 
241  NS_LOG_INFO ("Enable pcap tracing.");
242  //
243  // Do pcap tracing on all devices on all nodes.
244  //
245  csma.EnablePcapAll ("csma-star", false);
246 
247  NS_LOG_INFO ("Run Simulation.");
248  Simulator::Run ();
250  NS_LOG_INFO ("Done.");
251 
252  return 0;
253 }