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

ARP implementation. More...

#include <GlobalARP.h>

Inheritance diagram for inet::GlobalARP:
inet::IARP inet::ILifecycle

Classes

class  ARPCacheEntry
 

Public Types

typedef std::map< L3Address, ARPCacheEntry * > ARPCache
 
typedef std::vector< cMessage * > MsgPtrVector
 

Public Member Functions

 GlobalARP ()
 
virtual ~GlobalARP ()
 
virtual int numInitStages () const override
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 
virtual L3Address getL3AddressFor (const MACAddress &addr) const override
 IARPCache implementation. More...
 
virtual MACAddress resolveL3Address (const L3Address &address, const InterfaceEntry *ie) override
 Tries to resolve the given network address to a MAC address. More...
 
- Public Member Functions inherited from inet::IARP
virtual ~IARP ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Member Functions

MACAddress mapMulticastAddress (L3Address addr)
 
virtual void initialize (int stage) override
 
virtual void handleMessage (cMessage *msg) override
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual void finish () override
 
virtual void processSelfMessage (cMessage *msg)
 
virtual void handleMessageWhenDown (cMessage *msg)
 
virtual bool isNodeUp ()
 
virtual void stop ()
 
virtual void start ()
 
virtual void processARPPacket (ARPPacket *arp)
 

Protected Attributes

bool isUp = false
 
IInterfaceTableift = nullptr
 
IIPv4RoutingTablert = nullptr
 

Static Protected Attributes

static ARPCache globalArpCache
 
static int globalArpCacheRefCnt = 0
 

Additional Inherited Members

- Static Public Attributes inherited from inet::IARP
static const simsignal_t initiatedARPResolutionSignal = cComponent::registerSignal("initiatedARPResolution")
 Signals used to publish ARP state changes. More...
 
static const simsignal_t completedARPResolutionSignal = cComponent::registerSignal("completedARPResolution")
 
static const simsignal_t failedARPResolutionSignal = cComponent::registerSignal("failedARPResolution")
 

Detailed Description

ARP implementation.

Member Typedef Documentation

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

Constructor & Destructor Documentation

inet::GlobalARP::GlobalARP ( )
52 {
53  if (++globalArpCacheRefCnt == 1) {
54  if (!globalArpCache.empty())
55  throw cRuntimeError("Global ARP cache not empty, model error in previous run?");
56  }
57 
58  ift = nullptr;
59  rt = nullptr;
60 }
IIPv4RoutingTable * rt
Definition: GlobalARP.h:70
IInterfaceTable * ift
Definition: GlobalARP.h:69
static int globalArpCacheRefCnt
Definition: GlobalARP.h:67
static ARPCache globalArpCache
Definition: GlobalARP.h:66
inet::GlobalARP::~GlobalARP ( )
virtual
109 {
111  // delete my entries from the globalArpCache
112  for (auto it = globalArpCache.begin(); it != globalArpCache.end(); ) {
113  if (it->second->owner == this) {
114  auto cur = it++;
115  delete cur->second;
116  globalArpCache.erase(cur);
117  }
118  else
119  ++it;
120  }
121 }
static int globalArpCacheRefCnt
Definition: GlobalARP.h:67
static ARPCache globalArpCache
Definition: GlobalARP.h:66

Member Function Documentation

void inet::GlobalARP::finish ( )
overrideprotectedvirtual
105 {
106 }
L3Address inet::GlobalARP::getL3AddressFor ( const MACAddress addr) const
overridevirtual

IARPCache implementation.

Implements inet::IARP.

207 {
208  Enter_Method_Silent();
209 
210  if (macAddr.isUnspecified())
212 
213  for (ARPCache::const_iterator it = globalArpCache.begin(); it != globalArpCache.end(); it++)
214  if (it->second->macAddress == macAddr && it->first.getType() == L3Address::IPv4)
215  return it->first.toIPv4();
216 
217 
219 }
static const IPv4Address UNSPECIFIED_ADDRESS
0.0.0.0
Definition: IPv4Address.h:102
static ARPCache globalArpCache
Definition: GlobalARP.h:66
Definition: L3Address.h:46
void inet::GlobalARP::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
124 {
125  if (!isUp) {
127  return;
128  }
129 
130  if (msg->isSelfMessage())
131  processSelfMessage(msg);
132  else
133  processARPPacket(check_and_cast<ARPPacket *>(msg));
134 }
virtual void processARPPacket(ARPPacket *arp)
Definition: GlobalARP.cc:187
virtual void processSelfMessage(cMessage *msg)
Definition: GlobalARP.cc:136
virtual void handleMessageWhenDown(cMessage *msg)
Definition: GlobalARP.cc:141
bool isUp
Definition: GlobalARP.h:64
void inet::GlobalARP::handleMessageWhenDown ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

142 {
143  if (msg->isSelfMessage())
144  throw cRuntimeError("Model error: self msg '%s' received when protocol is down", msg->getName());
145  EV_ERROR << "Protocol is turned off, dropping '" << msg->getName() << "' message\n";
146  delete msg;
147 }
bool inet::GlobalARP::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprotectedvirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

150 {
151  Enter_Method_Silent();
152 
153  if (dynamic_cast<NodeStartOperation *>(operation)) {
155  start();
156  }
157  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
159  stop();
160  }
161  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
163  stop();
164  }
165  else {
166  throw cRuntimeError("Unsupported operation '%s'", operation->getClassName());
167  }
168  return true;
169 }
Definition: NodeOperations.h:50
virtual void stop()
Definition: GlobalARP.cc:176
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
Stage
Definition: NodeOperations.h:46
virtual void start()
Definition: GlobalARP.cc:171
Definition: NodeOperations.h:127
void inet::GlobalARP::initialize ( int  stage)
overrideprotectedvirtual
63 {
64  cSimpleModule::initialize(stage);
65 
66  if (stage == INITSTAGE_LOCAL) {
67  WATCH_PTRMAP(globalArpCache);
68  }
69  else if (stage == INITSTAGE_NETWORK_LAYER_3) { // IP addresses should be available
70  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
71  rt = getModuleFromPar<IIPv4RoutingTable>(par("routingTableModule"), this);
72 
73  isUp = isNodeUp();
74 
75  // register our addresses in the global cache
76  for (int i = 0; i < ift->getNumInterfaces(); i++) {
77  InterfaceEntry *ie = ift->getInterface(i);
78  if (ie->isLoopback())
79  continue;
80  if (!ie->ipv4Data())
81  continue;
82  IPv4Address nextHopAddr = ie->ipv4Data()->getIPAddress();
83  if (nextHopAddr.isUnspecified())
84  continue; // if the address is not defined it isn't included in the global cache
85  // check if the entry exist
86  auto it = globalArpCache.find(nextHopAddr);
87  if (it != globalArpCache.end())
88  continue;
89  ARPCacheEntry *entry = new ARPCacheEntry();
90  entry->owner = this;
91  entry->ie = ie;
92  entry->macAddress = ie->getMacAddress();
93 
94  auto where = globalArpCache.insert(globalArpCache.begin(), std::make_pair(nextHopAddr, entry));
95  ASSERT(where->second == entry);
96  entry->myIter = where; // note: "inserting a new element into a map does not invalidate iterators that point to existing elements"
97  }
98  cModule *host = findContainingNode(this);
99  if (host != nullptr)
100  host->subscribe(NF_INTERFACE_IPv4CONFIG_CHANGED, this);
101  }
102 }
IPv4InterfaceData * ipv4Data() const
Definition: InterfaceEntry.h:221
IIPv4RoutingTable * rt
Definition: GlobalARP.h:70
Initialization of network-layer protocols, stage 3.
Definition: InitStages.h:84
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Local initializations.
Definition: InitStages.h:35
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
simsignal_t NF_INTERFACE_IPv4CONFIG_CHANGED
Definition: NotifierConsts.cc:53
IPv4Address getIPAddress() const
Definition: IPv4InterfaceData.h:177
IInterfaceTable * ift
Definition: GlobalARP.h:69
virtual bool isNodeUp()
Definition: GlobalARP.cc:181
static ARPCache globalArpCache
Definition: GlobalARP.h:66
bool isUp
Definition: GlobalARP.h:64
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
bool inet::GlobalARP::isNodeUp ( )
protectedvirtual

Referenced by initialize().

182 {
183  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
184  return !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
185 }
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Definition: NodeStatus.h:40
MACAddress inet::GlobalARP::mapMulticastAddress ( L3Address  addr)
protected
virtual int inet::GlobalARP::numInitStages ( ) const
inlineoverridevirtual
79 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::GlobalARP::processARPPacket ( ARPPacket arp)
protectedvirtual

Referenced by handleMessage().

188 {
189  EV << "ARP packet " << arp << " arrived, dropped\n";
190  delete arp;
191 }
void inet::GlobalARP::processSelfMessage ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

137 {
138  throw cRuntimeError("Model error: unexpected self message");
139 }
void inet::GlobalARP::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overridevirtual
222 {
223  Enter_Method_Silent();
224  // host associated. Link is up. Change the state to init.
225  if (signalID == NF_INTERFACE_IPv4CONFIG_CHANGED) {
226  const InterfaceEntryChangeDetails *iecd = check_and_cast<const InterfaceEntryChangeDetails *>(obj);
227  InterfaceEntry *ie = iecd->getInterfaceEntry();
228  // rebuild the arp cache
229  if (ie->isLoopback())
230  return;
231  auto it = globalArpCache.begin();
232  for ( ; it != globalArpCache.end(); ++it) {
233  if (it->second->ie == ie)
234  break;
235  }
236  ARPCacheEntry *entry = nullptr;
237  if (it == globalArpCache.end()) {
238  if (!ie->ipv4Data() || ie->ipv4Data()->getIPAddress().isUnspecified())
239  return; // if the address is not defined it isn't included in the global cache
240  entry = new ARPCacheEntry();
241  entry->owner = this;
242  entry->ie = ie;
243  }
244  else {
245  // actualize
246  entry = it->second;
247  ASSERT(entry->owner == this);
248  globalArpCache.erase(it);
249  if (!ie->ipv4Data() || ie->ipv4Data()->getIPAddress().isUnspecified()) {
250  delete entry;
251  return; // if the address is not defined it isn't included in the global cache
252  }
253  }
254  entry->macAddress = ie->getMacAddress();
255  IPv4Address ipAddr = ie->ipv4Data()->getIPAddress();
256  auto where = globalArpCache.insert(globalArpCache.begin(), std::make_pair(ipAddr, entry));
257  ASSERT(where->second == entry);
258  entry->myIter = where; // note: "inserting a new element into a map does not invalidate iterators that point to existing elements"
259  }
260 }
simsignal_t NF_INTERFACE_IPv4CONFIG_CHANGED
Definition: NotifierConsts.cc:53
static ARPCache globalArpCache
Definition: GlobalARP.h:66
MACAddress inet::GlobalARP::resolveL3Address ( const L3Address address,
const InterfaceEntry ie 
)
overridevirtual

Tries to resolve the given network address to a MAC address.

If the MAC address is not yet resolved it returns an unspecified address and starts an address resolution procedure. A signal is emitted when the address resolution procedure terminates.

Implements inet::IARP.

194 {
195  Enter_Method_Silent();
196 
197  IPv4Address addr = address.toIPv4();
198  ARPCache::const_iterator it = globalArpCache.find(addr);
199  if (it != globalArpCache.end())
200  return it->second->macAddress;
201 
202  throw cRuntimeError("GlobalARP does not support dynamic address resolution");
204 }
static ARPCache globalArpCache
Definition: GlobalARP.h:66
static const MACAddress UNSPECIFIED_ADDRESS
The unspecified MAC address, 00:00:00:00:00:00.
Definition: MACAddress.h:57
void inet::GlobalARP::start ( )
protectedvirtual

Referenced by handleOperationStage().

172 {
173  isUp = true;
174 }
bool isUp
Definition: GlobalARP.h:64
void inet::GlobalARP::stop ( )
protectedvirtual

Referenced by handleOperationStage().

177 {
178  isUp = false;
179 }
bool isUp
Definition: GlobalARP.h:64

Member Data Documentation

GlobalARP::ARPCache inet::GlobalARP::globalArpCache
staticprotected
int inet::GlobalARP::globalArpCacheRefCnt = 0
staticprotected

Referenced by GlobalARP(), and ~GlobalARP().

IInterfaceTable* inet::GlobalARP::ift = nullptr
protected

Referenced by GlobalARP(), and initialize().

bool inet::GlobalARP::isUp = false
protected

Referenced by handleMessage(), initialize(), start(), and stop().

IIPv4RoutingTable* inet::GlobalARP::rt = nullptr
protected

Referenced by GlobalARP(), and initialize().


The documentation for this class was generated from the following files: