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 
39 TypeId
41 {
42  static TypeId tid = TypeId ("ns3::ArpCache")
43  .SetParent<Object> ()
44  .AddAttribute ("AliveTimeout",
45  "When this timeout expires, the matching cache entry needs refreshing",
46  TimeValue (Seconds (120)),
47  MakeTimeAccessor (&ArpCache::m_aliveTimeout),
48  MakeTimeChecker ())
49  .AddAttribute ("DeadTimeout",
50  "When this timeout expires, a new attempt to resolve the matching entry is made",
51  TimeValue (Seconds (100)),
52  MakeTimeAccessor (&ArpCache::m_deadTimeout),
53  MakeTimeChecker ())
54  .AddAttribute ("WaitReplyTimeout",
55  "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",
56  TimeValue (Seconds (1)),
57  MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
58  MakeTimeChecker ())
59  .AddAttribute ("MaxRetries",
60  "Number of retransmissions of ArpRequest before marking dead",
61  UintegerValue (3),
62  MakeUintegerAccessor (&ArpCache::m_maxRetries),
63  MakeUintegerChecker<uint32_t> ())
64  .AddAttribute ("PendingQueueSize",
65  "The size of the queue for packets pending an arp reply.",
66  UintegerValue (3),
67  MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
68  MakeUintegerChecker<uint32_t> ())
69  .AddTraceSource ("Drop",
70  "Packet dropped due to ArpCache entry in WaitReply expiring.",
72  ;
73  return tid;
74 }
75 
77  : m_device (0),
78  m_interface (0)
79 {
80  NS_LOG_FUNCTION (this);
81 }
82 
84 {
85  NS_LOG_FUNCTION (this);
86 }
87 
88 void
90 {
91  NS_LOG_FUNCTION (this);
92  Flush ();
93  m_device = 0;
94  m_interface = 0;
96  {
98  }
100 }
101 
102 void
104 {
105  NS_LOG_FUNCTION (this << device << interface);
106  m_device = device;
107  m_interface = interface;
108 }
109 
112 {
113  NS_LOG_FUNCTION (this);
114  return m_device;
115 }
116 
119 {
120  NS_LOG_FUNCTION (this);
121  return m_interface;
122 }
123 
124 void
126 {
127  NS_LOG_FUNCTION (this << aliveTimeout);
128  m_aliveTimeout = aliveTimeout;
129 }
130 void
132 {
133  NS_LOG_FUNCTION (this << deadTimeout);
134  m_deadTimeout = deadTimeout;
135 }
136 void
138 {
139  NS_LOG_FUNCTION (this << waitReplyTimeout);
140  m_waitReplyTimeout = waitReplyTimeout;
141 }
142 
143 Time
145 {
146  NS_LOG_FUNCTION (this);
147  return m_aliveTimeout;
148 }
149 Time
151 {
152  NS_LOG_FUNCTION (this);
153  return m_deadTimeout;
154 }
155 Time
157 {
158  NS_LOG_FUNCTION (this);
159  return m_waitReplyTimeout;
160 }
161 
162 void
164  Ipv4Address> arpRequestCallback)
165 {
166  NS_LOG_FUNCTION (this << &arpRequestCallback);
167  m_arpRequestCallback = arpRequestCallback;
168 }
169 
170 void
172 {
173  NS_LOG_FUNCTION (this);
174  if (!m_waitReplyTimer.IsRunning ())
175  {
176  NS_LOG_LOGIC ("Starting WaitReplyTimer at " << Simulator::Now () << " for " <<
180  }
181 }
182 
183 void
185 {
186  NS_LOG_FUNCTION (this);
187  ArpCache::Entry* entry;
188  bool restartWaitReplyTimer = false;
189  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
190  {
191  entry = (*i).second;
192  if (entry != 0 && entry->IsWaitReply ())
193  {
194  if (entry->GetRetries () < m_maxRetries)
195  {
196  NS_LOG_LOGIC ("node="<< m_device->GetNode ()->GetId () <<
197  ", ArpWaitTimeout for " << entry->GetIpv4Address () <<
198  " expired -- retransmitting arp request since retries = " <<
199  entry->GetRetries ());
200  m_arpRequestCallback (this, entry->GetIpv4Address ());
201  restartWaitReplyTimer = true;
202  entry->IncrementRetries ();
203  }
204  else
205  {
206  NS_LOG_LOGIC ("node="<<m_device->GetNode ()->GetId () <<
207  ", wait reply for " << entry->GetIpv4Address () <<
208  " expired -- drop since max retries exceeded: " <<
209  entry->GetRetries ());
210  entry->MarkDead ();
211  entry->ClearRetries ();
212  Ptr<Packet> pending = entry->DequeuePending ();
213  while (pending != 0)
214  {
215  m_dropTrace (pending);
216  pending = entry->DequeuePending ();
217  }
218  }
219  }
220 
221  }
222  if (restartWaitReplyTimer)
223  {
224  NS_LOG_LOGIC ("Restarting WaitReplyTimer at " << Simulator::Now ().GetSeconds ());
227  }
228 }
229 
230 void
232 {
233  NS_LOG_FUNCTION (this);
234  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
235  {
236  delete (*i).second;
237  }
238  m_arpCache.erase (m_arpCache.begin (), m_arpCache.end ());
240  {
241  NS_LOG_LOGIC ("Stopping WaitReplyTimer at " << Simulator::Now ().GetSeconds () << " due to ArpCache flush");
243  }
244 }
245 
248 {
249  NS_LOG_FUNCTION (this << to);
250  if (m_arpCache.find (to) != m_arpCache.end ())
251  {
252  ArpCache::Entry *entry = m_arpCache[to];
253  return entry;
254  }
255  return 0;
256 }
257 
260 {
261  NS_LOG_FUNCTION (this << to);
262  NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ());
263 
264  ArpCache::Entry *entry = new ArpCache::Entry (this);
265  m_arpCache[to] = entry;
266  entry->SetIpv4Address (to);
267  return entry;
268 }
269 
271  : m_arp (arp),
272  m_state (ALIVE),
273  m_retries (0)
274 {
275  NS_LOG_FUNCTION (this << arp);
276 }
277 
278 
279 bool
281 {
282  NS_LOG_FUNCTION (this);
283  return (m_state == DEAD) ? true : false;
284 }
285 bool
287 {
288  NS_LOG_FUNCTION (this);
289  return (m_state == ALIVE) ? true : false;
290 }
291 bool
293 {
294  NS_LOG_FUNCTION (this);
295  return (m_state == WAIT_REPLY) ? true : false;
296 }
297 
298 
299 void
301 {
302  NS_LOG_FUNCTION (this);
303  m_state = DEAD;
304  ClearRetries ();
305  UpdateSeen ();
306 }
307 void
309 {
310  NS_LOG_FUNCTION (this << macAddress);
311  NS_ASSERT (m_state == WAIT_REPLY);
312  m_macAddress = macAddress;
313  m_state = ALIVE;
314  ClearRetries ();
315  UpdateSeen ();
316 }
317 
318 bool
320 {
321  NS_LOG_FUNCTION (this << waiting);
322  NS_ASSERT (m_state == WAIT_REPLY);
323  /* We are already waiting for an answer so
324  * we dump the previously waiting packet and
325  * replace it with this one.
326  */
327  if (m_pending.size () >= m_arp->m_pendingQueueSize)
328  {
329  return false;
330  }
331  m_pending.push_back (waiting);
332  return true;
333 }
334 void
336 {
337  NS_LOG_FUNCTION (this << waiting);
338  NS_ASSERT (m_state == ALIVE || m_state == DEAD);
339  NS_ASSERT (m_pending.empty ());
340  m_state = WAIT_REPLY;
341  m_pending.push_back (waiting);
342  UpdateSeen ();
343  m_arp->StartWaitReplyTimer ();
344 }
345 
346 Address
348 {
349  NS_LOG_FUNCTION (this);
350  NS_ASSERT (m_state == ALIVE);
351  return m_macAddress;
352 }
355 {
356  NS_LOG_FUNCTION (this);
357  return m_ipv4Address;
358 }
359 void
361 {
362  NS_LOG_FUNCTION (this << destination);
363  m_ipv4Address = destination;
364 }
365 Time
367 {
368  NS_LOG_FUNCTION (this);
369  switch (m_state) {
371  return m_arp->GetWaitReplyTimeout ();
373  return m_arp->GetDeadTimeout ();
375  return m_arp->GetAliveTimeout ();
376  default:
377  NS_ASSERT (false);
378  return Seconds (0);
379  /* NOTREACHED */
380  }
381 }
382 bool
384 {
385  NS_LOG_FUNCTION (this);
386  Time timeout = GetTimeout ();
387  Time delta = Simulator::Now () - m_lastSeen;
388  NS_LOG_DEBUG ("delta=" << delta.GetSeconds () << "s");
389  if (delta > timeout)
390  {
391  return true;
392  }
393  return false;
394 }
397 {
398  NS_LOG_FUNCTION (this);
399  if (m_pending.empty ())
400  {
401  return 0;
402  }
403  else
404  {
405  Ptr<Packet> p = m_pending.front ();
406  m_pending.pop_front ();
407  return p;
408  }
409 }
410 void
412 {
413  NS_LOG_FUNCTION (this);
414  m_lastSeen = Simulator::Now ();
415 }
416 uint32_t
418 {
419  NS_LOG_FUNCTION (this);
420  return m_retries;
421 }
422 void
424 {
425  NS_LOG_FUNCTION (this);
426  m_retries++;
427  UpdateSeen ();
428 }
429 void
431 {
432  NS_LOG_FUNCTION (this);
433  m_retries = 0;
434 }
435 
436 } // namespace ns3
437 
void SetDevice(Ptr< NetDevice > device, Ptr< Ipv4Interface > interface)
Set the NetDevice and Ipv4Interface associated with the ArpCache.
Definition: arp-cache.cc:103
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:171
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
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:163
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
Callback template class.
Definition: callback.h:920
ArpCache::Entry * Add(Ipv4Address to)
Add an Ipv4Address to this ARP cache.
Definition: arp-cache.cc:259
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: arp-cache.cc:89
static TypeId GetTypeId(void)
Get the type ID.
Definition: arp-cache.cc:40
Definition: arp-cache.h:241
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
Definition: arp-cache.cc:247
#define NS_ASSERT(condition)
Definition: assert.h:64
Callback< void, Ptr< const ArpCache >, Ipv4Address > m_arpRequestCallback
reply timeout callback
Definition: arp-cache.h:284
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
Time GetDeadTimeout(void) const
Get the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:150
Ptr< NetDevice > GetDevice(void) const
Returns the NetDevice that this ARP cache is associated with.
Definition: arp-cache.cc:111
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
NS_LOG_COMPONENT_DEFINE("ArpCache")
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:824
ns3::Time timeout
bool IsAlive(void)
Definition: arp-cache.cc:286
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:274
void SetIpv4Address(Ipv4Address destination)
Definition: arp-cache.cc:360
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:184
hold objects of type ns3::Time
Definition: nstime.h:961
void MarkWaitReply(Ptr< Packet > waiting)
Definition: arp-cache.cc:335
Hold an unsigned integer type.
Definition: uinteger.h:46
uint32_t GetRetries(void) const
Definition: arp-cache.cc:417
bool IsDead(void)
Definition: arp-cache.cc:280
Ptr< Ipv4Interface > m_interface
Ipv4Interface associated with the cache.
Definition: arp-cache.h:279
bool IsExpired(void) const
Definition: arp-cache.cc:383
Ipv4Address GetIpv4Address(void) const
Definition: arp-cache.cc:354
Time m_waitReplyTimeout
cache reply state timeout
Definition: arp-cache.h:282
#define NS_LOG_LOGIC(msg)
Definition: log.h:368
Address GetMacAddress(void) const
Definition: arp-cache.cc:347
void SetDeadTimeout(Time deadTimeout)
Set the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:131
void SetAliveTimeout(Time aliveTimeout)
Set the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:125
Ptr< Ipv4Interface > GetInterface(void) const
Returns the Ipv4Interface that this ARP cache is associated with.
Definition: arp-cache.cc:118
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:423
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void MarkAlive(Address macAddress)
Definition: arp-cache.cc:308
Time GetAliveTimeout(void) const
Get the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:144
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:231
Entry(ArpCache *arp)
Constructor.
Definition: arp-cache.cc:270
Time GetTimeout(void) const
Returns the entry timeout.
Definition: arp-cache.cc:366
void UpdateSeen(void)
Update the entry when seeing a packet.
Definition: arp-cache.cc:411
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:319
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)
Definition: log.h:289
bool IsWaitReply(void)
Definition: arp-cache.cc:292
An ARP cache.
Definition: arp-cache.h:49
Ptr< Packet > DequeuePending(void)
Definition: arp-cache.cc:396
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:156
void ClearRetries(void)
Zero the counter of number of retries for an entry.
Definition: arp-cache.cc:430
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:452
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:300
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:63
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:137
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:611
Definition: arp-cache.h:242