84 DebugComponentEnable("Ipv4Interface"); |
83 DebugComponentEnable("Ipv4Interface"); |
85 DebugComponentEnable("ArpIpv4Interface"); |
84 DebugComponentEnable("ArpIpv4Interface"); |
86 DebugComponentEnable("Ipv4LoopbackInterface"); |
85 DebugComponentEnable("Ipv4LoopbackInterface"); |
87 #endif |
86 #endif |
88 |
87 |
89 DebugComponentEnable("Me"); |
88 DebugComponentEnable("UdpSocket"); |
|
89 DebugComponentEnable("UdpL4Protocol"); |
|
90 DebugComponentEnable("Ipv4L3Protocol"); |
|
91 DebugComponentEnable("Ipv4StaticRouting"); |
|
92 DebugComponentEnable("Ipv4Interface"); |
|
93 DebugComponentEnable("ArpIpv4Interface"); |
|
94 DebugComponentEnable("Ipv4LoopbackInterface"); |
|
95 |
|
96 DebugComponentEnable("CsmaMulticast"); |
90 DebugComponentEnable("CsmaChannel"); |
97 DebugComponentEnable("CsmaChannel"); |
91 DebugComponentEnable("CsmaNetDevice"); |
98 DebugComponentEnable("CsmaNetDevice"); |
92 DebugComponentEnable("UdpL4Protocol"); |
99 // |
93 |
100 // Set up default values for the simulation. Use the DefaultValue::Bind() |
94 // Set up some default values for the simulation. Use the Bind() |
101 // technique to tell the system what subclass of Queue to use. The Bind |
95 // technique to tell the system what subclass of Queue to use, |
102 // command command tells the queue factory which class to instantiate when the |
96 // and what the queue limit is |
103 // queue factory is invoked in the topology code |
97 |
104 // |
98 // The below Bind command tells the queue factory which class to |
|
99 // instantiate, when the queue factory is invoked in the topology code |
|
100 DefaultValue::Bind ("Queue", "DropTailQueue"); |
105 DefaultValue::Bind ("Queue", "DropTailQueue"); |
101 |
106 // |
102 // Allow the user to override any of the defaults and the above |
107 // Allow the user to override any of the defaults and the above Bind() at |
103 // Bind()s at run-time, via command-line arguments |
108 // run-time, via command-line arguments |
|
109 // |
104 CommandLine::Parse (argc, argv); |
110 CommandLine::Parse (argc, argv); |
105 |
111 // |
106 // Here, we will explicitly create four nodes. In more sophisticated |
112 // Explicitly create the nodes required by the topology (shown above). |
107 // topologies, we could configure a node factory. |
113 // |
108 NS_DEBUG("Create nodes."); |
114 NS_DEBUG("Create nodes."); |
109 Ptr<Node> n0 = Create<InternetNode> (); |
115 Ptr<Node> n0 = Create<InternetNode> (); |
110 Ptr<Node> n1 = Create<InternetNode> (); |
116 Ptr<Node> n1 = Create<InternetNode> (); |
111 Ptr<Node> n2 = Create<InternetNode> (); |
117 Ptr<Node> n2 = Create<InternetNode> (); |
112 Ptr<Node> n3 = Create<InternetNode> (); |
118 Ptr<Node> n3 = Create<InternetNode> (); |
|
119 Ptr<Node> n4 = Create<InternetNode> (); |
113 |
120 |
114 NS_DEBUG("Create channels."); |
121 NS_DEBUG("Create channels."); |
115 // We create the channels first without any IP addressing information |
122 // |
116 Ptr<CsmaChannel> channel0 = |
123 // Explicitly create the channels required by the topology (shown above). |
|
124 // |
|
125 Ptr<CsmaChannel> lan0 = |
117 CsmaTopology::CreateCsmaChannel( |
126 CsmaTopology::CreateCsmaChannel( |
118 DataRate(5000000), MilliSeconds(2)); |
127 DataRate(5000000), MilliSeconds(2)); |
119 |
128 |
|
129 Ptr<CsmaChannel> lan1 = |
|
130 CsmaTopology::CreateCsmaChannel( |
|
131 DataRate(5000000), MilliSeconds(2)); |
|
132 |
120 NS_DEBUG("Build Topology."); |
133 NS_DEBUG("Build Topology."); |
121 uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, |
134 // |
122 channel0, Eui48Address("10:54:23:54:23:50")); |
135 // Now fill out the topology by creating the net devices required to connect |
123 uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1, |
136 // the nodes to the channels and hooking them up. AddIpv4CsmaNetDevice will |
124 channel0, Eui48Address("10:54:23:54:23:51")); |
137 // create a net device, add a MAC address (in memory of the pink flamingo) and |
125 uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2, |
138 // connect the net device to a nodes and also to a channel. the |
126 channel0, Eui48Address("10:54:23:54:23:52")); |
139 // AddIpv4CsmaNetDevice method returns a net device index for the net device |
127 uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3, |
140 // created on the node. Interpret nd0 as the net device we created for node |
128 channel0, Eui48Address("10:54:23:54:23:53")); |
141 // zero. Interpret nd2Lan0 as the net device we created for node two to |
129 |
142 // connect to Lan0. |
130 NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0); |
143 // |
131 NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1); |
144 uint32_t nd0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n0, lan0, |
132 NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2); |
145 Eui48Address("08:00:2e:00:00:00")); |
133 NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3); |
146 uint32_t nd1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n1, lan0, |
134 |
147 Eui48Address("08:00:2e:00:00:01")); |
135 // Later, we add IP addresses. |
148 uint32_t nd2Lan0 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan0, |
|
149 Eui48Address("08:00:2e:00:00:02")); |
|
150 |
|
151 uint32_t nd2Lan1 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n2, lan1, |
|
152 Eui48Address("08:00:2e:00:00:00")); |
|
153 uint32_t nd3 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n3, lan1, |
|
154 Eui48Address("08:00:2e:00:00:01")); |
|
155 uint32_t nd4 = CsmaIpv4Topology::AddIpv4CsmaNetDevice (n4, lan1, |
|
156 Eui48Address("08:00:2e:00:00:02")); |
|
157 |
|
158 NS_DEBUG ("nd0 = " << nd0); |
|
159 NS_DEBUG ("nd1 = " << nd1); |
|
160 NS_DEBUG ("nd2Lan0 = " << nd2Lan0); |
|
161 NS_DEBUG ("nd2Lan1 = " << nd2Lan1); |
|
162 NS_DEBUG ("nd3 = " << nd3); |
|
163 NS_DEBUG ("nd4 = " << nd3); |
|
164 // |
|
165 // We've got the "hardware" in place. Now we need to add IP addresses. |
|
166 // |
136 NS_DEBUG("Assign IP Addresses."); |
167 NS_DEBUG("Assign IP Addresses."); |
137 // XXX BUGBUG |
168 // |
138 // Need a better way to get the interface index. The point-to-point topology |
169 // XXX BUGBUG |
139 // as implemented can't return the index since it creates interfaces on both |
170 // Need a better way to get the interface index. The point-to-point topology |
140 // sides (i.e., AddIpv4Addresses, not AddIpv4Address). Need a method on |
171 // as implemented can't return the index since it creates interfaces on both |
141 // Ipv4 to find the interface index corresponding to a given ipv4 address. |
172 // sides (i.e., it does AddIpv4Addresses, not AddIpv4Address). We need a |
142 uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0, |
173 // method on Ipv4 to find the interface index corresponding to a given ipv4 |
143 netDeviceNumberNode0, Ipv4Address ("10.1.1.1"), |
174 // address. |
144 Ipv4Mask ("255.255.255.0")); |
175 // |
145 |
176 // First, assign IP addresses to the net devices and associated interfaces |
146 uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1, |
177 // on Lan0. The AddIpv4Address method returns an Ipv4 interface index. |
147 netDeviceNumberNode1, Ipv4Address ("10.1.1.2"), |
178 // Interpret ifIndexNd0 as the interface index to use to reference the |
148 Ipv4Mask ("255.255.255.0")); |
179 // net device we created on node zero when coming in from the Ipv4 interface. |
149 |
180 // Net device numbers and interface indices are distinct. Interpret |
150 uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, |
181 // ifIndexNd2Lan0 as the interface index to use to reference the |
151 netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), |
182 // net device we created that connects node two to lan zero. |
152 Ipv4Mask ("255.255.255.0")); |
183 // |
153 |
184 uint32_t ifIndexNd0 = CsmaIpv4Topology::AddIpv4Address (n0, nd0, |
154 uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, |
185 Ipv4Address ("10.1.1.1"), Ipv4Mask ("255.255.255.0")); |
155 netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), |
186 |
156 Ipv4Mask ("255.255.255.0")); |
187 uint32_t ifIndexNd1 = CsmaIpv4Topology::AddIpv4Address (n1, nd1, |
157 |
188 Ipv4Address ("10.1.1.2"), Ipv4Mask ("255.255.255.0")); |
158 NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0); |
189 |
159 NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1); |
190 uint32_t ifIndexNd2Lan0 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan0, |
160 NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2); |
191 Ipv4Address ("10.1.1.3"), Ipv4Mask ("255.255.255.0")); |
161 NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3); |
192 // |
162 |
193 // Assign IP addresses to the net devices and associated interfaces on Lan1 |
163 // Configure multicasting |
194 // |
|
195 uint32_t ifIndexNd2Lan1 = CsmaIpv4Topology::AddIpv4Address (n2, nd2Lan1, |
|
196 Ipv4Address ("10.1.2.1"), Ipv4Mask ("255.255.255.0")); |
|
197 |
|
198 uint32_t ifIndexNd3 = CsmaIpv4Topology::AddIpv4Address (n3, nd1, |
|
199 Ipv4Address ("10.1.2.2"), Ipv4Mask ("255.255.255.0")); |
|
200 |
|
201 uint32_t ifIndexNd4 = CsmaIpv4Topology::AddIpv4Address (n4, nd4, |
|
202 Ipv4Address ("10.1.2.3"), Ipv4Mask ("255.255.255.0")); |
|
203 |
|
204 NS_DEBUG ("ifIndexNd0 = " << ifIndexNd0); |
|
205 NS_DEBUG ("ifIndexNd1 = " << ifIndexNd1); |
|
206 NS_DEBUG ("ifIndexNd2Lan0 = " << ifIndexNd2Lan0); |
|
207 NS_DEBUG ("ifIndexNd2Lan1 = " << ifIndexNd2Lan1); |
|
208 NS_DEBUG ("ifIndexNd3 = " << ifIndexNd3); |
|
209 NS_DEBUG ("ifIndexNd4 = " << ifIndexNd4); |
164 NS_DEBUG("Configure multicasting."); |
210 NS_DEBUG("Configure multicasting."); |
|
211 // |
|
212 // Now we can configure multicasting. As described above, the multicast |
|
213 // source is at node zero, which we assigned the IP address of 10.1.1.1 |
|
214 // earlier. We need to define a multicast group to send packets to. This |
|
215 // can be any multicast address from 224.0.0.0 through 239.255.255.255 |
|
216 // (avoiding the reserved routing protocol addresses). We just pick a |
|
217 // convenient number. |
|
218 // |
165 Ipv4Address multicastSource ("10.1.1.1"); |
219 Ipv4Address multicastSource ("10.1.1.1"); |
166 Ipv4Address multicastGroup ("225.0.0.0"); |
220 Ipv4Address multicastGroup ("225.0.0.0"); |
167 |
221 // |
|
222 // We are going to manually configure multicast routing. This means telling |
|
223 // node two that it should expect multicast data coming from IP address |
|
224 // 10.1.1.1 over its IP interface connected to Lan0. These are called |
|
225 // multicastSource and ifIndexNd2Lan0 respectively. When node two receives |
|
226 // these packets, they should be forwarded out the interface that connects it |
|
227 // to Lan1 which is called ifIndexNd2Lan1. All we need to do is to call the |
|
228 // AddMulticastRoute method on node two's Ipv4 interface and provide this |
|
229 // information. (Note: the vector of output interfaces is in case there are |
|
230 // multiple net devices on a node). |
|
231 // |
168 Ptr<Ipv4> ipv4; |
232 Ptr<Ipv4> ipv4; |
|
233 ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid); |
|
234 |
|
235 std::vector<uint32_t> outputInterfaces (1); |
|
236 outputInterfaces[0] = ifIndexNd2Lan1; |
|
237 |
|
238 ipv4->AddMulticastRoute (multicastSource, multicastGroup, ifIndexNd2Lan0, |
|
239 outputInterfaces); |
|
240 // |
|
241 // We also need to explain to the node zero forwarding code that when it sees |
|
242 // a packet destined for the multicast group it needs to send it out its |
|
243 // one and only interface. The 0xffffffff in the call means that the input |
|
244 // interface qualification is not applicable in this case (the packet has |
|
245 // not been received over an interface, it has been created locally). |
|
246 // |
169 ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid); |
247 ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid); |
170 |
248 |
171 std::vector<uint32_t> outputInterfaces (1); |
249 outputInterfaces[0] = ifIndexNd0;; |
172 outputInterfaces[0] = ifIndexNode0; |
250 |
173 |
251 ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0xffffffff, |
174 ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, |
|
175 outputInterfaces); |
252 outputInterfaces); |
176 |
253 // |
177 ipv4 = n1->QueryInterface<Ipv4> (Ipv4::iid); |
254 // As described above, node four will be the only node listening for the |
178 // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); |
255 // multicast data. To enable forwarding bits up the protocol stack, we need |
179 |
256 // to tell the stack to join the multicast group. |
180 ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid); |
257 // |
181 // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); |
258 ipv4 = n4->QueryInterface<Ipv4> (Ipv4::iid); |
182 |
259 ipv4->JoinMulticastGroup (multicastSource, multicastGroup); |
183 ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid); |
260 // |
184 // ipv4->JoinMulticastGroup (multicastSource, multicastGroup); |
261 // Create an OnOff application to send UDP datagrams from node zero to the |
185 |
262 // multicast group (node four will be listening). |
186 // Create the OnOff application to send UDP datagrams |
263 // |
187 // from n0 to the multicast group |
|
188 NS_DEBUG("Create Applications."); |
264 NS_DEBUG("Create Applications."); |
189 Ptr<OnOffApplication> ooff = Create<OnOffApplication> ( |
265 Ptr<OnOffApplication> ooff = Create<OnOffApplication> ( |
190 n0, |
266 n0, |
191 InetSocketAddress (multicastGroup, 80), |
267 InetSocketAddress (multicastGroup, 80), |
192 "Udp", |
268 "Udp", |
193 ConstantVariable(1), |
269 ConstantVariable(1), |
194 ConstantVariable(0), |
270 ConstantVariable(0), |
195 DataRate ("128b/s"), |
271 DataRate ("255b/s"), |
196 128); |
272 128); |
197 // Start the application |
273 // |
|
274 // Tell the application when to start and stop. |
|
275 // |
198 ooff->Start(Seconds(1.)); |
276 ooff->Start(Seconds(1.)); |
199 ooff->Stop (Seconds(10.)); |
277 ooff->Stop (Seconds(10.)); |
200 |
278 // |
201 // Configure tracing of all enqueue, dequeue, and NetDevice receive events |
279 // Configure tracing of all enqueue, dequeue, and NetDevice receive events. |
202 // Trace output will be sent to the csma-one-subnet.tr file |
280 // Trace output will be sent to the file "csma-multicast.tr" |
|
281 // |
203 NS_DEBUG("Configure Tracing."); |
282 NS_DEBUG("Configure Tracing."); |
204 AsciiTrace asciitrace ("csma-multicast.tr"); |
283 AsciiTrace asciitrace ("csma-multicast.tr"); |
205 asciitrace.TraceAllNetDeviceRx (); |
284 asciitrace.TraceAllNetDeviceRx (); |
206 asciitrace.TraceAllQueues (); |
285 asciitrace.TraceAllQueues (); |
207 |
286 // |
208 // Also configure some tcpdump traces; each interface will be traced |
287 // Also configure some tcpdump traces; each interface will be traced. |
209 // The output files will be named |
288 // The output files will be named: |
210 // simple-point-to-point.pcap-<nodeId>-<interfaceId> |
289 // csma-multicast.pcap-<nodeId>-<interfaceId> |
211 // and can be read by the "tcpdump -r" command (use "-tt" option to |
290 // and can be read by the "tcpdump -r" command (use "-tt" option to |
212 // display timestamps correctly) |
291 // display timestamps correctly) |
|
292 // |
213 PcapTrace pcaptrace ("csma-multicast.pcap"); |
293 PcapTrace pcaptrace ("csma-multicast.pcap"); |
214 pcaptrace.TraceAllIp (); |
294 pcaptrace.TraceAllIp (); |
215 |
295 // |
|
296 // Now, do the actual simulation. |
|
297 // |
216 NS_DEBUG("Run Simulation."); |
298 NS_DEBUG("Run Simulation."); |
217 Simulator::Run (); |
299 Simulator::Run (); |
218 Simulator::Destroy (); |
300 Simulator::Destroy (); |
219 NS_DEBUG("Done."); |
301 NS_DEBUG("Done."); |
220 } |
302 } |