00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ns3/packet.h"
00021 #include "ns3/log.h"
00022 #include "ns3/node.h"
00023 #include "ns3/net-device.h"
00024 #include "ns3/object-vector.h"
00025 #include "ns3/trace-source-accessor.h"
00026
00027 #include "ipv4-l3-protocol.h"
00028 #include "arp-l3-protocol.h"
00029 #include "arp-header.h"
00030 #include "arp-cache.h"
00031 #include "ipv4-interface.h"
00032
00033 NS_LOG_COMPONENT_DEFINE ("ArpL3Protocol");
00034
00035 namespace ns3 {
00036
00037 const uint16_t ArpL3Protocol::PROT_NUMBER = 0x0806;
00038
00039 NS_OBJECT_ENSURE_REGISTERED (ArpL3Protocol);
00040
00041 TypeId
00042 ArpL3Protocol::GetTypeId (void)
00043 {
00044 static TypeId tid = TypeId ("ns3::ArpL3Protocol")
00045 .SetParent<Object> ()
00046 .AddAttribute ("CacheList",
00047 "The list of ARP caches",
00048 ObjectVectorValue (),
00049 MakeObjectVectorAccessor (&ArpL3Protocol::m_cacheList),
00050 MakeObjectVectorChecker<ArpCache> ())
00051 .AddTraceSource ("Drop",
00052 "Packet dropped because not enough room in pending queue for a specific cache entry.",
00053 MakeTraceSourceAccessor (&ArpL3Protocol::m_dropTrace))
00054 ;
00055 return tid;
00056 }
00057
00058 ArpL3Protocol::ArpL3Protocol ()
00059 {
00060 NS_LOG_FUNCTION (this);
00061 }
00062
00063 ArpL3Protocol::~ArpL3Protocol ()
00064 {
00065 NS_LOG_FUNCTION (this);
00066 }
00067
00068 void
00069 ArpL3Protocol::SetNode (Ptr<Node> node)
00070 {
00071 NS_LOG_FUNCTION (this);
00072 m_node = node;
00073 }
00074
00075 void
00076 ArpL3Protocol::DoDispose (void)
00077 {
00078 NS_LOG_FUNCTION (this);
00079 for (CacheList::iterator i = m_cacheList.begin (); i != m_cacheList.end (); ++i)
00080 {
00081 Ptr<ArpCache> cache = *i;
00082 cache->Dispose ();
00083 }
00084 m_cacheList.clear ();
00085 m_node = 0;
00086 Object::DoDispose ();
00087 }
00088
00089 Ptr<ArpCache>
00090 ArpL3Protocol::CreateCache (Ptr<NetDevice> device, Ptr<Ipv4Interface> interface)
00091 {
00092 NS_LOG_FUNCTION (this << device << interface);
00093 Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
00094 Ptr<ArpCache> cache = CreateObject<ArpCache> ();
00095 cache->SetDevice (device, interface);
00096 NS_ASSERT (device->IsBroadcast ());
00097 device->SetLinkChangeCallback (MakeCallback (&ArpCache::Flush, cache));
00098 cache->SetArpRequestCallback (MakeCallback (&ArpL3Protocol::SendArpRequest, this));
00099 m_cacheList.push_back (cache);
00100 return cache;
00101 }
00102
00103 Ptr<ArpCache>
00104 ArpL3Protocol::FindCache (Ptr<NetDevice> device)
00105 {
00106 NS_LOG_FUNCTION (this << device);
00107 for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
00108 {
00109 if ((*i)->GetDevice () == device)
00110 {
00111 return *i;
00112 }
00113 }
00114 NS_ASSERT (false);
00115
00116 return 0;
00117 }
00118
00119 void
00120 ArpL3Protocol::Receive(Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
00121 const Address &to, NetDevice::PacketType packetType)
00122 {
00123 NS_LOG_FUNCTION (this << device << p->GetSize () << protocol << from << to << packetType);
00124
00125 Ptr<Packet> packet = p->Copy ();
00126
00127 Ptr<ArpCache> cache = FindCache (device);
00128 ArpHeader arp;
00129 packet->RemoveHeader (arp);
00130
00131 NS_LOG_LOGIC ("ARP: received "<< (arp.IsRequest ()? "request" : "reply") <<
00132 " node="<<m_node->GetId ()<<", got request from " <<
00133 arp.GetSourceIpv4Address () << " for address " <<
00134 arp.GetDestinationIpv4Address () << "; we have address " <<
00135 cache->GetInterface ()->GetAddress ());
00136
00137
00138
00139
00140
00141
00142 if (arp.IsRequest () &&
00143 arp.GetDestinationIpv4Address () == cache->GetInterface ()->GetAddress ())
00144 {
00145 NS_LOG_LOGIC ("node="<<m_node->GetId () <<", got request from " <<
00146 arp.GetSourceIpv4Address () << " -- send reply");
00147 SendArpReply (cache, arp.GetSourceIpv4Address (),
00148 arp.GetSourceHardwareAddress ());
00149 }
00150 else if (arp.IsReply () &&
00151 arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress ()) &&
00152 arp.GetDestinationHardwareAddress () == device->GetAddress ())
00153 {
00154 Ipv4Address from = arp.GetSourceIpv4Address ();
00155 ArpCache::Entry *entry = cache->Lookup (from);
00156 if (entry != 0)
00157 {
00158 if (entry->IsWaitReply ())
00159 {
00160 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply from " <<
00161 arp.GetSourceIpv4Address ()
00162 << " for waiting entry -- flush");
00163 Address from_mac = arp.GetSourceHardwareAddress ();
00164 entry->MarkAlive (from_mac);
00165 Ptr<Packet> pending = entry->DequeuePending();
00166 while (pending != 0)
00167 {
00168 cache->GetInterface ()->Send (pending,
00169 arp.GetSourceIpv4Address ());
00170 pending = entry->DequeuePending();
00171 }
00172 }
00173 else
00174 {
00175
00176
00177 NS_LOG_LOGIC("node="<<m_node->GetId ()<<", got reply from " <<
00178 arp.GetSourceIpv4Address () <<
00179 " for non-waiting entry -- drop");
00180 m_dropTrace (packet);
00181 }
00182 }
00183 else
00184 {
00185 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply for unknown entry -- drop");
00186 m_dropTrace (packet);
00187 }
00188 }
00189 else
00190 {
00191 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got request from " <<
00192 arp.GetSourceIpv4Address () << " for unknown address " <<
00193 arp.GetDestinationIpv4Address () << " -- drop");
00194 }
00195 }
00196 bool
00197 ArpL3Protocol::Lookup (Ptr<Packet> packet, Ipv4Address destination,
00198 Ptr<NetDevice> device,
00199 Ptr<ArpCache> cache,
00200 Address *hardwareDestination)
00201 {
00202 NS_LOG_FUNCTION (this << packet << destination << device << cache);
00203 ArpCache::Entry *entry = cache->Lookup (destination);
00204 if (entry != 0)
00205 {
00206 if (entry->IsExpired ())
00207 {
00208 if (entry->IsDead ())
00209 {
00210 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
00211 ", dead entry for " << destination << " expired -- send arp request");
00212 entry->MarkWaitReply (packet);
00213 SendArpRequest (cache, destination);
00214 }
00215 else if (entry->IsAlive ())
00216 {
00217 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
00218 ", alive entry for " << destination << " expired -- send arp request");
00219 entry->MarkWaitReply (packet);
00220 SendArpRequest (cache, destination);
00221 }
00222 else if (entry->IsWaitReply ())
00223 {
00224 NS_FATAL_ERROR ("Test for possibly unreachable code-- please file a bug report, with a test case, if this is ever hit");
00225 }
00226 }
00227 else
00228 {
00229 if (entry->IsDead ())
00230 {
00231 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
00232 ", dead entry for " << destination << " valid -- drop");
00233 m_dropTrace (packet);
00234 }
00235 else if (entry->IsAlive ())
00236 {
00237 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
00238 ", alive entry for " << destination << " valid -- send");
00239 *hardwareDestination = entry->GetMacAddress ();
00240 return true;
00241 }
00242 else if (entry->IsWaitReply ())
00243 {
00244 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
00245 ", wait reply for " << destination << " valid -- drop previous");
00246 if (!entry->UpdateWaitReply (packet))
00247 {
00248 m_dropTrace (packet);
00249 }
00250 }
00251 }
00252 }
00253 else
00254 {
00255
00256 NS_LOG_LOGIC ("node="<<m_node->GetId ()<<
00257 ", no entry for " << destination << " -- send arp request");
00258 entry = cache->Add (destination);
00259 entry->MarkWaitReply (packet);
00260 SendArpRequest (cache, destination);
00261 }
00262 return false;
00263 }
00264
00265 void
00266 ArpL3Protocol::SendArpRequest (Ptr<const ArpCache> cache, Ipv4Address to)
00267 {
00268 NS_LOG_FUNCTION (this << cache << to);
00269 ArpHeader arp;
00270 NS_LOG_LOGIC ("ARP: sending request from node "<<m_node->GetId ()<<
00271 " || src: " << cache->GetDevice ()->GetAddress () <<
00272 " / " << cache->GetInterface ()->GetAddress () <<
00273 " || dst: " << cache->GetDevice ()->GetBroadcast () <<
00274 " / " << to);
00275 arp.SetRequest (cache->GetDevice ()->GetAddress (),
00276 cache->GetInterface ()->GetAddress (),
00277 cache->GetDevice ()->GetBroadcast (),
00278 to);
00279 Ptr<Packet> packet = Create<Packet> ();
00280 packet->AddHeader (arp);
00281 cache->GetDevice ()->Send (packet, cache->GetDevice ()->GetBroadcast (), PROT_NUMBER);
00282 }
00283
00284 void
00285 ArpL3Protocol::SendArpReply (Ptr<const ArpCache> cache, Ipv4Address toIp, Address toMac)
00286 {
00287 NS_LOG_FUNCTION (this << cache << toIp << toMac);
00288 ArpHeader arp;
00289 NS_LOG_LOGIC ("ARP: sending reply from node "<<m_node->GetId ()<<
00290 "|| src: " << cache->GetDevice ()->GetAddress () <<
00291 " / " << cache->GetInterface ()->GetAddress () <<
00292 " || dst: " << toMac << " / " << toIp);
00293 arp.SetReply (cache->GetDevice ()->GetAddress (),
00294 cache->GetInterface ()->GetAddress (),
00295 toMac, toIp);
00296 Ptr<Packet> packet = Create<Packet> ();
00297 packet->AddHeader (arp);
00298 cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
00299 }
00300
00301 }