A Discrete-Event Network Simulator
API
node.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006 Georgia Tech Research Corporation, INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: George F. Riley<riley@ece.gatech.edu>
18  * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "node.h"
22 
23 #include "application.h"
24 #include "net-device.h"
25 #include "node-list.h"
26 
27 #include "ns3/assert.h"
28 #include "ns3/boolean.h"
29 #include "ns3/global-value.h"
30 #include "ns3/log.h"
31 #include "ns3/object-vector.h"
32 #include "ns3/packet.h"
33 #include "ns3/simulator.h"
34 #include "ns3/uinteger.h"
35 
36 namespace ns3
37 {
38 
40 
42 
48 static GlobalValue g_checksumEnabled =
49  GlobalValue("ChecksumEnabled",
50  "A global switch to enable all checksums for all protocols",
51  BooleanValue(false),
53 
54 TypeId
56 {
57  static TypeId tid =
58  TypeId("ns3::Node")
59  .SetParent<Object>()
60  .SetGroupName("Network")
61  .AddConstructor<Node>()
62  .AddAttribute("DeviceList",
63  "The list of devices associated to this Node.",
66  MakeObjectVectorChecker<NetDevice>())
67  .AddAttribute("ApplicationList",
68  "The list of applications associated to this Node.",
71  MakeObjectVectorChecker<Application>())
72  .AddAttribute("Id",
73  "The id (unique integer) of this Node.",
74  TypeId::ATTR_GET, // allow only getting it.
75  UintegerValue(0),
77  MakeUintegerChecker<uint32_t>())
78  .AddAttribute(
79  "SystemId",
80  "The systemId of this node: a unique integer used for parallel simulations.",
82  UintegerValue(0),
84  MakeUintegerChecker<uint32_t>());
85  return tid;
86 }
87 
89  : m_id(0),
90  m_sid(0)
91 {
92  NS_LOG_FUNCTION(this);
93  Construct();
94 }
95 
96 Node::Node(uint32_t sid)
97  : m_id(0),
98  m_sid(sid)
99 {
100  NS_LOG_FUNCTION(this << sid);
101  Construct();
102 }
103 
104 void
106 {
107  NS_LOG_FUNCTION(this);
108  m_id = NodeList::Add(this);
109 }
110 
112 {
113  NS_LOG_FUNCTION(this);
114 }
115 
116 uint32_t
117 Node::GetId() const
118 {
119  NS_LOG_FUNCTION(this);
120  return m_id;
121 }
122 
123 Time
125 {
126  NS_LOG_FUNCTION(this);
127  return Simulator::Now();
128 }
129 
130 uint32_t
132 {
133  NS_LOG_FUNCTION(this);
134  return m_sid;
135 }
136 
137 uint32_t
139 {
140  NS_LOG_FUNCTION(this << device);
141  uint32_t index = m_devices.size();
142  m_devices.push_back(device);
143  device->SetNode(this);
144  device->SetIfIndex(index);
145  device->SetReceiveCallback(MakeCallback(&Node::NonPromiscReceiveFromDevice, this));
147  NotifyDeviceAdded(device);
148  return index;
149 }
150 
152 Node::GetDevice(uint32_t index) const
153 {
154  NS_LOG_FUNCTION(this << index);
155  NS_ASSERT_MSG(index < m_devices.size(),
156  "Device index " << index << " is out of range (only have " << m_devices.size()
157  << " devices).");
158  return m_devices[index];
159 }
160 
161 uint32_t
163 {
164  NS_LOG_FUNCTION(this);
165  return m_devices.size();
166 }
167 
168 uint32_t
170 {
171  NS_LOG_FUNCTION(this << application);
172  uint32_t index = m_applications.size();
173  m_applications.push_back(application);
174  application->SetNode(this);
176  return index;
177 }
178 
180 Node::GetApplication(uint32_t index) const
181 {
182  NS_LOG_FUNCTION(this << index);
183  NS_ASSERT_MSG(index < m_applications.size(),
184  "Application index " << index << " is out of range (only have "
185  << m_applications.size() << " applications).");
186  return m_applications[index];
187 }
188 
189 uint32_t
191 {
192  NS_LOG_FUNCTION(this);
193  return m_applications.size();
194 }
195 
196 void
198 {
199  NS_LOG_FUNCTION(this);
201  m_handlers.clear();
202  for (std::vector<Ptr<NetDevice>>::iterator i = m_devices.begin(); i != m_devices.end(); i++)
203  {
204  Ptr<NetDevice> device = *i;
205  device->Dispose();
206  *i = nullptr;
207  }
208  m_devices.clear();
209  for (std::vector<Ptr<Application>>::iterator i = m_applications.begin();
210  i != m_applications.end();
211  i++)
212  {
213  Ptr<Application> application = *i;
214  application->Dispose();
215  *i = nullptr;
216  }
217  m_applications.clear();
219 }
220 
221 void
223 {
224  NS_LOG_FUNCTION(this);
225  for (std::vector<Ptr<NetDevice>>::iterator i = m_devices.begin(); i != m_devices.end(); i++)
226  {
227  Ptr<NetDevice> device = *i;
228  device->Initialize();
229  }
230  for (std::vector<Ptr<Application>>::iterator i = m_applications.begin();
231  i != m_applications.end();
232  i++)
233  {
234  Ptr<Application> application = *i;
235  application->Initialize();
236  }
237 
239 }
240 
241 void
243  uint16_t protocolType,
244  Ptr<NetDevice> device,
245  bool promiscuous)
246 {
247  NS_LOG_FUNCTION(this << &handler << protocolType << device << promiscuous);
248  struct Node::ProtocolHandlerEntry entry;
249  entry.handler = handler;
250  entry.protocol = protocolType;
251  entry.device = device;
252  entry.promiscuous = promiscuous;
253 
254  // On demand enable promiscuous mode in netdevices
255  if (promiscuous)
256  {
257  if (!device)
258  {
259  for (std::vector<Ptr<NetDevice>>::iterator i = m_devices.begin(); i != m_devices.end();
260  i++)
261  {
262  Ptr<NetDevice> dev = *i;
263  dev->SetPromiscReceiveCallback(MakeCallback(&Node::PromiscReceiveFromDevice, this));
264  }
265  }
266  else
267  {
268  device->SetPromiscReceiveCallback(MakeCallback(&Node::PromiscReceiveFromDevice, this));
269  }
270  }
271 
272  m_handlers.push_back(entry);
273 }
274 
275 void
277 {
278  NS_LOG_FUNCTION(this << &handler);
279  for (ProtocolHandlerList::iterator i = m_handlers.begin(); i != m_handlers.end(); i++)
280  {
281  if (i->handler.IsEqual(handler))
282  {
283  m_handlers.erase(i);
284  break;
285  }
286  }
287 }
288 
289 bool
291 {
293  BooleanValue val;
295  return val.Get();
296 }
297 
298 bool
300  Ptr<const Packet> packet,
301  uint16_t protocol,
302  const Address& from,
303  const Address& to,
304  NetDevice::PacketType packetType)
305 {
306  NS_LOG_FUNCTION(this << device << packet << protocol << &from << &to << packetType);
307  return ReceiveFromDevice(device, packet, protocol, from, to, packetType, true);
308 }
309 
310 bool
312  Ptr<const Packet> packet,
313  uint16_t protocol,
314  const Address& from)
315 {
316  NS_LOG_FUNCTION(this << device << packet << protocol << &from);
317  return ReceiveFromDevice(device,
318  packet,
319  protocol,
320  from,
321  device->GetAddress(),
323  false);
324 }
325 
326 bool
328  Ptr<const Packet> packet,
329  uint16_t protocol,
330  const Address& from,
331  const Address& to,
332  NetDevice::PacketType packetType,
333  bool promiscuous)
334 {
335  NS_LOG_FUNCTION(this << device << packet << protocol << &from << &to << packetType
336  << promiscuous);
338  "Received packet with erroneous context ; "
339  << "make sure the channels in use are correctly updating events context "
340  << "when transferring events from one node to another.");
341  NS_LOG_DEBUG("Node " << GetId() << " ReceiveFromDevice: dev " << device->GetIfIndex()
342  << " (type=" << device->GetInstanceTypeId().GetName() << ") Packet UID "
343  << packet->GetUid());
344  bool found = false;
345 
346  for (ProtocolHandlerList::iterator i = m_handlers.begin(); i != m_handlers.end(); i++)
347  {
348  if (!i->device || (i->device == device))
349  {
350  if (i->protocol == 0 || i->protocol == protocol)
351  {
352  if (promiscuous == i->promiscuous)
353  {
354  i->handler(device, packet, protocol, from, to, packetType);
355  found = true;
356  }
357  }
358  }
359  }
360  return found;
361 }
362 
363 void
365 {
366  NS_LOG_FUNCTION(this << &listener);
367  m_deviceAdditionListeners.push_back(listener);
368  // and, then, notify the new listener about all existing devices.
369  for (std::vector<Ptr<NetDevice>>::const_iterator i = m_devices.begin(); i != m_devices.end();
370  ++i)
371  {
372  listener(*i);
373  }
374 }
375 
376 void
378 {
379  NS_LOG_FUNCTION(this << &listener);
380  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin();
381  i != m_deviceAdditionListeners.end();
382  i++)
383  {
384  if ((*i).IsEqual(listener))
385  {
386  m_deviceAdditionListeners.erase(i);
387  break;
388  }
389  }
390 }
391 
392 void
394 {
395  NS_LOG_FUNCTION(this << device);
396  for (DeviceAdditionListenerList::iterator i = m_deviceAdditionListeners.begin();
397  i != m_deviceAdditionListeners.end();
398  i++)
399  {
400  (*i)(device);
401  }
402 }
403 
404 } // namespace ns3
a polymophic address class
Definition: address.h:100
void SetNode(Ptr< Node > node)
Definition: application.cc:114
AttributeValue implementation for Boolean.
Definition: boolean.h:37
bool Get() const
Definition: boolean.cc:55
Hold a so-called 'global value'.
Definition: global-value.h:76
void GetValue(AttributeValue &value) const
Get the value.
Definition: global-value.cc:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
A network Node.
Definition: node.h:56
void UnregisterProtocolHandler(ProtocolHandler handler)
Definition: node.cc:276
uint32_t GetSystemId() const
Definition: node.cc:131
void DoDispose() override
The dispose method.
Definition: node.cc:197
bool PromiscReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive a packet from a device in promiscuous mode.
Definition: node.cc:299
static GlobalValue g_checksumEnabled
Definition: node.cc:48
DeviceAdditionListenerList m_deviceAdditionListeners
Device addition listeners in the node.
Definition: node.h:305
std::vector< Ptr< Application > > m_applications
Applications associated to this node.
Definition: node.h:303
uint32_t AddDevice(Ptr< NetDevice > device)
Associate a NetDevice to this node.
Definition: node.cc:138
uint32_t m_id
Node id for this node.
Definition: node.h:300
uint32_t GetNDevices() const
Definition: node.cc:162
uint32_t GetNApplications() const
Definition: node.cc:190
Ptr< Application > GetApplication(uint32_t index) const
Retrieve the index-th Application associated to this node.
Definition: node.cc:180
bool ReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet >, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType, bool promisc)
Receive a packet from a device.
Definition: node.cc:327
bool NonPromiscReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &from)
Receive a packet from a device in non-promiscuous mode.
Definition: node.cc:311
uint32_t m_sid
System id for this node.
Definition: node.h:301
ProtocolHandlerList m_handlers
Protocol handlers in the node.
Definition: node.h:304
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:169
void Construct()
Finish node's construction by setting the correct node ID.
Definition: node.cc:105
static TypeId GetTypeId()
Get the type ID.
Definition: node.cc:55
uint32_t GetId() const
Definition: node.cc:117
Node()
Definition: node.cc:88
Time GetLocalTime() const
In the future, ns3 nodes may have clock that returned a local time different from the virtual time Si...
Definition: node.cc:124
void RegisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:364
void DoInitialize() override
Initialize() implementation.
Definition: node.cc:222
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:152
~Node() override
Definition: node.cc:111
void NotifyDeviceAdded(Ptr< NetDevice > device)
Notifies all the DeviceAdditionListener about the new device added.
Definition: node.cc:393
static bool ChecksumEnabled()
Definition: node.cc:290
void UnregisterDeviceAdditionListener(DeviceAdditionListener listener)
Definition: node.cc:377
std::vector< Ptr< NetDevice > > m_devices
Devices associated to this node.
Definition: node.h:302
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:242
static uint32_t Add(Ptr< Node > node)
Definition: node-list.cc:230
A base class which provides memory management and object aggregation.
Definition: object.h:89
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:186
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
void Dispose()
Dispose of this Object.
Definition: object.cc:219
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:587
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static uint32_t GetContext()
Get the current simulation context.
Definition: simulator.cc:309
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:60
@ ATTR_GET
The attribute can be read.
Definition: type-id.h:65
@ ATTR_SET
The attribute can be written.
Definition: type-id.h:66
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
ObjectPtrContainerValue ObjectVectorValue
ObjectVectorValue is an alias for ObjectPtrContainerValue.
Definition: object-vector.h:40
Ptr< const AttributeAccessor > MakeObjectVectorAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Definition: object-vector.h:76
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
Protocol handler entry.
Definition: node.h:288
bool promiscuous
true if it is a promiscuous handler
Definition: node.h:292
uint16_t protocol
the protocol number
Definition: node.h:291
Ptr< NetDevice > device
the NetDevice
Definition: node.h:290
ProtocolHandler handler
the protocol handler
Definition: node.h:289