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

Implements the IPv4 protocol. More...

#include <IPv4.h>

Inheritance diagram for inet::IPv4:
inet::QueueBase inet::INetfilter inet::ILifecycle inet::INetworkProtocol inet::AbstractQueue

Classes

class  QueuedDatagramForHook
 Represents an IPv4Datagram, queued by a Hook. More...
 

Public Types

typedef std::map< IPv4Address, cPacketQueue > PendingPackets
 

Public Member Functions

 IPv4 ()
 
virtual ~IPv4 ()
 
virtual void registerHook (int priority, IHook *hook) override
 registers a Hook to be executed during datagram processing More...
 
virtual void unregisterHook (int priority, IHook *hook) override
 unregisters a Hook to be executed during datagram processing More...
 
void dropQueuedDatagram (const INetworkDatagram *datagram) override
 drop a previously queued datagram More...
 
void reinjectQueuedDatagram (const INetworkDatagram *datagram) override
 re-injects a previously queued datagram More...
 
void sendOnTransportOutGateByProtocolId (cPacket *packet, int protocolId)
 send packet on transportOut gate specified by protocolId More...
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 ILifecycle method. More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 cListener method More...
 
- Public Member Functions inherited from inet::QueueBase
 QueueBase ()
 
- Public Member Functions inherited from inet::AbstractQueue
 AbstractQueue ()
 
virtual ~AbstractQueue ()
 
- Public Member Functions inherited from inet::INetfilter
virtual ~INetfilter ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::INetworkProtocol
virtual ~INetworkProtocol ()
 

Protected Types

typedef std::multimap< int, IHook * > HookList
 
typedef std::list< QueuedDatagramForHookDatagramQueueForHooks
 

Protected Member Functions

virtual const InterfaceEntrygetSourceInterfaceFrom (cPacket *packet)
 
virtual const InterfaceEntrygetShortestPathInterfaceToSource (IPv4Datagram *datagram)
 
virtual void refreshDisplay () const override
 
void arpResolutionCompleted (IARP::Notification *entry)
 
void arpResolutionTimedOut (IARP::Notification *entry)
 
virtual IPv4Datagramencapsulate (cPacket *transportPacket, IPv4ControlInfo *controlInfo)
 Encapsulate packet coming from higher layers into IPv4Datagram, using the given control info. More...
 
virtual IPv4DatagramcreateIPv4Datagram (const char *name)
 Creates a blank IPv4 datagram. More...
 
virtual void handleIncomingDatagram (IPv4Datagram *datagram, const InterfaceEntry *fromIE)
 Handle IPv4Datagram messages arriving from lower layer. More...
 
virtual void preroutingFinish (IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
 
virtual void handlePacketFromHL (cPacket *packet)
 Handle messages (typically packets to be send in IPv4) from transport or ICMP. More...
 
virtual void handlePacketFromARP (cPacket *packet)
 TODO. More...
 
virtual void datagramLocalOut (IPv4Datagram *datagram, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
 Routes and sends datagram received from higher layers. More...
 
virtual void handleIncomingARPPacket (ARPPacket *packet, const InterfaceEntry *fromIE)
 Handle incoming ARP packets by sending them over to ARP. More...
 
virtual void handleIncomingICMP (ICMPMessage *packet)
 Handle incoming ICMP messages. More...
 
virtual void routeUnicastPacket (IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address requestedNextHopAddress)
 Performs unicast routing. More...
 
void routeUnicastPacketFinish (IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
 
virtual void routeLocalBroadcastPacket (IPv4Datagram *datagram, const InterfaceEntry *destIE)
 Broadcasts the datagram on the specified interface. More...
 
virtual const InterfaceEntrydetermineOutgoingInterfaceForMulticastDatagram (IPv4Datagram *datagram, const InterfaceEntry *multicastIFOption)
 Determines the output interface for the given multicast datagram. More...
 
virtual void forwardMulticastPacket (IPv4Datagram *datagram, const InterfaceEntry *fromIE)
 Forwards packets to all multicast destinations, using fragmentAndSend(). More...
 
virtual void reassembleAndDeliver (IPv4Datagram *datagram)
 Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL(). More...
 
virtual void reassembleAndDeliverFinish (IPv4Datagram *datagram)
 
virtual cPacket * decapsulate (IPv4Datagram *datagram)
 Decapsulate and return encapsulated packet after attaching IPv4ControlInfo. More...
 
virtual void fragmentPostRouting (IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
 Call PostRouting Hook and continue with fragmentAndSend() if accepted. More...
 
virtual void fragmentAndSend (IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
 Fragment packet if needed, then send it to the selected interface using sendDatagramToOutput(). More...
 
virtual void sendDatagramToOutput (IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
 Send datagram on the given interface. More...
 
virtual MACAddress resolveNextHopMacAddress (cPacket *packet, IPv4Address nextHopAddr, const InterfaceEntry *destIE)
 
virtual void sendPacketToIeee802NIC (cPacket *packet, const InterfaceEntry *ie, const MACAddress &macAddress, int etherType)
 
virtual void sendPacketToNIC (cPacket *packet, const InterfaceEntry *ie)
 
virtual int numInitStages () const override
 
virtual void initialize (int stage) override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void endService (cPacket *packet) override
 Processing of IPv4 datagrams. More...
 
IHook::Result datagramPreRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
 called before a packet arriving from the network is routed More...
 
IHook::Result datagramForwardHook (INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
 called before a packet arriving from the network is delivered via the network More...
 
IHook::Result datagramPostRoutingHook (INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
 called before a packet is delivered via the network More...
 
IHook::Result datagramLocalInHook (INetworkDatagram *datagram, const InterfaceEntry *inIE)
 called before a packet arriving from the network is delivered locally More...
 
IHook::Result datagramLocalOutHook (INetworkDatagram *datagram, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
 called before a packet arriving locally is delivered More...
 
virtual bool isNodeUp ()
 
virtual void stop ()
 
virtual void start ()
 
virtual void flush ()
 
- Protected Member Functions inherited from inet::QueueBase
virtual void initialize () override
 
virtual void arrival (cPacket *msg) override
 Functions to (re)define behaviour. More...
 
virtual cPacket * arrivalWhenIdle (cPacket *msg) override
 Called when a message arrives at the module when the queue is empty. More...
 
virtual simtime_t startService (cPacket *msg) override
 Called when a message starts service, and should return the service time. More...
 
- Protected Member Functions inherited from inet::AbstractQueue
virtual cPacket * cancelService ()
 If a message is under service, aborts its service and returns the message. More...
 

Protected Attributes

IIPv4RoutingTablert = nullptr
 
IInterfaceTableift = nullptr
 
IARParp = nullptr
 
ICMPicmp = nullptr
 
cGate * arpInGate = nullptr
 
cGate * arpOutGate = nullptr
 
int transportInGateBaseId = -1
 
int queueOutGateBaseId = -1
 
int defaultTimeToLive = -1
 
int defaultMCTimeToLive = -1
 
simtime_t fragmentTimeoutTime
 
bool forceBroadcast = false
 
bool useProxyARP = false
 
bool isUp = false
 
long curFragmentId = -1
 
IPv4FragBuf fragbuf
 
simtime_t lastCheckTime
 
ProtocolMapping mapping
 
PendingPackets pendingPackets
 
int numMulticast = 0
 
int numLocalDeliver = 0
 
int numDropped = 0
 
int numUnroutable = 0
 
int numForwarded = 0
 
HookList hooks
 
DatagramQueueForHooks queuedDatagramsForHooks
 
- Protected Attributes inherited from inet::QueueBase
simtime_t delay
 
- Protected Attributes inherited from inet::AbstractQueue
cPacketQueue queue
 The queue. More...
 

Detailed Description

Implements the IPv4 protocol.

Member Typedef Documentation

typedef std::multimap<int, IHook *> inet::IPv4::HookList
protected
typedef std::map<IPv4Address, cPacketQueue> inet::IPv4::PendingPackets

Constructor & Destructor Documentation

inet::IPv4::IPv4 ( )
47  :
48  isUp(true)
49 {
50 }
bool isUp
Definition: IPv4.h:83
inet::IPv4::~IPv4 ( )
virtual
53 {
54  flush();
55 }
virtual void flush()
Definition: IPv4.cc:1087

Member Function Documentation

void inet::IPv4::arpResolutionCompleted ( IARP::Notification entry)
protected

Referenced by receiveSignal().

839 {
840  if (entry->l3Address.getType() != L3Address::IPv4)
841  return;
842  auto it = pendingPackets.find(entry->l3Address.toIPv4());
843  if (it != pendingPackets.end()) {
844  cPacketQueue& packetQueue = it->second;
845  EV << "ARP resolution completed for " << entry->l3Address << ". Sending " << packetQueue.getLength()
846  << " waiting packets from the queue\n";
847 
848  while (!packetQueue.isEmpty()) {
849  cPacket *msg = packetQueue.pop();
850  EV << "Sending out queued packet " << msg << "\n";
851  sendPacketToIeee802NIC(msg, entry->ie, entry->macAddress, ETHERTYPE_IPv4);
852  }
853  pendingPackets.erase(it);
854  }
855 }
PendingPackets pendingPackets
Definition: IPv4.h:90
virtual void sendPacketToIeee802NIC(cPacket *packet, const InterfaceEntry *ie, const MACAddress &macAddress, int etherType)
Definition: IPv4.cc:890
Definition: Ieee802Ctrl_m.h:115
Definition: L3Address.h:46
void inet::IPv4::arpResolutionTimedOut ( IARP::Notification entry)
protected

Referenced by receiveSignal().

858 {
859  if (entry->l3Address.getType() != L3Address::IPv4)
860  return;
861  auto it = pendingPackets.find(entry->l3Address.toIPv4());
862  if (it != pendingPackets.end()) {
863  cPacketQueue& packetQueue = it->second;
864  EV << "ARP resolution failed for " << entry->l3Address << ", dropping " << packetQueue.getLength() << " packets\n";
865  for (int i = 0; i < packetQueue.getLength(); i++) {
866  auto packet = packetQueue.get(i);
868  }
869  packetQueue.clear();
870  pendingPackets.erase(it);
871  }
872 }
PendingPackets pendingPackets
Definition: IPv4.h:90
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
Definition: L3Address.h:46
IPv4Datagram * inet::IPv4::createIPv4Datagram ( const char *  name)
protectedvirtual

Creates a blank IPv4 datagram.

Override when subclassing IPv4Datagram is needed

Referenced by encapsulate().

797 {
798  return new IPv4Datagram(name);
799 }
INetfilter::IHook::Result inet::IPv4::datagramForwardHook ( INetworkDatagram datagram,
const InterfaceEntry inIE,
const InterfaceEntry *&  outIE,
L3Address nextHopAddr 
)
protected

called before a packet arriving from the network is delivered via the network

Referenced by routeUnicastPacket().

1006 {
1007  for (auto & elem : hooks) {
1008  IHook::Result r = elem.second->datagramForwardHook(datagram, inIE, outIE, nextHopAddr);
1009  switch (r) {
1011  break; // continue iteration
1012 
1014  delete datagram;
1015  return r;
1016 
1018  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(dynamic_cast<IPv4Datagram *>(datagram), inIE, outIE, nextHopAddr.toIPv4(), INetfilter::IHook::FORWARD));
1019  return r;
1020 
1022  return r;
1023 
1024  default:
1025  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1026  }
1027  }
1029 }
doesn&#39;t allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:51
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
HookList hooks
Definition: IPv4.h:101
Result
Definition: INetfilter.h:49
doesn&#39;t allow datagram to pass to next hook, but won&#39;t be deleted
Definition: INetfilter.h:53
Definition: INetfilter.h:44
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:52
INetfilter::IHook::Result inet::IPv4::datagramLocalInHook ( INetworkDatagram datagram,
const InterfaceEntry inIE 
)
protected

called before a packet arriving from the network is delivered locally

Referenced by reassembleAndDeliver().

1114 {
1115  for (auto & elem : hooks) {
1116  IHook::Result r = elem.second->datagramLocalInHook(datagram, inIE);
1117  switch (r) {
1119  break; // continue iteration
1120 
1122  delete datagram;
1123  return r;
1124 
1125  case INetfilter::IHook::QUEUE: {
1126  IPv4Datagram *dgram = check_and_cast<IPv4Datagram *>(datagram);
1127  if (dgram->getOwner() != this)
1128  throw cRuntimeError("Model error: netfilter hook changed the owner of queued datagram '%s'", dgram->getFullName());
1129  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(dgram, inIE, nullptr, IPv4Address::UNSPECIFIED_ADDRESS, INetfilter::IHook::LOCALIN));
1130  return r;
1131  }
1132 
1134  return r;
1135 
1136  default:
1137  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1138  }
1139  }
1141 }
doesn&#39;t allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:51
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
Definition: INetfilter.h:43
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
HookList hooks
Definition: IPv4.h:101
Result
Definition: INetfilter.h:49
doesn&#39;t allow datagram to pass to next hook, but won&#39;t be deleted
Definition: INetfilter.h:53
static const IPv4Address UNSPECIFIED_ADDRESS
0.0.0.0
Definition: IPv4Address.h:102
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:52
void inet::IPv4::datagramLocalOut ( IPv4Datagram datagram,
const InterfaceEntry destIE,
IPv4Address  nextHopAddr 
)
protectedvirtual

Routes and sends datagram received from higher layers.

Invokes datagramLocalOutHook(), then routePacket().

Referenced by handlePacketFromHL(), and reinjectQueuedDatagram().

338 {
339  IPv4ControlInfo *controlInfo = check_and_cast_nullable<IPv4ControlInfo *>(datagram->removeControlInfo());
340  bool multicastLoop = true;
341  if (controlInfo != nullptr) {
342  multicastLoop = controlInfo->getMulticastLoop();
343  delete controlInfo;
344  }
345 
346  // send
347  IPv4Address& destAddr = datagram->getDestAddress();
348 
349  EV_DETAIL << "Sending datagram " << datagram << " with destination = " << destAddr << "\n";
350 
351  if (datagram->getDestAddress().isMulticast()) {
352  destIE = determineOutgoingInterfaceForMulticastDatagram(datagram, destIE);
353 
354  // loop back a copy
355  if (multicastLoop && (!destIE || !destIE->isLoopback())) {
356  const InterfaceEntry *loopbackIF = ift->getFirstLoopbackInterface();
357  if (loopbackIF)
358  fragmentPostRouting(datagram->dup(), loopbackIF, destAddr);
359  }
360 
361  if (destIE) {
362  numMulticast++;
363  fragmentPostRouting(datagram, destIE, destAddr);
364  }
365  else {
366  EV_ERROR << "No multicast interface, packet dropped\n";
367  numUnroutable++;
369  delete datagram;
370  }
371  }
372  else { // unicast and broadcast
373  // check for local delivery
374  if (rt->isLocalAddress(destAddr)) {
375  EV_INFO << "Delivering " << datagram << " locally.\n";
376  if (destIE && !destIE->isLoopback()) {
377  EV_DETAIL << "datagram destination address is local, ignoring destination interface specified in the control info\n";
378  destIE = nullptr;
379  }
380  if (!destIE)
381  destIE = ift->getFirstLoopbackInterface();
382  ASSERT(destIE);
383  routeUnicastPacket(datagram, nullptr, destIE, destAddr);
384  }
385  else if (destAddr.isLimitedBroadcastAddress() || rt->isLocalBroadcastAddress(destAddr))
386  routeLocalBroadcastPacket(datagram, destIE);
387  else
388  routeUnicastPacket(datagram, nullptr, destIE, requestedNextHopAddress);
389  }
390 }
virtual bool isLocalBroadcastAddress(const IPv4Address &dest) const =0
Checks if the address is a local network broadcast address, i.e.
int numMulticast
Definition: IPv4.h:93
IIPv4RoutingTable * rt
Definition: IPv4.h:66
virtual const InterfaceEntry * determineOutgoingInterfaceForMulticastDatagram(IPv4Datagram *datagram, const InterfaceEntry *multicastIFOption)
Determines the output interface for the given multicast datagram.
Definition: IPv4.cc:398
virtual bool isLocalAddress(const IPv4Address &dest) const =0
Checks if the address is a local one, i.e.
virtual InterfaceEntry * getFirstLoopbackInterface() const =0
Returns the first interface with the isLoopback flag set.
virtual void routeUnicastPacket(IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address requestedNextHopAddress)
Performs unicast routing.
Definition: IPv4.cc:425
IInterfaceTable * ift
Definition: IPv4.h:67
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
virtual void fragmentPostRouting(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Call PostRouting Hook and continue with fragmentAndSend() if accepted.
Definition: IPv4.cc:669
int numUnroutable
Definition: IPv4.h:96
virtual void routeLocalBroadcastPacket(IPv4Datagram *datagram, const InterfaceEntry *destIE)
Broadcasts the datagram on the specified interface.
Definition: IPv4.cc:479
INetfilter::IHook::Result inet::IPv4::datagramLocalOutHook ( INetworkDatagram datagram,
const InterfaceEntry *&  outIE,
L3Address nextHopAddr 
)
protected

called before a packet arriving locally is delivered

Referenced by handlePacketFromHL().

1144 {
1145  for (auto & elem : hooks) {
1146  IHook::Result r = elem.second->datagramLocalOutHook(datagram, outIE, nextHopAddr);
1147  switch (r) {
1149  break; // continue iteration
1150 
1152  delete datagram;
1153  return r;
1154 
1156  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(dynamic_cast<IPv4Datagram *>(datagram), nullptr, outIE, nextHopAddr.toIPv4(), INetfilter::IHook::LOCALOUT));
1157  return r;
1158 
1160  return r;
1161 
1162  default:
1163  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1164  }
1165  }
1167 }
doesn&#39;t allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:51
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
Definition: INetfilter.h:46
HookList hooks
Definition: IPv4.h:101
Result
Definition: INetfilter.h:49
doesn&#39;t allow datagram to pass to next hook, but won&#39;t be deleted
Definition: INetfilter.h:53
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:52
INetfilter::IHook::Result inet::IPv4::datagramPostRoutingHook ( INetworkDatagram datagram,
const InterfaceEntry inIE,
const InterfaceEntry *&  outIE,
L3Address nextHopAddr 
)
protected

called before a packet is delivered via the network

Referenced by fragmentPostRouting().

1032 {
1033  for (auto & elem : hooks) {
1034  IHook::Result r = elem.second->datagramPostRoutingHook(datagram, inIE, outIE, nextHopAddr);
1035  switch (r) {
1037  break; // continue iteration
1038 
1040  delete datagram;
1041  return r;
1042 
1044  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(dynamic_cast<IPv4Datagram *>(datagram), inIE, outIE, nextHopAddr.toIPv4(), INetfilter::IHook::POSTROUTING));
1045  return r;
1046 
1048  return r;
1049 
1050  default:
1051  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1052  }
1053  }
1055 }
doesn&#39;t allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:51
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
Definition: INetfilter.h:45
HookList hooks
Definition: IPv4.h:101
Result
Definition: INetfilter.h:49
doesn&#39;t allow datagram to pass to next hook, but won&#39;t be deleted
Definition: INetfilter.h:53
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:52
INetfilter::IHook::Result inet::IPv4::datagramPreRoutingHook ( INetworkDatagram datagram,
const InterfaceEntry inIE,
const InterfaceEntry *&  outIE,
L3Address nextHopAddr 
)
protected

called before a packet arriving from the network is routed

Referenced by handleIncomingDatagram().

980 {
981  for (auto & elem : hooks) {
982  IHook::Result r = elem.second->datagramPreRoutingHook(datagram, inIE, outIE, nextHopAddr);
983  switch (r) {
985  break; // continue iteration
986 
988  delete datagram;
989  return r;
990 
992  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(dynamic_cast<IPv4Datagram *>(datagram), inIE, outIE, nextHopAddr.toIPv4(), INetfilter::IHook::PREROUTING));
993  return r;
994 
996  return r;
997 
998  default:
999  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1000  }
1001  }
1003 }
doesn&#39;t allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:51
Definition: INetfilter.h:42
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
HookList hooks
Definition: IPv4.h:101
Result
Definition: INetfilter.h:49
doesn&#39;t allow datagram to pass to next hook, but won&#39;t be deleted
Definition: INetfilter.h:53
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:52
cPacket * inet::IPv4::decapsulate ( IPv4Datagram datagram)
protectedvirtual

Decapsulate and return encapsulated packet after attaching IPv4ControlInfo.

Referenced by reassembleAndDeliverFinish().

646 {
647  // decapsulate transport packet
648  const InterfaceEntry *fromIE = getSourceInterfaceFrom(datagram);
649  cPacket *packet = datagram->decapsulate();
650 
651  // create and fill in control info
652  IPv4ControlInfo *controlInfo = new IPv4ControlInfo();
653  controlInfo->setProtocol(datagram->getTransportProtocol());
654  controlInfo->setSrcAddr(datagram->getSrcAddress());
655  controlInfo->setDestAddr(datagram->getDestAddress());
656  controlInfo->setTypeOfService(datagram->getTypeOfService());
657  controlInfo->setInterfaceId(fromIE ? fromIE->getInterfaceId() : -1);
658  controlInfo->setTimeToLive(datagram->getTimeToLive());
659 
660  // original IPv4 datagram might be needed in upper layers to send back ICMP error message
661  controlInfo->setOrigDatagram(datagram);
662 
663  // attach control info
664  packet->setControlInfo(controlInfo);
665 
666  return packet;
667 }
virtual const InterfaceEntry * getSourceInterfaceFrom(cPacket *packet)
Definition: IPv4.cc:159
const InterfaceEntry * inet::IPv4::determineOutgoingInterfaceForMulticastDatagram ( IPv4Datagram datagram,
const InterfaceEntry multicastIFOption 
)
protectedvirtual

Determines the output interface for the given multicast datagram.

Referenced by datagramLocalOut().

399 {
400  const InterfaceEntry *ie = nullptr;
401  if (multicastIFOption) {
402  ie = multicastIFOption;
403  EV_DETAIL << "multicast packet routed by socket option via output interface " << ie->getName() << "\n";
404  }
405  if (!ie) {
406  IPv4Route *route = rt->findBestMatchingRoute(datagram->getDestAddress());
407  if (route)
408  ie = route->getInterface();
409  if (ie)
410  EV_DETAIL << "multicast packet routed by routing table via output interface " << ie->getName() << "\n";
411  }
412  if (!ie) {
413  ie = rt->getInterfaceByAddress(datagram->getSrcAddress());
414  if (ie)
415  EV_DETAIL << "multicast packet routed by source address via output interface " << ie->getName() << "\n";
416  }
417  if (!ie) {
419  if (ie)
420  EV_DETAIL << "multicast packet routed via the first multicast interface " << ie->getName() << "\n";
421  }
422  return ie;
423 }
virtual InterfaceEntry * getInterfaceByAddress(const IPv4Address &address) const =0
Returns an interface given by its address.
IIPv4RoutingTable * rt
Definition: IPv4.h:66
virtual InterfaceEntry * getFirstMulticastInterface() const =0
Returns the first multicast capable interface.
IInterfaceTable * ift
Definition: IPv4.h:67
InterfaceEntry * getInterface() const override
Next hop interface.
Definition: IPv4Route.h:114
virtual IPv4Route * findBestMatchingRoute(const IPv4Address &dest) const =0
The routing function.
void inet::IPv4::dropQueuedDatagram ( const INetworkDatagram datagram)
overridevirtual

drop a previously queued datagram

Implements inet::INetfilter.

930 {
931  Enter_Method("dropQueuedDatagram()");
932  for (auto iter = queuedDatagramsForHooks.begin(); iter != queuedDatagramsForHooks.end(); iter++) {
933  if (iter->datagram == datagram) {
934  delete datagram;
935  queuedDatagramsForHooks.erase(iter);
936  return;
937  }
938  }
939 }
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
IPv4Datagram * inet::IPv4::encapsulate ( cPacket *  transportPacket,
IPv4ControlInfo controlInfo 
)
protectedvirtual

Encapsulate packet coming from higher layers into IPv4Datagram, using the given control info.

Override if you subclassed controlInfo and/or want to add options etc to the datagram.

Referenced by handlePacketFromHL().

749 {
750  IPv4Datagram *datagram = createIPv4Datagram(transportPacket->getName());
751  datagram->setByteLength(IP_HEADER_BYTES);
752  datagram->encapsulate(transportPacket);
753 
754  // set source and destination address
755  IPv4Address dest = controlInfo->getDestAddr();
756  datagram->setDestAddress(dest);
757 
758  IPv4Address src = controlInfo->getSrcAddr();
759 
760  // when source address was given, use it; otherwise it'll get the address
761  // of the outgoing interface after routing
762  if (!src.isUnspecified()) {
763  // if interface parameter does not match existing interface, do not send datagram
764  if (rt->getInterfaceByAddress(src) == nullptr)
765  throw cRuntimeError("Wrong source address %s in (%s)%s: no interface with such address",
766  src.str().c_str(), transportPacket->getClassName(), transportPacket->getFullName());
767 
768  datagram->setSrcAddress(src);
769  }
770 
771  // set other fields
772  datagram->setTypeOfService(controlInfo->getTypeOfService());
773 
774  datagram->setIdentification(curFragmentId++);
775  datagram->setMoreFragments(false);
776  datagram->setDontFragment(controlInfo->getDontFragment());
777  datagram->setFragmentOffset(0);
778 
779  short ttl;
780  if (controlInfo->getTimeToLive() > 0)
781  ttl = controlInfo->getTimeToLive();
782  else if (datagram->getDestAddress().isLinkLocalMulticast())
783  ttl = 1;
784  else if (datagram->getDestAddress().isMulticast())
785  ttl = defaultMCTimeToLive;
786  else
787  ttl = defaultTimeToLive;
788  datagram->setTimeToLive(ttl);
789  datagram->setTransportProtocol(controlInfo->getProtocol());
790 
791  // setting IPv4 options is currently not supported
792 
793  return datagram;
794 }
virtual InterfaceEntry * getInterfaceByAddress(const IPv4Address &address) const =0
Returns an interface given by its address.
const int IP_HEADER_BYTES
Definition: IPv4Datagram_m.h:41
IIPv4RoutingTable * rt
Definition: IPv4.h:66
int defaultMCTimeToLive
Definition: IPv4.h:77
virtual IPv4Datagram * createIPv4Datagram(const char *name)
Creates a blank IPv4 datagram.
Definition: IPv4.cc:796
long curFragmentId
Definition: IPv4.h:84
virtual void setDestAddress(const IPv4Address &destAddress)
int defaultTimeToLive
Definition: IPv4.h:76
uint8_t ttl
Definition: TCP_NSC.cc:87
void inet::IPv4::endService ( cPacket *  packet)
overrideprotectedvirtual

Processing of IPv4 datagrams.

Called when a datagram reaches the front of the queue.

Implements inet::AbstractQueue.

Referenced by handleMessage().

135 {
136  if (!isUp) {
137  EV_ERROR << "IPv4 is down -- discarding message\n";
138  delete packet;
139  return;
140  }
141  if (packet->getArrivalGate()->isName("transportIn")) { //TODO packet->getArrivalGate()->getBaseId() == transportInGateBaseId
142  handlePacketFromHL(packet);
143  }
144  else if (packet->getArrivalGate() == arpInGate) {
145  handlePacketFromARP(packet);
146  }
147  else { // from network
148  EV_INFO << "Received " << packet << " from network.\n";
149  const InterfaceEntry *fromIE = getSourceInterfaceFrom(packet);
150  if (auto arpPacket = dynamic_cast<ARPPacket *>(packet))
151  handleIncomingARPPacket(arpPacket, fromIE);
152  else if (auto dgram = dynamic_cast<IPv4Datagram *>(packet))
153  handleIncomingDatagram(dgram, fromIE);
154  else
155  throw cRuntimeError(packet, "Unexpected packet type");
156  }
157 }
cGate * arpInGate
Definition: IPv4.h:70
bool isUp
Definition: IPv4.h:83
virtual void handlePacketFromARP(cPacket *packet)
TODO.
Definition: IPv4.cc:328
virtual void handleIncomingARPPacket(ARPPacket *packet, const InterfaceEntry *fromIE)
Handle incoming ARP packets by sending them over to ARP.
Definition: IPv4.cc:262
virtual void handlePacketFromHL(cPacket *packet)
Handle messages (typically packets to be send in IPv4) from transport or ICMP.
Definition: IPv4.cc:298
virtual void handleIncomingDatagram(IPv4Datagram *datagram, const InterfaceEntry *fromIE)
Handle IPv4Datagram messages arriving from lower layer.
Definition: IPv4.cc:165
virtual const InterfaceEntry * getSourceInterfaceFrom(cPacket *packet)
Definition: IPv4.cc:159
void inet::IPv4::flush ( )
protectedvirtual

Referenced by stop(), and ~IPv4().

1088 {
1089  delete cancelService();
1090  EV_DEBUG << "IPv4::flush(): packets in queue: " << queue.str() << endl;
1091  queue.clear();
1092 
1093  EV_DEBUG << "IPv4::flush(): pending packets:\n";
1094  for (auto & elem : pendingPackets) {
1095  EV_DEBUG << "IPv4::flush(): " << elem.first << ": " << elem.second.str() << endl;
1096  elem.second.clear();
1097  }
1098  pendingPackets.clear();
1099 
1100  EV_DEBUG << "IPv4::flush(): packets in hooks: " << queuedDatagramsForHooks.size() << endl;
1101  for (auto & elem : queuedDatagramsForHooks) {
1102  delete elem.datagram;
1103  }
1104  queuedDatagramsForHooks.clear();
1105 }
PendingPackets pendingPackets
Definition: IPv4.h:90
virtual cPacket * cancelService()
If a message is under service, aborts its service and returns the message.
Definition: AbstractQueue.cc:81
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
cPacketQueue queue
The queue.
Definition: AbstractQueue.h:48
void inet::IPv4::forwardMulticastPacket ( IPv4Datagram datagram,
const InterfaceEntry fromIE 
)
protectedvirtual

Forwards packets to all multicast destinations, using fragmentAndSend().

Referenced by preroutingFinish().

508 {
509  ASSERT(fromIE);
510  const IPv4Address& srcAddr = datagram->getSrcAddress();
511  const IPv4Address& destAddr = datagram->getDestAddress();
512  ASSERT(destAddr.isMulticast());
513  ASSERT(!destAddr.isLinkLocalMulticast());
514 
515  EV_INFO << "Forwarding multicast datagram `" << datagram->getName() << "' with dest=" << destAddr << "\n";
516 
517  numMulticast++;
518 
519  const IPv4MulticastRoute *route = rt->findBestMatchingMulticastRoute(srcAddr, destAddr);
520  if (!route) {
521  EV_WARN << "Multicast route does not exist, try to add.\n";
522  emit(NF_IPv4_NEW_MULTICAST, datagram);
523 
524  // read new record
525  route = rt->findBestMatchingMulticastRoute(srcAddr, destAddr);
526 
527  if (!route) {
528  EV_ERROR << "No route, packet dropped.\n";
529  numUnroutable++;
531  delete datagram;
532  return;
533  }
534  }
535 
536  if (route->getInInterface() && fromIE != route->getInInterface()->getInterface()) {
537  EV_ERROR << "Did not arrive on input interface, packet dropped.\n";
538  emit(NF_IPv4_DATA_ON_NONRPF, datagram);
539  numDropped++;
541  delete datagram;
542  }
543  // backward compatible: no parent means shortest path interface to source (RPB routing)
544  else if (!route->getInInterface() && fromIE != getShortestPathInterfaceToSource(datagram)) {
545  EV_ERROR << "Did not arrive on shortest path, packet dropped.\n";
546  numDropped++;
548  delete datagram;
549  }
550  else {
551  emit(NF_IPv4_DATA_ON_RPF, datagram); // forwarding hook
552 
553  numForwarded++;
554  // copy original datagram for multiple destinations
555  for (unsigned int i = 0; i < route->getNumOutInterfaces(); i++) {
556  IPv4MulticastRoute::OutInterface *outInterface = route->getOutInterface(i);
557  const InterfaceEntry *destIE = outInterface->getInterface();
558  if (destIE != fromIE && outInterface->isEnabled()) {
559  int ttlThreshold = destIE->ipv4Data()->getMulticastTtlThreshold();
560  if (datagram->getTimeToLive() <= ttlThreshold)
561  EV_WARN << "Not forwarding to " << destIE->getName() << " (ttl treshold reached)\n";
562  else if (outInterface->isLeaf() && !destIE->ipv4Data()->hasMulticastListener(destAddr))
563  EV_WARN << "Not forwarding to " << destIE->getName() << " (no listeners)\n";
564  else {
565  EV_DETAIL << "Forwarding to " << destIE->getName() << "\n";
566  fragmentPostRouting(datagram->dup(), destIE, destAddr);
567  }
568  }
569  }
570 
571  emit(NF_IPv4_MDATA_REGISTER, datagram); // postRouting hook
572 
573  // only copies sent, delete original datagram
574  delete datagram;
575  }
576 }
virtual const InterfaceEntry * getShortestPathInterfaceToSource(IPv4Datagram *datagram)
Definition: IPv4.cc:502
simsignal_t NF_IPv4_DATA_ON_RPF
Definition: NotifierConsts.cc:74
int numMulticast
Definition: IPv4.h:93
IIPv4RoutingTable * rt
Definition: IPv4.h:66
simsignal_t NF_IPv4_NEW_MULTICAST
Definition: NotifierConsts.cc:70
int numForwarded
Definition: IPv4.h:97
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
int numDropped
Definition: IPv4.h:95
simsignal_t NF_IPv4_MDATA_REGISTER
Definition: NotifierConsts.cc:77
virtual void fragmentPostRouting(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Call PostRouting Hook and continue with fragmentAndSend() if accepted.
Definition: IPv4.cc:669
int numUnroutable
Definition: IPv4.h:96
simsignal_t NF_IPv4_DATA_ON_NONRPF
Definition: NotifierConsts.cc:73
virtual const IPv4MulticastRoute * findBestMatchingMulticastRoute(const IPv4Address &origin, const IPv4Address &group) const =0
Returns route for a multicast origin and group.
void inet::IPv4::fragmentAndSend ( IPv4Datagram datagram,
const InterfaceEntry ie,
IPv4Address  nextHopAddr 
)
protectedvirtual

Fragment packet if needed, then send it to the selected interface using sendDatagramToOutput().

Referenced by fragmentPostRouting(), and reinjectQueuedDatagram().

677 {
678  // fill in source address
679  if (datagram->getSrcAddress().isUnspecified())
680  datagram->setSrcAddress(ie->ipv4Data()->getIPAddress());
681 
682  // hop counter check
683  if (datagram->getTimeToLive() <= 0) {
684  // drop datagram, destruction responsibility in ICMP
686  EV_WARN << "datagram TTL reached zero, sending ICMP_TIME_EXCEEDED\n";
687  icmp->sendErrorMessage(datagram, -1 /*TODO*/, ICMP_TIME_EXCEEDED, 0);
688  numDropped++;
689  return;
690  }
691 
692  int mtu = ie->getMTU();
693 
694  // send datagram straight out if it doesn't require fragmentation (note: mtu==0 means infinite mtu)
695  if (mtu == 0 || datagram->getByteLength() <= mtu) {
696  sendDatagramToOutput(datagram, ie, nextHopAddr);
697  return;
698  }
699 
700  // if "don't fragment" bit is set, throw datagram away and send ICMP error message
701  if (datagram->getDontFragment()) {
703  EV_WARN << "datagram larger than MTU and don't fragment bit set, sending ICMP_DESTINATION_UNREACHABLE\n";
704  icmp->sendErrorMessage(datagram, -1 /*TODO*/, ICMP_DESTINATION_UNREACHABLE,
706  numDropped++;
707  return;
708  }
709 
710  // FIXME some IP options should not be copied into each fragment, check their COPY bit
711  int headerLength = datagram->getHeaderLength();
712  int payloadLength = datagram->getByteLength() - headerLength;
713  int fragmentLength = ((mtu - headerLength) / 8) * 8; // payload only (without header)
714  int offsetBase = datagram->getFragmentOffset();
715  if (fragmentLength <= 0)
716  throw cRuntimeError("Cannot fragment datagram: MTU=%d too small for header size (%d bytes)", mtu, headerLength); // exception and not ICMP because this is likely a simulation configuration error, not something one wants to simulate
717 
718  int noOfFragments = (payloadLength + fragmentLength - 1) / fragmentLength;
719  EV_DETAIL << "Breaking datagram into " << noOfFragments << " fragments\n";
720 
721  // create and send fragments
722  std::string fragMsgName = datagram->getName();
723  fragMsgName += "-frag";
724 
725  for (int offset = 0; offset < payloadLength; offset += fragmentLength) {
726  bool lastFragment = (offset + fragmentLength >= payloadLength);
727  // length equal to fragmentLength, except for last fragment;
728  int thisFragmentLength = lastFragment ? payloadLength - offset : fragmentLength;
729 
730  // FIXME is it ok that full encapsulated packet travels in every datagram fragment?
731  // should better travel in the last fragment only. Cf. with reassembly code!
732  IPv4Datagram *fragment = datagram->dup();
733  fragment->setName(fragMsgName.c_str());
734 
735  // "more fragments" bit is unchanged in the last fragment, otherwise true
736  if (!lastFragment)
737  fragment->setMoreFragments(true);
738 
739  fragment->setByteLength(headerLength + thisFragmentLength);
740  fragment->setFragmentOffset(offsetBase + offset);
741 
742  sendDatagramToOutput(fragment, ie, nextHopAddr);
743  }
744 
745  delete datagram;
746 }
ICMP * icmp
Definition: IPv4.h:69
virtual void sendErrorMessage(IPv4Datagram *datagram, int inputInterfaceId, ICMPType type, ICMPCode code)
This method can be called from other modules to send an ICMP error packet in response to a received b...
Definition: ICMP.cc:66
Definition: ICMPMessage_m.h:66
virtual void sendDatagramToOutput(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Send datagram on the given interface.
Definition: IPv4.cc:801
Definition: ICMPMessage_m.h:171
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
int numDropped
Definition: IPv4.h:95
Definition: ICMPMessage_m.h:72
void inet::IPv4::fragmentPostRouting ( IPv4Datagram datagram,
const InterfaceEntry ie,
IPv4Address  nextHopAddr 
)
protectedvirtual

Call PostRouting Hook and continue with fragmentAndSend() if accepted.

Referenced by datagramLocalOut(), forwardMulticastPacket(), preroutingFinish(), routeLocalBroadcastPacket(), and routeUnicastPacketFinish().

670 {
671  L3Address nextHop(nextHopAddr);
672  if (datagramPostRoutingHook(datagram, getSourceInterfaceFrom(datagram), ie, nextHop) == INetfilter::IHook::ACCEPT)
673  fragmentAndSend(datagram, ie, nextHop.toIPv4());
674 }
virtual void fragmentAndSend(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Fragment packet if needed, then send it to the selected interface using sendDatagramToOutput().
Definition: IPv4.cc:676
IHook::Result datagramPostRoutingHook(INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
called before a packet is delivered via the network
Definition: IPv4.cc:1031
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
virtual const InterfaceEntry * getSourceInterfaceFrom(cPacket *packet)
Definition: IPv4.cc:159
const InterfaceEntry * inet::IPv4::getShortestPathInterfaceToSource ( IPv4Datagram datagram)
protectedvirtual

Referenced by forwardMulticastPacket().

503 {
504  return rt->getInterfaceForDestAddr(datagram->getSrcAddress());
505 }
virtual InterfaceEntry * getInterfaceForDestAddr(const IPv4Address &dest) const =0
Convenience function based on findBestMatchingRoute().
IIPv4RoutingTable * rt
Definition: IPv4.h:66
const InterfaceEntry * inet::IPv4::getSourceInterfaceFrom ( cPacket *  packet)
protectedvirtual

Referenced by decapsulate(), endService(), fragmentPostRouting(), reassembleAndDeliver(), and reassembleAndDeliverFinish().

160 {
161  cGate *g = packet->getArrivalGate();
162  return g ? ift->getInterfaceByNetworkLayerGateIndex(g->getIndex()) : nullptr;
163 }
virtual InterfaceEntry * getInterfaceByNetworkLayerGateIndex(int index)=0
Returns an interface given by its getNetworkLayerGateIndex().
IInterfaceTable * ift
Definition: IPv4.h:67
milli< kg >::type g
Definition: Units.h:900
void inet::IPv4::handleIncomingARPPacket ( ARPPacket packet,
const InterfaceEntry fromIE 
)
protectedvirtual

Handle incoming ARP packets by sending them over to ARP.

Referenced by endService().

263 {
264  // give it to the ARP module
265  IMACProtocolControlInfo *ctrl = check_and_cast<IMACProtocolControlInfo *>(packet->getControlInfo());
266  ctrl->setInterfaceId(fromIE->getInterfaceId());
267  EV_INFO << "Sending " << packet << " to arp.\n";
268  send(packet, arpOutGate);
269 }
cGate * arpOutGate
Definition: IPv4.h:71
void inet::IPv4::handleIncomingDatagram ( IPv4Datagram datagram,
const InterfaceEntry fromIE 
)
protectedvirtual

Handle IPv4Datagram messages arriving from lower layer.

Decrements TTL, then invokes routePacket().

Referenced by endService().

166 {
167  ASSERT(datagram);
168  ASSERT(fromIE);
170 
171  //
172  // "Prerouting"
173  //
174 
175  // check for header biterror
176  if (datagram->hasBitError()) {
177  // probability of bit error in header = size of header / size of total message
178  // (ignore bit error if in payload)
179  double relativeHeaderLength = datagram->getHeaderLength() / (double)datagram->getByteLength();
180  if (dblrand() <= relativeHeaderLength) {
181  EV_WARN << "bit error found, sending ICMP_PARAMETER_PROBLEM\n";
182  icmp->sendErrorMessage(datagram, fromIE->getInterfaceId(), ICMP_PARAMETER_PROBLEM, 0);
183  return;
184  }
185  }
186 
187  // hop counter decrement
188  datagram->setTimeToLive(datagram->getTimeToLive() - 1);
189 
190  EV_DETAIL << "Received datagram `" << datagram->getName() << "' with dest=" << datagram->getDestAddress() << "\n";
191 
192  const InterfaceEntry *destIE = nullptr;
193  L3Address nextHop(IPv4Address::UNSPECIFIED_ADDRESS);
194  if (datagramPreRoutingHook(datagram, fromIE, destIE, nextHop) == INetfilter::IHook::ACCEPT)
195  preroutingFinish(datagram, fromIE, destIE, nextHop.toIPv4());
196 }
ICMP * icmp
Definition: IPv4.h:69
virtual void sendErrorMessage(IPv4Datagram *datagram, int inputInterfaceId, ICMPType type, ICMPCode code)
This method can be called from other modules to send an ICMP error packet in response to a received b...
Definition: ICMP.cc:66
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
IHook::Result datagramPreRoutingHook(INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
called before a packet arriving from the network is routed
Definition: IPv4.cc:979
static const IPv4Address UNSPECIFIED_ADDRESS
0.0.0.0
Definition: IPv4Address.h:102
virtual void preroutingFinish(IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
Definition: IPv4.cc:198
Definition: ICMPMessage_m.h:73
static simsignal_t packetReceivedFromLowerSignal
Definition: LayeredProtocolBase.h:33
void inet::IPv4::handleIncomingICMP ( ICMPMessage packet)
protectedvirtual

Handle incoming ICMP messages.

Referenced by reassembleAndDeliverFinish().

272 {
273  switch (packet->getType()) {
274  case ICMP_REDIRECT: // TODO implement redirect handling
276  case ICMP_TIME_EXCEEDED:
277  case ICMP_PARAMETER_PROBLEM: {
278  // ICMP errors are delivered to the appropriate higher layer protocol
279  IPv4Datagram *bogusPacket = check_and_cast<IPv4Datagram *>(packet->getEncapsulatedPacket());
280  int protocol = bogusPacket->getTransportProtocol();
281  int gateindex = mapping.getOutputGateForProtocol(protocol);
282  send(packet, "transportOut", gateindex);
284  break;
285  }
286 
287  default: {
288  // all others are delivered to ICMP: ICMP_ECHO_REQUEST, ICMP_ECHO_REPLY,
289  // ICMP_TIMESTAMP_REQUEST, ICMP_TIMESTAMP_REPLY, etc.
291  send(packet, "transportOut", gateindex);
293  break;
294  }
295  }
296 }
Definition: ICMPMessage_m.h:66
uint8_t protocol
Definition: TCP_NSC.cc:88
ProtocolMapping mapping
Definition: IPv4.h:87
Definition: IPProtocolId_m.h:77
Definition: ICMPMessage_m.h:72
Definition: ICMPMessage_m.h:73
Definition: ICMPMessage_m.h:68
int getOutputGateForProtocol(int protocol) const
find output gate index for protocol ID and returns it.
Definition: ProtocolMap.cc:74
static simsignal_t packetSentToUpperSignal
Definition: LayeredProtocolBase.h:28
void inet::IPv4::handleMessage ( cMessage *  msg)
overrideprotectedvirtual

Reimplemented from inet::AbstractQueue.

122 {
123  if (dynamic_cast<RegisterTransportProtocolCommand *>(msg)) {
124  RegisterTransportProtocolCommand *command = check_and_cast<RegisterTransportProtocolCommand *>(msg);
125  mapping.addProtocolMapping(command->getProtocol(), msg->getArrivalGate()->getIndex());
126  delete msg;
127  }
128  else if (!msg->isSelfMessage() && msg->getArrivalGate()->isName("arpIn"))
129  endService(PK(msg));
130  else
132 }
void addProtocolMapping(int protocol, int gateIndex)
Definition: ProtocolMap.cc:82
ProtocolMapping mapping
Definition: IPv4.h:87
virtual void endService(cPacket *packet) override
Processing of IPv4 datagrams.
Definition: IPv4.cc:134
virtual void handleMessage(cMessage *msg) override
Definition: AbstractQueue.cc:43
#define PK(msg)
Definition: INETDefs.h:92
bool inet::IPv4::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overridevirtual

ILifecycle method.

Implements inet::ILifecycle.

1058 {
1059  Enter_Method_Silent();
1060  if (dynamic_cast<NodeStartOperation *>(operation)) {
1062  start();
1063  }
1064  else if (dynamic_cast<NodeShutdownOperation *>(operation)) {
1066  stop();
1067  }
1068  else if (dynamic_cast<NodeCrashOperation *>(operation)) {
1070  stop();
1071  }
1072  return true;
1073 }
Definition: NodeOperations.h:50
virtual void start()
Definition: IPv4.cc:1075
Stage
Definition: NodeOperations.h:71
Stage
Definition: NodeOperations.h:126
virtual void stop()
Definition: IPv4.cc:1081
Stage
Definition: NodeOperations.h:46
Definition: NodeOperations.h:127
void inet::IPv4::handlePacketFromARP ( cPacket *  packet)
protectedvirtual

TODO.

Referenced by endService().

329 {
330  EV_INFO << "Received " << packet << " from arp.\n";
331  // send out packet on the appropriate interface
332  IMACProtocolControlInfo *ctrl = check_and_cast<IMACProtocolControlInfo *>(packet->getControlInfo());
333  InterfaceEntry *destIE = ift->getInterfaceById(ctrl->getInterfaceId());
334  sendPacketToNIC(packet, destIE);
335 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual void sendPacketToNIC(cPacket *packet, const InterfaceEntry *ie)
Definition: IPv4.cc:904
IInterfaceTable * ift
Definition: IPv4.h:67
void inet::IPv4::handlePacketFromHL ( cPacket *  packet)
protectedvirtual

Handle messages (typically packets to be send in IPv4) from transport or ICMP.

Invokes encapsulate(), then routePacket().

Referenced by endService().

299 {
300  EV_INFO << "Received " << packet << " from upper layer.\n";
302 
303  // if no interface exists, do not send datagram
304  if (ift->getNumInterfaces() == 0) {
305  EV_ERROR << "No interfaces exist, dropping packet\n";
306  numDropped++;
308  delete packet;
309  return;
310  }
311 
312  // encapsulate
313  IPv4ControlInfo *controlInfo = check_and_cast<IPv4ControlInfo *>(packet->removeControlInfo());
314  IPv4Datagram *datagram = encapsulate(packet, controlInfo);
315 
316  // extract requested interface and next hop
317  const InterfaceEntry *destIE = controlInfo ? const_cast<const InterfaceEntry *>(ift->getInterfaceById(controlInfo->getInterfaceId())) : nullptr;
318 
319  if (controlInfo)
320  datagram->setControlInfo(controlInfo); //FIXME ne rakjuk bele a cntrInfot!!!!! de kell :( kulonben a hook queue-ban elveszik a multicastloop flag
321 
322  // TODO:
323  L3Address nextHopAddr(IPv4Address::UNSPECIFIED_ADDRESS);
324  if (datagramLocalOutHook(datagram, destIE, nextHopAddr) == INetfilter::IHook::ACCEPT)
325  datagramLocalOut(datagram, destIE, nextHopAddr.toIPv4());
326 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
IHook::Result datagramLocalOutHook(INetworkDatagram *datagram, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
called before a packet arriving locally is delivered
Definition: IPv4.cc:1143
virtual IPv4Datagram * encapsulate(cPacket *transportPacket, IPv4ControlInfo *controlInfo)
Encapsulate packet coming from higher layers into IPv4Datagram, using the given control info...
Definition: IPv4.cc:748
static simsignal_t packetReceivedFromUpperSignal
Definition: LayeredProtocolBase.h:29
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
virtual void datagramLocalOut(IPv4Datagram *datagram, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
Routes and sends datagram received from higher layers.
Definition: IPv4.cc:337
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
IInterfaceTable * ift
Definition: IPv4.h:67
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
int numDropped
Definition: IPv4.h:95
static const IPv4Address UNSPECIFIED_ADDRESS
0.0.0.0
Definition: IPv4Address.h:102
void inet::IPv4::initialize ( int  stage)
overrideprotectedvirtual
58 {
59  if (stage == INITSTAGE_LOCAL) {
61 
62  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
63  rt = getModuleFromPar<IIPv4RoutingTable>(par("routingTableModule"), this);
64  arp = getModuleFromPar<IARP>(par("arpModule"), this);
65  icmp = getModuleFromPar<ICMP>(par("icmpModule"), this);
66 
67  arpInGate = gate("arpIn");
68  arpOutGate = gate("arpOut");
69  transportInGateBaseId = gateBaseId("transportIn");
70  queueOutGateBaseId = gateBaseId("queueOut");
71 
72  defaultTimeToLive = par("timeToLive");
73  defaultMCTimeToLive = par("multicastTimeToLive");
74  fragmentTimeoutTime = par("fragmentTimeout");
75  forceBroadcast = par("forceBroadcast");
76  useProxyARP = par("useProxyARP");
77 
78  curFragmentId = 0;
79  lastCheckTime = 0;
80  fragbuf.init(icmp);
81 
83 
84  // NetFilter:
85  hooks.clear();
87 
88  pendingPackets.clear();
89  cModule *arpModule = check_and_cast<cModule *>(arp);
90  arpModule->subscribe(IARP::completedARPResolutionSignal, this);
91  arpModule->subscribe(IARP::failedARPResolutionSignal, this);
92 
93  WATCH(numMulticast);
94  WATCH(numLocalDeliver);
95  WATCH(numDropped);
96  WATCH(numUnroutable);
97  WATCH(numForwarded);
98  WATCH_MAP(pendingPackets);
99  }
100  else if (stage == INITSTAGE_NETWORK_LAYER) {
101  isUp = isNodeUp();
102  }
103 }
cGate * arpInGate
Definition: IPv4.h:70
int numLocalDeliver
Definition: IPv4.h:94
int transportInGateBaseId
Definition: IPv4.h:72
ICMP * icmp
Definition: IPv4.h:69
simtime_t fragmentTimeoutTime
Definition: IPv4.h:78
bool isUp
Definition: IPv4.h:83
PendingPackets pendingPackets
Definition: IPv4.h:90
void init(ICMP *icmp)
Initialize fragmentation buffer.
Definition: IPv4FragBuf.cc:47
int numMulticast
Definition: IPv4.h:93
virtual bool isNodeUp()
Definition: IPv4.cc:1107
IPv4FragBuf fragbuf
Definition: IPv4.h:85
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
IIPv4RoutingTable * rt
Definition: IPv4.h:66
bool useProxyARP
Definition: IPv4.h:80
Initialization of network-layer protocols, stage 1.
Definition: InitStages.h:72
Local initializations.
Definition: InitStages.h:35
int numForwarded
Definition: IPv4.h:97
HookList hooks
Definition: IPv4.h:101
int defaultMCTimeToLive
Definition: IPv4.h:77
IInterfaceTable * ift
Definition: IPv4.h:67
int numDropped
Definition: IPv4.h:95
bool forceBroadcast
Definition: IPv4.h:79
int queueOutGateBaseId
Definition: IPv4.h:73
simtime_t lastCheckTime
Definition: IPv4.h:86
cGate * arpOutGate
Definition: IPv4.h:71
int numUnroutable
Definition: IPv4.h:96
virtual void initialize() override
Definition: QueueBase.cc:22
long curFragmentId
Definition: IPv4.h:84
static const simsignal_t failedARPResolutionSignal
Definition: IARP.h:57
static const simsignal_t completedARPResolutionSignal
Definition: IARP.h:56
int defaultTimeToLive
Definition: IPv4.h:76
IARP * arp
Definition: IPv4.h:68
bool inet::IPv4::isNodeUp ( )
protectedvirtual

Referenced by initialize().

1108 {
1109  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
1110  return !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
1111 }
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Definition: NodeStatus.h:40
virtual int inet::IPv4::numInitStages ( ) const
inlineoverrideprotectedvirtual
235 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::IPv4::preroutingFinish ( IPv4Datagram datagram,
const InterfaceEntry fromIE,
const InterfaceEntry destIE,
IPv4Address  nextHopAddr 
)
protectedvirtual

Referenced by handleIncomingDatagram(), and reinjectQueuedDatagram().

199 {
200  IPv4Address& destAddr = datagram->getDestAddress();
201 
202  // remove control info
203  delete datagram->removeControlInfo();
204 
205  // route packet
206 
207  if (fromIE->isLoopback()) {
208  reassembleAndDeliver(datagram);
209  }
210  else if (destAddr.isMulticast()) {
211  // check for local delivery
212  // Note: multicast routers will receive IGMP datagrams even if their interface is not joined to the group
213  if (fromIE->ipv4Data()->isMemberOfMulticastGroup(destAddr) ||
214  (rt->isMulticastForwardingEnabled() && datagram->getTransportProtocol() == IP_PROT_IGMP))
215  reassembleAndDeliver(datagram->dup());
216  else
217  EV_WARN << "Skip local delivery of multicast datagram (input interface not in multicast group)\n";
218 
219  // don't forward if IP forwarding is off, or if dest address is link-scope
221  EV_WARN << "Skip forwarding of multicast datagram (forwarding disabled)\n";
222  delete datagram;
223  }
224  else if (destAddr.isLinkLocalMulticast()) {
225  EV_WARN << "Skip forwarding of multicast datagram (packet is link-local)\n";
226  delete datagram;
227  }
228  else if (datagram->getTimeToLive() == 0) {
229  EV_WARN << "Skip forwarding of multicast datagram (TTL reached 0)\n";
230  delete datagram;
231  }
232  else
233  forwardMulticastPacket(datagram, fromIE);
234  }
235  else {
236  const InterfaceEntry *broadcastIE = nullptr;
237 
238  // check for local delivery; we must accept also packets coming from the interfaces that
239  // do not yet have an IP address assigned. This happens during DHCP requests.
240  if (rt->isLocalAddress(destAddr) || fromIE->ipv4Data()->getIPAddress().isUnspecified()) {
241  reassembleAndDeliver(datagram);
242  }
243  else if (destAddr.isLimitedBroadcastAddress() || (broadcastIE = rt->findInterfaceByLocalBroadcastAddress(destAddr))) {
244  // broadcast datagram on the target subnet if we are a router
245  if (broadcastIE && fromIE != broadcastIE && rt->isForwardingEnabled())
246  fragmentPostRouting(datagram->dup(), broadcastIE, IPv4Address::ALLONES_ADDRESS);
247 
248  EV_INFO << "Broadcast received\n";
249  reassembleAndDeliver(datagram);
250  }
251  else if (!rt->isForwardingEnabled()) {
252  EV_WARN << "forwarding off, dropping packet\n";
253  numDropped++;
255  delete datagram;
256  }
257  else
258  routeUnicastPacket(datagram, fromIE, destIE, nextHopAddr);
259  }
260 }
virtual void forwardMulticastPacket(IPv4Datagram *datagram, const InterfaceEntry *fromIE)
Forwards packets to all multicast destinations, using fragmentAndSend().
Definition: IPv4.cc:507
IIPv4RoutingTable * rt
Definition: IPv4.h:66
virtual bool isLocalAddress(const IPv4Address &dest) const =0
Checks if the address is a local one, i.e.
virtual bool isForwardingEnabled() const =0
Forwarding on/off.
virtual void routeUnicastPacket(IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address requestedNextHopAddress)
Performs unicast routing.
Definition: IPv4.cc:425
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
int numDropped
Definition: IPv4.h:95
virtual bool isMulticastForwardingEnabled() const =0
Multicast forwarding on/off.
virtual InterfaceEntry * findInterfaceByLocalBroadcastAddress(const IPv4Address &dest) const =0
Returns the interface entry having the specified address as its local broadcast address.
virtual void fragmentPostRouting(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Call PostRouting Hook and continue with fragmentAndSend() if accepted.
Definition: IPv4.cc:669
static const IPv4Address ALLONES_ADDRESS
255.255.255.255
Definition: IPv4Address.h:105
Definition: IPProtocolId_m.h:78
virtual void reassembleAndDeliver(IPv4Datagram *datagram)
Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL()...
Definition: IPv4.cc:578
void inet::IPv4::reassembleAndDeliver ( IPv4Datagram datagram)
protectedvirtual

Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL().

Referenced by preroutingFinish().

579 {
580  EV_INFO << "Delivering " << datagram << " locally.\n";
581 
582  if (datagram->getSrcAddress().isUnspecified())
583  EV_WARN << "Received datagram '" << datagram->getName() << "' without source address filled in\n";
584 
585  // reassemble the packet (if fragmented)
586  if (datagram->getFragmentOffset() != 0 || datagram->getMoreFragments()) {
587  EV_DETAIL << "Datagram fragment: offset=" << datagram->getFragmentOffset()
588  << ", MORE=" << (datagram->getMoreFragments() ? "true" : "false") << ".\n";
589 
590  // erase timed out fragments in fragmentation buffer; check every 10 seconds max
591  if (simTime() >= lastCheckTime + 10) {
592  lastCheckTime = simTime();
594  }
595 
596  datagram = fragbuf.addFragment(datagram, simTime());
597  if (!datagram) {
598  EV_DETAIL << "No complete datagram yet.\n";
599  return;
600  }
601  EV_DETAIL << "This fragment completes the datagram.\n";
602  }
603 
605  return;
606  }
607 
608  reassembleAndDeliverFinish(datagram);
609 }
simtime_t fragmentTimeoutTime
Definition: IPv4.h:78
IHook::Result datagramLocalInHook(INetworkDatagram *datagram, const InterfaceEntry *inIE)
called before a packet arriving from the network is delivered locally
Definition: IPv4.cc:1113
virtual void reassembleAndDeliverFinish(IPv4Datagram *datagram)
Definition: IPv4.cc:611
IPv4FragBuf fragbuf
Definition: IPv4.h:85
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
simtime_t lastCheckTime
Definition: IPv4.h:86
void purgeStaleFragments(simtime_t lastupdate)
Throws out all fragments which are incomplete and their last update (last fragment arrival) was befor...
Definition: IPv4FragBuf.cc:154
virtual const InterfaceEntry * getSourceInterfaceFrom(cPacket *packet)
Definition: IPv4.cc:159
IPv4Datagram * addFragment(IPv4Datagram *datagram, simtime_t now)
Takes a fragment and inserts it into the reassembly buffer.
Definition: IPv4FragBuf.cc:52
void inet::IPv4::reassembleAndDeliverFinish ( IPv4Datagram datagram)
protectedvirtual

Referenced by reassembleAndDeliver(), and reinjectQueuedDatagram().

612 {
613  // decapsulate and send on appropriate output gate
614  int protocol = datagram->getTransportProtocol();
615 
616  if (protocol == IP_PROT_ICMP) {
617  // incoming ICMP packets are handled specially
618  handleIncomingICMP(check_and_cast<ICMPMessage *>(decapsulate(datagram)));
619  numLocalDeliver++;
620  }
621  else if (protocol == IP_PROT_IP) {
622  // tunnelled IP packets are handled separately
623  send(decapsulate(datagram), "preRoutingOut"); //FIXME There is no "preRoutingOut" gate in the IPv4 module.
624  }
625  else {
626  int gateindex = mapping.findOutputGateForProtocol(protocol);
627  // check if the transportOut port are connected, otherwise discard the packet
628  if (gateindex >= 0) {
629  cGate *outGate = gate("transportOut", gateindex);
630  if (outGate->isPathOK()) {
631  cPacket *packet = decapsulate(datagram);
632  send(packet, outGate);
634  numLocalDeliver++;
635  return;
636  }
637  }
638 
639  EV_ERROR << "Transport protocol ID=" << protocol << " not connected, discarding packet\n";
640  int inputInterfaceId = getSourceInterfaceFrom(datagram)->getInterfaceId();
642  }
643 }
int getInterfaceId() const
Definition: InterfaceEntry.h:185
int numLocalDeliver
Definition: IPv4.h:94
ICMP * icmp
Definition: IPv4.h:69
virtual void sendErrorMessage(IPv4Datagram *datagram, int inputInterfaceId, ICMPType type, ICMPCode code)
This method can be called from other modules to send an ICMP error packet in response to a received b...
Definition: ICMP.cc:66
Definition: ICMPMessage_m.h:66
virtual void handleIncomingICMP(ICMPMessage *packet)
Handle incoming ICMP messages.
Definition: IPv4.cc:271
uint8_t protocol
Definition: TCP_NSC.cc:88
ProtocolMapping mapping
Definition: IPv4.h:87
int findOutputGateForProtocol(int protocol) const
find output gate index for protocol ID and returns it.
Definition: ProtocolMap.cc:64
Definition: IPProtocolId_m.h:77
Definition: IPProtocolId_m.h:79
virtual cPacket * decapsulate(IPv4Datagram *datagram)
Decapsulate and return encapsulated packet after attaching IPv4ControlInfo.
Definition: IPv4.cc:645
Definition: ICMPMessage_m.h:169
static simsignal_t packetSentToUpperSignal
Definition: LayeredProtocolBase.h:28
virtual const InterfaceEntry * getSourceInterfaceFrom(cPacket *packet)
Definition: IPv4.cc:159
void inet::IPv4::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overridevirtual

cListener method

1178 {
1179  Enter_Method_Silent();
1180 
1181  if (signalID == IARP::completedARPResolutionSignal) {
1182  arpResolutionCompleted(check_and_cast<IARP::Notification *>(obj));
1183  }
1184  if (signalID == IARP::failedARPResolutionSignal) {
1185  arpResolutionTimedOut(check_and_cast<IARP::Notification *>(obj));
1186  }
1187 }
void arpResolutionTimedOut(IARP::Notification *entry)
Definition: IPv4.cc:857
void arpResolutionCompleted(IARP::Notification *entry)
Definition: IPv4.cc:838
static const simsignal_t failedARPResolutionSignal
Definition: IARP.h:57
static const simsignal_t completedARPResolutionSignal
Definition: IARP.h:56
void inet::IPv4::refreshDisplay ( ) const
overrideprotectedvirtual
106 {
107  char buf[80] = "";
108  if (numForwarded > 0)
109  sprintf(buf + strlen(buf), "fwd:%d ", numForwarded);
110  if (numLocalDeliver > 0)
111  sprintf(buf + strlen(buf), "up:%d ", numLocalDeliver);
112  if (numMulticast > 0)
113  sprintf(buf + strlen(buf), "mcast:%d ", numMulticast);
114  if (numDropped > 0)
115  sprintf(buf + strlen(buf), "DROP:%d ", numDropped);
116  if (numUnroutable > 0)
117  sprintf(buf + strlen(buf), "UNROUTABLE:%d ", numUnroutable);
118  getDisplayString().setTagArg("t", 0, buf);
119 }
int numLocalDeliver
Definition: IPv4.h:94
int numMulticast
Definition: IPv4.h:93
int numForwarded
Definition: IPv4.h:97
int numDropped
Definition: IPv4.h:95
int numUnroutable
Definition: IPv4.h:96
void inet::IPv4::registerHook ( int  priority,
INetfilter::IHook hook 
)
overridevirtual

registers a Hook to be executed during datagram processing

Implements inet::INetfilter.

Referenced by inet::CloudDelayerBase::initialize().

913 {
914  Enter_Method("registerHook()");
915  hooks.insert(std::pair<int, INetfilter::IHook *>(priority, hook));
916 }
HookList hooks
Definition: IPv4.h:101
void inet::IPv4::reinjectQueuedDatagram ( const INetworkDatagram datagram)
overridevirtual

re-injects a previously queued datagram

Implements inet::INetfilter.

Referenced by inet::CloudDelayerBase::handleMessage().

942 {
943  Enter_Method("reinjectDatagram()");
944  for (auto iter = queuedDatagramsForHooks.begin(); iter != queuedDatagramsForHooks.end(); iter++) {
945  if (iter->datagram == datagram) {
946  IPv4Datagram *datagram = iter->datagram;
947  take(datagram);
948  switch (iter->hookType) {
950  datagramLocalOut(datagram, iter->outIE, iter->nextHopAddr);
951  break;
952 
954  preroutingFinish(datagram, iter->inIE, iter->outIE, iter->nextHopAddr);
955  break;
956 
958  fragmentAndSend(datagram, iter->outIE, iter->nextHopAddr);
959  break;
960 
962  reassembleAndDeliverFinish(datagram);
963  break;
964 
966  routeUnicastPacketFinish(datagram, iter->inIE, iter->outIE, iter->nextHopAddr);
967  break;
968 
969  default:
970  throw cRuntimeError("Unknown hook ID: %d", (int)(iter->hookType));
971  break;
972  }
973  queuedDatagramsForHooks.erase(iter);
974  return;
975  }
976  }
977 }
virtual void fragmentAndSend(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Fragment packet if needed, then send it to the selected interface using sendDatagramToOutput().
Definition: IPv4.cc:676
Definition: INetfilter.h:42
virtual void reassembleAndDeliverFinish(IPv4Datagram *datagram)
Definition: IPv4.cc:611
DatagramQueueForHooks queuedDatagramsForHooks
Definition: IPv4.h:103
Definition: INetfilter.h:43
virtual void datagramLocalOut(IPv4Datagram *datagram, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
Routes and sends datagram received from higher layers.
Definition: IPv4.cc:337
void routeUnicastPacketFinish(IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
Definition: IPv4.cc:472
Definition: INetfilter.h:45
Definition: INetfilter.h:46
virtual void preroutingFinish(IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
Definition: IPv4.cc:198
Definition: INetfilter.h:44
MACAddress inet::IPv4::resolveNextHopMacAddress ( cPacket *  packet,
IPv4Address  nextHopAddr,
const InterfaceEntry destIE 
)
protectedvirtual

Referenced by sendDatagramToOutput().

875 {
876  if (nextHopAddr.isLimitedBroadcastAddress() || nextHopAddr == destIE->ipv4Data()->getNetworkBroadcastAddress()) {
877  EV_DETAIL << "destination address is broadcast, sending packet to broadcast MAC address\n";
879  }
880 
881  if (nextHopAddr.isMulticast()) {
882  MACAddress macAddr = MACAddress::makeMulticastAddress(nextHopAddr);
883  EV_DETAIL << "destination address is multicast, sending packet to MAC address " << macAddr << "\n";
884  return macAddr;
885  }
886 
887  return arp->resolveL3Address(nextHopAddr, destIE);
888 }
static MACAddress makeMulticastAddress(IPv4Address addr)
Form a MAC address for a multicast IPv4 address, see RFC 1112, section 6.4.
Definition: MACAddress.cc:158
virtual MACAddress resolveL3Address(const L3Address &address, const InterfaceEntry *ie)=0
Tries to resolve the given network address to a MAC address.
IARP * arp
Definition: IPv4.h:68
static const MACAddress BROADCAST_ADDRESS
The broadcast MAC address, ff:ff:ff:ff:ff:ff.
Definition: MACAddress.h:60
void inet::IPv4::routeLocalBroadcastPacket ( IPv4Datagram datagram,
const InterfaceEntry destIE 
)
protectedvirtual

Broadcasts the datagram on the specified interface.

When destIE is nullptr, the datagram is broadcasted on each interface.

Referenced by datagramLocalOut().

480 {
481  // The destination address is 255.255.255.255 or local subnet broadcast address.
482  // We always use 255.255.255.255 as nextHopAddress, because it is recognized by ARP,
483  // and mapped to the broadcast MAC address.
484  if (destIE != nullptr) {
486  }
487  else if (forceBroadcast) {
488  // forward to each interface including loopback
489  for (int i = 0; i < ift->getNumInterfaces(); i++) {
490  const InterfaceEntry *ie = ift->getInterface(i);
492  }
493  delete datagram;
494  }
495  else {
496  numDropped++;
498  delete datagram;
499  }
500 }
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
IInterfaceTable * ift
Definition: IPv4.h:67
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
int numDropped
Definition: IPv4.h:95
bool forceBroadcast
Definition: IPv4.h:79
virtual void fragmentPostRouting(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Call PostRouting Hook and continue with fragmentAndSend() if accepted.
Definition: IPv4.cc:669
static const IPv4Address ALLONES_ADDRESS
255.255.255.255
Definition: IPv4Address.h:105
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
void inet::IPv4::routeUnicastPacket ( IPv4Datagram datagram,
const InterfaceEntry fromIE,
const InterfaceEntry destIE,
IPv4Address  requestedNextHopAddress 
)
protectedvirtual

Performs unicast routing.

Based on the routing decision, it sends the datagram through the outgoing interface.

Referenced by datagramLocalOut(), and preroutingFinish().

426 {
427  IPv4Address destAddr = datagram->getDestAddress();
428  EV_INFO << "Routing " << datagram << " with destination = " << destAddr << ", ";
429 
430  IPv4Address nextHopAddr;
431  // if output port was explicitly requested, use that, otherwise use IPv4 routing
432  if (destIE) {
433  EV_DETAIL << "using manually specified output interface " << destIE->getName() << "\n";
434  // and nextHopAddr remains unspecified
435  if (!requestedNextHopAddress.isUnspecified())
436  nextHopAddr = requestedNextHopAddress;
437  // special case ICMP reply
438  else if (destIE->isBroadcast()) {
439  // if the interface is broadcast we must search the next hop
440  const IPv4Route *re = rt->findBestMatchingRoute(destAddr);
441  if (re && re->getInterface() == destIE)
442  nextHopAddr = re->getGateway();
443  }
444  }
445  else {
446  // use IPv4 routing (lookup in routing table)
447  const IPv4Route *re = rt->findBestMatchingRoute(destAddr);
448  if (re) {
449  destIE = re->getInterface();
450  nextHopAddr = re->getGateway();
451  }
452  }
453 
454  if (!destIE) { // no route found
455  EV_WARN << "unroutable, sending ICMP_DESTINATION_UNREACHABLE, dropping packet\n";
456  numUnroutable++;
458  icmp->sendErrorMessage(datagram, fromIE ? fromIE->getInterfaceId() : -1, ICMP_DESTINATION_UNREACHABLE, 0);
459  }
460  else { // fragment and send
461  L3Address nextHop(nextHopAddr);
462  if (fromIE != nullptr) {
463  if (datagramForwardHook(datagram, fromIE, destIE, nextHop) != INetfilter::IHook::ACCEPT)
464  return;
465  nextHopAddr = nextHop.toIPv4();
466  }
467 
468  routeUnicastPacketFinish(datagram, fromIE, destIE, nextHopAddr);
469  }
470 }
ICMP * icmp
Definition: IPv4.h:69
virtual void sendErrorMessage(IPv4Datagram *datagram, int inputInterfaceId, ICMPType type, ICMPCode code)
This method can be called from other modules to send an ICMP error packet in response to a received b...
Definition: ICMP.cc:66
Definition: ICMPMessage_m.h:66
IHook::Result datagramForwardHook(INetworkDatagram *datagram, const InterfaceEntry *inIE, const InterfaceEntry *&outIE, L3Address &nextHopAddr)
called before a packet arriving from the network is delivered via the network
Definition: IPv4.cc:1005
IIPv4RoutingTable * rt
Definition: IPv4.h:66
allows the datagram to pass to the next hook
Definition: INetfilter.h:50
void routeUnicastPacketFinish(IPv4Datagram *datagram, const InterfaceEntry *fromIE, const InterfaceEntry *destIE, IPv4Address nextHopAddr)
Definition: IPv4.cc:472
IPv4Address getGateway() const
Next hop address.
Definition: IPv4Route.h:111
static simsignal_t packetFromUpperDroppedSignal
Definition: LayeredProtocolBase.h:30
InterfaceEntry * getInterface() const override
Next hop interface.
Definition: IPv4Route.h:114
virtual IPv4Route * findBestMatchingRoute(const IPv4Address &dest) const =0
The routing function.
int numUnroutable
Definition: IPv4.h:96
void inet::IPv4::routeUnicastPacketFinish ( IPv4Datagram datagram,
const InterfaceEntry fromIE,
const InterfaceEntry destIE,
IPv4Address  nextHopAddr 
)
protected

Referenced by reinjectQueuedDatagram(), and routeUnicastPacket().

473 {
474  EV_INFO << "output interface = " << destIE->getName() << ", next hop address = " << nextHopAddr << "\n";
475  numForwarded++;
476  fragmentPostRouting(datagram, destIE, nextHopAddr);
477 }
int numForwarded
Definition: IPv4.h:97
virtual void fragmentPostRouting(IPv4Datagram *datagram, const InterfaceEntry *ie, IPv4Address nextHopAddr)
Call PostRouting Hook and continue with fragmentAndSend() if accepted.
Definition: IPv4.cc:669
void inet::IPv4::sendDatagramToOutput ( IPv4Datagram datagram,
const InterfaceEntry ie,
IPv4Address  nextHopAddr 
)
protectedvirtual

Send datagram on the given interface.

Referenced by fragmentAndSend().

802 {
803  {
804  bool isIeee802Lan = ie->isBroadcast() && !ie->getMacAddress().isUnspecified(); // we only need/can do ARP on IEEE 802 LANs
805  if (!isIeee802Lan) {
806  sendPacketToNIC(datagram, ie);
807  }
808  else {
809  if (nextHopAddr.isUnspecified()) {
810  IPv4InterfaceData *ipv4Data = ie->ipv4Data();
811  IPv4Address destAddress = datagram->getDestAddress();
812  if (IPv4Address::maskedAddrAreEqual(destAddress, ie->ipv4Data()->getIPAddress(), ipv4Data->getNetmask()))
813  nextHopAddr = destAddress;
814  else if (useProxyARP) {
815  nextHopAddr = destAddress;
816  EV_WARN << "no next-hop address, using destination address " << nextHopAddr << " (proxy ARP)\n";
817  }
818  else {
819  throw cRuntimeError(datagram, "Cannot send datagram on broadcast interface: no next-hop address and Proxy ARP is disabled");
820  }
821  }
822 
823  MACAddress nextHopMacAddr; // unspecified
824  nextHopMacAddr = resolveNextHopMacAddress(datagram, nextHopAddr, ie);
825 
826  if (nextHopMacAddr.isUnspecified()) {
827  EV_INFO << "Pending " << datagram << " to ARP resolution.\n";
828  pendingPackets[nextHopAddr].insert(datagram);
829  }
830  else {
831  ASSERT2(pendingPackets.find(nextHopAddr) == pendingPackets.end(), "IPv4-ARP error: nextHopAddr found in ARP table, but IPv4 queue for nextHopAddr not empty");
832  sendPacketToIeee802NIC(datagram, ie, nextHopMacAddr, ETHERTYPE_IPv4);
833  }
834  }
835  }
836 }
static bool maskedAddrAreEqual(const IPv4Address &addr1, const IPv4Address &addr2, const IPv4Address &netmask)
Test if the masked addresses (ie the mask is applied to addr1 and addr2) are equal.
Definition: IPv4Address.cc:260
PendingPackets pendingPackets
Definition: IPv4.h:90
virtual MACAddress resolveNextHopMacAddress(cPacket *packet, IPv4Address nextHopAddr, const InterfaceEntry *destIE)
Definition: IPv4.cc:874
virtual void sendPacketToNIC(cPacket *packet, const InterfaceEntry *ie)
Definition: IPv4.cc:904
bool useProxyARP
Definition: IPv4.h:80
virtual void sendPacketToIeee802NIC(cPacket *packet, const InterfaceEntry *ie, const MACAddress &macAddress, int etherType)
Definition: IPv4.cc:890
Definition: Ieee802Ctrl_m.h:115
void inet::IPv4::sendOnTransportOutGateByProtocolId ( cPacket *  packet,
int  protocolId 
)

send packet on transportOut gate specified by protocolId

1170 {
1171  int gateindex = mapping.getOutputGateForProtocol(protocolId);
1172  cGate *outGate = gate("transportOut", gateindex);
1173  send(packet, outGate);
1175 }
ProtocolMapping mapping
Definition: IPv4.h:87
int getOutputGateForProtocol(int protocol) const
find output gate index for protocol ID and returns it.
Definition: ProtocolMap.cc:74
static simsignal_t packetSentToUpperSignal
Definition: LayeredProtocolBase.h:28
void inet::IPv4::sendPacketToIeee802NIC ( cPacket *  packet,
const InterfaceEntry ie,
const MACAddress macAddress,
int  etherType 
)
protectedvirtual

Referenced by arpResolutionCompleted(), and sendDatagramToOutput().

891 {
892  // remove old control info
893  delete packet->removeControlInfo();
894 
895  // add control info with MAC address
896  Ieee802Ctrl *controlInfo = new Ieee802Ctrl();
897  controlInfo->setDest(macAddress);
898  controlInfo->setEtherType(etherType);
899  packet->setControlInfo(controlInfo);
900 
901  sendPacketToNIC(packet, ie);
902 }
virtual void sendPacketToNIC(cPacket *packet, const InterfaceEntry *ie)
Definition: IPv4.cc:904
void inet::IPv4::sendPacketToNIC ( cPacket *  packet,
const InterfaceEntry ie 
)
protectedvirtual

Referenced by handlePacketFromARP(), sendDatagramToOutput(), and sendPacketToIeee802NIC().

905 {
906  EV_INFO << "Sending " << packet << " to output interface = " << ie->getName() << ".\n";
907  send(packet, queueOutGateBaseId + ie->getNetworkLayerGateIndex());
908 }
int queueOutGateBaseId
Definition: IPv4.h:73
void inet::IPv4::start ( )
protectedvirtual

Referenced by handleOperationStage().

1076 {
1077  ASSERT(queue.isEmpty());
1078  isUp = true;
1079 }
bool isUp
Definition: IPv4.h:83
cPacketQueue queue
The queue.
Definition: AbstractQueue.h:48
void inet::IPv4::stop ( )
protectedvirtual

Referenced by handleOperationStage().

1082 {
1083  isUp = false;
1084  flush();
1085 }
virtual void flush()
Definition: IPv4.cc:1087
bool isUp
Definition: IPv4.h:83
void inet::IPv4::unregisterHook ( int  priority,
INetfilter::IHook hook 
)
overridevirtual

unregisters a Hook to be executed during datagram processing

Implements inet::INetfilter.

Referenced by inet::sctp::SCTPNatHook::finish(), inet::CloudDelayerBase::finish(), inet::CloudDelayerBase::~CloudDelayerBase(), and inet::sctp::SCTPNatHook::~SCTPNatHook().

919 {
920  Enter_Method("unregisterHook()");
921  for (auto iter = hooks.begin(); iter != hooks.end(); iter++) {
922  if ((iter->first == priority) && (iter->second == hook)) {
923  hooks.erase(iter);
924  return;
925  }
926  }
927 }
HookList hooks
Definition: IPv4.h:101

Member Data Documentation

IARP* inet::IPv4::arp = nullptr
protected
cGate* inet::IPv4::arpInGate = nullptr
protected

Referenced by endService(), and initialize().

cGate* inet::IPv4::arpOutGate = nullptr
protected
long inet::IPv4::curFragmentId = -1
protected

Referenced by encapsulate(), and initialize().

int inet::IPv4::defaultMCTimeToLive = -1
protected

Referenced by encapsulate(), and initialize().

int inet::IPv4::defaultTimeToLive = -1
protected

Referenced by encapsulate(), and initialize().

bool inet::IPv4::forceBroadcast = false
protected
IPv4FragBuf inet::IPv4::fragbuf
protected

Referenced by initialize(), and reassembleAndDeliver().

simtime_t inet::IPv4::fragmentTimeoutTime
protected

Referenced by initialize(), and reassembleAndDeliver().

ICMP* inet::IPv4::icmp = nullptr
protected
bool inet::IPv4::isUp = false
protected

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

simtime_t inet::IPv4::lastCheckTime
protected

Referenced by initialize(), and reassembleAndDeliver().

int inet::IPv4::numForwarded = 0
protected
int inet::IPv4::numLocalDeliver = 0
protected
int inet::IPv4::numMulticast = 0
protected
int inet::IPv4::numUnroutable = 0
protected
int inet::IPv4::queueOutGateBaseId = -1
protected

Referenced by initialize(), and sendPacketToNIC().

int inet::IPv4::transportInGateBaseId = -1
protected

Referenced by initialize().

bool inet::IPv4::useProxyARP = false
protected

Referenced by initialize(), and sendDatagramToOutput().


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