A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
arp-cache.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006 INRIA
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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "ns3/assert.h"
21 #include "ns3/packet.h"
22 #include "ns3/simulator.h"
23 #include "ns3/uinteger.h"
24 #include "ns3/log.h"
25 #include "ns3/node.h"
26 #include "ns3/trace-source-accessor.h"
27 
28 #include "arp-cache.h"
29 #include "arp-header.h"
30 #include "ipv4-interface.h"
31 
32 NS_LOG_COMPONENT_DEFINE ("ArpCache");
33 
34 namespace ns3 {
35 
37 
38 TypeId
40 {
41  static TypeId tid = TypeId ("ns3::ArpCache")
42  .SetParent<Object> ()
43  .AddAttribute ("AliveTimeout",
44  "When this timeout expires, the matching cache entry needs refreshing",
45  TimeValue (Seconds (120)),
46  MakeTimeAccessor (&ArpCache::m_aliveTimeout),
47  MakeTimeChecker ())
48  .AddAttribute ("DeadTimeout",
49  "When this timeout expires, a new attempt to resolve the matching entry is made",
50  TimeValue (Seconds (100)),
51  MakeTimeAccessor (&ArpCache::m_deadTimeout),
52  MakeTimeChecker ())
53  .AddAttribute ("WaitReplyTimeout",
54  "When this timeout expires, the cache entries will be scanned and entries in WaitReply state will resend ArpRequest unless MaxRetries has been exceeded, in which case the entry is marked dead",
55  TimeValue (Seconds (1)),
56  MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
57  MakeTimeChecker ())
58  .AddAttribute ("MaxRetries",
59  "Number of retransmissions of ArpRequest before marking dead",
60  UintegerValue (3),
61  MakeUintegerAccessor (&ArpCache::m_maxRetries),
62  MakeUintegerChecker<uint32_t> ())
63  .AddAttribute ("PendingQueueSize",
64  "The size of the queue for packets pending an arp reply.",
65  UintegerValue (3),
66  MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
67  MakeUintegerChecker<uint32_t> ())
68  .AddTraceSource ("Drop",
69  "Packet dropped due to ArpCache entry in WaitReply expiring.",
71  ;
72  return tid;
73 }
74 
76  : m_device (0),
77  m_interface (0)
78 {
79  NS_LOG_FUNCTION (this);
80 }
81 
83 {
84  NS_LOG_FUNCTION (this);
85 }
86 
87 void
89 {
90  NS_LOG_FUNCTION (this);
91  Flush ();
92  m_device = 0;
93  m_interface = 0;
95  {
97  }
99 }
100 
101 void
103 {
104  NS_LOG_FUNCTION (this << device << interface);
105  m_device = device;
106  m_interface = interface;
107 }
108 
111 {
112  NS_LOG_FUNCTION (this);
113  return m_device;
114 }
115 
118 {
119  NS_LOG_FUNCTION (this);
120  return m_interface;
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION (this << aliveTimeout);
127  m_aliveTimeout = aliveTimeout;
128 }
129 void
131 {
132  NS_LOG_FUNCTION (this << deadTimeout);
133  m_deadTimeout = deadTimeout;
134 }
135 void
137 {
138  NS_LOG_FUNCTION (this << waitReplyTimeout);
139  m_waitReplyTimeout = waitReplyTimeout;
140 }
141 
142 Time
144 {
145  NS_LOG_FUNCTION (this);
146  return m_aliveTimeout;
147 }
148 Time
150 {
151  NS_LOG_FUNCTION (this);
152  return m_deadTimeout;
153 }
154 Time
156 {
157  NS_LOG_FUNCTION (this);
158  return m_waitReplyTimeout;
159 }
160 
161 void
163  Ipv4Address> arpRequestCallback)
164 {
165  NS_LOG_FUNCTION (this << &arpRequestCallback);
166  m_arpRequestCallback = arpRequestCallback;
167 }
168 
169 void
171 {
172  NS_LOG_FUNCTION (this);
173  if (!m_waitReplyTimer.IsRunning ())
174  {
175  NS_LOG_LOGIC ("Starting WaitReplyTimer at " << Simulator::Now () << " for " <<
179  }
180 }
181 
182 void
184 {
185  NS_LOG_FUNCTION (this);
186  ArpCache::Entry* entry;
187  bool restartWaitReplyTimer = false;
188  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
189  {
190  entry = (*i).second;
191  if (entry != 0 && entry->IsWaitReply ())
192  {
193  if (entry->GetRetries () < m_maxRetries)
194  {
195  NS_LOG_LOGIC ("node="<< m_device->GetNode ()->GetId () <<
196  ", ArpWaitTimeout for " << entry->GetIpv4Address () <<
197  " expired -- retransmitting arp request since retries = " <<
198  entry->GetRetries ());
199  m_arpRequestCallback (this, entry->GetIpv4Address ());
200  restartWaitReplyTimer = true;
201  entry->IncrementRetries ();
202  }
203  else
204  {
205  NS_LOG_LOGIC ("node="<<m_device->GetNode ()->GetId () <<
206  ", wait reply for " << entry->GetIpv4Address () <<
207  " expired -- drop since max retries exceeded: " <<
208  entry->GetRetries ());
209  entry->MarkDead ();
210  entry->ClearRetries ();
211  Ptr<Packet> pending = entry->DequeuePending ();
212  while (pending != 0)
213  {
214  m_dropTrace (pending);
215  pending = entry->DequeuePending ();
216  }
217  }
218  }
219 
220  }
221  if (restartWaitReplyTimer)
222  {
223  NS_LOG_LOGIC ("Restarting WaitReplyTimer at " << Simulator::Now ().GetSeconds ());
226  }
227 }
228 
229 void
231 {
232  NS_LOG_FUNCTION (this);
233  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
234  {
235  delete (*i).second;
236  }
237  m_arpCache.erase (m_arpCache.begin (), m_arpCache.end ());
239  {
240  NS_LOG_LOGIC ("Stopping WaitReplyTimer at " << Simulator::Now ().GetSeconds () << " due to ArpCache flush");
242  }
243 }
244 
247 {
248  NS_LOG_FUNCTION (this << to);
249  if (m_arpCache.find (to) != m_arpCache.end ())
250  {
251  ArpCache::Entry *entry = m_arpCache[to];
252  return entry;
253  }
254  return 0;
255 }
256 
259 {
260  NS_LOG_FUNCTION (this << to);
261  NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ());
262 
263  ArpCache::Entry *entry = new ArpCache::Entry (this);
264  m_arpCache[to] = entry;
265  entry->SetIpv4Address (to);
266  return entry;
267 }
268 
270  : m_arp (arp),
271  m_state (ALIVE),
272  m_retries (0)
273 {
274  NS_LOG_FUNCTION (this << arp);
275 }
276 
277 
278 bool
280 {
281  NS_LOG_FUNCTION (this);
282  return (m_state == DEAD) ? true : false;
283 }
284 bool
286 {
287  NS_LOG_FUNCTION (this);
288  return (m_state == ALIVE) ? true : false;
289 }
290 bool
292 {
293  NS_LOG_FUNCTION (this);
294  return (m_state == WAIT_REPLY) ? true : false;
295 }
296 
297 
298 void
300 {
301  NS_LOG_FUNCTION (this);
302  m_state = DEAD;
303  ClearRetries ();
304  UpdateSeen ();
305 }
306 void
308 {
309  NS_LOG_FUNCTION (this << macAddress);
310  NS_ASSERT (m_state == WAIT_REPLY);
311  m_macAddress = macAddress;
312  m_state = ALIVE;
313  ClearRetries ();
314  UpdateSeen ();
315 }
316 
317 bool
319 {
320  NS_LOG_FUNCTION (this << waiting);
321  NS_ASSERT (m_state == WAIT_REPLY);
322  /* We are already waiting for an answer so
323  * we dump the previously waiting packet and
324  * replace it with this one.
325  */
326  if (m_pending.size () >= m_arp->m_pendingQueueSize)
327  {
328  return false;
329  }
330  m_pending.push_back (waiting);
331  return true;
332 }
333 void
335 {
336  NS_LOG_FUNCTION (this << waiting);
337  NS_ASSERT (m_state == ALIVE || m_state == DEAD);
338  NS_ASSERT (m_pending.empty ());
339  m_state = WAIT_REPLY;
340  m_pending.push_back (waiting);
341  UpdateSeen ();
342  m_arp->StartWaitReplyTimer ();
343 }
344 
345 Address
347 {
348  NS_LOG_FUNCTION (this);
349  NS_ASSERT (m_state == ALIVE);
350  return m_macAddress;
351 }
354 {
355  NS_LOG_FUNCTION (this);
356  return m_ipv4Address;
357 }
358 void
360 {
361  NS_LOG_FUNCTION (this << destination);
362  m_ipv4Address = destination;
363 }
364 Time
366 {
367  NS_LOG_FUNCTION (this);
368  switch (m_state) {
370  return m_arp->GetWaitReplyTimeout ();
372  return m_arp->GetDeadTimeout ();
374  return m_arp->GetAliveTimeout ();
375  default:
376  NS_ASSERT (false);
377  return Seconds (0);
378  /* NOTREACHED */
379  }
380 }
381 bool
383 {
384  NS_LOG_FUNCTION (this);
385  Time timeout = GetTimeout ();
386  Time delta = Simulator::Now () - m_lastSeen;
387  NS_LOG_DEBUG ("delta=" << delta.GetSeconds () << "s");
388  if (delta > timeout)
389  {
390  return true;
391  }
392  return false;
393 }
396 {
397  NS_LOG_FUNCTION (this);
398  if (m_pending.empty ())
399  {
400  return 0;
401  }
402  else
403  {
404  Ptr<Packet> p = m_pending.front ();
405  m_pending.pop_front ();
406  return p;
407  }
408 }
409 void
411 {
412  NS_LOG_FUNCTION (this);
413  m_lastSeen = Simulator::Now ();
414 }
415 uint32_t
417 {
418  NS_LOG_FUNCTION (this);
419  return m_retries;
420 }
421 void
423 {
424  NS_LOG_FUNCTION (this);
425  m_retries++;
426  UpdateSeen ();
427 }
428 void
430 {
431  NS_LOG_FUNCTION (this);
432  m_retries = 0;
433 }
434 
435 } // namespace ns3
436 
void SetDevice(Ptr< NetDevice > device, Ptr< Ipv4Interface > interface)
Set the NetDevice and Ipv4Interface associated with the ArpCache.
Definition: arp-cache.cc:102
uint32_t m_maxRetries
max retries for a resolution
Definition: arp-cache.h:285
void StartWaitReplyTimer(void)
This method will schedule a timeout at WaitReplyTimeout interval in the future, unless a timer is alr...
Definition: arp-cache.cc:170
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:79
void SetArpRequestCallback(Callback< void, Ptr< const ArpCache >, Ipv4Address > arpRequestCallback)
This callback is set when the ArpCache is set up and allows the cache to generate an Arp request when...
Definition: arp-cache.cc:162
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:60
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Callback template class.
Definition: callback.h:924
ArpCache::Entry * Add(Ipv4Address to)
Add an Ipv4Address to this ARP cache.
Definition: arp-cache.cc:258
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: arp-cache.cc:88
static TypeId GetTypeId(void)
Get the type ID.
Definition: arp-cache.cc:39
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
Definition: arp-cache.h:241
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
Definition: arp-cache.cc:246
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
Callback< void, Ptr< const ArpCache >, Ipv4Address > m_arpRequestCallback
reply timeout callback
Definition: arp-cache.h:284
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
Time GetDeadTimeout(void) const
Get the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:149
Ptr< NetDevice > GetDevice(void) const
Returns the NetDevice that this ARP cache is associated with.
Definition: arp-cache.cc:110
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:335
bool IsRunning(void) const
This method is syntactic sugar for the ns3::Simulator::isExpired method.
Definition: event-id.cc:59
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:825
ns3::Time timeout
bool IsAlive(void)
Definition: arp-cache.cc:285
EventId m_waitReplyTimer
cache alive state timer
Definition: arp-cache.h:283
a polymophic address class
Definition: address.h:86
Cache m_arpCache
the ARP cache
Definition: arp-cache.h:294
double GetSeconds(void) const
Definition: nstime.h:272
void SetIpv4Address(Ipv4Address destination)
Definition: arp-cache.cc:359
void HandleWaitReplyTimeout(void)
This function is an event handler for the event that the ArpCache wants to check whether it must retr...
Definition: arp-cache.cc:183
hold objects of type ns3::Time
Definition: nstime.h:1008
void MarkWaitReply(Ptr< Packet > waiting)
Definition: arp-cache.cc:334
Hold an unsigned integer type.
Definition: uinteger.h:46
uint32_t GetRetries(void) const
Definition: arp-cache.cc:416
bool IsDead(void)
Definition: arp-cache.cc:279
Ptr< Ipv4Interface > m_interface
Ipv4Interface associated with the cache.
Definition: arp-cache.h:279
bool IsExpired(void) const
Definition: arp-cache.cc:382
Ipv4Address GetIpv4Address(void) const
Definition: arp-cache.cc:353
Time m_waitReplyTimeout
cache reply state timeout
Definition: arp-cache.h:282
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
Address GetMacAddress(void) const
Definition: arp-cache.cc:346
void SetDeadTimeout(Time deadTimeout)
Set the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:130
void SetAliveTimeout(Time aliveTimeout)
Set the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:124
Ptr< Ipv4Interface > GetInterface(void) const
Returns the Ipv4Interface that this ARP cache is associated with.
Definition: arp-cache.cc:117
static void Remove(const EventId &id)
Remove an event from the event list.
Definition: simulator.cc:258
void IncrementRetries(void)
Increment the counter of number of retries for an entry.
Definition: arp-cache.cc:422
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void MarkAlive(Address macAddress)
Definition: arp-cache.cc:307
Time GetAliveTimeout(void) const
Get the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:143
A record that that holds information about an ArpCache entry.
Definition: arp-cache.h:160
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
void Flush(void)
Clear the ArpCache of all entries.
Definition: arp-cache.cc:230
Entry(ArpCache *arp)
Constructor.
Definition: arp-cache.cc:269
Time GetTimeout(void) const
Returns the entry timeout.
Definition: arp-cache.cc:365
void UpdateSeen(void)
Update the entry when seeing a packet.
Definition: arp-cache.cc:410
TracedCallback< Ptr< const Packet > > m_dropTrace
trace for packets dropped by the ARP cache queue
Definition: arp-cache.h:295
bool UpdateWaitReply(Ptr< Packet > waiting)
Definition: arp-cache.cc:318
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
sgi::hash_map< Ipv4Address, ArpCache::Entry *, Ipv4AddressHash >::iterator CacheI
ARP Cache container iterator.
Definition: arp-cache.h:274
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:213
bool IsWaitReply(void)
Definition: arp-cache.cc:291
An ARP cache.
Definition: arp-cache.h:49
Ptr< Packet > DequeuePending(void)
Definition: arp-cache.cc:395
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::cancel method.
Definition: event-id.cc:47
Time GetWaitReplyTimeout(void) const
Get the time the entry will be in WAIT_REPLY state.
Definition: arp-cache.cc:155
void ClearRetries(void)
Zero the counter of number of retries for an entry.
Definition: arp-cache.cc:429
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:441
Ptr< NetDevice > m_device
NetDevice associated with the cache.
Definition: arp-cache.h:278
void MarkDead(void)
Changes the state of this entry to dead.
Definition: arp-cache.cc:299
Time m_deadTimeout
cache dead state timeout
Definition: arp-cache.h:281
Definition: arp-cache.h:243
a base class which provides memory management and object aggregation
Definition: object.h:64
uint32_t m_pendingQueueSize
number of packets waiting for a resolution
Definition: arp-cache.h:293
void SetWaitReplyTimeout(Time waitReplyTimeout)
Set the time the entry will be in WAIT_REPLY state.
Definition: arp-cache.cc:136
Time m_aliveTimeout
cache alive state timeout
Definition: arp-cache.h:280
a unique identifier for an interface.
Definition: type-id.h:49
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
Definition: arp-cache.h:242