20 #include "ns3/packet.h"
23 #include "ns3/net-device.h"
24 #include "ns3/object-vector.h"
25 #include "ns3/trace-source-accessor.h"
27 #include "ipv4-l3-protocol.h"
28 #include "arp-l3-protocol.h"
29 #include "arp-header.h"
30 #include "arp-cache.h"
31 #include "ipv4-interface.h"
38 NS_OBJECT_ENSURE_REGISTERED (ArpL3Protocol);
41 ArpL3Protocol::GetTypeId (
void)
43 static TypeId tid = TypeId (
"ns3::ArpL3Protocol")
45 .AddConstructor<ArpL3Protocol> ()
46 .AddAttribute (
"CacheList",
47 "The list of ARP caches",
49 MakeObjectVectorAccessor (&ArpL3Protocol::m_cacheList),
50 MakeObjectVectorChecker<ArpCache> ())
51 .AddTraceSource (
"Drop",
52 "Packet dropped because not enough room in pending queue for a specific cache entry.",
58 ArpL3Protocol::ArpL3Protocol ()
63 ArpL3Protocol::~ArpL3Protocol ()
69 ArpL3Protocol::SetNode (Ptr<Node> node)
100 for (CacheList::iterator i = m_cacheList.begin (); i != m_cacheList.end (); ++i)
105 m_cacheList.clear ();
119 cache->SetArpRequestCallback (
MakeCallback (&ArpL3Protocol::SendArpRequest,
this));
120 m_cacheList.push_back (cache);
125 ArpL3Protocol::FindCache (Ptr<NetDevice> device)
128 for (CacheList::const_iterator i = m_cacheList.begin (); i != m_cacheList.end (); i++)
130 if ((*i)->GetDevice () == device)
148 NS_LOG_LOGIC (
"ARP: received packet of size "<< packet->GetSize ());
160 uint32_t size = packet->RemoveHeader (arp);
166 NS_LOG_LOGIC (
"ARP: received "<< (arp.IsRequest () ?
"request" :
"reply") <<
167 " node="<<m_node->
GetId ()<<
", got request from " <<
168 arp.GetSourceIpv4Address () <<
" for address " <<
169 arp.GetDestinationIpv4Address () <<
"; we have addresses: ");
170 for (uint32_t i = 0; i < cache->GetInterface ()->GetNAddresses (); i++)
172 NS_LOG_LOGIC (cache->GetInterface ()->GetAddress (i).GetLocal () <<
", ");
180 for (uint32_t i = 0; i < cache->GetInterface ()->GetNAddresses (); i++)
182 if (arp.IsRequest () && arp.GetDestinationIpv4Address () ==
183 cache->GetInterface ()->GetAddress (i).GetLocal ())
187 arp.GetSourceIpv4Address () <<
" -- send reply");
188 SendArpReply (cache, arp.GetDestinationIpv4Address (), arp.GetSourceIpv4Address (),
189 arp.GetSourceHardwareAddress ());
192 else if (arp.IsReply () &&
193 arp.GetDestinationIpv4Address ().
IsEqual (cache->GetInterface ()->GetAddress (i).GetLocal ()) &&
194 arp.GetDestinationHardwareAddress () == device->GetAddress ())
204 ", got reply from " << arp.GetSourceIpv4Address ()
205 <<
" for waiting entry -- flush");
206 Address from_mac = arp.GetSourceHardwareAddress ();
211 cache->GetInterface ()->Send (pending,
212 arp.GetSourceIpv4Address ());
221 arp.GetSourceIpv4Address () <<
222 " for non-waiting entry -- drop");
223 m_dropTrace (packet);
228 NS_LOG_LOGIC (
"node="<<m_node->
GetId ()<<
", got reply for unknown entry -- drop");
229 m_dropTrace (packet);
237 arp.GetSourceIpv4Address () <<
" for unknown address " <<
238 arp.GetDestinationIpv4Address () <<
" -- drop");
248 NS_LOG_FUNCTION (
this << packet << destination << device << cache << hardwareDestination);
257 ", dead entry for " << destination <<
" expired -- send arp request");
259 SendArpRequest (cache, destination);
264 ", alive entry for " << destination <<
" expired -- send arp request");
266 SendArpRequest (cache, destination);
270 NS_FATAL_ERROR (
"Test for possibly unreachable code-- please file a bug report, with a test case, if this is ever hit");
278 ", dead entry for " << destination <<
" valid -- drop");
279 m_dropTrace (packet);
284 ", alive entry for " << destination <<
" valid -- send");
288 if (!bytes && m_node->IsCognitiveRadio()) {
289 destAddress = destAddress + (RECEIVER_RADIO-CONTROL_RADIO);
291 *hardwareDestination = destAddress;
297 ", wait reply for " << destination <<
" valid -- drop previous");
300 m_dropTrace (packet);
309 ", no entry for " << destination <<
" -- send arp request");
310 entry = cache->
Add (destination);
312 SendArpRequest (cache, destination);
329 Ipv4Address source = ipv4->SelectSourceAddress (device, to, Ipv4InterfaceAddress::GLOBAL);
331 " || src: " << device->GetAddress () <<
" / " << source <<
332 " || dst: " << device->GetBroadcast () <<
" / " << to);
333 arp.SetRequest (device->GetAddress (), source, device->GetBroadcast (), to);
335 cache->GetDevice ()->Send (packet, device->GetBroadcast (), PROT_NUMBER);
339 ArpL3Protocol::SendArpReply (Ptr<const ArpCache> cache, Ipv4Address myIp, Ipv4Address toIp, Address toMac)
344 "|| src: " << cache->GetDevice ()->GetAddress () <<
346 " || dst: " << toMac <<
" / " << toIp);
347 arp.SetReply (cache->GetDevice ()->GetAddress (), myIp, toMac, toIp);
348 Ptr<Packet> packet = Create<Packet> ();
350 cache->GetDevice ()->Send (packet, toMac, PROT_NUMBER);
void SetDevice(Ptr< NetDevice > device, Ptr< Ipv4Interface > interface)
void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Receive a packet.
#define NS_LOG_FUNCTION(parameters)
ArpCache::Entry * Add(Ipv4Address to)
Add an Ipv4Address to this ARP cache.
ArpCache::Entry * Lookup(Ipv4Address destination)
Do lookup in the ARP cache against an IP address.
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
uint32_t GetSize(void) const
virtual void DoDispose(void)
#define NS_FATAL_ERROR(msg)
fatal error handling
a polymophic address class
bool PeekPacketTag(Tag &tag) const
virtual void NotifyNewAggregate()
virtual void DoDispose(void)
void MarkWaitReply(Ptr< Packet > waiting)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
bool IsExpired(void) const
#define NS_LOG_LOGIC(msg)
Address GetMacAddress(void) const
virtual void NotifyNewAggregate(void)
Ptr< Packet > Copy(void) const
Implement the Ipv4 layer.
bool IsEqual(const Ipv4Address &other) const
Comparison operation between two Ipv4Addresses.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void MarkAlive(Address macAddress)
A record that that holds information about an ArpCache entry.
void Flush(void)
Clear the ArpCache of all entries.
bool UpdateWaitReply(Ptr< Packet > waiting)
Ipv4 addresses are stored in host order in this class.
uint32_t GetId(void) const
bool Lookup(Ptr< Packet > p, Ipv4Address destination, Ptr< NetDevice > device, Ptr< ArpCache > cache, Address *hardwareDestination)
Perform an ARP lookup.
Ptr< Packet > DequeuePending(void)
Ptr< T > GetObject(void) const
void AddHeader(const Header &header)