A Discrete-Event Network Simulator
API
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 #include "ns3/names.h"
28 
29 #include "arp-cache.h"
30 #include "arp-header.h"
31 #include "ipv4-interface.h"
32 
33 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("ArpCache");
36 
38 
39 TypeId
41 {
42  static TypeId tid = TypeId ("ns3::ArpCache")
43  .SetParent<Object> ()
44  .AddAttribute ("AliveTimeout",
45  "When this timeout expires, "
46  "the matching cache entry needs refreshing",
47  TimeValue (Seconds (120)),
49  MakeTimeChecker ())
50  .AddAttribute ("DeadTimeout",
51  "When this timeout expires, "
52  "a new attempt to resolve the matching entry is made",
53  TimeValue (Seconds (100)),
55  MakeTimeChecker ())
56  .AddAttribute ("WaitReplyTimeout",
57  "When this timeout expires, "
58  "the cache entries will be scanned and "
59  "entries in WaitReply state will resend ArpRequest "
60  "unless MaxRetries has been exceeded, "
61  "in which case the entry is marked dead",
62  TimeValue (Seconds (1)),
64  MakeTimeChecker ())
65  .AddAttribute ("MaxRetries",
66  "Number of retransmissions of ArpRequest "
67  "before marking dead",
68  UintegerValue (3),
70  MakeUintegerChecker<uint32_t> ())
71  .AddAttribute ("PendingQueueSize",
72  "The size of the queue for packets pending an arp reply.",
73  UintegerValue (3),
75  MakeUintegerChecker<uint32_t> ())
76  .AddTraceSource ("Drop",
77  "Packet dropped due to ArpCache entry "
78  "in WaitReply expiring.",
80  "ns3::Packet::TracedCallback")
81  ;
82  return tid;
83 }
84 
86  : m_device (0),
87  m_interface (0)
88 {
89  NS_LOG_FUNCTION (this);
90 }
91 
93 {
94  NS_LOG_FUNCTION (this);
95 }
96 
97 void
99 {
100  NS_LOG_FUNCTION (this);
101  Flush ();
102  m_device = 0;
103  m_interface = 0;
104  if (!m_waitReplyTimer.IsRunning ())
105  {
107  }
109 }
110 
111 void
113 {
114  NS_LOG_FUNCTION (this << device << interface);
115  m_device = device;
116  m_interface = interface;
117 }
118 
121 {
122  NS_LOG_FUNCTION (this);
123  return m_device;
124 }
125 
128 {
129  NS_LOG_FUNCTION (this);
130  return m_interface;
131 }
132 
133 void
135 {
136  NS_LOG_FUNCTION (this << aliveTimeout);
137  m_aliveTimeout = aliveTimeout;
138 }
139 void
141 {
142  NS_LOG_FUNCTION (this << deadTimeout);
143  m_deadTimeout = deadTimeout;
144 }
145 void
147 {
148  NS_LOG_FUNCTION (this << waitReplyTimeout);
149  m_waitReplyTimeout = waitReplyTimeout;
150 }
151 
152 Time
154 {
155  NS_LOG_FUNCTION (this);
156  return m_aliveTimeout;
157 }
158 Time
160 {
161  NS_LOG_FUNCTION (this);
162  return m_deadTimeout;
163 }
164 Time
166 {
167  NS_LOG_FUNCTION (this);
168  return m_waitReplyTimeout;
169 }
170 
171 void
173  Ipv4Address> arpRequestCallback)
174 {
175  NS_LOG_FUNCTION (this << &arpRequestCallback);
176  m_arpRequestCallback = arpRequestCallback;
177 }
178 
179 void
181 {
182  NS_LOG_FUNCTION (this);
183  if (!m_waitReplyTimer.IsRunning ())
184  {
185  NS_LOG_LOGIC ("Starting WaitReplyTimer at " << Simulator::Now () << " for " <<
189  }
190 }
191 
192 void
194 {
195  NS_LOG_FUNCTION (this);
196  ArpCache::Entry* entry;
197  bool restartWaitReplyTimer = false;
198  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
199  {
200  entry = (*i).second;
201  if (entry != 0 && entry->IsWaitReply ())
202  {
203  if (entry->GetRetries () < m_maxRetries)
204  {
205  NS_LOG_LOGIC ("node="<< m_device->GetNode ()->GetId () <<
206  ", ArpWaitTimeout for " << entry->GetIpv4Address () <<
207  " expired -- retransmitting arp request since retries = " <<
208  entry->GetRetries ());
209  m_arpRequestCallback (this, entry->GetIpv4Address ());
210  restartWaitReplyTimer = true;
211  entry->IncrementRetries ();
212  }
213  else
214  {
215  NS_LOG_LOGIC ("node="<<m_device->GetNode ()->GetId () <<
216  ", wait reply for " << entry->GetIpv4Address () <<
217  " expired -- drop since max retries exceeded: " <<
218  entry->GetRetries ());
219  entry->MarkDead ();
220  entry->ClearRetries ();
221  Ptr<Packet> pending = entry->DequeuePending ();
222  while (pending != 0)
223  {
224  m_dropTrace (pending);
225  pending = entry->DequeuePending ();
226  }
227  }
228  }
229 
230  }
231  if (restartWaitReplyTimer)
232  {
233  NS_LOG_LOGIC ("Restarting WaitReplyTimer at " << Simulator::Now ().GetSeconds ());
236  }
237 }
238 
239 void
241 {
242  NS_LOG_FUNCTION (this);
243  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
244  {
245  delete (*i).second;
246  }
247  m_arpCache.erase (m_arpCache.begin (), m_arpCache.end ());
249  {
250  NS_LOG_LOGIC ("Stopping WaitReplyTimer at " << Simulator::Now ().GetSeconds () << " due to ArpCache flush");
252  }
253 }
254 
255 void
257 {
258  NS_LOG_FUNCTION (this << stream);
259  std::ostream* os = stream->GetStream ();
260 
261  for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
262  {
263  *os << i->first << " dev ";
264  std::string found = Names::FindName (m_device);
265  if (Names::FindName (m_device) != "")
266  {
267  *os << found;
268  }
269  else
270  {
271  *os << static_cast<int> (m_device->GetIfIndex ());
272  }
273 
274  *os << " lladdr " << i->second->GetMacAddress ();
275 
276  if (i->second->IsAlive ())
277  {
278  *os << " REACHABLE\n";
279  }
280  else if (i->second->IsWaitReply ())
281  {
282  *os << " DELAY\n";
283  }
284  else
285  {
286  *os << " STALE\n";
287  }
288  }
289 }
290 
293 {
294  NS_LOG_FUNCTION (this << to);
295  if (m_arpCache.find (to) != m_arpCache.end ())
296  {
297  ArpCache::Entry *entry = m_arpCache[to];
298  return entry;
299  }
300  return 0;
301 }
302 
305 {
306  NS_LOG_FUNCTION (this << to);
307  NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ());
308 
309  ArpCache::Entry *entry = new ArpCache::Entry (this);
310  m_arpCache[to] = entry;
311  entry->SetIpv4Address (to);
312  return entry;
313 }
314 
316  : m_arp (arp),
317  m_state (ALIVE),
318  m_retries (0)
319 {
320  NS_LOG_FUNCTION (this << arp);
321 }
322 
323 
324 bool
326 {
327  NS_LOG_FUNCTION (this);
328  return (m_state == DEAD) ? true : false;
329 }
330 bool
332 {
333  NS_LOG_FUNCTION (this);
334  return (m_state == ALIVE) ? true : false;
335 }
336 bool
338 {
339  NS_LOG_FUNCTION (this);
340  return (m_state == WAIT_REPLY) ? true : false;
341 }
342 
343 
344 void
346 {
347  NS_LOG_FUNCTION (this);
348  m_state = DEAD;
349  ClearRetries ();
350  UpdateSeen ();
351 }
352 void
354 {
355  NS_LOG_FUNCTION (this << macAddress);
356  NS_ASSERT (m_state == WAIT_REPLY);
357  m_macAddress = macAddress;
358  m_state = ALIVE;
359  ClearRetries ();
360  UpdateSeen ();
361 }
362 
363 bool
365 {
366  NS_LOG_FUNCTION (this << waiting);
367  NS_ASSERT (m_state == WAIT_REPLY);
368  /* We are already waiting for an answer so
369  * we dump the previously waiting packet and
370  * replace it with this one.
371  */
372  if (m_pending.size () >= m_arp->m_pendingQueueSize)
373  {
374  return false;
375  }
376  m_pending.push_back (waiting);
377  return true;
378 }
379 void
381 {
382  NS_LOG_FUNCTION (this << waiting);
383  NS_ASSERT (m_state == ALIVE || m_state == DEAD);
384  NS_ASSERT (m_pending.empty ());
385  m_state = WAIT_REPLY;
386  m_pending.push_back (waiting);
387  UpdateSeen ();
388  m_arp->StartWaitReplyTimer ();
389 }
390 
391 Address
393 {
394  NS_LOG_FUNCTION (this);
395  return m_macAddress;
396 }
399 {
400  NS_LOG_FUNCTION (this);
401  return m_ipv4Address;
402 }
403 void
405 {
406  NS_LOG_FUNCTION (this << destination);
407  m_ipv4Address = destination;
408 }
409 Time
411 {
412  NS_LOG_FUNCTION (this);
413  switch (m_state) {
415  return m_arp->GetWaitReplyTimeout ();
417  return m_arp->GetDeadTimeout ();
419  return m_arp->GetAliveTimeout ();
420  default:
421  NS_ASSERT (false);
422  return Seconds (0);
423  /* NOTREACHED */
424  }
425 }
426 bool
428 {
429  NS_LOG_FUNCTION (this);
430  Time timeout = GetTimeout ();
431  Time delta = Simulator::Now () - m_lastSeen;
432  NS_LOG_DEBUG ("delta=" << delta.GetSeconds () << "s");
433  if (delta > timeout)
434  {
435  return true;
436  }
437  return false;
438 }
441 {
442  NS_LOG_FUNCTION (this);
443  if (m_pending.empty ())
444  {
445  return 0;
446  }
447  else
448  {
449  Ptr<Packet> p = m_pending.front ();
450  m_pending.pop_front ();
451  return p;
452  }
453 }
454 void
456 {
457  NS_LOG_FUNCTION (this);
458  m_lastSeen = Simulator::Now ();
459 }
460 uint32_t
462 {
463  NS_LOG_FUNCTION (this);
464  return m_retries;
465 }
466 void
468 {
469  NS_LOG_FUNCTION (this);
470  m_retries++;
471  UpdateSeen ();
472 }
473 void
475 {
476  NS_LOG_FUNCTION (this);
477  m_retries = 0;
478 }
479 
480 } // namespace ns3
481 
void SetDevice(Ptr< NetDevice > device, Ptr< Ipv4Interface > interface)
Set the NetDevice and Ipv4Interface associated with the ArpCache.
Definition: arp-cache.cc:112
uint32_t m_maxRetries
max retries for a resolution
Definition: arp-cache.h:293
void StartWaitReplyTimer(void)
This method will schedule a timeout at WaitReplyTimeout interval in the future, unless a timer is alr...
Definition: arp-cache.cc:180
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:95
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:172
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#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:978
ArpCache::Entry * Add(Ipv4Address to)
Add an Ipv4Address to this ARP cache.
Definition: arp-cache.cc:304
virtual void DoDispose(void)
Destructor implementation.
Definition: arp-cache.cc:98
static TypeId GetTypeId(void)
Get the type ID.
Definition: arp-cache.cc:40
void PrintArpCache(Ptr< OutputStreamWrapper > stream)
Print the ARP cache entries.
Definition: arp-cache.cc:256
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
Definition: arp-cache.cc:292
#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:292
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
Time GetDeadTimeout(void) const
Get the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:159
Ptr< NetDevice > GetDevice(void) const
Returns the NetDevice that this ARP cache is associated with.
Definition: arp-cache.cc:120
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:338
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
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:819
ns3::Time timeout
bool IsAlive(void)
Definition: arp-cache.cc:331
EventId m_waitReplyTimer
cache alive state timer
Definition: arp-cache.h:291
a polymophic address class
Definition: address.h:90
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
Cache m_arpCache
the ARP cache
Definition: arp-cache.h:302
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:327
void SetIpv4Address(Ipv4Address destination)
Definition: arp-cache.cc:404
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:193
AttributeValue implementation for Time.
Definition: nstime.h:921
void MarkWaitReply(Ptr< Packet > waiting)
Definition: arp-cache.cc:380
Hold an unsigned integer type.
Definition: uinteger.h:44
uint32_t GetRetries(void) const
Definition: arp-cache.cc:461
bool IsDead(void)
Definition: arp-cache.cc:325
Ptr< Ipv4Interface > m_interface
Ipv4Interface associated with the cache.
Definition: arp-cache.h:287
bool IsExpired(void) const
Definition: arp-cache.cc:427
Ipv4Address GetIpv4Address(void) const
Definition: arp-cache.cc:398
Time m_waitReplyTimeout
cache reply state timeout
Definition: arp-cache.h:290
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
Address GetMacAddress(void) const
Definition: arp-cache.cc:392
void SetDeadTimeout(Time deadTimeout)
Set the time the entry will be in DEAD state before being removed.
Definition: arp-cache.cc:140
void SetAliveTimeout(Time aliveTimeout)
Set the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:134
Ptr< Ipv4Interface > GetInterface(void) const
Returns the Ipv4Interface that this ARP cache is associated with.
Definition: arp-cache.cc:127
static void Remove(const EventId &id)
Remove an event from the event list.
Definition: simulator.cc:301
void IncrementRetries(void)
Increment the counter of number of retries for an entry.
Definition: arp-cache.cc:467
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void MarkAlive(Address macAddress)
Definition: arp-cache.cc:353
Time GetAliveTimeout(void) const
Get the time the entry will be in ALIVE state (unless refreshed)
Definition: arp-cache.cc:153
A record that that holds information about an ArpCache entry.
Definition: arp-cache.h:168
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:922
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
void Flush(void)
Clear the ArpCache of all entries.
Definition: arp-cache.cc:240
Entry(ArpCache *arp)
Constructor.
Definition: arp-cache.cc:315
Time GetTimeout(void) const
Returns the entry timeout.
Definition: arp-cache.cc:410
void UpdateSeen(void)
Update the entry when seeing a packet.
Definition: arp-cache.cc:455
TracedCallback< Ptr< const Packet > > m_dropTrace
trace for packets dropped by the ARP cache queue
Definition: arp-cache.h:303
bool UpdateWaitReply(Ptr< Packet > waiting)
Definition: arp-cache.cc:364
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
sgi::hash_map< Ipv4Address, ArpCache::Entry *, Ipv4AddressHash >::iterator CacheI
ARP Cache container iterator.
Definition: arp-cache.h:282
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
bool IsWaitReply(void)
Definition: arp-cache.cc:337
An ARP cache.
Definition: arp-cache.h:50
Ptr< Packet > DequeuePending(void)
Definition: arp-cache.cc:440
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
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:664
Time GetWaitReplyTimeout(void) const
Get the time the entry will be in WAIT_REPLY state.
Definition: arp-cache.cc:165
void ClearRetries(void)
Zero the counter of number of retries for an entry.
Definition: arp-cache.cc:474
Ptr< NetDevice > m_device
NetDevice associated with the cache.
Definition: arp-cache.h:286
void MarkDead(void)
Changes the state of this entry to dead.
Definition: arp-cache.cc:345
Time m_deadTimeout
cache dead state timeout
Definition: arp-cache.h:289
A base class which provides memory management and object aggregation.
Definition: object.h:87
uint32_t m_pendingQueueSize
number of packets waiting for a resolution
Definition: arp-cache.h:301
void SetWaitReplyTimeout(Time waitReplyTimeout)
Set the time the entry will be in WAIT_REPLY state.
Definition: arp-cache.cc:146
Time m_aliveTimeout
cache alive state timeout
Definition: arp-cache.h:288
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:45
a unique identifier for an interface.
Definition: type-id.h:51
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.