A Discrete-Event Network Simulator
API
dhcp-server.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011 UPB
4 * Copyright (c) 2017 NITK Surathkal
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Author: Radu Lupu <rlupu@elcom.pub.ro>
20 * Ankit Deepak <adadeepak8@gmail.com>
21 * Deepti Rajagopal <deeptir96@gmail.com>
22 *
23 */
24
25#include <algorithm>
26#include "ns3/log.h"
27#include "ns3/assert.h"
28#include "ns3/nstime.h"
29#include "ns3/ipv4-packet-info-tag.h"
30#include "ns3/socket.h"
31#include "ns3/simulator.h"
32#include "ns3/packet.h"
33#include "ns3/ipv4.h"
34#include "dhcp-server.h"
35#include "dhcp-header.h"
36
37namespace ns3 {
38
39NS_LOG_COMPONENT_DEFINE ("DhcpServer");
41
42TypeId
44{
45 static TypeId tid = TypeId ("ns3::DhcpServer")
47 .AddConstructor<DhcpServer> ()
48 .SetGroupName ("Internet-Apps")
49 .AddAttribute ("LeaseTime",
50 "Lease for which address will be leased.",
51 TimeValue (Seconds (30)),
54 .AddAttribute ("RenewTime",
55 "Time after which client should renew.",
56 TimeValue (Seconds (15)),
59 .AddAttribute ("RebindTime",
60 "Time after which client should rebind.",
61 TimeValue (Seconds (25)),
64 .AddAttribute ("PoolAddresses",
65 "Pool of addresses to provide on request.",
67 MakeIpv4AddressAccessor (&DhcpServer::m_poolAddress),
68 MakeIpv4AddressChecker ())
69 .AddAttribute ("FirstAddress",
70 "The First valid address that can be given.",
72 MakeIpv4AddressAccessor (&DhcpServer::m_minAddress),
73 MakeIpv4AddressChecker ())
74 .AddAttribute ("LastAddress",
75 "The Last valid address that can be given.",
77 MakeIpv4AddressAccessor (&DhcpServer::m_maxAddress),
78 MakeIpv4AddressChecker ())
79 .AddAttribute ("PoolMask",
80 "Mask of the pool of addresses.",
82 MakeIpv4MaskAccessor (&DhcpServer::m_poolMask),
83 MakeIpv4MaskChecker ())
84 .AddAttribute ("Gateway",
85 "Address of default gateway",
87 MakeIpv4AddressAccessor (&DhcpServer::m_gateway),
88 MakeIpv4AddressChecker ())
89 ;
90 return tid;
91}
92
94{
95 NS_LOG_FUNCTION (this);
96}
97
99{
100 NS_LOG_FUNCTION (this);
101}
102
103void
105{
106 NS_LOG_FUNCTION (this);
108}
109
111{
112 NS_LOG_FUNCTION (this);
113
114 NS_ASSERT_MSG (m_minAddress < m_maxAddress,"Invalid Address range");
115
116 Ipv4Address myOwnAddress;
117
118 if (m_socket)
119 {
120 NS_ABORT_MSG ("DHCP daemon is not (yet) meant to be started twice or more.");
121 }
122
123 uint32_t addrIndex;
124
125 //add the DHCP local address to the leased addresses list, if it is defined!
126 Ptr<Ipv4> ipv4 = GetNode ()->GetObject<Ipv4> ();
127 int32_t ifIndex = ipv4->GetInterfaceForPrefix (m_poolAddress, m_poolMask);
128
129 if (ifIndex < 0)
130 {
131 NS_ABORT_MSG ("DHCP daemon must be run on the same subnet it is assigning the addresses.");
132 }
133
134 for (addrIndex = 0; addrIndex < ipv4->GetNAddresses (ifIndex); addrIndex++)
135 {
136 if (ipv4->GetAddress (ifIndex, addrIndex).GetLocal ().CombineMask (m_poolMask) == m_poolAddress &&
137 ipv4->GetAddress (ifIndex, addrIndex).GetLocal ().Get () >= m_minAddress.Get () &&
138 ipv4->GetAddress (ifIndex, addrIndex).GetLocal ().Get () <= m_maxAddress.Get ())
139 {
140 // set infinite GRANTED_LEASED_TIME for my address
141
142 myOwnAddress = ipv4->GetAddress (ifIndex, addrIndex).GetLocal ();
143 m_leasedAddresses[Address ()] = std::make_pair (myOwnAddress, 0xffffffff);
144 break;
145 }
146 }
147
148 TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
152 m_socket->BindToNetDevice (ipv4->GetNetDevice (ifIndex));
153 m_socket->Bind (local);
154 m_socket->SetRecvPktInfo (true);
155
156 uint32_t range = m_maxAddress.Get () - m_minAddress.Get () + 1;
157 for (uint32_t searchSeq = 0; searchSeq < range; searchSeq ++)
158 {
159 Ipv4Address poolAddress = Ipv4Address (m_minAddress.Get () + searchSeq);
160 if (poolAddress != myOwnAddress)
161 {
162 NS_LOG_LOGIC ("Adding " << poolAddress << " to the pool");
163 m_availableAddresses.push_back (poolAddress);
164 }
165 }
166
169}
170
172{
173 NS_LOG_FUNCTION (this);
174
175 if (m_socket)
176 {
178 }
179
180 m_leasedAddresses.clear ();
182}
183
185{
186 NS_LOG_FUNCTION (this);
187
188 // Set up timeout events and release of unsolicited addresses from the list
190 for (i = m_leasedAddresses.begin (); i != m_leasedAddresses.end (); i++)
191 {
192 // update the address state
193 if (i->second.second != 0xffffffff && i->second.second != 0)
194 {
195 i->second.second--;
196 if (i->second.second == 0)
197 {
198 NS_LOG_INFO ("Address leased state expired, address removed - " <<
199 "chaddr: " << i->first <<
200 " IP address " << i->second.first);
201 i->second.second = 0;
202 m_expiredAddresses.push_front (i->first);
203 }
204 }
205 }
207}
208
210{
211 NS_LOG_FUNCTION (this << socket);
212
213 DhcpHeader header;
214 Ptr<Packet> packet = 0;
215 Address from;
216 packet = m_socket->RecvFrom (from);
217
219
220 Ipv4PacketInfoTag interfaceInfo;
221 if (!packet->RemovePacketTag (interfaceInfo))
222 {
223 NS_ABORT_MSG ("No incoming interface on DHCP message, aborting.");
224 }
225 uint32_t incomingIf = interfaceInfo.GetRecvIf ();
226 Ptr<NetDevice> iDev = GetNode ()->GetDevice (incomingIf);
227
228 if (packet->RemoveHeader (header) == 0)
229 {
230 return;
231 }
232 if (header.GetType () == DhcpHeader::DHCPDISCOVER)
233 {
234 SendOffer (iDev, header, senderAddr);
235 }
236 if (header.GetType () == DhcpHeader::DHCPREQ && (header.GetReq ()).Get () >= m_minAddress.Get () && (header.GetReq ()).Get () <= m_maxAddress.Get ())
237 {
238 SendAck (iDev, header, senderAddr);
239 }
240}
241
243{
244 NS_LOG_FUNCTION (this << iDev << header << from);
245
246 DhcpHeader newDhcpHeader;
247 Address sourceChaddr = header.GetChaddr ();
248 uint32_t tran = header.GetTran ();
249 Ptr<Packet> packet = 0;
250 Ipv4Address offeredAddress;
251
252 NS_LOG_INFO ("DHCP DISCOVER from: " << from.GetIpv4 () << " source port: " << from.GetPort ());
253
254 LeasedAddressIter iter = m_leasedAddresses.find (sourceChaddr);
255 if (iter != m_leasedAddresses.end ())
256 {
257 // We know this client from some time ago
258 if (m_leasedAddresses[sourceChaddr].second != 0 && m_leasedAddresses[sourceChaddr].second != 0xffffffff)
259 {
260 NS_LOG_LOGIC ("This client is sending a DISCOVER but it has still a lease active - perhaps it didn't shut down gracefully: " << sourceChaddr);
261 }
262
263 m_expiredAddresses.remove (sourceChaddr);
264 offeredAddress = m_leasedAddresses[sourceChaddr].first;
265
266 }
267 else
268 {
269 // No previous record of the client, we must find a suitable address and create a record.
270 if (!m_availableAddresses.empty ())
271 {
272 // use an address never used before (if there is one)
273 offeredAddress = m_availableAddresses.front ();
274 m_availableAddresses.pop_front ();
275 }
276 else
277 {
278 // there's still hope: reuse the old ones.
279 if (!m_expiredAddresses.empty ())
280 {
281 Address oldestChaddr = m_expiredAddresses.back ();
282 m_expiredAddresses.pop_back ();
283 offeredAddress = m_leasedAddresses[oldestChaddr].first;
284 m_leasedAddresses.erase (oldestChaddr);
285 }
286 }
287 }
288
289 if (offeredAddress != Ipv4Address ())
290 {
291 m_leasedAddresses[sourceChaddr] = std::make_pair (offeredAddress, m_lease.GetSeconds ());
292
293 packet = Create<Packet> ();
294 newDhcpHeader.ResetOpt ();
295 newDhcpHeader.SetType (DhcpHeader::DHCPOFFER);
296 newDhcpHeader.SetChaddr (sourceChaddr);
297 newDhcpHeader.SetYiaddr (offeredAddress);
298
299 Ptr<Ipv4> ipv4 = GetNode ()->GetObject<Ipv4> ();
300 Ipv4Address myAddress = ipv4->SelectSourceAddress (iDev, offeredAddress, Ipv4InterfaceAddress::InterfaceAddressScope_e::GLOBAL);
301
302 newDhcpHeader.SetDhcps (myAddress);
303 newDhcpHeader.SetMask (m_poolMask.Get ());
304 newDhcpHeader.SetTran (tran);
305 newDhcpHeader.SetLease (m_lease.GetSeconds ());
306 newDhcpHeader.SetRenew (m_renew.GetSeconds ());
307 newDhcpHeader.SetRebind (m_rebind.GetSeconds ());
308 newDhcpHeader.SetTime ();
309 if (m_gateway != Ipv4Address ())
310 {
311 newDhcpHeader.SetRouter (m_gateway);
312 }
313 packet->AddHeader (newDhcpHeader);
314
315 if ((m_socket->SendTo (packet, 0, InetSocketAddress (Ipv4Address ("255.255.255.255"), from.GetPort ()))) >= 0)
316 {
317 NS_LOG_INFO ("DHCP OFFER" << " Offered Address: " << offeredAddress);
318 }
319 else
320 {
321 NS_LOG_INFO ("Error while sending DHCP OFFER");
322 }
323 }
324}
325
327{
328 NS_LOG_FUNCTION (this << iDev << header << from);
329
330 DhcpHeader newDhcpHeader;
331 Address sourceChaddr = header.GetChaddr ();
332 uint32_t tran = header.GetTran ();
333 Ptr<Packet> packet = 0;
334 Ipv4Address address = header.GetReq ();
335
336 NS_LOG_INFO ("DHCP REQUEST from: " << from.GetIpv4 () <<
337 " source port: " << from.GetPort () <<
338 " - refreshed addr: " << address);
339
341 iter = m_leasedAddresses.find (sourceChaddr);
342 if (iter != m_leasedAddresses.end ())
343 {
344 // update the lease time of this address - send ACK
345 (iter->second.second) += m_lease.GetSeconds ();
346 packet = Create<Packet> ();
347 newDhcpHeader.ResetOpt ();
348 newDhcpHeader.SetType (DhcpHeader::DHCPACK);
349 newDhcpHeader.SetChaddr (sourceChaddr);
350 newDhcpHeader.SetYiaddr (address);
351 newDhcpHeader.SetTran (tran);
352 newDhcpHeader.SetTime ();
353 packet->AddHeader (newDhcpHeader);
354 if (from.GetIpv4 () != address)
355 {
356 m_socket->SendTo (packet, 0, InetSocketAddress (Ipv4Address ("255.255.255.255"), from.GetPort ()));
357 }
358 else
359 {
360 m_socket->SendTo (packet, 0, from);
361 }
362 }
363 else
364 {
365 // Deleted or expired lease - send NACK
366 packet = Create<Packet> ();
367 newDhcpHeader.ResetOpt ();
368 newDhcpHeader.SetType (DhcpHeader::DHCPNACK);
369 newDhcpHeader.SetChaddr (sourceChaddr);
370 newDhcpHeader.SetYiaddr (address);
371 newDhcpHeader.SetTran (tran);
372 newDhcpHeader.SetTime ();
373 packet->AddHeader (newDhcpHeader);
374 if (from.GetIpv4 () != address)
375 {
376 m_socket->SendTo (packet, 0, InetSocketAddress (Ipv4Address ("255.255.255.255"), from.GetPort ()));
377 }
378 else
379 {
380 m_socket->SendTo (packet, 0, from);
381 }
382 NS_LOG_INFO ("IP addr does not exists or released!");
383 }
384}
385
387{
388 NS_LOG_FUNCTION (this << chaddr << addr);
389 Address cleanedCaddr;
390
391 NS_ASSERT_MSG (addr.Get () >= m_minAddress.Get () && addr.Get () <= m_maxAddress.Get (),
392 "Required address is not in the pool " << addr << " is not in [" << m_minAddress << ", " << m_maxAddress << "]");
393
394 // We need to cleanup the type from the stored chaddr, or later we'll fail to compare it.
395 // Moreover, the length is always 16, because chaddr is 16 bytes.
396 uint8_t buffer[Address::MAX_SIZE];
397 std::memset (buffer, 0, Address::MAX_SIZE);
398 uint32_t len = chaddr.CopyTo (buffer);
399 NS_ASSERT_MSG (len <= 16, "DHCP server can not handle a chaddr larger than 16 bytes");
400 cleanedCaddr.CopyFrom (buffer, 16);
401
402 NS_ASSERT_MSG (m_leasedAddresses.find (cleanedCaddr) == m_leasedAddresses.end (),
403 "Client has already an active lease: " << m_leasedAddresses[cleanedCaddr].first);
404
405 AvailableAddress::iterator it = find (m_availableAddresses.begin (), m_availableAddresses.end (), addr);
407 "Required address is not available (perhaps it has been already assigned): " << addr);
408
409 m_availableAddresses.remove (addr);
410 m_leasedAddresses[cleanedCaddr] = std::make_pair (addr, 0xffffffff);
411}
412
413} // Namespace ns3
a polymophic address class
Definition: address.h:91
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition: address.cc:101
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:82
The base class for all ns3 applications.
Definition: application.h:61
virtual void DoDispose(void)
Destructor implementation.
Definition: application.cc:83
Ptr< Node > GetNode() const
Definition: application.cc:104
BOOTP header with DHCP messages supports the following options: Subnet Mask (1), Address Request (50)...
Definition: dhcp-header.h:82
void SetTime()
Set the time when message is sent.
Definition: dhcp-header.cc:106
void ResetOpt()
Reset the BOOTP options.
Definition: dhcp-header.cc:247
void SetType(uint8_t type)
Set the type of BOOTP and DHCP messages.
Definition: dhcp-header.cc:74
@ DHCPACK
Code for DHCP ACK.
Definition: dhcp-header.h:120
@ DHCPOFFER
Code for DHCP Offer.
Definition: dhcp-header.h:118
@ DHCPDISCOVER
Code for DHCP Discover.
Definition: dhcp-header.h:117
@ DHCPREQ
Code for DHCP Request.
Definition: dhcp-header.h:119
@ DHCPNACK
Code for DHCP NACK.
Definition: dhcp-header.h:121
void SetTran(uint32_t tran)
Set the transaction ID.
Definition: dhcp-header.cc:96
void SetYiaddr(Ipv4Address addr)
Set the IPv4Address of the client.
Definition: dhcp-header.cc:132
void SetDhcps(Ipv4Address addr)
Set the DHCP server information.
Definition: dhcp-header.cc:142
void SetRenew(uint32_t time)
Set the Renewal time of the IPv4Address.
Definition: dhcp-header.cc:217
Ipv4Address GetReq(void) const
Get the IPv4Address requested by the client.
Definition: dhcp-header.cc:167
void SetLease(uint32_t time)
Set the lease time of the IPv4Address.
Definition: dhcp-header.cc:202
void SetRouter(Ipv4Address addr)
Set the Ipv4Address of gateway to be used.
Definition: dhcp-header.cc:187
void SetMask(uint32_t addr)
Set the mask of the IPv4Address.
Definition: dhcp-header.cc:172
uint32_t GetTran(void) const
Get the transaction id.
Definition: dhcp-header.cc:101
uint8_t GetType(void) const
Return the type of DHCP message.
Definition: dhcp-header.cc:85
void SetRebind(uint32_t time)
Set the Rebind time of the IPv4Address.
Definition: dhcp-header.cc:232
Address GetChaddr(void)
Get the Address of the client.
Definition: dhcp-header.cc:125
void SetChaddr(Address addr)
Set the Address of the device.
Definition: dhcp-header.cc:111
EventId m_expiredEvent
The Event to trigger TimerHandler.
Definition: dhcp-server.h:139
static const int PORT
Port number of DHCP server.
Definition: dhcp-server.h:70
virtual ~DhcpServer()
Definition: dhcp-server.cc:98
virtual void StopApplication(void)
Stops the DHCP client application.
Definition: dhcp-server.cc:171
AvailableAddress m_availableAddresses
Available addresses to be used (IP addresses)
Definition: dhcp-server.h:135
virtual void DoDispose(void)
Destructor implementation.
Definition: dhcp-server.cc:104
void TimerHandler(void)
Modifies the remaining lease time of addresses.
Definition: dhcp-server.cc:184
Time m_rebind
The rebinding time for an address.
Definition: dhcp-server.h:138
Time m_lease
The granted lease time for an address.
Definition: dhcp-server.h:136
static TypeId GetTypeId(void)
Get the type ID.
Definition: dhcp-server.cc:43
Ipv4Mask m_poolMask
The network mask of the pool.
Definition: dhcp-server.h:113
Ptr< Socket > m_socket
The socket bound to port 67.
Definition: dhcp-server.h:109
ExpiredAddress m_expiredAddresses
Expired addresses to be reused (chaddr of the clients)
Definition: dhcp-server.h:134
void AddStaticDhcpEntry(Address chaddr, Ipv4Address addr)
Add a static entry to the pool.
Definition: dhcp-server.cc:386
LeasedAddress m_leasedAddresses
Leased address and their status (cache memory)
Definition: dhcp-server.h:133
Ipv4Address m_minAddress
The first address in the address pool.
Definition: dhcp-server.h:111
Ipv4Address m_gateway
The gateway address.
Definition: dhcp-server.h:114
Time m_renew
The renewal time for an address.
Definition: dhcp-server.h:137
Ipv4Address m_maxAddress
The last address in the address pool.
Definition: dhcp-server.h:112
virtual void StartApplication(void)
Starts the DHCP Server application.
Definition: dhcp-server.cc:110
Ipv4Address m_poolAddress
The network address available to the server.
Definition: dhcp-server.h:110
void NetHandler(Ptr< Socket > socket)
Handles incoming packets from the network.
Definition: dhcp-server.cc:209
void SendAck(Ptr< NetDevice > iDev, DhcpHeader header, InetSocketAddress from)
Sends DHCP ACK (or NACK) after receiving Request.
Definition: dhcp-server.cc:326
std::map< Address, std::pair< Ipv4Address, uint32_t > >::iterator LeasedAddressIter
Leased address iterator - chaddr + IP addr / lease time.
Definition: dhcp-server.h:119
void SendOffer(Ptr< NetDevice > iDev, DhcpHeader header, InetSocketAddress from)
Sends DHCP offer after receiving DHCP Discover.
Definition: dhcp-server.cc:242
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
an Inet address class
uint16_t GetPort(void) const
Ipv4Address GetIpv4(void) const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
uint32_t Get(void) const
Get the host-order 32-bit IP address.
static Ipv4Address GetAny(void)
AttributeValue implementation for Ipv4Address.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:77
uint32_t Get(void) const
Get the host-order 32-bit IP mask.
AttributeValue implementation for Ipv4Mask.
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
uint32_t GetRecvIf(void) const
Get the tag's receiving interface.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:144
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:963
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:555
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:357
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:380
AttributeValue implementation for Time.
Definition: nstime.h:1309
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:829
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#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:88
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1310
Callback< R, Args... > MakeNullCallback(void)
Definition: callback.h:697
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:206
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:290
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:282
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1245
address
Definition: first.py:40
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:661
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:522
Definition: second.py:1