INET Framework for OMNeT++/OMNEST
inet::Arp Class Reference

ARP implementation. More...

#include <Arp.h>

Inheritance diagram for inet::Arp:
inet::OperationalBase inet::IArp inet::OperationalMixin< cSimpleModule > inet::ILifecycle

Classes

class  ArpCacheEntry
 

Public Types

typedef std::map< Ipv4Address, ArpCacheEntry * > ArpCache
 
typedef std::vector< cMessage * > MsgPtrVector
 

Public Member Functions

 Arp ()
 
virtual ~Arp ()
 
virtual int numInitStages () const override
 
void sendArpGratuitous (const NetworkInterface *ie, MacAddress srcAddr, Ipv4Address ipAddr, ArpOpcode opCode=ARP_REQUEST)
 
void sendArpProbe (const NetworkInterface *ie, MacAddress srcAddr, Ipv4Address probedAddr)
 
virtual MacAddress resolveL3Address (const L3Address &address, const NetworkInterface *ie) override
 IArp implementation. More...
 
virtual L3Address getL3AddressFor (const MacAddress &addr) const override
 Returns the Layer 3 address for the given MAC address. More...
 
- Public Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual ~OperationalMixin ()
 }@ More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::IArp
virtual ~IArp ()
 

Protected Member Functions

MacAddress mapMulticastAddress (Ipv4Address addr)
 
virtual void initialize (int stage) override
 
virtual void handleMessageWhenUp (cMessage *msg) override
 
virtual void finish () override
 
virtual bool isInitializeStage (int stage) const override
 
virtual bool isModuleStartStage (int stage) const override
 
virtual bool isModuleStopStage (int stage) const override
 
virtual void handleStartOperation (LifecycleOperation *operation) override
 
virtual void handleStopOperation (LifecycleOperation *operation) override
 
virtual void handleCrashOperation (LifecycleOperation *operation) override
 
virtual void flush ()
 
virtual void initiateArpResolution (Ipv4Address ipv4Address, ArpCacheEntry *entry)
 
virtual void sendArpRequest (const NetworkInterface *ie, Ipv4Address ipAddress)
 
virtual void requestTimedOut (cMessage *selfmsg)
 
virtual bool addressRecognized (Ipv4Address destAddr, NetworkInterface *ie)
 
virtual void processArpPacket (Packet *packet)
 
virtual void updateArpCache (ArpCacheEntry *entry, const MacAddress &macAddress)
 
virtual MacAddress resolveMacAddressForArpReply (const NetworkInterface *ie, const ArpPacket *arp)
 
virtual void dumpArpPacket (const ArpPacket *arp)
 
virtual void refreshDisplay () const override
 
- Protected Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual int numInitStages () const override
 
virtual void refreshDisplay () const override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void handleMessageWhenDown (cMessage *msg)
 
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual State getInitialOperationalState () const
 Returns initial operational state: OPERATING or NOT_OPERATING. More...
 
virtual void handleActiveOperationTimeout (cMessage *message)
 
virtual bool isUp () const
 utility functions More...
 
virtual bool isDown () const
 
virtual void setOperationalState (State newState)
 
virtual void scheduleOperationTimeout (simtime_t timeout)
 
virtual void setupActiveOperation (LifecycleOperation *operation, IDoneCallback *doneCallback, State)
 
virtual void delayActiveOperationFinish (simtime_t timeout)
 
virtual void startActiveOperationExtraTime (simtime_t delay=SIMTIME_ZERO)
 
virtual void startActiveOperationExtraTimeOrFinish (simtime_t extraTime)
 
virtual void finishActiveOperation ()
 

Protected Attributes

simtime_t retryTimeout
 
int retryCount = 0
 
simtime_t cacheTimeout
 
std::string proxyArpInterfaces = ""
 
long numResolutions = 0
 
long numFailedResolutions = 0
 
long numRequestsSent = 0
 
long numRepliesSent = 0
 
cPatternMatcher proxyArpInterfacesMatcher
 
ArpCache arpCache
 
ModuleRefByPar< IInterfaceTableift
 
ModuleRefByPar< IIpv4RoutingTablert
 
- Protected Attributes inherited from inet::OperationalMixin< cSimpleModule >
State operationalState
 
simtime_t lastChange
 
Operation activeOperation
 
cMessage * activeOperationTimeout
 
cMessage * activeOperationExtraTimer
 

Static Protected Attributes

static simsignal_t arpRequestSentSignal = registerSignal("arpRequestSent")
 
static simsignal_t arpReplySentSignal = registerSignal("arpReplySent")
 

Additional Inherited Members

- Static Public Attributes inherited from inet::IArp
static const simsignal_t arpResolutionInitiatedSignal = cComponent::registerSignal("arpResolutionInitiated")
 Signals used to publish ARP state changes. More...
 
static const simsignal_t arpResolutionCompletedSignal = cComponent::registerSignal("arpResolutionCompleted")
 
static const simsignal_t arpResolutionFailedSignal = cComponent::registerSignal("arpResolutionFailed")
 
- Protected Types inherited from inet::OperationalMixin< cSimpleModule >
enum  State
 

Detailed Description

ARP implementation.

Member Typedef Documentation

◆ ArpCache

◆ MsgPtrVector

typedef std::vector<cMessage *> inet::Arp::MsgPtrVector

Constructor & Destructor Documentation

◆ Arp()

inet::Arp::Arp ( )
42 {
43 }

◆ ~Arp()

inet::Arp::~Arp ( )
virtual
80 {
81  for (auto& elem : arpCache)
82  delete elem.second;
83 }

Member Function Documentation

◆ addressRecognized()

bool inet::Arp::addressRecognized ( Ipv4Address  destAddr,
NetworkInterface ie 
)
protectedvirtual
214 {
215  if (rt->isLocalAddress(destAddr))
216  return true;
217  else {
218  // if proxy ARP is enables in interface ie
219  if (proxyArpInterfacesMatcher.matches(ie->getInterfaceName())) {
220  // if we can route this packet, and the output port is
221  // different from this one, then say yes
222  NetworkInterface *rtie = rt->getInterfaceForDestAddr(destAddr);
223  return rtie != nullptr && rtie != ie;
224  }
225  else
226  return false;
227  }
228 }

Referenced by processArpPacket().

◆ dumpArpPacket()

void inet::Arp::dumpArpPacket ( const ArpPacket arp)
protectedvirtual
231 {
232  EV_DETAIL << (arp->getOpcode() == ARP_REQUEST ? "ARP_REQ" : arp->getOpcode() == ARP_REPLY ? "ARP_REPLY" : "unknown type")
233  << " src=" << arp->getSrcIpAddress() << " / " << arp->getSrcMacAddress()
234  << " dest=" << arp->getDestIpAddress() << " / " << arp->getDestMacAddress() << "\n";
235 }

Referenced by processArpPacket().

◆ finish()

void inet::Arp::finish ( )
overrideprotectedvirtual
76 {
77 }

◆ flush()

void inet::Arp::flush ( )
protectedvirtual
112 {
113  while (!arpCache.empty()) {
114  auto i = arpCache.begin();
115  ArpCacheEntry *entry = i->second;
116  cancelAndDelete(entry->timer);
117  entry->timer = nullptr;
118  delete entry;
119  arpCache.erase(i);
120  }
121 }

Referenced by handleCrashOperation(), and handleStopOperation().

◆ getL3AddressFor()

L3Address inet::Arp::getL3AddressFor ( const MacAddress ) const
overridevirtual

Returns the Layer 3 address for the given MAC address.

If it is not available (not in the cache, pending resolution, or already expired), UNSPECIFIED_ADDRESS is returned.

Implements inet::IArp.

433 {
434  Enter_Method("getL3AddressFor");
435 
436  if (macAddr.isUnspecified())
438 
439  simtime_t now = simTime();
440  for (const auto& elem : arpCache)
441  if (elem.second->macAddress == macAddr && elem.second->lastUpdate + cacheTimeout >= now)
442  return elem.first;
443 
445 }

◆ handleCrashOperation()

void inet::Arp::handleCrashOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

107 {
108  flush();
109 }

◆ handleMessageWhenUp()

void inet::Arp::handleMessageWhenUp ( cMessage *  msg)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

86 {
87  if (msg->isSelfMessage()) {
88  requestTimedOut(msg);
89  }
90  else {
91  Packet *packet = check_and_cast<Packet *>(msg);
92  processArpPacket(packet);
93  }
94 }

◆ handleStartOperation()

void inet::Arp::handleStartOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

97 {
98  ASSERT(arpCache.empty());
99 }

◆ handleStopOperation()

void inet::Arp::handleStopOperation ( LifecycleOperation operation)
overrideprotectedvirtual

Implements inet::OperationalMixin< cSimpleModule >.

102 {
103  flush();
104 }

◆ initialize()

void inet::Arp::initialize ( int  stage)
overrideprotectedvirtual

Reimplemented from inet::OperationalMixin< cSimpleModule >.

46 {
48 
49  if (stage == INITSTAGE_LOCAL) {
50  retryTimeout = par("retryTimeout");
51  retryCount = par("retryCount");
52  cacheTimeout = par("cacheTimeout");
53  proxyArpInterfaces = par("proxyArpInterfaces").stdstringValue();
54 
55  proxyArpInterfacesMatcher.setPattern(proxyArpInterfaces.c_str(), false, true, false);
56 
57  // init statistics
60  WATCH(numRequestsSent);
61  WATCH(numRepliesSent);
62  WATCH(numResolutions);
63  WATCH(numFailedResolutions);
64 
65  WATCH_PTRMAP(arpCache);
66  }
67  else if (stage == INITSTAGE_NETWORK_LAYER) {
68  ift.reference(this, "interfaceTableModule", true);
69  rt.reference(this, "routingTableModule", true);
70  registerService(Protocol::arp, gate("netwIn"), gate("netwOut"));
71  registerProtocol(Protocol::arp, gate("ifOut"), gate("ifIn"));
72  }
73 }

◆ initiateArpResolution()

void inet::Arp::initiateArpResolution ( Ipv4Address  ipv4Address,
ArpCacheEntry entry 
)
protectedvirtual
136 {
137  entry->pending = true;
138  entry->numRetries = 0;
139  entry->lastUpdate = SIMTIME_ZERO;
140  entry->macAddress = MacAddress::UNSPECIFIED_ADDRESS;
141  entry->ipv4Address = nextHopAddr;
142  sendArpRequest(entry->ie, nextHopAddr);
143 
144  // start timer
145  cMessage *msg = entry->timer = new cMessage("ARP timeout");
146  msg->setContextPointer(entry);
147  scheduleAfter(retryTimeout, msg);
148 
149  numResolutions++;
150  Notification signal(nextHopAddr, MacAddress::UNSPECIFIED_ADDRESS, entry->ie);
151  emit(arpResolutionInitiatedSignal, &signal);
152 }

Referenced by resolveL3Address().

◆ isInitializeStage()

virtual bool inet::Arp::isInitializeStage ( int  stage) const
inlineoverrideprotectedvirtual

◆ isModuleStartStage()

virtual bool inet::Arp::isModuleStartStage ( int  stage) const
inlineoverrideprotectedvirtual

◆ isModuleStopStage()

virtual bool inet::Arp::isModuleStopStage ( int  stage) const
inlineoverrideprotectedvirtual

◆ mapMulticastAddress()

MacAddress inet::Arp::mapMulticastAddress ( Ipv4Address  addr)
protected

◆ numInitStages()

virtual int inet::Arp::numInitStages ( ) const
inlineoverridevirtual
84 { return NUM_INIT_STAGES; }

◆ processArpPacket()

void inet::Arp::processArpPacket ( Packet packet)
protectedvirtual
238 {
239  EV_INFO << "Received " << packet << " from network protocol.\n";
240  const auto& arp = packet->peekAtFront<ArpPacket>();
241  dumpArpPacket(arp.get());
242 
243  // extract input port
244  NetworkInterface *ie = ift->getInterfaceById(packet->getTag<InterfaceInd>()->getInterfaceId());
245 
246  //
247  // Recipe a'la RFC 826:
248  //
249  // ?Do I have the hardware type in ar$hrd?
250  // Yes: (almost definitely)
251  // [optionally check the hardware length ar$hln]
252  // ?Do I speak the protocol in ar$pro?
253  // Yes:
254  // [optionally check the protocol length ar$pln]
255  // Merge_flag := false
256  // If the pair <protocol type, sender protocol address> is
257  // already in my translation table, update the sender
258  // hardware address field of the entry with the new
259  // information in the packet and set Merge_flag to true.
260  // ?Am I the target protocol address?
261  // Yes:
262  // If Merge_flag is false, add the triplet <protocol type,
263  // sender protocol address, sender hardware address> to
264  // the translation table.
265  // ?Is the opcode ares_op$REQUEST? (NOW look at the opcode!!)
266  // Yes:
267  // Swap hardware and protocol fields, putting the local
268  // hardware and protocol addresses in the sender fields.
269  // Set the ar$op field to ares_op$REPLY
270  // Send the packet to the (new) target hardware address on
271  // the same hardware on which the request was received.
272  //
273 
274  MacAddress srcMacAddress = arp->getSrcMacAddress();
275  Ipv4Address srcIpAddress = arp->getSrcIpAddress();
276 
277  if (srcMacAddress.isUnspecified())
278  throw cRuntimeError("wrong ARP packet: source MAC address is empty");
279  if (srcIpAddress.isUnspecified())
280  throw cRuntimeError("wrong ARP packet: source IPv4 address is empty");
281 
282  bool mergeFlag = false;
283  // "If ... sender protocol address is already in my translation table"
284  auto it = arpCache.find(srcIpAddress);
285  if (it != arpCache.end()) {
286  // "update the sender hardware address field"
287  ArpCacheEntry *entry = it->second;
288  updateArpCache(entry, srcMacAddress);
289  mergeFlag = true;
290  }
291 
292  // "?Am I the target protocol address?"
293  // if Proxy ARP is enabled, we also have to reply if we're a router to the dest IPv4 address
294  if (addressRecognized(arp->getDestIpAddress(), ie)) {
295  // "If Merge_flag is false, add the triplet protocol type, sender
296  // protocol address, sender hardware address to the translation table"
297  if (!mergeFlag) {
298  ArpCacheEntry *entry;
299  if (it != arpCache.end()) {
300  entry = it->second;
301  }
302  else {
303  entry = new ArpCacheEntry();
304  arpCache.insert(arpCache.begin(), std::make_pair(srcIpAddress, entry));
305  entry->ipv4Address = srcIpAddress;
306  entry->ie = ie;
307 
308  entry->pending = false;
309  entry->timer = nullptr;
310  entry->numRetries = 0;
311  }
312  updateArpCache(entry, srcMacAddress);
313  }
314 
315  // "?Is the opcode ares_op$REQUEST? (NOW look at the opcode!!)"
316  switch (arp->getOpcode()) {
317  case ARP_REQUEST: {
318  EV_DETAIL << "Packet was ARP REQUEST, sending REPLY\n";
319  MacAddress myMACAddress = resolveMacAddressForArpReply(ie, arp.get());
320  if (myMACAddress.isUnspecified()) {
321  delete packet;
322  return;
323  }
324 
325  Ipv4Address myIPAddress = ie->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
326 
327  // "Swap hardware and protocol fields", etc.
328  const auto& arpReply = makeShared<ArpPacket>();
329  Ipv4Address origDestAddress = arp->getDestIpAddress();
330  arpReply->setDestIpAddress(srcIpAddress);
331  arpReply->setDestMacAddress(srcMacAddress);
332  arpReply->setSrcIpAddress(origDestAddress);
333  arpReply->setSrcMacAddress(myMACAddress);
334  arpReply->setOpcode(ARP_REPLY);
335  Packet *outPk = new Packet("arpREPLY");
336  outPk->insertAtFront(arpReply);
337  outPk->addTag<MacAddressReq>()->setDestAddress(srcMacAddress);
338  outPk->addTag<InterfaceReq>()->setInterfaceId(ie->getInterfaceId());
339  if (ie->getProtocol() != nullptr)
340  outPk->addTag<DispatchProtocolReq>()->setProtocol(ie->getProtocol());
341  else
342  outPk->removeTagIfPresent<DispatchProtocolReq>();
343  outPk->addTag<PacketProtocolTag>()->setProtocol(&Protocol::arp);
344 
345  // send out
346  EV_INFO << "Sending " << outPk << " to network protocol.\n";
347  emit(arpReplySentSignal, outPk);
348  send(outPk, "ifOut");
349  numRepliesSent++;
350  break;
351  }
352 
353  case ARP_REPLY: {
354  EV_DETAIL << "Discarding packet\n";
355  break;
356  }
357 
358  case ARP_RARP_REQUEST:
359  throw cRuntimeError("RARP request received: RARP is not supported");
360 
361  case ARP_RARP_REPLY:
362  throw cRuntimeError("RARP reply received: RARP is not supported");
363 
364  default:
365  throw cRuntimeError("Unsupported opcode %d in received ARP packet", arp->getOpcode());
366  }
367  }
368  else {
369  // address not recognized
370  EV_INFO << "IPv4 address " << arp->getDestIpAddress() << " not recognized, dropping ARP packet\n";
371  }
372  delete packet;
373 }

Referenced by handleMessageWhenUp().

◆ refreshDisplay()

void inet::Arp::refreshDisplay ( ) const
overrideprotectedvirtual
124 {
126 
127  std::stringstream os;
128 
129  os << "size:" << arpCache.size() << " sent:" << numRequestsSent << "\n"
130  << "repl:" << numRepliesSent << " fail:" << numFailedResolutions;
131 
132  getDisplayString().setTagArg("t", 0, os.str().c_str());
133 }

◆ requestTimedOut()

void inet::Arp::requestTimedOut ( cMessage *  selfmsg)
protectedvirtual
189 {
190  ArpCacheEntry *entry = (ArpCacheEntry *)selfmsg->getContextPointer();
191  entry->numRetries++;
192  if (entry->numRetries < retryCount) {
193  // retry
194  Ipv4Address nextHopAddr = entry->ipv4Address;
195  EV_INFO << "ARP request for " << nextHopAddr << " timed out, resending\n";
196  sendArpRequest(entry->ie, nextHopAddr);
197  scheduleAfter(retryTimeout, selfmsg);
198  return;
199  }
200 
201  delete selfmsg;
202 
203  // max retry count reached: ARP failure.
204  // throw out entry from cache
205  EV << "ARP timeout, max retry count " << retryCount << " for " << entry->ipv4Address << " reached.\n";
206  Notification signal(entry->ipv4Address, MacAddress::UNSPECIFIED_ADDRESS, entry->ie);
207  emit(arpResolutionFailedSignal, &signal);
208  arpCache.erase(entry->ipv4Address);
209  delete entry;
211 }

Referenced by handleMessageWhenUp().

◆ resolveL3Address()

MacAddress inet::Arp::resolveL3Address ( const L3Address address,
const NetworkInterface ie 
)
overridevirtual

IArp implementation.

Implements inet::IArp.

398 {
399  Enter_Method("resolveMACAddress(%s,%s)", address.str().c_str(), ie->getInterfaceName());
400 
401  Ipv4Address addr = address.toIpv4();
402  auto it = arpCache.find(addr);
403  if (it == arpCache.end()) {
404  // no cache entry: launch ARP request
405  ArpCacheEntry *entry = new ArpCacheEntry();
406  entry->owner = this;
407  arpCache.insert(arpCache.begin(), std::make_pair(addr, entry));
408  entry->ipv4Address = addr;
409  entry->ie = ie;
410 
411  EV << "Starting ARP resolution for " << addr << "\n";
412  initiateArpResolution(addr, entry);
414  }
415  else if (it->second->pending) {
416  // an ARP request is already pending for this address
417  EV << "ARP resolution for " << addr << " is already pending\n";
419  }
420  else if (it->second->lastUpdate + cacheTimeout >= simTime()) {
421  return it->second->macAddress;
422  }
423  else {
424  EV << "ARP cache entry for " << addr << " expired, starting new ARP resolution\n";
425  ArpCacheEntry *entry = it->second;
426  entry->ie = ie; // routing table may have changed
427  initiateArpResolution(addr, entry);
428  }
430 }

◆ resolveMacAddressForArpReply()

MacAddress inet::Arp::resolveMacAddressForArpReply ( const NetworkInterface ie,
const ArpPacket arp 
)
protectedvirtual
376 {
377  return ie->getMacAddress();
378 }

Referenced by processArpPacket().

◆ sendArpGratuitous()

void inet::Arp::sendArpGratuitous ( const NetworkInterface ie,
MacAddress  srcAddr,
Ipv4Address  ipAddr,
ArpOpcode  opCode = ARP_REQUEST 
)
449 {
450  Enter_Method("sendArpGratuitous");
451 
452  // both must be set
453  ASSERT(!srcAddr.isUnspecified());
454  ASSERT(!ipAddr.isUnspecified());
455 
456  // fill out everything in ARP Request packet except dest MAC address
457  Packet *packet = new Packet("arpGrt");
458  const auto& arp = makeShared<ArpPacket>();
459  arp->setOpcode(opCode);
460  arp->setSrcMacAddress(srcAddr);
461  arp->setSrcIpAddress(ipAddr);
462  arp->setDestIpAddress(ipAddr);
463  arp->setDestMacAddress(MacAddress::BROADCAST_ADDRESS);
464  packet->insertAtFront(arp);
465 
466  auto macAddrReq = packet->addTag<MacAddressReq>();
467  macAddrReq->setSrcAddress(srcAddr);
468  macAddrReq->setDestAddress(MacAddress::BROADCAST_ADDRESS);
469  packet->addTag<InterfaceReq>()->setInterfaceId(ie->getInterfaceId());
470  if (ie->getProtocol() != nullptr)
471  packet->addTag<DispatchProtocolReq>()->setProtocol(ie->getProtocol());
472  else
473  packet->removeTagIfPresent<DispatchProtocolReq>();
474  packet->addTag<PacketProtocolTag>()->setProtocol(&Protocol::arp);
475 
476  ArpCacheEntry *entry = new ArpCacheEntry();
477  arpCache.insert(arpCache.begin(), std::make_pair(ipAddr, entry));
478  entry->ipv4Address = ipAddr;
479  entry->ie = ie;
480 
481  entry->pending = false;
482  entry->timer = nullptr;
483  entry->numRetries = 0;
484 
485  entry->lastUpdate = simTime();
486  // updateARPCache(entry, srcAddr); //FIXME
487 
488  // send out
489  send(packet, "ifOut");
490 }

◆ sendArpProbe()

void inet::Arp::sendArpProbe ( const NetworkInterface ie,
MacAddress  srcAddr,
Ipv4Address  probedAddr 
)
495 {
496  Enter_Method("sendArpProbe");
497 
498  // both must be set
499  ASSERT(!srcAddr.isUnspecified());
500  ASSERT(!probedAddr.isUnspecified());
501 
502  Packet *packet = new Packet("arpProbe");
503  const auto& arp = makeShared<ArpPacket>();
504  arp->setOpcode(ARP_REQUEST);
505  arp->setSrcMacAddress(srcAddr);
506  arp->setSrcIpAddress(Ipv4Address::UNSPECIFIED_ADDRESS);
507  arp->setDestIpAddress(probedAddr);
508  arp->setDestMacAddress(MacAddress::UNSPECIFIED_ADDRESS);
509  packet->insertAtFront(arp);
510 
511  auto macAddrReq = packet->addTag<MacAddressReq>();
512  macAddrReq->setSrcAddress(srcAddr);
513  macAddrReq->setDestAddress(MacAddress::BROADCAST_ADDRESS);
514  packet->addTag<InterfaceReq>()->setInterfaceId(ie->getInterfaceId());
515  if (ie->getProtocol() != nullptr)
516  packet->addTag<DispatchProtocolReq>()->setProtocol(ie->getProtocol());
517  else
518  packet->removeTagIfPresent<DispatchProtocolReq>();
519  packet->addTag<PacketProtocolTag>()->setProtocol(&Protocol::arp);
520 
521  // send out
522  send(packet, "ifOut");
523 }

◆ sendArpRequest()

void inet::Arp::sendArpRequest ( const NetworkInterface ie,
Ipv4Address  ipAddress 
)
protectedvirtual
155 {
156  // find our own IPv4 address and MAC address on the given interface
157  MacAddress myMACAddress = ie->getMacAddress();
158  Ipv4Address myIPAddress = ie->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
159 
160  // both must be set
161  ASSERT(!myMACAddress.isUnspecified());
162  ASSERT(!myIPAddress.isUnspecified());
163 
164  // fill out everything in ARP Request packet except dest MAC address
165  Packet *packet = new Packet("arpREQ");
166  const auto& arp = makeShared<ArpPacket>();
167  arp->setOpcode(ARP_REQUEST);
168  arp->setSrcMacAddress(myMACAddress);
169  arp->setSrcIpAddress(myIPAddress);
170  arp->setDestIpAddress(ipAddress);
171  packet->insertAtFront(arp);
172 
173  packet->addTag<MacAddressReq>()->setDestAddress(MacAddress::BROADCAST_ADDRESS);
174  packet->addTag<InterfaceReq>()->setInterfaceId(ie->getInterfaceId());
175  if (ie->getProtocol() != nullptr)
176  packet->addTag<DispatchProtocolReq>()->setProtocol(ie->getProtocol());
177  else
178  packet->removeTagIfPresent<DispatchProtocolReq>();
179  packet->addTag<PacketProtocolTag>()->setProtocol(&Protocol::arp);
180 
181  // send out
182  EV_INFO << "Sending " << packet << " to network protocol.\n";
183  emit(arpRequestSentSignal, packet);
184  send(packet, "ifOut");
185  numRequestsSent++;
186 }

Referenced by initiateArpResolution(), and requestTimedOut().

◆ updateArpCache()

void inet::Arp::updateArpCache ( ArpCacheEntry entry,
const MacAddress macAddress 
)
protectedvirtual
381 {
382  EV_DETAIL << "Updating ARP cache entry: " << entry->ipv4Address << " <--> " << macAddress << "\n";
383 
384  // update entry
385  if (entry->pending) {
386  entry->pending = false;
387  cancelAndDelete(entry->timer);
388  entry->timer = nullptr;
389  entry->numRetries = 0;
390  }
391  entry->macAddress = macAddress;
392  entry->lastUpdate = simTime();
393  Notification signal(entry->ipv4Address, macAddress, entry->ie);
394  emit(arpResolutionCompletedSignal, &signal);
395 }

Referenced by processArpPacket().

Member Data Documentation

◆ arpCache

◆ arpReplySentSignal

simsignal_t inet::Arp::arpReplySentSignal = registerSignal("arpReplySent")
staticprotected

Referenced by processArpPacket().

◆ arpRequestSentSignal

simsignal_t inet::Arp::arpRequestSentSignal = registerSignal("arpRequestSent")
staticprotected

Referenced by sendArpRequest().

◆ cacheTimeout

simtime_t inet::Arp::cacheTimeout
protected

◆ ift

ModuleRefByPar<IInterfaceTable> inet::Arp::ift
protected

Referenced by initialize(), and processArpPacket().

◆ numFailedResolutions

long inet::Arp::numFailedResolutions = 0
protected

◆ numRepliesSent

long inet::Arp::numRepliesSent = 0
protected

◆ numRequestsSent

long inet::Arp::numRequestsSent = 0
protected

◆ numResolutions

long inet::Arp::numResolutions = 0
protected

◆ proxyArpInterfaces

std::string inet::Arp::proxyArpInterfaces = ""
protected

Referenced by initialize().

◆ proxyArpInterfacesMatcher

cPatternMatcher inet::Arp::proxyArpInterfacesMatcher
protected

Referenced by addressRecognized(), and initialize().

◆ retryCount

int inet::Arp::retryCount = 0
protected

Referenced by initialize(), and requestTimedOut().

◆ retryTimeout

simtime_t inet::Arp::retryTimeout
protected

◆ rt

ModuleRefByPar<IIpv4RoutingTable> inet::Arp::rt
protected

Referenced by addressRecognized(), and initialize().


The documentation for this class was generated from the following files:
inet::Protocol::arp
static const Protocol arp
Definition: Protocol.h:53
inet::ARP_REQUEST
@ ARP_REQUEST
Definition: ArpPacket_m.h:64
inet::Arp::retryCount
int retryCount
Definition: Arp.h:59
inet::Arp::rt
ModuleRefByPar< IIpv4RoutingTable > rt
Definition: Arp.h:75
inet::ModuleStopOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:53
inet::Arp::arpRequestSentSignal
static simsignal_t arpRequestSentSignal
Definition: Arp.h:69
inet::OperationalMixin< cSimpleModule >::initialize
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
inet::ARP_REPLY
@ ARP_REPLY
Definition: ArpPacket_m.h:65
inet::ModuleStartOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:29
InterfaceReq
removed InterfaceReq
Definition: IUdp-gates.txt:11
DispatchProtocolReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DispatchProtocolReq
Definition: IUdp-gates.txt:25
inet::INITSTAGE_NETWORK_LAYER
INET_API InitStage INITSTAGE_NETWORK_LAYER
Initialization of network layer protocols.
inet::Arp::dumpArpPacket
virtual void dumpArpPacket(const ArpPacket *arp)
Definition: Arp.cc:230
inet::ARP_RARP_REPLY
@ ARP_RARP_REPLY
Definition: ArpPacket_m.h:67
inet::Arp::retryTimeout
simtime_t retryTimeout
Definition: Arp.h:58
inet::Arp::cacheTimeout
simtime_t cacheTimeout
Definition: Arp.h:60
inet::registerService
void registerService(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a service primitive (SDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:14
inet::Arp::arpReplySentSignal
static simsignal_t arpReplySentSignal
Definition: Arp.h:70
inet::Arp::proxyArpInterfaces
std::string proxyArpInterfaces
Definition: Arp.h:61
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::Arp::arpCache
ArpCache arpCache
Definition: Arp.h:72
inet::Arp::updateArpCache
virtual void updateArpCache(ArpCacheEntry *entry, const MacAddress &macAddress)
Definition: Arp.cc:380
inet::Arp::processArpPacket
virtual void processArpPacket(Packet *packet)
Definition: Arp.cc:237
inet::Arp::addressRecognized
virtual bool addressRecognized(Ipv4Address destAddr, NetworkInterface *ie)
Definition: Arp.cc:213
inet::Arp::resolveMacAddressForArpReply
virtual MacAddress resolveMacAddressForArpReply(const NetworkInterface *ie, const ArpPacket *arp)
Definition: Arp.cc:375
inet::Arp::flush
virtual void flush()
Definition: Arp.cc:111
inet::Arp::sendArpRequest
virtual void sendArpRequest(const NetworkInterface *ie, Ipv4Address ipAddress)
Definition: Arp.cc:154
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::Arp::numRequestsSent
long numRequestsSent
Definition: Arp.h:64
inet::IArp::arpResolutionFailedSignal
static const simsignal_t arpResolutionFailedSignal
Definition: IArp.h:43
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::Arp::numResolutions
long numResolutions
Definition: Arp.h:62
inet::Arp::ift
ModuleRefByPar< IInterfaceTable > ift
Definition: Arp.h:74
inet::ARP_RARP_REQUEST
@ ARP_RARP_REQUEST
Definition: ArpPacket_m.h:66
inet::Arp::initiateArpResolution
virtual void initiateArpResolution(Ipv4Address ipv4Address, ArpCacheEntry *entry)
Definition: Arp.cc:135
inet::IArp::arpResolutionInitiatedSignal
static const simsignal_t arpResolutionInitiatedSignal
Signals used to publish ARP state changes.
Definition: IArp.h:41
inet::Ipv4Address::UNSPECIFIED_ADDRESS
static const Ipv4Address UNSPECIFIED_ADDRESS
0.0.0.0
Definition: Ipv4Address.h:91
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::MacAddress::BROADCAST_ADDRESS
static const MacAddress BROADCAST_ADDRESS
The broadcast MAC address, ff:ff:ff:ff:ff:ff.
Definition: MacAddress.h:34
inet::IArp::arpResolutionCompletedSignal
static const simsignal_t arpResolutionCompletedSignal
Definition: IArp.h:42
inet::Arp::numFailedResolutions
long numFailedResolutions
Definition: Arp.h:63
inet::Arp::requestTimedOut
virtual void requestTimedOut(cMessage *selfmsg)
Definition: Arp.cc:188
inet::Arp::numRepliesSent
long numRepliesSent
Definition: Arp.h:65
inet::MacAddress::UNSPECIFIED_ADDRESS
static const MacAddress UNSPECIFIED_ADDRESS
The unspecified MAC address, 00:00:00:00:00:00.
Definition: MacAddress.h:31
inet::OperationalMixin< cSimpleModule >::refreshDisplay
virtual void refreshDisplay() const override
Definition: OperationalMixinImpl.h:200
inet::registerProtocol
void registerProtocol(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a protocol primitive (PDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:83
inet::Arp::proxyArpInterfacesMatcher
cPatternMatcher proxyArpInterfacesMatcher
Definition: Arp.h:67