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

This class provides an IArp implementation whithout exchanging packets. More...

#include <GlobalArp.h>

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

Classes

class  ArpCacheEntry
 

Public Types

typedef std::map< L3Address, ArpCacheEntry * > ArpCache
 

Public Member Functions

 GlobalArp ()
 
virtual ~GlobalArp ()
 
virtual int numInitStages () const override
 
- 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 ()
 

Static Public Member Functions

static MacAddress toMulticastMacAddress (Ipv4Address address)
 
static MacAddress toMulticastMacAddress (Ipv6Address address)
 

Protected Member Functions

void ensureCacheEntry (const L3Address &address, const NetworkInterface *networkInterface)
 
MacAddress mapUnicastAddress (L3Address address)
 
- 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

ModuleRefByPar< IInterfaceTableinterfaceTable
 
L3Address::AddressType addressType = static_cast<L3Address::AddressType>(-1)
 
- Protected Attributes inherited from inet::OperationalMixin< cSimpleModule >
State operationalState
 
simtime_t lastChange
 
Operation activeOperation
 
cMessage * activeOperationTimeout
 
cMessage * activeOperationExtraTimer
 

Static Protected Attributes

static ArpCache globalArpCache
 
static int globalArpCacheRefCnt = 0
 

IArp implementation

virtual void initialize (int stage) override
 
virtual void handleMessageWhenUp (cMessage *msg) override
 
virtual void handleSelfMessage (cMessage *msg)
 
virtual void handlePacket (Packet *packet)
 
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 L3Address getL3AddressFor (const MacAddress &addr) const override
 Returns the Layer 3 address for the given MAC address. More...
 
virtual MacAddress resolveL3Address (const L3Address &address, const NetworkInterface *networkInterface) override
 Tries to resolve the given network address to a MAC address. More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 

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

This class provides an IArp implementation whithout exchanging packets.

Member Typedef Documentation

◆ ArpCache

Constructor & Destructor Documentation

◆ GlobalArp()

inet::GlobalArp::GlobalArp ( )
33 {
34  if (++globalArpCacheRefCnt == 1) {
35  if (!globalArpCache.empty())
36  throw cRuntimeError("Global ARP cache not empty, model error in previous run?");
37  }
38 }

◆ ~GlobalArp()

inet::GlobalArp::~GlobalArp ( )
virtual
41 {
43  // delete my entries from the globalArpCache
44  for (auto it = globalArpCache.begin(); it != globalArpCache.end();) {
45  if (it->second->owner == this) {
46  auto cur = it++;
47  delete cur->second;
48  globalArpCache.erase(cur);
49  }
50  else
51  ++it;
52  }
53 }

Member Function Documentation

◆ ensureCacheEntry()

void inet::GlobalArp::ensureCacheEntry ( const L3Address address,
const NetworkInterface networkInterface 
)
protected
321 {
322  auto it = globalArpCache.find(address);
323  if (it == globalArpCache.end()) {
324  ArpCacheEntry *entry = new ArpCacheEntry();
325  entry->owner = this;
326  entry->networkInterface = networkInterface;
327  auto where = globalArpCache.insert(globalArpCache.begin(), std::make_pair(address, entry));
328  ASSERT(where->second == entry);
329  }
330 }

Referenced by initialize().

◆ getL3AddressFor()

L3Address inet::GlobalArp::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.

194 {
195  Enter_Method("getL3AddressFor");
196  switch (addressType) {
197 #ifdef INET_WITH_IPv4
198  case L3Address::IPv4: {
199  if (macAddress.isUnspecified())
201  for (ArpCache::const_iterator it = globalArpCache.begin(); it != globalArpCache.end(); it++)
202  if (it->second->networkInterface->getMacAddress() == macAddress && it->first.getType() == L3Address::IPv4)
203  return it->first;
205  }
206 #endif
207 #ifdef INET_WITH_IPv6
208  case L3Address::IPv6: {
209  if (macAddress.isUnspecified())
211  for (ArpCache::const_iterator it = globalArpCache.begin(); it != globalArpCache.end(); it++)
212  if (it->second->networkInterface->getMacAddress() == macAddress && it->first.getType() == L3Address::IPv6)
213  return it->first;
215  }
216 #endif
217  case L3Address::MAC:
218  return L3Address(macAddress);
219  case L3Address::MODULEID: {
220  if (macAddress.isUnspecified())
221  return ModuleIdAddress();
222  for (ArpCache::const_iterator it = globalArpCache.begin(); it != globalArpCache.end(); it++)
223  if (it->second->networkInterface->getMacAddress() == macAddress && it->first.getType() == L3Address::MODULEID)
224  return it->first;
225  return ModuleIdAddress();
226  }
227  case L3Address::MODULEPATH: {
228  if (macAddress.isUnspecified())
229  return ModulePathAddress();
230  for (ArpCache::const_iterator it = globalArpCache.begin(); it != globalArpCache.end(); it++)
231  if (it->second->networkInterface->getMacAddress() == macAddress && it->first.getType() == L3Address::MODULEPATH)
232  return it->first;
233  return ModulePathAddress();
234  }
235  default:
236  throw cRuntimeError("Unknown address type");
237  }
238 }

◆ handleCrashOperation()

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

Implements inet::OperationalMixin< cSimpleModule >.

140 {
141 }

◆ handleMessageWhenUp()

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

Implements inet::OperationalMixin< cSimpleModule >.

113 {
114  if (msg->isSelfMessage())
115  handleSelfMessage(msg);
116  else
117  handlePacket(check_and_cast<Packet *>(msg));
118 }

◆ handlePacket()

void inet::GlobalArp::handlePacket ( Packet packet)
protectedvirtual
126 {
127  EV << "Packet " << packet << " arrived, dropping it\n";
128  delete packet;
129 }

Referenced by handleMessageWhenUp().

◆ handleSelfMessage()

void inet::GlobalArp::handleSelfMessage ( cMessage *  msg)
protectedvirtual
121 {
122  throw cRuntimeError("Model error: unexpected self message");
123 }

Referenced by handleMessageWhenUp().

◆ handleStartOperation()

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

Implements inet::OperationalMixin< cSimpleModule >.

132 {
133 }

◆ handleStopOperation()

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

Implements inet::OperationalMixin< cSimpleModule >.

136 {
137 }

◆ initialize()

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

Reimplemented from inet::OperationalMixin< cSimpleModule >.

56 {
58 
59  if (stage == INITSTAGE_LOCAL) {
60  const char *addressTypeString = par("addressType");
61  if (!strcmp(addressTypeString, "ipv4"))
63  else if (!strcmp(addressTypeString, "ipv6"))
65  else if (!strcmp(addressTypeString, "mac"))
67  else if (!strcmp(addressTypeString, "modulepath"))
69  else if (!strcmp(addressTypeString, "moduleid"))
71  else
72  throw cRuntimeError("Unknown address type");
73  WATCH_PTRMAP(globalArpCache);
74  }
75  else if (stage == INITSTAGE_NETWORK_LAYER) {
76  interfaceTable.reference(this, "interfaceTableModule", true);
77  // register our addresses in the global cache
78  for (int i = 0; i < interfaceTable->getNumInterfaces(); i++) {
79  NetworkInterface *networkInterface = interfaceTable->getInterface(i);
80  if (!networkInterface->isLoopback()) {
81 #ifdef INET_WITH_IPv4
82  if (auto ipv4Data = networkInterface->findProtocolData<Ipv4InterfaceData>()) {
83  Ipv4Address ipv4Address = ipv4Data->getIPAddress();
84  if (!ipv4Address.isUnspecified())
85  ensureCacheEntry(ipv4Address, networkInterface);
86  }
87 #endif
88 #ifdef INET_WITH_IPv6
89  if (auto ipv6Data = networkInterface->findProtocolData<Ipv6InterfaceData>()) {
90  Ipv6Address ipv6Address = ipv6Data->getLinkLocalAddress();
91  if (!ipv6Address.isUnspecified())
92  ensureCacheEntry(ipv6Address, networkInterface);
93  }
94 #endif
95 #ifdef INET_WITH_NEXTHOP
96  if (auto genericData = networkInterface->findProtocolData<NextHopInterfaceData>()) {
97  L3Address address = genericData->getAddress();
98  if (!address.isUnspecified())
99  ensureCacheEntry(address, networkInterface);
100  }
101 #endif
102  }
103  }
104  cModule *node = findContainingNode(this);
105  if (node != nullptr) {
106  node->subscribe(interfaceIpv4ConfigChangedSignal, this);
107  node->subscribe(interfaceIpv6ConfigChangedSignal, this);
108  }
109  }
110 }

◆ isInitializeStage()

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

◆ isModuleStartStage()

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

◆ isModuleStopStage()

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

◆ mapUnicastAddress()

MacAddress inet::GlobalArp::mapUnicastAddress ( L3Address  address)
protected
156 {
157  switch (address.getType()) {
158 #ifdef INET_WITH_IPv4
159  case L3Address::IPv4: {
160  Ipv4Address ipv4Address = address.toIpv4();
161  auto it = globalArpCache.find(ipv4Address);
162  if (it != globalArpCache.end())
163  return it->second->networkInterface->getMacAddress();
164  throw cRuntimeError("GlobalArp does not support dynamic address resolution");
166  }
167 #endif
168 #ifdef INET_WITH_IPv6
169  case L3Address::IPv6: {
170  Ipv6Address ipv6Address = address.toIpv6();
171  auto it = globalArpCache.find(ipv6Address);
172  if (it != globalArpCache.end())
173  return it->second->networkInterface->getMacAddress();
174  throw cRuntimeError("GlobalArp does not support dynamic address resolution");
176  }
177 #endif
178  case L3Address::MAC:
179  return address.toMac();
180  case L3Address::MODULEID: {
181  auto networkInterface = check_and_cast<NetworkInterface *>(getSimulation()->getModule(address.toModuleId().getId()));
182  return networkInterface->getMacAddress();
183  }
184  case L3Address::MODULEPATH: {
185  auto networkInterface = check_and_cast<NetworkInterface *>(getSimulation()->getModule(address.toModulePath().getId()));
186  return networkInterface->getMacAddress();
187  }
188  default:
189  throw cRuntimeError("Unknown address type");
190  }
191 }

Referenced by resolveL3Address().

◆ numInitStages()

virtual int inet::GlobalArp::numInitStages ( ) const
inlineoverridevirtual
55 { return NUM_INIT_STAGES; }

◆ receiveSignal()

void inet::GlobalArp::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overridevirtual
241 {
242  Enter_Method("%s", cComponent::getSignalName(signalID));
243 
244  // host associated. Link is up. Change the state to init.
246  const NetworkInterfaceChangeDetails *iecd = check_and_cast<const NetworkInterfaceChangeDetails *>(obj);
247  NetworkInterface *networkInterface = iecd->getNetworkInterface();
248  if (networkInterface->isLoopback())
249  return;
250  auto it = globalArpCache.begin();
251  ArpCacheEntry *entry = nullptr;
252 #ifdef INET_WITH_IPv4
253  if (signalID == interfaceIpv4ConfigChangedSignal) {
254  for (; it != globalArpCache.end(); ++it) {
255  if (it->second->networkInterface == networkInterface && it->first.getType() == L3Address::IPv4)
256  break;
257  }
258  if (it == globalArpCache.end()) {
259  auto ipv4Data = networkInterface->findProtocolData<Ipv4InterfaceData>();
260  if (!ipv4Data || ipv4Data->getIPAddress().isUnspecified())
261  return; // if the address is not defined it isn't included in the global cache
262  entry = new ArpCacheEntry();
263  entry->owner = this;
264  entry->networkInterface = networkInterface;
265  }
266  else {
267  // actualize
268  entry = it->second;
269  ASSERT(entry->owner == this);
270  globalArpCache.erase(it);
271  auto ipv4Data = networkInterface->findProtocolData<Ipv4InterfaceData>();
272  if (!ipv4Data || ipv4Data->getIPAddress().isUnspecified()) {
273  delete entry;
274  return; // if the address is not defined it isn't included in the global cache
275  }
276  }
277  Ipv4Address ipv4Address = networkInterface->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
278  auto where = globalArpCache.insert(globalArpCache.begin(), std::make_pair(ipv4Address, entry));
279  ASSERT(where->second == entry);
280  }
281  else
282 #endif
283 #ifdef INET_WITH_IPv6
284  if (signalID == interfaceIpv6ConfigChangedSignal) {
285  for (; it != globalArpCache.end(); ++it) {
286  if (it->second->networkInterface == networkInterface && it->first.getType() == L3Address::IPv6)
287  break;
288  }
289  if (it == globalArpCache.end()) {
290  auto ipv6Data = networkInterface->findProtocolData<Ipv6InterfaceData>();
291  if (ipv6Data == nullptr || ipv6Data->getLinkLocalAddress().isUnspecified())
292  return; // if the address is not defined it isn't included in the global cache
293  entry = new ArpCacheEntry();
294  entry->owner = this;
295  entry->networkInterface = networkInterface;
296  }
297  else {
298  // actualize
299  entry = it->second;
300  ASSERT(entry->owner == this);
301  globalArpCache.erase(it);
302  auto ipv6Data = networkInterface->findProtocolData<Ipv6InterfaceData>();
303  if (ipv6Data == nullptr || ipv6Data->getLinkLocalAddress().isUnspecified()) {
304  delete entry;
305  return; // if the address is not defined it isn't included in the global cache
306  }
307  }
308  Ipv6Address ipv6Address = networkInterface->getProtocolData<Ipv6InterfaceData>()->getLinkLocalAddress();
309  auto where = globalArpCache.insert(globalArpCache.begin(), std::make_pair(ipv6Address, entry));
310  ASSERT(where->second == entry);
311  }
312  else
313 #endif
314  {}
315  }
316  else
317  throw cRuntimeError("Unknown signal");
318 }

◆ resolveL3Address()

MacAddress inet::GlobalArp::resolveL3Address ( const L3Address address,
const NetworkInterface 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.

144 {
145  Enter_Method("resolveL3Address");
146  if (address.isUnicast())
147  return mapUnicastAddress(address);
148  else if (address.isMulticast())
149  return address.mapToMulticastMacAddress();
150  else if (address.isBroadcast())
152  throw cRuntimeError("Address must be one of unicast, multicast, or broadcast");
153 }

◆ toMulticastMacAddress() [1/2]

static MacAddress inet::GlobalArp::toMulticastMacAddress ( Ipv4Address  address)
static

◆ toMulticastMacAddress() [2/2]

static MacAddress inet::GlobalArp::toMulticastMacAddress ( Ipv6Address  address)
static

Member Data Documentation

◆ addressType

L3Address::AddressType inet::GlobalArp::addressType = static_cast<L3Address::AddressType>(-1)
protected

Referenced by getL3AddressFor(), and initialize().

◆ globalArpCache

GlobalArp::ArpCache inet::GlobalArp::globalArpCache
staticprotected

◆ globalArpCacheRefCnt

int inet::GlobalArp::globalArpCacheRefCnt = 0
staticprotected

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

◆ interfaceTable

ModuleRefByPar<IInterfaceTable> inet::GlobalArp::interfaceTable
protected

Referenced by initialize().


The documentation for this class was generated from the following files:
inet::findContainingNode
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:31
inet::L3Address::MODULEID
@ MODULEID
Definition: L3Address.h:40
inet::GlobalArp::mapUnicastAddress
MacAddress mapUnicastAddress(L3Address address)
Definition: GlobalArp.cc:155
inet::ModuleStopOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:53
inet::OperationalMixin< cSimpleModule >::initialize
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
inet::ModuleStartOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:29
inet::INITSTAGE_NETWORK_LAYER
INET_API InitStage INITSTAGE_NETWORK_LAYER
Initialization of network layer protocols.
inet::L3Address::IPv4
@ IPv4
Definition: L3Address.h:35
inet::L3Address::MODULEPATH
@ MODULEPATH
Definition: L3Address.h:39
inet::GlobalArp::addressType
L3Address::AddressType addressType
Definition: GlobalArp.h:43
inet::GlobalArp::handlePacket
virtual void handlePacket(Packet *packet)
Definition: GlobalArp.cc:125
inet::Ipv6Address::UNSPECIFIED_ADDRESS
static const Ipv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: Ipv6Address.h:54
inet::GlobalArp::ensureCacheEntry
void ensureCacheEntry(const L3Address &address, const NetworkInterface *networkInterface)
Definition: GlobalArp.cc:320
inet::GlobalArp::globalArpCacheRefCnt
static int globalArpCacheRefCnt
Definition: GlobalArp.h:46
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::GlobalArp::handleSelfMessage
virtual void handleSelfMessage(cMessage *msg)
Definition: GlobalArp.cc:120
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::GlobalArp::globalArpCache
static ArpCache globalArpCache
Definition: GlobalArp.h:45
inet::L3Address::IPv6
@ IPv6
Definition: L3Address.h:36
inet::GlobalArp::interfaceTable
ModuleRefByPar< IInterfaceTable > interfaceTable
Definition: GlobalArp.h:42
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::L3Address::MAC
@ MAC
Definition: L3Address.h:38
inet::interfaceIpv4ConfigChangedSignal
simsignal_t interfaceIpv4ConfigChangedSignal
Definition: Simsignals.cc:35
inet::MacAddress::BROADCAST_ADDRESS
static const MacAddress BROADCAST_ADDRESS
The broadcast MAC address, ff:ff:ff:ff:ff:ff.
Definition: MacAddress.h:34
inet::MacAddress::UNSPECIFIED_ADDRESS
static const MacAddress UNSPECIFIED_ADDRESS
The unspecified MAC address, 00:00:00:00:00:00.
Definition: MacAddress.h:31
inet::interfaceIpv6ConfigChangedSignal
simsignal_t interfaceIpv6ConfigChangedSignal
Definition: Simsignals.cc:36