00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ns3/assert.h"
00021 #include "ns3/packet.h"
00022 #include "ns3/simulator.h"
00023 #include "ns3/uinteger.h"
00024 #include "ns3/log.h"
00025 #include "ns3/node.h"
00026 #include "ns3/trace-source-accessor.h"
00027
00028 #include "arp-cache.h"
00029 #include "arp-header.h"
00030 #include "ipv4-interface.h"
00031
00032 NS_LOG_COMPONENT_DEFINE ("ArpCache");
00033
00034 namespace ns3 {
00035
00036 TypeId
00037 ArpCache::GetTypeId (void)
00038 {
00039 static TypeId tid = TypeId ("ns3::ArpCache")
00040 .SetParent<Object> ()
00041 .AddAttribute ("AliveTimeout",
00042 "When this timeout expires, the matching cache entry needs refreshing",
00043 TimeValue (Seconds (120)),
00044 MakeTimeAccessor (&ArpCache::m_aliveTimeout),
00045 MakeTimeChecker ())
00046 .AddAttribute ("DeadTimeout",
00047 "When this timeout expires, a new attempt to resolve the matching entry is made",
00048 TimeValue (Seconds (100)),
00049 MakeTimeAccessor (&ArpCache::m_deadTimeout),
00050 MakeTimeChecker ())
00051 .AddAttribute ("WaitReplyTimeout",
00052 "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",
00053 TimeValue (Seconds (1)),
00054 MakeTimeAccessor (&ArpCache::m_waitReplyTimeout),
00055 MakeTimeChecker ())
00056 .AddAttribute ("MaxRetries",
00057 "Number of retransmissions of ArpRequest before marking dead",
00058 UintegerValue (3),
00059 MakeUintegerAccessor (&ArpCache::m_maxRetries),
00060 MakeUintegerChecker<uint32_t> ())
00061 .AddAttribute ("PendingQueueSize",
00062 "The size of the queue for packets pending an arp reply.",
00063 UintegerValue (3),
00064 MakeUintegerAccessor (&ArpCache::m_pendingQueueSize),
00065 MakeUintegerChecker<uint32_t> ())
00066 .AddTraceSource ("Drop",
00067 "Packet dropped due to ArpCache entry in WaitReply expiring.",
00068 MakeTraceSourceAccessor (&ArpCache::m_dropTrace))
00069 ;
00070 return tid;
00071 }
00072
00073 ArpCache::ArpCache ()
00074 : m_device (0),
00075 m_interface (0)
00076 {
00077 NS_LOG_FUNCTION (this);
00078 }
00079
00080 ArpCache::~ArpCache ()
00081 {
00082 NS_LOG_FUNCTION (this);
00083 }
00084
00085 void
00086 ArpCache::DoDispose (void)
00087 {
00088 NS_LOG_FUNCTION (this);
00089 Flush ();
00090 m_device = 0;
00091 m_interface = 0;
00092 if (!m_waitReplyTimer.IsRunning ())
00093 {
00094 Simulator::Remove (m_waitReplyTimer);
00095 }
00096 Object::DoDispose ();
00097 }
00098
00099 void
00100 ArpCache::SetDevice (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
00101 {
00102 NS_LOG_FUNCTION_NOARGS ();
00103 m_device = device;
00104 m_interface = interface;
00105 }
00106
00107 Ptr<NetDevice>
00108 ArpCache::GetDevice (void) const
00109 {
00110 NS_LOG_FUNCTION_NOARGS ();
00111 return m_device;
00112 }
00113
00114 Ptr<Ipv4Interface>
00115 ArpCache::GetInterface (void) const
00116 {
00117 NS_LOG_FUNCTION_NOARGS ();
00118 return m_interface;
00119 }
00120
00121 void
00122 ArpCache::SetAliveTimeout (Time aliveTimeout)
00123 {
00124 NS_LOG_FUNCTION_NOARGS ();
00125 m_aliveTimeout = aliveTimeout;
00126 }
00127 void
00128 ArpCache::SetDeadTimeout (Time deadTimeout)
00129 {
00130 NS_LOG_FUNCTION_NOARGS ();
00131 m_deadTimeout = deadTimeout;
00132 }
00133 void
00134 ArpCache::SetWaitReplyTimeout (Time waitReplyTimeout)
00135 {
00136 NS_LOG_FUNCTION_NOARGS ();
00137 m_waitReplyTimeout = waitReplyTimeout;
00138 }
00139
00140 Time
00141 ArpCache::GetAliveTimeout (void) const
00142 {
00143 NS_LOG_FUNCTION_NOARGS ();
00144 return m_aliveTimeout;
00145 }
00146 Time
00147 ArpCache::GetDeadTimeout (void) const
00148 {
00149 NS_LOG_FUNCTION_NOARGS ();
00150 return m_deadTimeout;
00151 }
00152 Time
00153 ArpCache::GetWaitReplyTimeout (void) const
00154 {
00155 NS_LOG_FUNCTION_NOARGS ();
00156 return m_waitReplyTimeout;
00157 }
00158
00159 void
00160 ArpCache::SetArpRequestCallback (Callback<void, Ptr<const ArpCache>,
00161 Ipv4Address> arpRequestCallback)
00162 {
00163 NS_LOG_FUNCTION_NOARGS ();
00164 m_arpRequestCallback = arpRequestCallback;
00165 }
00166
00167 void
00168 ArpCache::StartWaitReplyTimer (void)
00169 {
00170 NS_LOG_FUNCTION_NOARGS ();
00171 if (!m_waitReplyTimer.IsRunning ())
00172 {
00173 NS_LOG_LOGIC ("Starting WaitReplyTimer at " << Simulator::Now ().GetSeconds ());
00174 m_waitReplyTimer = Simulator::Schedule (m_waitReplyTimeout,
00175 &ArpCache::HandleWaitReplyTimeout, this);
00176 }
00177 }
00178
00179 void
00180 ArpCache::HandleWaitReplyTimeout (void)
00181 {
00182 NS_LOG_FUNCTION_NOARGS ();
00183 ArpCache::Entry* entry;
00184 bool restartWaitReplyTimer = false;
00185 for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
00186 {
00187 entry = (*i).second;
00188 if (entry != 0 && entry->IsWaitReply () && entry->IsExpired ())
00189 {
00190 if (entry->GetRetries () < m_maxRetries)
00191 {
00192 NS_LOG_LOGIC ("node="<< m_device->GetNode ()->GetId () <<
00193 ", ArpWaitTimeout for " << entry->GetIpv4Address () <<
00194 " expired -- retransmitting arp request since retries = " <<
00195 entry->GetRetries ());
00196 m_arpRequestCallback (this, entry->GetIpv4Address ());
00197 restartWaitReplyTimer = true;
00198 entry->IncrementRetries ();
00199 }
00200 else
00201 {
00202 NS_LOG_LOGIC ("node="<<m_device->GetNode ()->GetId () <<
00203 ", wait reply for " << entry->GetIpv4Address () <<
00204 " expired -- drop since max retries exceeded: " <<
00205 entry->GetRetries ());
00206 entry->MarkDead ();
00207 entry->ClearRetries ();
00208 Ptr<Packet> pending = entry->DequeuePending();
00209 while (pending != 0)
00210 {
00211 m_dropTrace (pending);
00212 pending = entry->DequeuePending();
00213 }
00214 }
00215 }
00216
00217 }
00218 if (restartWaitReplyTimer)
00219 {
00220 NS_LOG_LOGIC ("Restarting WaitReplyTimer at " << Simulator::Now ().GetSeconds ());
00221 m_waitReplyTimer = Simulator::Schedule (m_waitReplyTimeout,
00222 &ArpCache::HandleWaitReplyTimeout, this);
00223 }
00224 }
00225
00226 void
00227 ArpCache::Flush (void)
00228 {
00229 NS_LOG_FUNCTION_NOARGS ();
00230 for (CacheI i = m_arpCache.begin (); i != m_arpCache.end (); i++)
00231 {
00232 delete (*i).second;
00233 }
00234 m_arpCache.erase (m_arpCache.begin (), m_arpCache.end ());
00235 if (m_waitReplyTimer.IsRunning ())
00236 {
00237 NS_LOG_LOGIC ("Stopping WaitReplyTimer at " << Simulator::Now ().GetSeconds () << " due to ArpCache flush");
00238 m_waitReplyTimer.Cancel ();
00239 }
00240 }
00241
00242 ArpCache::Entry *
00243 ArpCache::Lookup (Ipv4Address to)
00244 {
00245 NS_LOG_FUNCTION_NOARGS ();
00246 if (m_arpCache.find (to) != m_arpCache.end ())
00247 {
00248 ArpCache::Entry *entry = m_arpCache[to];
00249 return entry;
00250 }
00251 return 0;
00252 }
00253
00254 ArpCache::Entry *
00255 ArpCache::Add (Ipv4Address to)
00256 {
00257 NS_LOG_FUNCTION_NOARGS ();
00258 NS_ASSERT (m_arpCache.find (to) == m_arpCache.end ());
00259
00260 ArpCache::Entry *entry = new ArpCache::Entry (this);
00261 m_arpCache[to] = entry;
00262 entry->SetIpv4Address (to);
00263 return entry;
00264 }
00265
00266 ArpCache::Entry::Entry (ArpCache *arp)
00267 : m_arp (arp),
00268 m_state (ALIVE),
00269 m_retries (0)
00270 {
00271 NS_LOG_FUNCTION_NOARGS ();
00272 }
00273
00274
00275 bool
00276 ArpCache::Entry::IsDead (void)
00277 {
00278 NS_LOG_FUNCTION_NOARGS ();
00279 return (m_state == DEAD)?true:false;
00280 }
00281 bool
00282 ArpCache::Entry::IsAlive (void)
00283 {
00284 NS_LOG_FUNCTION_NOARGS ();
00285 return (m_state == ALIVE)?true:false;
00286 }
00287 bool
00288 ArpCache::Entry::IsWaitReply (void)
00289 {
00290 NS_LOG_FUNCTION_NOARGS ();
00291 return (m_state == WAIT_REPLY)?true:false;
00292 }
00293
00294
00295 void
00296 ArpCache::Entry::MarkDead (void)
00297 {
00298 NS_LOG_FUNCTION_NOARGS ();
00299 m_state = DEAD;
00300 ClearRetries ();
00301 UpdateSeen ();
00302 }
00303 void
00304 ArpCache::Entry::MarkAlive (Address macAddress)
00305 {
00306 NS_LOG_FUNCTION_NOARGS ();
00307 NS_ASSERT (m_state == WAIT_REPLY);
00308 m_macAddress = macAddress;
00309 m_state = ALIVE;
00310 ClearRetries ();
00311 UpdateSeen ();
00312 }
00313
00314 bool
00315 ArpCache::Entry::UpdateWaitReply (Ptr<Packet> waiting)
00316 {
00317 NS_LOG_FUNCTION_NOARGS ();
00318 NS_ASSERT (m_state == WAIT_REPLY);
00319
00320
00321
00322
00323 if (m_pending.size () >= m_arp->m_pendingQueueSize)
00324 {
00325 return false;
00326 }
00327 m_pending.push_back (waiting);
00328 return true;
00329 }
00330 void
00331 ArpCache::Entry::MarkWaitReply (Ptr<Packet> waiting)
00332 {
00333 NS_LOG_FUNCTION_NOARGS ();
00334 NS_ASSERT (m_state == ALIVE || m_state == DEAD);
00335 NS_ASSERT (m_pending.empty ());
00336 m_state = WAIT_REPLY;
00337 m_pending.push_back (waiting);
00338 UpdateSeen ();
00339 m_arp->StartWaitReplyTimer ();
00340 }
00341
00342 Address
00343 ArpCache::Entry::GetMacAddress (void) const
00344 {
00345 NS_LOG_FUNCTION_NOARGS ();
00346 NS_ASSERT (m_state == ALIVE);
00347 return m_macAddress;
00348 }
00349 Ipv4Address
00350 ArpCache::Entry::GetIpv4Address (void) const
00351 {
00352 NS_LOG_FUNCTION_NOARGS ();
00353 return m_ipv4Address;
00354 }
00355 void
00356 ArpCache::Entry::SetIpv4Address (Ipv4Address destination)
00357 {
00358 NS_LOG_FUNCTION (this << destination);
00359 m_ipv4Address = destination;
00360 }
00361
00362 bool
00363 ArpCache::Entry::IsExpired (void)
00364 {
00365 NS_LOG_FUNCTION_NOARGS ();
00366 Time timeout;
00367 switch (m_state) {
00368 case ArpCache::Entry::WAIT_REPLY:
00369 timeout = m_arp->GetWaitReplyTimeout ();
00370 break;
00371 case ArpCache::Entry::DEAD:
00372 timeout = m_arp->GetDeadTimeout ();
00373 break;
00374 case ArpCache::Entry::ALIVE:
00375 timeout = m_arp->GetAliveTimeout ();
00376 break;
00377 default:
00378 NS_ASSERT (false);
00379 timeout = Seconds (0);
00380
00381 break;
00382 }
00383 Time delta = Simulator::Now () - m_lastSeen;
00384 if (delta >= timeout)
00385 {
00386 return true;
00387 }
00388 else
00389 {
00390 return false;
00391 }
00392 }
00393 Ptr<Packet>
00394 ArpCache::Entry::DequeuePending (void)
00395 {
00396 NS_LOG_FUNCTION_NOARGS ();
00397 if (m_pending.empty ())
00398 {
00399 return 0;
00400 }
00401 else
00402 {
00403 Ptr<Packet> p = m_pending.front ();
00404 m_pending.pop_front ();
00405 return p;
00406 }
00407 }
00408 void
00409 ArpCache::Entry::UpdateSeen (void)
00410 {
00411 NS_LOG_FUNCTION_NOARGS ();
00412 m_lastSeen = Simulator::Now ();
00413 }
00414 uint32_t
00415 ArpCache::Entry::GetRetries (void) const
00416 {
00417 NS_LOG_FUNCTION_NOARGS ();
00418 return m_retries;
00419 }
00420 void
00421 ArpCache::Entry::IncrementRetries (void)
00422 {
00423 NS_LOG_FUNCTION_NOARGS ();
00424 m_retries++;
00425 UpdateSeen ();
00426 }
00427 void
00428 ArpCache::Entry::ClearRetries (void)
00429 {
00430 NS_LOG_FUNCTION_NOARGS ();
00431 m_retries = 0;
00432 }
00433
00434 }
00435