A Discrete-Event Network Simulator
API
ipv4-global-routing.cc
Go to the documentation of this file.
1// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
2//
3// Copyright (c) 2008 University of Washington
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
19#include <vector>
20#include <iomanip>
21#include "ns3/names.h"
22#include "ns3/log.h"
23#include "ns3/simulator.h"
24#include "ns3/object.h"
25#include "ns3/packet.h"
26#include "ns3/net-device.h"
27#include "ns3/ipv4-route.h"
28#include "ns3/ipv4-routing-table-entry.h"
29#include "ns3/boolean.h"
30#include "ns3/node.h"
31#include "ipv4-global-routing.h"
33
34namespace ns3 {
35
36NS_LOG_COMPONENT_DEFINE ("Ipv4GlobalRouting");
37
38NS_OBJECT_ENSURE_REGISTERED (Ipv4GlobalRouting);
39
40TypeId
42{
43 static TypeId tid = TypeId ("ns3::Ipv4GlobalRouting")
44 .SetParent<Object> ()
45 .SetGroupName ("Internet")
46 .AddAttribute ("RandomEcmpRouting",
47 "Set to true if packets are randomly routed among ECMP; set to false for using only one route consistently",
48 BooleanValue (false),
51 .AddAttribute ("RespondToInterfaceEvents",
52 "Set to true if you want to dynamically recompute the global routes upon Interface notification events (up/down, or add/remove address)",
53 BooleanValue (false),
56 ;
57 return tid;
58}
59
61 : m_randomEcmpRouting (false),
62 m_respondToInterfaceEvents (false)
63{
64 NS_LOG_FUNCTION (this);
65
66 m_rand = CreateObject<UniformRandomVariable> ();
67}
68
70{
71 NS_LOG_FUNCTION (this);
72}
73
74void
76 Ipv4Address nextHop,
77 uint32_t interface)
78{
79 NS_LOG_FUNCTION (this << dest << nextHop << interface);
81 *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, nextHop, interface);
82 m_hostRoutes.push_back (route);
83}
84
85void
87 uint32_t interface)
88{
89 NS_LOG_FUNCTION (this << dest << interface);
91 *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, interface);
92 m_hostRoutes.push_back (route);
93}
94
95void
97 Ipv4Mask networkMask,
98 Ipv4Address nextHop,
99 uint32_t interface)
100{
101 NS_LOG_FUNCTION (this << network << networkMask << nextHop << interface);
104 networkMask,
105 nextHop,
106 interface);
107 m_networkRoutes.push_back (route);
108}
109
110void
112 Ipv4Mask networkMask,
113 uint32_t interface)
114{
115 NS_LOG_FUNCTION (this << network << networkMask << interface);
118 networkMask,
119 interface);
120 m_networkRoutes.push_back (route);
121}
122
123void
125 Ipv4Mask networkMask,
126 Ipv4Address nextHop,
127 uint32_t interface)
128{
129 NS_LOG_FUNCTION (this << network << networkMask << nextHop << interface);
132 networkMask,
133 nextHop,
134 interface);
135 m_ASexternalRoutes.push_back (route);
136}
137
138
141{
142 NS_LOG_FUNCTION (this << dest << oif);
143 NS_LOG_LOGIC ("Looking for route for destination " << dest);
144 Ptr<Ipv4Route> rtentry = 0;
145 // store all available routes that bring packets to their destination
146 typedef std::vector<Ipv4RoutingTableEntry*> RouteVec_t;
147 RouteVec_t allRoutes;
148
149 NS_LOG_LOGIC ("Number of m_hostRoutes = " << m_hostRoutes.size ());
150 for (HostRoutesCI i = m_hostRoutes.begin ();
151 i != m_hostRoutes.end ();
152 i++)
153 {
154 NS_ASSERT ((*i)->IsHost ());
155 if ((*i)->GetDest () == dest)
156 {
157 if (oif != 0)
158 {
159 if (oif != m_ipv4->GetNetDevice ((*i)->GetInterface ()))
160 {
161 NS_LOG_LOGIC ("Not on requested interface, skipping");
162 continue;
163 }
164 }
165 allRoutes.push_back (*i);
166 NS_LOG_LOGIC (allRoutes.size () << "Found global host route" << *i);
167 }
168 }
169 if (allRoutes.size () == 0) // if no host route is found
170 {
171 NS_LOG_LOGIC ("Number of m_networkRoutes" << m_networkRoutes.size ());
172 for (NetworkRoutesI j = m_networkRoutes.begin ();
173 j != m_networkRoutes.end ();
174 j++)
175 {
176 Ipv4Mask mask = (*j)->GetDestNetworkMask ();
177 Ipv4Address entry = (*j)->GetDestNetwork ();
178 if (mask.IsMatch (dest, entry))
179 {
180 if (oif != 0)
181 {
182 if (oif != m_ipv4->GetNetDevice ((*j)->GetInterface ()))
183 {
184 NS_LOG_LOGIC ("Not on requested interface, skipping");
185 continue;
186 }
187 }
188 allRoutes.push_back (*j);
189 NS_LOG_LOGIC (allRoutes.size () << "Found global network route" << *j);
190 }
191 }
192 }
193 if (allRoutes.size () == 0) // consider external if no host/network found
194 {
195 for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
196 k != m_ASexternalRoutes.end ();
197 k++)
198 {
199 Ipv4Mask mask = (*k)->GetDestNetworkMask ();
200 Ipv4Address entry = (*k)->GetDestNetwork ();
201 if (mask.IsMatch (dest, entry))
202 {
203 NS_LOG_LOGIC ("Found external route" << *k);
204 if (oif != 0)
205 {
206 if (oif != m_ipv4->GetNetDevice ((*k)->GetInterface ()))
207 {
208 NS_LOG_LOGIC ("Not on requested interface, skipping");
209 continue;
210 }
211 }
212 allRoutes.push_back (*k);
213 break;
214 }
215 }
216 }
217 if (allRoutes.size () > 0 ) // if route(s) is found
218 {
219 // pick up one of the routes uniformly at random if random
220 // ECMP routing is enabled, or always select the first route
221 // consistently if random ECMP routing is disabled
222 uint32_t selectIndex;
224 {
225 selectIndex = m_rand->GetInteger (0, allRoutes.size ()-1);
226 }
227 else
228 {
229 selectIndex = 0;
230 }
231 Ipv4RoutingTableEntry* route = allRoutes.at (selectIndex);
232 // create a Ipv4Route object from the selected routing table entry
233 rtentry = Create<Ipv4Route> ();
234 rtentry->SetDestination (route->GetDest ());
236 rtentry->SetSource (m_ipv4->GetAddress (route->GetInterface (), 0).GetLocal ());
237 rtentry->SetGateway (route->GetGateway ());
238 uint32_t interfaceIdx = route->GetInterface ();
239 rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
240 return rtentry;
241 }
242 else
243 {
244 return 0;
245 }
246}
247
250{
251 NS_LOG_FUNCTION (this);
252 uint32_t n = 0;
253 n += m_hostRoutes.size ();
254 n += m_networkRoutes.size ();
255 n += m_ASexternalRoutes.size ();
256 return n;
257}
258
261{
262 NS_LOG_FUNCTION (this << index);
263 if (index < m_hostRoutes.size ())
264 {
265 uint32_t tmp = 0;
266 for (HostRoutesCI i = m_hostRoutes.begin ();
267 i != m_hostRoutes.end ();
268 i++)
269 {
270 if (tmp == index)
271 {
272 return *i;
273 }
274 tmp++;
275 }
276 }
277 index -= m_hostRoutes.size ();
278 uint32_t tmp = 0;
279 if (index < m_networkRoutes.size ())
280 {
281 for (NetworkRoutesCI j = m_networkRoutes.begin ();
282 j != m_networkRoutes.end ();
283 j++)
284 {
285 if (tmp == index)
286 {
287 return *j;
288 }
289 tmp++;
290 }
291 }
292 index -= m_networkRoutes.size ();
293 tmp = 0;
294 for (ASExternalRoutesCI k = m_ASexternalRoutes.begin ();
295 k != m_ASexternalRoutes.end ();
296 k++)
297 {
298 if (tmp == index)
299 {
300 return *k;
301 }
302 tmp++;
303 }
304 NS_ASSERT (false);
305 // quiet compiler.
306 return 0;
307}
308void
310{
311 NS_LOG_FUNCTION (this << index);
312 if (index < m_hostRoutes.size ())
313 {
314 uint32_t tmp = 0;
315 for (HostRoutesI i = m_hostRoutes.begin ();
316 i != m_hostRoutes.end ();
317 i++)
318 {
319 if (tmp == index)
320 {
321 NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_hostRoutes.size ());
322 delete *i;
323 m_hostRoutes.erase (i);
324 NS_LOG_LOGIC ("Done removing host route " << index << "; host route remaining size = " << m_hostRoutes.size ());
325 return;
326 }
327 tmp++;
328 }
329 }
330 index -= m_hostRoutes.size ();
331 uint32_t tmp = 0;
332 for (NetworkRoutesI j = m_networkRoutes.begin ();
333 j != m_networkRoutes.end ();
334 j++)
335 {
336 if (tmp == index)
337 {
338 NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_networkRoutes.size ());
339 delete *j;
340 m_networkRoutes.erase (j);
341 NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size ());
342 return;
343 }
344 tmp++;
345 }
346 index -= m_networkRoutes.size ();
347 tmp = 0;
348 for (ASExternalRoutesI k = m_ASexternalRoutes.begin ();
349 k != m_ASexternalRoutes.end ();
350 k++)
351 {
352 if (tmp == index)
353 {
354 NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_ASexternalRoutes.size ());
355 delete *k;
356 m_ASexternalRoutes.erase (k);
357 NS_LOG_LOGIC ("Done removing network route " << index << "; network route remaining size = " << m_networkRoutes.size ());
358 return;
359 }
360 tmp++;
361 }
362 NS_ASSERT (false);
363}
364
365int64_t
367{
368 NS_LOG_FUNCTION (this << stream);
369 m_rand->SetStream (stream);
370 return 1;
371}
372
373void
375{
376 NS_LOG_FUNCTION (this);
377 for (HostRoutesI i = m_hostRoutes.begin ();
378 i != m_hostRoutes.end ();
379 i = m_hostRoutes.erase (i))
380 {
381 delete (*i);
382 }
383 for (NetworkRoutesI j = m_networkRoutes.begin ();
384 j != m_networkRoutes.end ();
385 j = m_networkRoutes.erase (j))
386 {
387 delete (*j);
388 }
389 for (ASExternalRoutesI l = m_ASexternalRoutes.begin ();
390 l != m_ASexternalRoutes.end ();
391 l = m_ASexternalRoutes.erase (l))
392 {
393 delete (*l);
394 }
395
397}
398
399// Formatted like output of "route -n" command
400void
402{
403 NS_LOG_FUNCTION (this << stream);
404 std::ostream* os = stream->GetStream ();
405 // Copy the current ostream state
406 std::ios oldState (nullptr);
407 oldState.copyfmt (*os);
408
409 *os << std::resetiosflags (std::ios::adjustfield) << std::setiosflags (std::ios::left);
410
411 *os << "Node: " << m_ipv4->GetObject<Node> ()->GetId ()
412 << ", Time: " << Now().As (unit)
413 << ", Local time: " << m_ipv4->GetObject<Node> ()->GetLocalTime ().As (unit)
414 << ", Ipv4GlobalRouting table" << std::endl;
415
416 if (GetNRoutes () > 0)
417 {
418 *os << "Destination Gateway Genmask Flags Metric Ref Use Iface" << std::endl;
419 for (uint32_t j = 0; j < GetNRoutes (); j++)
420 {
421 std::ostringstream dest, gw, mask, flags;
423 dest << route.GetDest ();
424 *os << std::setw (16) << dest.str ();
425 gw << route.GetGateway ();
426 *os << std::setw (16) << gw.str ();
427 mask << route.GetDestNetworkMask ();
428 *os << std::setw (16) << mask.str ();
429 flags << "U";
430 if (route.IsHost ())
431 {
432 flags << "H";
433 }
434 else if (route.IsGateway ())
435 {
436 flags << "G";
437 }
438 *os << std::setw (6) << flags.str ();
439 // Metric not implemented
440 *os << "-" << " ";
441 // Ref ct not implemented
442 *os << "-" << " ";
443 // Use not implemented
444 *os << "-" << " ";
445 if (Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ())) != "")
446 {
447 *os << Names::FindName (m_ipv4->GetNetDevice (route.GetInterface ()));
448 }
449 else
450 {
451 *os << route.GetInterface ();
452 }
453 *os << std::endl;
454 }
455 }
456 *os << std::endl;
457 // Restore the previous ostream state
458 (*os).copyfmt (oldState);
459}
460
463{
464 NS_LOG_FUNCTION (this << p << &header << oif << &sockerr);
465//
466// First, see if this is a multicast packet we have a route for. If we
467// have a route, then send the packet down each of the specified interfaces.
468//
469 if (header.GetDestination ().IsMulticast ())
470 {
471 NS_LOG_LOGIC ("Multicast destination-- returning false");
472 return 0; // Let other routing protocols try to handle this
473 }
474//
475// See if this is a unicast packet we have a route for.
476//
477 NS_LOG_LOGIC ("Unicast destination- looking up");
478 Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination (), oif);
479 if (rtentry)
480 {
481 sockerr = Socket::ERROR_NOTERROR;
482 }
483 else
484 {
486 }
487 return rtentry;
488}
489
490bool
493{
494 NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev << &lcb << &ecb);
495 // Check if input device supports IP
496 NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
497 uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
498
499 if (m_ipv4->IsDestinationAddress (header.GetDestination (), iif))
500 {
501 if (!lcb.IsNull ())
502 {
503 NS_LOG_LOGIC ("Local delivery to " << header.GetDestination ());
504 lcb (p, header, iif);
505 return true;
506 }
507 else
508 {
509 // The local delivery callback is null. This may be a multicast
510 // or broadcast packet, so return false so that another
511 // multicast routing protocol can handle it. It should be possible
512 // to extend this to explicitly check whether it is a unicast
513 // packet, and invoke the error callback if so
514 return false;
515 }
516 }
517
518 // Check if input device supports IP forwarding
519 if (m_ipv4->IsForwarding (iif) == false)
520 {
521 NS_LOG_LOGIC ("Forwarding disabled for this interface");
522 ecb (p, header, Socket::ERROR_NOROUTETOHOST);
523 return true;
524 }
525 // Next, try to find a route
526 NS_LOG_LOGIC ("Unicast destination- looking up global route");
527 Ptr<Ipv4Route> rtentry = LookupGlobal (header.GetDestination ());
528 if (rtentry != 0)
529 {
530 NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
531 ucb (rtentry, p, header);
532 return true;
533 }
534 else
535 {
536 NS_LOG_LOGIC ("Did not find unicast destination- returning false");
537 return false; // Let other routing protocols try to handle this
538 // route request.
539 }
540}
541void
543{
544 NS_LOG_FUNCTION (this << i);
545 if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
546 {
550 }
551}
552
553void
555{
556 NS_LOG_FUNCTION (this << i);
557 if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
558 {
562 }
563}
564
565void
567{
568 NS_LOG_FUNCTION (this << interface << address);
569 if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
570 {
574 }
575}
576
577void
579{
580 NS_LOG_FUNCTION (this << interface << address);
581 if (m_respondToInterfaceEvents && Simulator::Now ().GetSeconds () > 0) // avoid startup events
582 {
586 }
587}
588
589void
591{
592 NS_LOG_FUNCTION (this << ipv4);
593 NS_ASSERT (m_ipv4 == 0 && ipv4 != 0);
594 m_ipv4 = ipv4;
595}
596
597
598} // namespace ns3
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:1279
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1386
static void DeleteGlobalRoutes()
Delete all static routes on all nodes that have a GlobalRouterInterface.
static void InitializeRoutes()
Compute routes using a Dijkstra SPF computation and populate per-node forwarding tables.
static void BuildGlobalRoutingDatabase()
Build the routing database by gathering Link State Advertisements from each node exporting a GlobalRo...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
bool IsMulticast(void) const
void AddHostRouteTo(Ipv4Address dest, Ipv4Address nextHop, uint32_t interface)
Add a host route to the global routing table.
std::list< Ipv4RoutingTableEntry * >::iterator HostRoutesI
iterator of container of Ipv4RoutingTableEntry (routes to hosts)
virtual void NotifyInterfaceDown(uint32_t interface)
void AddASExternalRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
Add an external route to the global routing table.
Ipv4RoutingTableEntry * GetRoute(uint32_t i) const
Get a route from the global unicast routing table.
virtual bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
Route an input packet (to be forwarded or locally delivered)
virtual void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address)
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< UniformRandomVariable > m_rand
A uniform random number generator for randomly routing packets among ECMP.
void DoDispose(void)
Destructor implementation.
void RemoveRoute(uint32_t i)
Remove a route from the global unicast routing table.
virtual void SetIpv4(Ptr< Ipv4 > ipv4)
virtual void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address)
virtual Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr)
Query routing cache for an existing route, for an outbound packet.
Ptr< Ipv4Route > LookupGlobal(Ipv4Address dest, Ptr< NetDevice > oif=0)
Lookup in the forwarding table for destination.
std::list< Ipv4RoutingTableEntry * >::iterator ASExternalRoutesI
iterator of container of Ipv4RoutingTableEntry (routes to external AS)
Ipv4GlobalRouting()
Construct an empty Ipv4GlobalRouting routing protocol,.
std::list< Ipv4RoutingTableEntry * >::const_iterator NetworkRoutesCI
const iterator of container of Ipv4RoutingTableEntry (routes to networks)
Ptr< Ipv4 > m_ipv4
associated IPv4 instance
void AddNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
Add a network route to the global routing table.
uint32_t GetNRoutes(void) const
Get the number of individual unicast routes that have been added to the routing table.
std::list< Ipv4RoutingTableEntry * >::const_iterator HostRoutesCI
const iterator of container of Ipv4RoutingTableEntry (routes to hosts)
std::list< Ipv4RoutingTableEntry * >::iterator NetworkRoutesI
iterator of container of Ipv4RoutingTableEntry (routes to networks)
ASExternalRoutes m_ASexternalRoutes
External routes imported.
virtual void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const
Print the Routing Table entries.
HostRoutes m_hostRoutes
Routes to hosts.
static TypeId GetTypeId(void)
Get the type ID.
bool m_respondToInterfaceEvents
Set to true if this interface should respond to interface events by globallly recomputing routes.
bool m_randomEcmpRouting
Set to true if packets are randomly routed among ECMP; set to false for using only one route consiste...
NetworkRoutes m_networkRoutes
Routes to networks.
std::list< Ipv4RoutingTableEntry * >::const_iterator ASExternalRoutesCI
const iterator of container of Ipv4RoutingTableEntry (routes to external AS)
virtual void NotifyInterfaceUp(uint32_t interface)
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
a class to store IPv4 address information on an interface
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:256
bool IsMatch(Ipv4Address a, Ipv4Address b) const
A record of an IPv4 routing table entry for Ipv4GlobalRouting and Ipv4StaticRouting.
bool IsHost(void) const
uint32_t GetInterface(void) const
bool IsGateway(void) const
Ipv4Address GetDest(void) const
Ipv4Mask GetDestNetworkMask(void) const
static Ipv4RoutingTableEntry CreateNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
static Ipv4RoutingTableEntry CreateHostRouteTo(Ipv4Address dest, Ipv4Address nextHop, uint32_t interface)
Ipv4Address GetGateway(void) const
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition: names.cc:817
A network Node.
Definition: node.h:57
A base class which provides memory management and object aggregation.
Definition: object.h:88
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
@ ERROR_NOROUTETOHOST
Definition: socket.h:93
@ ERROR_NOTERROR
Definition: socket.h:83
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:109
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:432
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:85
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:287
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.