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

Implements the Ipv4 protocol. More...

#include <Ipv4.h>

Inheritance diagram for inet::Ipv4:
inet::OperationalBase inet::NetfilterBase inet::INetworkProtocol inet::DefaultProtocolRegistrationListener inet::OperationalMixin< cSimpleModule > inet::INetfilter inet::IProtocolRegistrationListener inet::ILifecycle

Classes

class  QueuedDatagramForHook
 Represents an Ipv4Header, queued by a Hook. More...
 
struct  SocketDescriptor
 

Public Types

typedef std::map< Ipv4Address, cPacketQueue > PendingPackets
 

Public Member Functions

 Ipv4 ()
 
virtual ~Ipv4 ()
 
virtual void handleRegisterService (const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterProtocol (const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void registerHook (int priority, IHook *hook) override
 registers a Hook to be executed during datagram processing More...
 
virtual void unregisterHook (IHook *hook) override
 unregisters a Hook to be executed during datagram processing More...
 
virtual void dropQueuedDatagram (const Packet *datagram) override
 drop a previously queued datagram More...
 
virtual void reinjectQueuedDatagram (const Packet *datagram) override
 re-injects a previously queued datagram More...
 
virtual bool isInitializeStage (int stage) const override
 ILifecycle methods. More...
 
virtual bool isModuleStartStage (int stage) const override
 
virtual bool isModuleStopStage (int stage) const override
 
virtual void handleStartOperation (LifecycleOperation *operation) override
 
virtual void handleStopOperation (LifecycleOperation *operation) override
 
virtual void handleCrashOperation (LifecycleOperation *operation) override
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 cListener method More...
 
- Public Member Functions inherited from inet::OperationalMixin< cSimpleModule >
virtual ~OperationalMixin ()
 }@ More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- Public Member Functions inherited from inet::NetfilterBase
virtual ~NetfilterBase ()
 
- Public Member Functions inherited from inet::INetfilter
virtual ~INetfilter ()
 
- Public Member Functions inherited from inet::INetworkProtocol
virtual ~INetworkProtocol ()
 
- Public Member Functions inherited from inet::DefaultProtocolRegistrationListener
virtual void handleRegisterServiceGroup (const ProtocolGroup &protocolGroup, cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterProtocolGroup (const ProtocolGroup &protocolGroup, cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterAnyService (cGate *gate, ServicePrimitive servicePrimitive) override
 
virtual void handleRegisterAnyProtocol (cGate *gate, ServicePrimitive servicePrimitive) override
 

Static Public Member Functions

static void insertCrc (const Ptr< Ipv4Header > &ipv4Header)
 

Protected Types

typedef std::list< QueuedDatagramForHookDatagramQueueForHooks
 
- Protected Types inherited from inet::OperationalMixin< cSimpleModule >
enum  State
 

Protected Member Functions

virtual const NetworkInterfacegetSourceInterface (Packet *packet)
 
virtual const NetworkInterfacegetDestInterface (Packet *packet)
 
virtual Ipv4Address getNextHop (Packet *packet)
 
virtual const NetworkInterfacegetShortestPathInterfaceToSource (const Ptr< const Ipv4Header > &ipv4Header) const
 
virtual void refreshDisplay () const override
 
void arpResolutionCompleted (IArp::Notification *entry)
 
void arpResolutionTimedOut (IArp::Notification *entry)
 
bool verifyCrc (const Ptr< const Ipv4Header > &ipv4Header)
 
void setComputedCrc (Ptr< Ipv4Header > &ipv4Header)
 
virtual void encapsulate (Packet *packet)
 Encapsulate packet coming from higher layers into Ipv4Header, using the given control info. More...
 
virtual void handleIncomingDatagram (Packet *packet)
 Handle Ipv4Header messages arriving from lower layer. More...
 
virtual void preroutingFinish (Packet *packet)
 
virtual void handlePacketFromHL (Packet *packet)
 Handle messages (typically packets to be send in Ipv4) from transport or ICMP. More...
 
virtual void datagramLocalOut (Packet *packet)
 Routes and sends datagram received from higher layers. More...
 
virtual void routeUnicastPacket (Packet *packet)
 Performs unicast routing. More...
 
void routeUnicastPacketFinish (Packet *packet)
 
virtual void routeLocalBroadcastPacket (Packet *packet)
 Broadcasts the datagram on the specified interface. More...
 
virtual const NetworkInterfacedetermineOutgoingInterfaceForMulticastDatagram (const Ptr< const Ipv4Header > &ipv4Header, const NetworkInterface *multicastIFOption)
 Determines the output interface for the given multicast datagram. More...
 
virtual void forwardMulticastPacket (Packet *packet)
 Forwards packets to all multicast destinations, using fragmentAndSend(). More...
 
virtual void reassembleAndDeliver (Packet *packet)
 Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL(). More...
 
virtual void reassembleAndDeliverFinish (Packet *packet)
 
virtual void decapsulate (Packet *packet)
 Decapsulate packet. More...
 
virtual void fragmentPostRouting (Packet *datagram)
 Call PostRouting Hook and continue with fragmentAndSend() if accepted. More...
 
virtual void fragmentAndSend (Packet *packet)
 Fragment packet if needed, then send it to the selected interface using sendDatagramToOutput(). More...
 
virtual void sendDatagramToOutput (Packet *packet)
 Send datagram on the given interface. More...
 
virtual MacAddress resolveNextHopMacAddress (cPacket *packet, Ipv4Address nextHopAddr, const NetworkInterface *destIE)
 
virtual void sendPacketToNIC (Packet *packet)
 
virtual void sendIcmpError (Packet *packet, int inputInterfaceId, IcmpType type, IcmpCode code)
 
virtual PacketprepareForForwarding (Packet *packet) const
 
virtual int numInitStages () const override
 
virtual void initialize (int stage) override
 
virtual void handleMessageWhenUp (cMessage *msg) override
 
void handleRequest (Request *request)
 
IHook::Result datagramPreRoutingHook (Packet *datagram)
 called before a packet arriving from the network is routed More...
 
IHook::Result datagramForwardHook (Packet *datagram)
 called before a packet arriving from the network is delivered via the network More...
 
IHook::Result datagramPostRoutingHook (Packet *datagram)
 called before a packet is delivered via the network More...
 
IHook::Result datagramLocalInHook (Packet *datagram)
 called before a packet arriving from the network is delivered locally More...
 
IHook::Result datagramLocalOutHook (Packet *datagram)
 called before a packet arriving locally is delivered More...
 
virtual void start ()
 
virtual void stop ()
 
virtual void flush ()
 
- 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< IIpv4RoutingTablert
 
ModuleRefByPar< IInterfaceTableift
 
ModuleRefByPar< IArparp
 
ModuleRefByPar< Icmpicmp
 
int transportInGateBaseId = -1
 
CrcMode crcMode = CRC_MODE_UNDEFINED
 
int defaultTimeToLive = -1
 
int defaultMCTimeToLive = -1
 
simtime_t fragmentTimeoutTime
 
bool limitedBroadcast = false
 
std::string directBroadcastInterfaces = ""
 
cPatternMatcher directBroadcastInterfaceMatcher
 
uint16_t curFragmentId = -1
 
Ipv4FragBuf fragbuf
 
simtime_t lastCheckTime
 
std::set< const Protocol * > upperProtocols
 
std::map< int, SocketDescriptor * > socketIdToSocketDescriptor
 
PendingPackets pendingPackets
 
int numMulticast = 0
 
int numLocalDeliver = 0
 
int numDropped = 0
 
int numUnroutable = 0
 
int numForwarded = 0
 
DatagramQueueForHooks queuedDatagramsForHooks
 
- Protected Attributes inherited from inet::OperationalMixin< cSimpleModule >
State operationalState
 
simtime_t lastChange
 
Operation activeOperation
 
cMessage * activeOperationTimeout
 
cMessage * activeOperationExtraTimer
 
- Protected Attributes inherited from inet::NetfilterBase
std::multimap< int, IHook * > hooks
 

Detailed Description

Implements the Ipv4 protocol.

Member Typedef Documentation

◆ DatagramQueueForHooks

◆ PendingPackets

typedef std::map<Ipv4Address, cPacketQueue> inet::Ipv4::PendingPackets

Constructor & Destructor Documentation

◆ Ipv4()

inet::Ipv4::Ipv4 ( )
54 {
55 }

◆ ~Ipv4()

inet::Ipv4::~Ipv4 ( )
virtual
58 {
59  for (auto it : socketIdToSocketDescriptor)
60  delete it.second;
61  flush();
62 }

Member Function Documentation

◆ arpResolutionCompleted()

void inet::Ipv4::arpResolutionCompleted ( IArp::Notification entry)
protected
1081 {
1082  if (entry->l3Address.getType() != L3Address::IPv4)
1083  return;
1084  auto it = pendingPackets.find(entry->l3Address.toIpv4());
1085  if (it != pendingPackets.end()) {
1086  cPacketQueue& packetQueue = it->second;
1087  EV << "ARP resolution completed for " << entry->l3Address << ". Sending " << packetQueue.getLength()
1088  << " waiting packets from the queue\n";
1089 
1090  while (!packetQueue.isEmpty()) {
1091  Packet *packet = check_and_cast<Packet *>(packetQueue.pop());
1092  EV << "Sending out queued packet " << packet << "\n";
1093  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(entry->ie->getInterfaceId());
1094  packet->addTagIfAbsent<MacAddressReq>()->setDestAddress(entry->macAddress);
1095  sendPacketToNIC(packet);
1096  }
1097  pendingPackets.erase(it);
1098  }
1099 }

Referenced by receiveSignal().

◆ arpResolutionTimedOut()

void inet::Ipv4::arpResolutionTimedOut ( IArp::Notification entry)
protected
1102 {
1103  if (entry->l3Address.getType() != L3Address::IPv4)
1104  return;
1105  auto it = pendingPackets.find(entry->l3Address.toIpv4());
1106  if (it != pendingPackets.end()) {
1107  cPacketQueue& packetQueue = it->second;
1108  EV << "ARP resolution failed for " << entry->l3Address << ", dropping " << packetQueue.getLength() << " packets\n";
1109  for (int i = 0; i < packetQueue.getLength(); i++) {
1110  auto packet = packetQueue.get(i);
1111  PacketDropDetails details;
1112  details.setReason(ADDRESS_RESOLUTION_FAILED);
1113  emit(packetDroppedSignal, packet, &details);
1114  }
1115  packetQueue.clear();
1116  pendingPackets.erase(it);
1117  }
1118 }

Referenced by receiveSignal().

◆ datagramForwardHook()

INetfilter::IHook::Result inet::Ipv4::datagramForwardHook ( Packet datagram)
protected

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

1248 {
1249  for (auto& elem : hooks) {
1250  IHook::Result r = elem.second->datagramForwardHook(packet);
1251  switch (r) {
1253  break; // continue iteration
1254 
1256  delete packet;
1257  return r;
1258 
1260  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::FORWARD));
1261  return r;
1262 
1264  return r;
1265 
1266  default:
1267  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1268  }
1269  }
1271 }

Referenced by routeUnicastPacket().

◆ datagramLocalInHook()

INetfilter::IHook::Result inet::Ipv4::datagramLocalInHook ( Packet datagram)
protected

called before a packet arriving from the network is delivered locally

1346 {
1347  for (auto& elem : hooks) {
1348  IHook::Result r = elem.second->datagramLocalInHook(packet);
1349  switch (r) {
1351  break; // continue iteration
1352 
1354  delete packet;
1355  return r;
1356 
1357  case INetfilter::IHook::QUEUE: {
1358  if (packet->getOwner() != this)
1359  throw cRuntimeError("Model error: netfilter hook changed the owner of queued datagram '%s'", packet->getFullName());
1360  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::LOCALIN));
1361  return r;
1362  }
1363 
1365  return r;
1366 
1367  default:
1368  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1369  }
1370  }
1372 }

Referenced by reassembleAndDeliver().

◆ datagramLocalOut()

void inet::Ipv4::datagramLocalOut ( Packet packet)
protectedvirtual

Routes and sends datagram received from higher layers.

Invokes datagramLocalOutHook(), then routePacket().

418 {
419  const NetworkInterface *destIE = getDestInterface(packet);
420  Ipv4Address requestedNextHopAddress = getNextHop(packet);
421 
422  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
423  bool multicastLoop = false;
424  const auto& mcr = packet->findTag<MulticastReq>();
425  if (mcr != nullptr) {
426  multicastLoop = mcr->getMulticastLoop();
427  }
428 
429  // send
430  Ipv4Address destAddr = ipv4Header->getDestAddress();
431 
432  EV_DETAIL << "Sending datagram '" << packet->getName() << "' with destination = " << destAddr << "\n";
433 
434  if (ipv4Header->getDestAddress().isMulticast()) {
435  destIE = determineOutgoingInterfaceForMulticastDatagram(ipv4Header, destIE);
436  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(destIE ? destIE->getInterfaceId() : -1);
437 
438  // loop back a copy
439  if (multicastLoop && (!destIE || !destIE->isLoopback())) {
440  const NetworkInterface *loopbackIF = ift->findFirstLoopbackInterface();
441  if (loopbackIF) {
442  auto packetCopy = packet->dup();
443  packetCopy->addTagIfAbsent<InterfaceReq>()->setInterfaceId(loopbackIF->getInterfaceId());
444  packetCopy->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(destAddr);
445  fragmentPostRouting(packetCopy);
446  }
447  }
448 
449  if (destIE) {
450  numMulticast++;
451  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(destIE->getInterfaceId()); // KLUDGE is it needed?
452  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(destAddr);
453  fragmentPostRouting(packet);
454  }
455  else {
456  EV_ERROR << "No multicast interface, packet dropped\n";
457  numUnroutable++;
458  PacketDropDetails details;
459  details.setReason(NO_INTERFACE_FOUND);
460  emit(packetDroppedSignal, packet, &details);
461  delete packet;
462  }
463  }
464  else { // unicast and broadcast
465  // check for local delivery
466  if (rt->isLocalAddress(destAddr)) {
467  EV_INFO << "Delivering " << packet << " locally.\n";
468  if (destIE && !destIE->isLoopback()) {
469  EV_DETAIL << "datagram destination address is local, ignoring destination interface specified in the control info\n";
470  destIE = nullptr;
471  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(-1);
472  }
473  if (!destIE) {
474  destIE = ift->findFirstLoopbackInterface();
475  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(destIE ? destIE->getInterfaceId() : -1);
476  }
477  ASSERT(destIE);
478  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(destAddr);
479  routeUnicastPacket(packet);
480  }
481  else if (destAddr.isLimitedBroadcastAddress() || rt->isLocalBroadcastAddress(destAddr))
483  else {
484  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(requestedNextHopAddress);
485  routeUnicastPacket(packet);
486  }
487  }
488 }

Referenced by handlePacketFromHL(), and reinjectQueuedDatagram().

◆ datagramLocalOutHook()

INetfilter::IHook::Result inet::Ipv4::datagramLocalOutHook ( Packet datagram)
protected

called before a packet arriving locally is delivered

1375 {
1376  for (auto& elem : hooks) {
1377  IHook::Result r = elem.second->datagramLocalOutHook(packet);
1378  switch (r) {
1380  break; // continue iteration
1381 
1383  delete packet;
1384  return r;
1385 
1387  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::LOCALOUT));
1388  return r;
1389 
1391  return r;
1392 
1393  default:
1394  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1395  }
1396  }
1398 }

Referenced by handlePacketFromHL().

◆ datagramPostRoutingHook()

INetfilter::IHook::Result inet::Ipv4::datagramPostRoutingHook ( Packet datagram)
protected

called before a packet is delivered via the network

1274 {
1275  for (auto& elem : hooks) {
1276  IHook::Result r = elem.second->datagramPostRoutingHook(packet);
1277  switch (r) {
1279  break; // continue iteration
1280 
1282  delete packet;
1283  return r;
1284 
1286  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::POSTROUTING));
1287  return r;
1288 
1290  return r;
1291 
1292  default:
1293  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1294  }
1295  }
1297 }

Referenced by fragmentPostRouting().

◆ datagramPreRoutingHook()

INetfilter::IHook::Result inet::Ipv4::datagramPreRoutingHook ( Packet datagram)
protected

called before a packet arriving from the network is routed

1222 {
1223  for (auto& elem : hooks) {
1224  IHook::Result r = elem.second->datagramPreRoutingHook(packet);
1225  switch (r) {
1227  break; // continue iteration
1228 
1230  delete packet;
1231  return r;
1232 
1234  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::PREROUTING));
1235  return r;
1236 
1238  return r;
1239 
1240  default:
1241  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1242  }
1243  }
1245 }

Referenced by handleIncomingDatagram().

◆ decapsulate()

void inet::Ipv4::decapsulate ( Packet packet)
protectedvirtual

Decapsulate packet.

788 {
789  // decapsulate transport packet
790  const auto& ipv4Header = packet->popAtFront<Ipv4Header>();
791 
792  // create and fill in control info
793  packet->addTagIfAbsent<DscpInd>()->setDifferentiatedServicesCodePoint(ipv4Header->getDscp());
794  packet->addTagIfAbsent<EcnInd>()->setExplicitCongestionNotification(ipv4Header->getEcn());
795  packet->addTagIfAbsent<TosInd>()->setTos(ipv4Header->getTypeOfService());
796 
797  // original Ipv4 datagram might be needed in upper layers to send back ICMP error message
798 
799  auto transportProtocol = ProtocolGroup::ipprotocol.getProtocol(ipv4Header->getProtocolId());
800  packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(transportProtocol);
801  packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(transportProtocol);
802  auto l3AddressInd = packet->addTagIfAbsent<L3AddressInd>();
803  l3AddressInd->setSrcAddress(ipv4Header->getSrcAddress());
804  l3AddressInd->setDestAddress(ipv4Header->getDestAddress());
805  packet->addTagIfAbsent<HopLimitInd>()->setHopLimit(ipv4Header->getTimeToLive());
806 }

Referenced by reassembleAndDeliverFinish().

◆ determineOutgoingInterfaceForMulticastDatagram()

const NetworkInterface * inet::Ipv4::determineOutgoingInterfaceForMulticastDatagram ( const Ptr< const Ipv4Header > &  ipv4Header,
const NetworkInterface multicastIFOption 
)
protectedvirtual

Determines the output interface for the given multicast datagram.

497 {
498  const NetworkInterface *ie = nullptr;
499  if (multicastIFOption) {
500  ie = multicastIFOption;
501  EV_DETAIL << "multicast packet routed by socket option via output interface " << ie->getInterfaceName() << "\n";
502  }
503  if (!ie) {
504  Ipv4Route *route = rt->findBestMatchingRoute(ipv4Header->getDestAddress());
505  if (route)
506  ie = route->getInterface();
507  if (ie)
508  EV_DETAIL << "multicast packet routed by routing table via output interface " << ie->getInterfaceName() << "\n";
509  }
510  if (!ie) {
511  ie = rt->getInterfaceByAddress(ipv4Header->getSrcAddress());
512  if (ie)
513  EV_DETAIL << "multicast packet routed by source address via output interface " << ie->getInterfaceName() << "\n";
514  }
515  if (!ie) {
516  ie = ift->findFirstMulticastInterface();
517  if (ie)
518  EV_DETAIL << "multicast packet routed via the first multicast interface " << ie->getInterfaceName() << "\n";
519  }
520  return ie;
521 }

Referenced by datagramLocalOut().

◆ dropQueuedDatagram()

void inet::Ipv4::dropQueuedDatagram ( const Packet datagram)
overridevirtual

drop a previously queued datagram

Implements inet::INetfilter.

1172 {
1173  Enter_Method("dropQueuedDatagram()");
1174  for (auto iter = queuedDatagramsForHooks.begin(); iter != queuedDatagramsForHooks.end(); iter++) {
1175  if (iter->packet == packet) {
1176  delete packet;
1177  queuedDatagramsForHooks.erase(iter);
1178  return;
1179  }
1180  }
1181 }

◆ encapsulate()

void inet::Ipv4::encapsulate ( Packet packet)
protectedvirtual

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

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

961 {
962  const auto& ipv4Header = makeShared<Ipv4Header>();
963 
964  auto l3AddressReq = transportPacket->removeTag<L3AddressReq>();
965  Ipv4Address src = l3AddressReq->getSrcAddress().toIpv4();
966  bool nonLocalSrcAddress = l3AddressReq->getNonLocalSrcAddress();
967  Ipv4Address dest = l3AddressReq->getDestAddress().toIpv4();
968 
969  ipv4Header->setProtocolId((IpProtocolId)ProtocolGroup::ipprotocol.getProtocolNumber(transportPacket->getTag<PacketProtocolTag>()->getProtocol()));
970 
971  auto hopLimitReq = transportPacket->removeTagIfPresent<HopLimitReq>();
972  short ttl = (hopLimitReq != nullptr) ? hopLimitReq->getHopLimit() : -1;
973  bool dontFragment = false;
974  if (auto& dontFragmentReq = transportPacket->removeTagIfPresent<FragmentationReq>())
975  dontFragment = dontFragmentReq->getDontFragment();
976 
977  // set source and destination address
978  ipv4Header->setDestAddress(dest);
979 
980  // when source address was given, use it; otherwise it'll get the address
981  // of the outgoing interface after routing
982  if (!src.isUnspecified()) {
983  if (!nonLocalSrcAddress && rt->getInterfaceByAddress(src) == nullptr)
984  // if interface parameter does not match existing interface, do not send datagram
985  throw cRuntimeError("Wrong source address %s in (%s)%s: no interface with such address",
986  src.str().c_str(), transportPacket->getClassName(), transportPacket->getFullName());
987 
988  ipv4Header->setSrcAddress(src);
989  }
990 
991  // set other fields
992  if (auto& tosReq = transportPacket->removeTagIfPresent<TosReq>()) {
993  ipv4Header->setTypeOfService(tosReq->getTos());
994  if (transportPacket->findTag<DscpReq>())
995  throw cRuntimeError("TosReq and DscpReq found together");
996  if (transportPacket->findTag<EcnReq>())
997  throw cRuntimeError("TosReq and EcnReq found together");
998  transportPacket->addTag<TosInd>()->setTos(ipv4Header->getTypeOfService());
999  }
1000  if (auto& dscpReq = transportPacket->removeTagIfPresent<DscpReq>()) {
1001  ipv4Header->setDscp(dscpReq->getDifferentiatedServicesCodePoint());
1002  transportPacket->addTag<DscpInd>()->setDifferentiatedServicesCodePoint(ipv4Header->getDscp());
1003  }
1004  if (auto& ecnReq = transportPacket->removeTagIfPresent<EcnReq>()) {
1005  ipv4Header->setEcn(ecnReq->getExplicitCongestionNotification());
1006  transportPacket->addTag<EcnInd>()->setExplicitCongestionNotification(ipv4Header->getEcn());
1007  }
1008 
1009  ipv4Header->setIdentification(curFragmentId++);
1010  ipv4Header->setMoreFragments(false);
1011  ipv4Header->setDontFragment(dontFragment);
1012  ipv4Header->setFragmentOffset(0);
1013 
1014  if (ttl != -1) {
1015  ASSERT(ttl > 0);
1016  }
1017  else if (ipv4Header->getDestAddress().isLinkLocalMulticast())
1018  ttl = 1;
1019  else if (ipv4Header->getDestAddress().isMulticast())
1020  ttl = defaultMCTimeToLive;
1021  else
1022  ttl = defaultTimeToLive;
1023  ipv4Header->setTimeToLive(ttl);
1024 
1025  if (auto& optReq = transportPacket->removeTagIfPresent<Ipv4OptionsReq>()) {
1026  for (size_t i = 0; i < optReq->getOptionArraySize(); i++) {
1027  auto opt = optReq->removeOption(i);
1028  ipv4Header->addOption(opt);
1029  ipv4Header->addChunkLength(B(opt->getLength()));
1030  }
1031  }
1032 
1033  ASSERT(ipv4Header->getChunkLength() <= IPv4_MAX_HEADER_LENGTH);
1034  ipv4Header->setHeaderLength(ipv4Header->getChunkLength());
1035  ipv4Header->setTotalLengthField(ipv4Header->getChunkLength() + transportPacket->getDataLength());
1036  ipv4Header->setCrcMode(crcMode);
1037  ipv4Header->setCrc(0);
1038  switch (crcMode) {
1039  case CRC_DECLARED_CORRECT:
1040  // if the CRC mode is declared to be correct, then set the CRC to an easily recognizable value
1041  ipv4Header->setCrc(0xC00D);
1042  break;
1044  // if the CRC mode is declared to be incorrect, then set the CRC to an easily recognizable value
1045  ipv4Header->setCrc(0xBAAD);
1046  break;
1047  case CRC_COMPUTED: {
1048  ipv4Header->setCrc(0);
1049  // crc will be calculated in fragmentAndSend()
1050  break;
1051  }
1052  default:
1053  throw cRuntimeError("Unknown CRC mode");
1054  }
1055  insertNetworkProtocolHeader(transportPacket, Protocol::ipv4, ipv4Header);
1056  // setting Ipv4 options is currently not supported
1057 }

Referenced by handlePacketFromHL().

◆ flush()

void inet::Ipv4::flush ( )
protectedvirtual
1328 {
1329  EV_DEBUG << "Ipv4::flush(): pending packets:\n";
1330  for (auto& elem : pendingPackets) {
1331  EV_DEBUG << "Ipv4::flush(): " << elem.first << ": " << elem.second.str() << endl;
1332  elem.second.clear();
1333  }
1334  pendingPackets.clear();
1335 
1336  EV_DEBUG << "Ipv4::flush(): packets in hooks: " << queuedDatagramsForHooks.size() << endl;
1337  for (auto& elem : queuedDatagramsForHooks) {
1338  delete elem.packet;
1339  }
1340  queuedDatagramsForHooks.clear();
1341 
1342  fragbuf.flush();
1343 }

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

◆ forwardMulticastPacket()

void inet::Ipv4::forwardMulticastPacket ( Packet packet)
protectedvirtual

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

629 {
630  const NetworkInterface *fromIE = ift->getInterfaceById(packet->getTag<InterfaceInd>()->getInterfaceId());
631  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
632  const Ipv4Address& srcAddr = ipv4Header->getSrcAddress();
633  const Ipv4Address& destAddr = ipv4Header->getDestAddress();
634  ASSERT(destAddr.isMulticast());
635  ASSERT(!destAddr.isLinkLocalMulticast());
636 
637  EV_INFO << "Forwarding multicast datagram `" << packet->getName() << "' with dest=" << destAddr << "\n";
638 
639  numMulticast++;
640 
641  const Ipv4MulticastRoute *route = rt->findBestMatchingMulticastRoute(srcAddr, destAddr);
642  if (!route) {
643  EV_WARN << "Multicast route does not exist, try to add.\n";
644  // TODO no need to emit fromIE when tags will be used in place of control infos
645  emit(ipv4NewMulticastSignal, ipv4Header.get(), const_cast<NetworkInterface *>(fromIE));
646 
647  // read new record
648  route = rt->findBestMatchingMulticastRoute(srcAddr, destAddr);
649 
650  if (!route) {
651  EV_ERROR << "No route, packet dropped.\n";
652  numUnroutable++;
653  PacketDropDetails details;
654  details.setReason(NO_ROUTE_FOUND);
655  emit(packetDroppedSignal, packet, &details);
656  delete packet;
657  return;
658  }
659  }
660 
661  if (route->getInInterface() && fromIE != route->getInInterface()->getInterface()) {
662  EV_ERROR << "Did not arrive on input interface, packet dropped.\n";
663  // TODO no need to emit fromIE when tags will be used in place of control infos
664  emit(ipv4DataOnNonrpfSignal, ipv4Header.get(), const_cast<NetworkInterface *>(fromIE));
665  numDropped++;
666  PacketDropDetails details;
667  emit(packetDroppedSignal, packet, &details);
668  delete packet;
669  }
670  // backward compatible: no parent means shortest path interface to source (RPB routing)
671  else if (!route->getInInterface() && fromIE != getShortestPathInterfaceToSource(ipv4Header)) {
672  EV_ERROR << "Did not arrive on shortest path, packet dropped.\n";
673  numDropped++;
674  PacketDropDetails details;
675  emit(packetDroppedSignal, packet, &details);
676  delete packet;
677  }
678  else {
679  // TODO no need to emit fromIE when tags will be used in place of control infos
680  emit(ipv4DataOnRpfSignal, ipv4Header.get(), const_cast<NetworkInterface *>(fromIE)); // forwarding hook
681 
682  numForwarded++;
683  // copy original datagram for multiple destinations
684  for (unsigned int i = 0; i < route->getNumOutInterfaces(); i++) {
685  Ipv4MulticastRoute::OutInterface *outInterface = route->getOutInterface(i);
686  const NetworkInterface *destIE = outInterface->getInterface();
687  if (destIE != fromIE && outInterface->isEnabled()) {
688  int ttlThreshold = destIE->getProtocolData<Ipv4InterfaceData>()->getMulticastTtlThreshold();
689  if (ipv4Header->getTimeToLive() <= ttlThreshold)
690  EV_WARN << "Not forwarding to " << destIE->getInterfaceName() << " (ttl threshold reached)\n";
691  else if (outInterface->isLeaf() && !destIE->getProtocolData<Ipv4InterfaceData>()->hasMulticastListener(destAddr))
692  EV_WARN << "Not forwarding to " << destIE->getInterfaceName() << " (no listeners)\n";
693  else {
694  EV_DETAIL << "Forwarding to " << destIE->getInterfaceName() << "\n";
695  auto packetCopy = packet->dup();
696  packetCopy->addTagIfAbsent<InterfaceReq>()->setInterfaceId(destIE->getInterfaceId());
697  packetCopy->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(destAddr);
698  fragmentPostRouting(packetCopy);
699  }
700  }
701  }
702 
703  // TODO no need to emit fromIE when tags will be use, d in place of control infos
704  emit(ipv4MdataRegisterSignal, packet, const_cast<NetworkInterface *>(fromIE)); // postRouting hook
705 
706  // only copies sent, delete original packet
707  delete packet;
708  }
709 }

Referenced by preroutingFinish().

◆ fragmentAndSend()

void inet::Ipv4::fragmentAndSend ( Packet packet)
protectedvirtual

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

861 {
862  const NetworkInterface *destIE = ift->getInterfaceById(packet->getTag<InterfaceReq>()->getInterfaceId());
863  Ipv4Address nextHopAddr = getNextHop(packet);
864  if (nextHopAddr.isUnspecified()) {
865  nextHopAddr = packet->peekAtFront<Ipv4Header>()->getDestAddress();
866  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(nextHopAddr);
867  }
868 
869  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
870 
871  // hop counter check
872  if (ipv4Header->getTimeToLive() <= 0) {
873  // drop datagram, destruction responsibility in ICMP
874  PacketDropDetails details;
875  details.setReason(HOP_LIMIT_REACHED);
876  emit(packetDroppedSignal, packet, &details);
877  EV_WARN << "datagram TTL reached zero, sending ICMP_TIME_EXCEEDED\n";
878  sendIcmpError(packet, -1 /*TODO*/, ICMP_TIME_EXCEEDED, 0);
879  numDropped++;
880  return;
881  }
882 
883  int mtu = destIE->getMtu();
884 
885  // send datagram straight out if it doesn't require fragmentation (note: mtu==0 means infinite mtu)
886  if (mtu == 0 || packet->getByteLength() <= mtu) {
887  if (crcMode == CRC_COMPUTED) {
888  auto ipv4Header = removeNetworkProtocolHeader<Ipv4Header>(packet);
889  setComputedCrc(ipv4Header);
890  insertNetworkProtocolHeader(packet, Protocol::ipv4, ipv4Header);
891  }
892  sendDatagramToOutput(packet);
893  return;
894  }
895 
896  // if "don't fragment" bit is set, throw datagram away and send ICMP error message
897  if (ipv4Header->getDontFragment()) {
898  PacketDropDetails details;
899  emit(packetDroppedSignal, packet, &details);
900  EV_WARN << "datagram larger than MTU and don't fragment bit set, sending ICMP_DESTINATION_UNREACHABLE\n";
901  icmp->sendPtbMessage(packet, mtu);
902  numDropped++;
903  delete packet;
904  return;
905  }
906 
907  // FIXME some IP options should not be copied into each fragment, check their COPY bit
908  int headerLength = B(ipv4Header->getHeaderLength()).get();
909  int payloadLength = B(packet->getDataLength()).get() - headerLength;
910  int fragmentLength = ((mtu - headerLength) / 8) * 8; // payload only (without header)
911  int offsetBase = ipv4Header->getFragmentOffset();
912  if (fragmentLength <= 0)
913  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
914 
915  int noOfFragments = (payloadLength + fragmentLength - 1) / fragmentLength;
916  EV_DETAIL << "Breaking datagram into " << noOfFragments << " fragments\n";
917 
918  // create and send fragments
919  std::string fragMsgName = packet->getName();
920  fragMsgName += "-frag-";
921 
922  int offset = 0;
923  while (offset < payloadLength) {
924  bool lastFragment = (offset + fragmentLength >= payloadLength);
925  // length equal to fragmentLength, except for last fragment;
926  int thisFragmentLength = lastFragment ? payloadLength - offset : fragmentLength;
927 
928  std::string curFragName = fragMsgName + std::to_string(offset);
929  if (lastFragment)
930  curFragName += "-last";
931  Packet *fragment = new Packet(curFragName.c_str()); // TODO add offset or index to fragment name
932 
933  // copy Tags from packet to fragment
934  fragment->copyTags(*packet);
935 
936  ASSERT(fragment->getByteLength() == 0);
937  auto fraghdr = staticPtrCast<Ipv4Header>(ipv4Header->dupShared());
938  const auto& fragData = packet->peekDataAt(B(headerLength + offset), B(thisFragmentLength));
939  ASSERT(fragData->getChunkLength() == B(thisFragmentLength));
940  fragment->insertAtBack(fragData);
941 
942  // "more fragments" bit is unchanged in the last fragment, otherwise true
943  if (!lastFragment)
944  fraghdr->setMoreFragments(true);
945 
946  fraghdr->setFragmentOffset(offsetBase + offset);
947  fraghdr->setTotalLengthField(B(headerLength + thisFragmentLength));
948  if (crcMode == CRC_COMPUTED)
949  setComputedCrc(fraghdr);
950 
951  fragment->insertAtFront(fraghdr);
952  ASSERT(fragment->getByteLength() == headerLength + thisFragmentLength);
953  sendDatagramToOutput(fragment);
954  offset += thisFragmentLength;
955  }
956 
957  delete packet;
958 }

Referenced by fragmentPostRouting(), and reinjectQueuedDatagram().

◆ fragmentPostRouting()

void inet::Ipv4::fragmentPostRouting ( Packet datagram)
protectedvirtual

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

809 {
810  const NetworkInterface *destIE = ift->getInterfaceById(packet->getTag<InterfaceReq>()->getInterfaceId());
811  // fill in source address
812  if (packet->peekAtFront<Ipv4Header>()->getSrcAddress().isUnspecified()) {
813  auto ipv4Header = removeNetworkProtocolHeader<Ipv4Header>(packet);
814  ipv4Header->setSrcAddress(destIE->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
815  insertNetworkProtocolHeader(packet, Protocol::ipv4, ipv4Header);
816  }
818  fragmentAndSend(packet);
819 }

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

◆ getDestInterface()

const NetworkInterface * inet::Ipv4::getDestInterface ( Packet packet)
protectedvirtual
241 {
242  const auto& tag = packet->findTag<InterfaceReq>();
243  return tag != nullptr ? ift->getInterfaceById(tag->getInterfaceId()) : nullptr;
244 }

Referenced by datagramLocalOut(), routeUnicastPacket(), and routeUnicastPacketFinish().

◆ getNextHop()

Ipv4Address inet::Ipv4::getNextHop ( Packet packet)
protectedvirtual
247 {
248  const auto& tag = packet->findTag<NextHopAddressReq>();
249  return tag != nullptr ? tag->getNextHopAddress().toIpv4() : Ipv4Address::UNSPECIFIED_ADDRESS;
250 }

Referenced by datagramLocalOut(), fragmentAndSend(), preroutingFinish(), routeUnicastPacket(), and routeUnicastPacketFinish().

◆ getShortestPathInterfaceToSource()

const NetworkInterface * inet::Ipv4::getShortestPathInterfaceToSource ( const Ptr< const Ipv4Header > &  ipv4Header) const
protectedvirtual
624 {
625  return rt->getInterfaceForDestAddr(ipv4Header->getSrcAddress());
626 }

Referenced by forwardMulticastPacket().

◆ getSourceInterface()

const NetworkInterface * inet::Ipv4::getSourceInterface ( Packet packet)
protectedvirtual
235 {
236  const auto& tag = packet->findTag<InterfaceInd>();
237  return tag != nullptr ? ift->getInterfaceById(tag->getInterfaceId()) : nullptr;
238 }

Referenced by reassembleAndDeliverFinish(), and routeUnicastPacket().

◆ handleCrashOperation()

void inet::Ipv4::handleCrashOperation ( LifecycleOperation operation)
overridevirtual

Implements inet::OperationalMixin< cSimpleModule >.

1311 {
1312  stop();
1313 }

◆ handleIncomingDatagram()

void inet::Ipv4::handleIncomingDatagram ( Packet packet)
protectedvirtual

Handle Ipv4Header messages arriving from lower layer.

Decrements TTL, then invokes routePacket().

253 {
254  ASSERT(packet);
255  int interfaceId = packet->getTag<InterfaceInd>()->getInterfaceId();
256  emit(packetReceivedFromLowerSignal, packet);
257 
258  //
259  // "Prerouting"
260  //
261 
262  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
263  packet->addTagIfAbsent<NetworkProtocolInd>()->setProtocol(&Protocol::ipv4);
264  packet->addTagIfAbsent<NetworkProtocolInd>()->setNetworkProtocolHeader(ipv4Header);
265 
266  if (!verifyCrc(ipv4Header)) {
267  EV_WARN << "CRC error found, drop packet\n";
268  PacketDropDetails details;
269  details.setReason(INCORRECTLY_RECEIVED);
270  emit(packetDroppedSignal, packet, &details);
271  delete packet;
272  return;
273  }
274 
275  if (ipv4Header->getTotalLengthField() > packet->getDataLength()) {
276  EV_WARN << "length error found, sending ICMP_PARAMETER_PROBLEM\n";
277  sendIcmpError(packet, interfaceId, ICMP_PARAMETER_PROBLEM, 0);
278  return;
279  }
280 
281  // remove lower layer paddings:
282  if (ipv4Header->getTotalLengthField() < packet->getDataLength()) {
283  packet->setBackOffset(packet->getFrontOffset() + ipv4Header->getTotalLengthField());
284  }
285 
286  // check for header biterror
287  if (packet->hasBitError()) {
288  // probability of bit error in header = size of header / size of total message
289  // (ignore bit error if in payload)
290  double relativeHeaderLength = B(ipv4Header->getHeaderLength()).get() / (double)B(ipv4Header->getChunkLength()).get();
291  if (dblrand() <= relativeHeaderLength) {
292  EV_WARN << "bit error found, sending ICMP_PARAMETER_PROBLEM\n";
293  sendIcmpError(packet, interfaceId, ICMP_PARAMETER_PROBLEM, 0);
294  return;
295  }
296  }
297 
298  EV_DETAIL << "Received datagram `" << ipv4Header->getName() << "' with dest=" << ipv4Header->getDestAddress() << "\n";
299 
301  preroutingFinish(packet);
302 }

Referenced by handleMessageWhenUp().

◆ handleMessageWhenUp()

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

Implements inet::OperationalMixin< cSimpleModule >.

192 {
193  if (msg->arrivedOn("transportIn")) { // TODO packet->getArrivalGate()->getBaseId() == transportInGateBaseId
194  if (auto request = dynamic_cast<Request *>(msg))
195  handleRequest(request);
196  else
197  handlePacketFromHL(check_and_cast<Packet *>(msg));
198  }
199  else if (msg->arrivedOn("queueIn")) { // from network
200  EV_INFO << "Received " << msg << " from network.\n";
201  handleIncomingDatagram(check_and_cast<Packet *>(msg));
202  }
203  else
204  throw cRuntimeError("message arrived on unknown gate '%s'", msg->getArrivalGate()->getName());
205 }

◆ handlePacketFromHL()

void inet::Ipv4::handlePacketFromHL ( Packet packet)
protectedvirtual

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

Invokes encapsulate(), then routePacket().

393 {
394  EV_INFO << "Received " << packet << " from upper layer.\n";
395  emit(packetReceivedFromUpperSignal, packet);
396 
397  // if no interface exists, do not send datagram
398  if (ift->getNumInterfaces() == 0) {
399  EV_ERROR << "No interfaces exist, dropping packet\n";
400  numDropped++;
401  PacketDropDetails details;
402  details.setReason(NO_INTERFACE_FOUND);
403  emit(packetDroppedSignal, packet, &details);
404  delete packet;
405  return;
406  }
407 
408  // encapsulate
409  encapsulate(packet);
410 
411  // TODO
412  L3Address nextHopAddr(Ipv4Address::UNSPECIFIED_ADDRESS);
414  datagramLocalOut(packet);
415 }

Referenced by handleMessageWhenUp().

◆ handleRegisterProtocol()

void inet::Ipv4::handleRegisterProtocol ( const Protocol protocol,
cGate *  gate,
ServicePrimitive  servicePrimitive 
)
overridevirtual

Reimplemented from inet::DefaultProtocolRegistrationListener.

122 {
123  Enter_Method("handleRegisterProtocol");
124  if (gate->isName("transportOut"))
125  upperProtocols.insert(&protocol);
126 }

◆ handleRegisterService()

void inet::Ipv4::handleRegisterService ( const Protocol protocol,
cGate *  gate,
ServicePrimitive  servicePrimitive 
)
overridevirtual

Reimplemented from inet::DefaultProtocolRegistrationListener.

117 {
118  Enter_Method("handleRegisterService");
119 }

◆ handleRequest()

void inet::Ipv4::handleRequest ( Request request)
protected
147 {
148  auto ctrl = request->getControlInfo();
149  if (ctrl == nullptr)
150  throw cRuntimeError("Request '%s' arrived without controlinfo", request->getName());
151  else if (Ipv4SocketBindCommand *command = dynamic_cast<Ipv4SocketBindCommand *>(ctrl)) {
152  int socketId = request->getTag<SocketReq>()->getSocketId();
153  SocketDescriptor *descriptor = new SocketDescriptor(socketId, command->getProtocol()->getId(), command->getLocalAddress());
154  socketIdToSocketDescriptor[socketId] = descriptor;
155  delete request;
156  }
157  else if (Ipv4SocketConnectCommand *command = dynamic_cast<Ipv4SocketConnectCommand *>(ctrl)) {
158  int socketId = request->getTag<SocketReq>()->getSocketId();
159  if (!containsKey(socketIdToSocketDescriptor, socketId))
160  throw cRuntimeError("Ipv4Socket: should use bind() before connect()");
161  socketIdToSocketDescriptor[socketId]->remoteAddress = command->getRemoteAddress();
162  delete request;
163  }
164  else if (dynamic_cast<Ipv4SocketCloseCommand *>(ctrl) != nullptr) {
165  int socketId = request->getTag<SocketReq>()->getSocketId();
166  auto it = socketIdToSocketDescriptor.find(socketId);
167  if (it != socketIdToSocketDescriptor.end()) {
168  delete it->second;
169  socketIdToSocketDescriptor.erase(it);
170  auto indication = new Indication("closed", IPv4_I_SOCKET_CLOSED);
171  auto ctrl = new Ipv4SocketClosedIndication();
172  indication->setControlInfo(ctrl);
173  indication->addTag<SocketInd>()->setSocketId(socketId);
174  send(indication, "transportOut");
175  }
176  delete request;
177  }
178  else if (dynamic_cast<Ipv4SocketDestroyCommand *>(ctrl) != nullptr) {
179  int socketId = request->getTag<SocketReq>()->getSocketId();
180  auto it = socketIdToSocketDescriptor.find(socketId);
181  if (it != socketIdToSocketDescriptor.end()) {
182  delete it->second;
183  socketIdToSocketDescriptor.erase(it);
184  }
185  delete request;
186  }
187  else
188  throw cRuntimeError("Unknown command: '%s' with %s", request->getName(), ctrl->getClassName());
189 }

Referenced by handleMessageWhenUp().

◆ handleStartOperation()

void inet::Ipv4::handleStartOperation ( LifecycleOperation operation)
overridevirtual

Implements inet::OperationalMixin< cSimpleModule >.

1300 {
1301  start();
1302 }

◆ handleStopOperation()

void inet::Ipv4::handleStopOperation ( LifecycleOperation operation)
overridevirtual

Implements inet::OperationalMixin< cSimpleModule >.

1305 {
1306  // TODO stop should send and wait pending packets
1307  stop();
1308 }

◆ initialize()

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

Reimplemented from inet::OperationalMixin< cSimpleModule >.

65 {
67 
68  if (stage == INITSTAGE_LOCAL) {
69  ift.reference(this, "interfaceTableModule", true);
70  rt.reference(this, "routingTableModule", true);
71  arp.reference(this, "arpModule", true);
72  icmp.reference(this, "icmpModule", true);
73 
74  transportInGateBaseId = gateBaseId("transportIn");
75 
76  const char *crcModeString = par("crcMode");
77  crcMode = parseCrcMode(crcModeString, false);
78 
79  defaultTimeToLive = par("timeToLive");
80  defaultMCTimeToLive = par("multicastTimeToLive");
81  fragmentTimeoutTime = par("fragmentTimeout");
82  limitedBroadcast = par("limitedBroadcast");
83  directBroadcastInterfaces = par("directBroadcastInterfaces").stdstringValue();
84 
85  directBroadcastInterfaceMatcher.setPattern(directBroadcastInterfaces.c_str(), false, true, false);
86 
87  curFragmentId = 0;
88  lastCheckTime = 0;
89 
91 
92  // NetFilter:
93  hooks.clear();
95 
96  pendingPackets.clear();
97 
98  WATCH(numMulticast);
99  WATCH(numLocalDeliver);
100  WATCH(numDropped);
101  WATCH(numUnroutable);
102  WATCH(numForwarded);
103  WATCH_MAP(pendingPackets);
104  WATCH_MAP(socketIdToSocketDescriptor);
105  }
106  else if (stage == INITSTAGE_NETWORK_LAYER) {
107  cModule *arpModule = check_and_cast<cModule *>(arp.get());
108  arpModule->subscribe(IArp::arpResolutionCompletedSignal, this);
109  arpModule->subscribe(IArp::arpResolutionFailedSignal, this);
110 
111  registerService(Protocol::ipv4, gate("transportIn"), gate("transportOut"));
112  registerProtocol(Protocol::ipv4, gate("queueOut"), gate("queueIn"));
113  }
114 }

◆ insertCrc()

void inet::Ipv4::insertCrc ( const Ptr< Ipv4Header > &  ipv4Header)
static
833 {
834  CrcMode crcMode = ipv4Header->getCrcMode();
835  switch (crcMode) {
837  // if the CRC mode is declared to be correct, then set the CRC to an easily recognizable value
838  ipv4Header->setCrc(0xC00D);
839  break;
841  // if the CRC mode is declared to be incorrect, then set the CRC to an easily recognizable value
842  ipv4Header->setCrc(0xBAAD);
843  break;
844  case CRC_COMPUTED: {
845  // if the CRC mode is computed, then compute the CRC and set it
846  // this computation is delayed after the routing decision, see INetfilter hook
847  ipv4Header->setCrc(0x0000); // make sure that the CRC is 0 in the Udp header before computing the CRC
848  MemoryOutputStream ipv4HeaderStream;
849  Chunk::serialize(ipv4HeaderStream, ipv4Header);
850  // compute the CRC
851  uint16_t crc = TcpIpChecksum::checksum(ipv4HeaderStream.getData());
852  ipv4Header->setCrc(crc);
853  break;
854  }
855  default:
856  throw cRuntimeError("Unknown CRC mode: %d", (int)crcMode);
857  }
858 }

Referenced by inet::DscpMarker::markPacket(), inet::PimSm::sendPIMRegisterNull(), and inet::queueing::EcnMarker::setEcn().

◆ isInitializeStage()

virtual bool inet::Ipv4::isInitializeStage ( int  stage) const
inlineoverridevirtual

ILifecycle methods.

Implements inet::OperationalMixin< cSimpleModule >.

287 { return stage == INITSTAGE_NETWORK_LAYER; }

◆ isModuleStartStage()

virtual bool inet::Ipv4::isModuleStartStage ( int  stage) const
inlineoverridevirtual

◆ isModuleStopStage()

virtual bool inet::Ipv4::isModuleStopStage ( int  stage) const
inlineoverridevirtual

◆ numInitStages()

virtual int inet::Ipv4::numInitStages ( ) const
inlineoverrideprotectedvirtual
229 { return NUM_INIT_STAGES; }

◆ prepareForForwarding()

Packet * inet::Ipv4::prepareForForwarding ( Packet packet) const
protectedvirtual
305 {
306  const auto& ipv4Header = removeNetworkProtocolHeader<Ipv4Header>(packet);
307  ipv4Header->setTimeToLive(ipv4Header->getTimeToLive() - 1);
308  insertNetworkProtocolHeader(packet, Protocol::ipv4, ipv4Header);
309  return packet;
310 }

Referenced by preroutingFinish().

◆ preroutingFinish()

void inet::Ipv4::preroutingFinish ( Packet packet)
protectedvirtual
313 {
314  const NetworkInterface *fromIE = ift->getInterfaceById(packet->getTag<InterfaceInd>()->getInterfaceId());
315  Ipv4Address nextHopAddr = getNextHop(packet);
316 
317  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
318  ASSERT(ipv4Header);
319  Ipv4Address destAddr = ipv4Header->getDestAddress();
320 
321  // route packet
322 
323  if (fromIE->isLoopback()) {
324  reassembleAndDeliver(packet);
325  }
326  else if (destAddr.isMulticast()) {
327  // check for local delivery
328  // Note: multicast routers will receive IGMP datagrams even if their interface is not joined to the group
329  if (fromIE->getProtocolData<Ipv4InterfaceData>()->isMemberOfMulticastGroup(destAddr) ||
330  (rt->isMulticastForwardingEnabled() && ipv4Header->getProtocolId() == IP_PROT_IGMP))
331  reassembleAndDeliver(packet->dup());
332  else
333  EV_WARN << "Skip local delivery of multicast datagram (input interface not in multicast group)\n";
334 
335  // don't forward if IP forwarding is off, or if dest address is link-scope
336  if (!rt->isMulticastForwardingEnabled()) {
337  EV_WARN << "Skip forwarding of multicast datagram (forwarding disabled)\n";
338  delete packet;
339  }
340  else if (destAddr.isLinkLocalMulticast()) {
341  EV_WARN << "Skip forwarding of multicast datagram (packet is link-local)\n";
342  delete packet;
343  }
344  else if (ipv4Header->getTimeToLive() <= 1) { // TTL before decrement
345  EV_WARN << "Skip forwarding of multicast datagram (TTL reached 0)\n";
346  delete packet;
347  }
348  else
350  }
351  else {
352  const NetworkInterface *broadcastIE = nullptr;
353 
354  // check for local delivery; we must accept also packets coming from the interfaces that
355  // do not yet have an IP address assigned. This happens during DHCP requests.
356  if (rt->isLocalAddress(destAddr) || fromIE->getProtocolData<Ipv4InterfaceData>()->getIPAddress().isUnspecified()) {
357  reassembleAndDeliver(packet);
358  }
359  else if (destAddr.isLimitedBroadcastAddress() || (broadcastIE = rt->findInterfaceByLocalBroadcastAddress(destAddr))) {
360  // broadcast datagram on the target subnet if we are a router
361  if (broadcastIE && fromIE != broadcastIE && rt->isForwardingEnabled()) {
362  if (directBroadcastInterfaceMatcher.matches(broadcastIE->getInterfaceName()) ||
363  directBroadcastInterfaceMatcher.matches(broadcastIE->getInterfaceFullPath().c_str()))
364  {
365  auto packetCopy = prepareForForwarding(packet->dup());
366  packetCopy->addTagIfAbsent<InterfaceReq>()->setInterfaceId(broadcastIE->getInterfaceId());
367  packetCopy->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(Ipv4Address::ALLONES_ADDRESS);
368  fragmentPostRouting(packetCopy);
369  }
370  else
371  EV_INFO << "Forwarding of direct broadcast packets is disabled on interface " << broadcastIE->getInterfaceName() << std::endl;
372  }
373 
374  EV_INFO << "Broadcast received\n";
375  reassembleAndDeliver(packet);
376  }
377  else if (!rt->isForwardingEnabled()) {
378  EV_WARN << "forwarding off, dropping packet\n";
379  numDropped++;
380  PacketDropDetails details;
381  details.setReason(FORWARDING_DISABLED);
382  emit(packetDroppedSignal, packet, &details);
383  delete packet;
384  }
385  else {
386  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(nextHopAddr);
388  }
389  }
390 }

Referenced by handleIncomingDatagram(), and reinjectQueuedDatagram().

◆ reassembleAndDeliver()

void inet::Ipv4::reassembleAndDeliver ( Packet packet)
protectedvirtual

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

712 {
713  EV_INFO << "Delivering " << packet << " locally.\n";
714 
715  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
716  if (ipv4Header->getSrcAddress().isUnspecified())
717  EV_WARN << "Received datagram '" << packet->getName() << "' without source address filled in\n";
718 
719  // reassemble the packet (if fragmented)
720  if (ipv4Header->getFragmentOffset() != 0 || ipv4Header->getMoreFragments()) {
721  EV_DETAIL << "Datagram fragment: offset=" << ipv4Header->getFragmentOffset()
722  << ", MORE=" << (ipv4Header->getMoreFragments() ? "true" : "false") << ".\n";
723 
724  // erase timed out fragments in fragmentation buffer; check every 10 seconds max
725  if (simTime() >= lastCheckTime + 10) {
726  lastCheckTime = simTime();
728  }
729 
730  packet = fragbuf.addFragment(packet, simTime());
731  if (!packet) {
732  EV_DETAIL << "No complete datagram yet.\n";
733  return;
734  }
735  if (packet->peekAtFront<Ipv4Header>()->getCrcMode() == CRC_COMPUTED) {
736  auto ipv4Header = removeNetworkProtocolHeader<Ipv4Header>(packet);
737  setComputedCrc(ipv4Header);
738  insertNetworkProtocolHeader(packet, Protocol::ipv4, ipv4Header);
739  }
740  EV_DETAIL << "This fragment completes the datagram.\n";
741  }
742 
745 }

Referenced by preroutingFinish().

◆ reassembleAndDeliverFinish()

void inet::Ipv4::reassembleAndDeliverFinish ( Packet packet)
protectedvirtual
748 {
749  auto ipv4HeaderPosition = packet->getFrontOffset();
750  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
751  const Protocol *protocol = ipv4Header->getProtocol();
752  auto remoteAddress(ipv4Header->getSrcAddress());
753  auto localAddress(ipv4Header->getDestAddress());
754  decapsulate(packet);
755  bool hasSocket = false;
756  for (const auto& elem : socketIdToSocketDescriptor) {
757  if (elem.second->protocolId == protocol->getId()
758  && (elem.second->localAddress.isUnspecified() || elem.second->localAddress == localAddress)
759  && (elem.second->remoteAddress.isUnspecified() || elem.second->remoteAddress == remoteAddress))
760  {
761  auto *packetCopy = packet->dup();
762  packetCopy->setKind(IPv4_I_DATA);
763  packetCopy->addTagIfAbsent<SocketInd>()->setSocketId(elem.second->socketId);
764  EV_INFO << "Passing up to socket " << elem.second->socketId << "\n";
765  emit(packetSentToUpperSignal, packetCopy);
766  send(packetCopy, "transportOut");
767  hasSocket = true;
768  }
769  }
771  EV_INFO << "Passing up to protocol " << *protocol << "\n";
772  emit(packetSentToUpperSignal, packet);
773  send(packet, "transportOut");
774  numLocalDeliver++;
775  }
776  else if (hasSocket) {
777  delete packet;
778  }
779  else {
780  EV_ERROR << "Transport protocol '" << protocol->getName() << "' not connected, discarding packet\n";
781  packet->setFrontOffset(ipv4HeaderPosition);
782  const NetworkInterface *fromIE = getSourceInterface(packet);
783  sendIcmpError(packet, fromIE ? fromIE->getInterfaceId() : -1, ICMP_DESTINATION_UNREACHABLE, ICMP_DU_PROTOCOL_UNREACHABLE);
784  }
785 }

Referenced by reassembleAndDeliver(), and reinjectQueuedDatagram().

◆ receiveSignal()

void inet::Ipv4::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overridevirtual

cListener method

1401 {
1402  Enter_Method("%s", cComponent::getSignalName(signalID));
1403 
1404  if (signalID == IArp::arpResolutionCompletedSignal) {
1405  arpResolutionCompleted(check_and_cast<IArp::Notification *>(obj));
1406  }
1407  if (signalID == IArp::arpResolutionFailedSignal) {
1408  arpResolutionTimedOut(check_and_cast<IArp::Notification *>(obj));
1409  }
1410 }

◆ refreshDisplay()

void inet::Ipv4::refreshDisplay ( ) const
overrideprotectedvirtual
129 {
131 
132  char buf[80] = "";
133  if (numForwarded > 0)
134  sprintf(buf + strlen(buf), "fwd:%d ", numForwarded);
135  if (numLocalDeliver > 0)
136  sprintf(buf + strlen(buf), "up:%d ", numLocalDeliver);
137  if (numMulticast > 0)
138  sprintf(buf + strlen(buf), "mcast:%d ", numMulticast);
139  if (numDropped > 0)
140  sprintf(buf + strlen(buf), "DROP:%d ", numDropped);
141  if (numUnroutable > 0)
142  sprintf(buf + strlen(buf), "UNROUTABLE:%d ", numUnroutable);
143  getDisplayString().setTagArg("t", 0, buf);
144 }

◆ registerHook()

void inet::Ipv4::registerHook ( int  priority,
INetfilter::IHook hook 
)
overridevirtual

registers a Hook to be executed during datagram processing

Reimplemented from inet::NetfilterBase.

1160 {
1161  Enter_Method("registerHook()");
1162  NetfilterBase::registerHook(priority, hook);
1163 }

◆ reinjectQueuedDatagram()

void inet::Ipv4::reinjectQueuedDatagram ( const Packet datagram)
overridevirtual

re-injects a previously queued datagram

Implements inet::INetfilter.

1184 {
1185  Enter_Method("reinjectDatagram()");
1186  for (auto iter = queuedDatagramsForHooks.begin(); iter != queuedDatagramsForHooks.end(); iter++) {
1187  if (iter->packet == packet) {
1188  auto *qPacket = iter->packet;
1189  take(qPacket);
1190  switch (iter->hookType) {
1192  datagramLocalOut(qPacket);
1193  break;
1194 
1196  preroutingFinish(qPacket);
1197  break;
1198 
1200  fragmentAndSend(qPacket);
1201  break;
1202 
1204  reassembleAndDeliverFinish(qPacket);
1205  break;
1206 
1208  routeUnicastPacketFinish(qPacket);
1209  break;
1210 
1211  default:
1212  throw cRuntimeError("Unknown hook ID: %d", (int)(iter->hookType));
1213  break;
1214  }
1215  queuedDatagramsForHooks.erase(iter);
1216  return;
1217  }
1218  }
1219 }

◆ resolveNextHopMacAddress()

MacAddress inet::Ipv4::resolveNextHopMacAddress ( cPacket *  packet,
Ipv4Address  nextHopAddr,
const NetworkInterface destIE 
)
protectedvirtual
1121 {
1122  if (nextHopAddr.isLimitedBroadcastAddress() || nextHopAddr == destIE->getProtocolData<Ipv4InterfaceData>()->getNetworkBroadcastAddress()) {
1123  EV_DETAIL << "destination address is broadcast, sending packet to broadcast MAC address\n";
1125  }
1126 
1127  if (nextHopAddr.isMulticast()) {
1128  MacAddress macAddr = nextHopAddr.mapToMulticastMacAddress();
1129  EV_DETAIL << "destination address is multicast, sending packet to MAC address " << macAddr << "\n";
1130  return macAddr;
1131  }
1132 
1133  return arp->resolveL3Address(nextHopAddr, destIE);
1134 }

Referenced by sendDatagramToOutput().

◆ routeLocalBroadcastPacket()

void inet::Ipv4::routeLocalBroadcastPacket ( Packet packet)
protectedvirtual

Broadcasts the datagram on the specified interface.

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

585 {
586  const auto& interfaceReq = packet->findTag<InterfaceReq>();
587  const NetworkInterface *destIE = interfaceReq != nullptr ? ift->getInterfaceById(interfaceReq->getInterfaceId()) : nullptr;
588  // The destination address is 255.255.255.255 or local subnet broadcast address.
589  // We always use 255.255.255.255 as nextHopAddress, because it is recognized by ARP,
590  // and mapped to the broadcast MAC address.
591  if (destIE != nullptr) {
592  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(destIE->getInterfaceId()); // KLUDGE is it needed?
593  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(Ipv4Address::ALLONES_ADDRESS);
594  fragmentPostRouting(packet);
595  }
596  else if (limitedBroadcast) {
597  auto destAddr = packet->peekAtFront<Ipv4Header>()->getDestAddress();
598  // forward to each matching interfaces including loopback
599  for (int i = 0; i < ift->getNumInterfaces(); i++) {
600  const NetworkInterface *ie = ift->getInterface(i);
601  if (!destAddr.isLimitedBroadcastAddress()) {
602  Ipv4Address interfaceAddr = ie->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
603  Ipv4Address broadcastAddr = interfaceAddr.makeBroadcastAddress(ie->getProtocolData<Ipv4InterfaceData>()->getNetmask());
604  if (destAddr != broadcastAddr)
605  continue;
606  }
607  auto packetCopy = packet->dup();
608  packetCopy->addTagIfAbsent<InterfaceReq>()->setInterfaceId(ie->getInterfaceId());
609  packetCopy->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(Ipv4Address::ALLONES_ADDRESS);
610  fragmentPostRouting(packetCopy);
611  }
612  delete packet;
613  }
614  else {
615  numDropped++;
616  PacketDropDetails details;
617  details.setReason(NO_INTERFACE_FOUND);
618  emit(packetDroppedSignal, packet, &details);
619  delete packet;
620  }
621 }

Referenced by datagramLocalOut().

◆ routeUnicastPacket()

void inet::Ipv4::routeUnicastPacket ( Packet packet)
protectedvirtual

Performs unicast routing.

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

524 {
525  const NetworkInterface *fromIE = getSourceInterface(packet);
526  const NetworkInterface *destIE = getDestInterface(packet);
527  Ipv4Address nextHopAddress = getNextHop(packet);
528 
529  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
530  Ipv4Address destAddr = ipv4Header->getDestAddress();
531  EV_INFO << "Routing " << packet << " with destination = " << destAddr << ", ";
532 
533  // if output port was explicitly requested, use that, otherwise use Ipv4 routing
534  if (destIE) {
535  EV_DETAIL << "using manually specified output interface " << destIE->getInterfaceName() << "\n";
536  // and nextHopAddr remains unspecified
537  if (!nextHopAddress.isUnspecified()) {
538  // do nothing, next hop address already specified
539  }
540  // special case ICMP reply
541  else if (destIE->isBroadcast()) {
542  // if the interface is broadcast we must search the next hop
543  const Ipv4Route *re = rt->findBestMatchingRoute(destAddr);
544  if (re && re->getInterface() == destIE) {
545  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(re->getGateway());
546  }
547  }
548  }
549  else {
550  // use Ipv4 routing (lookup in routing table)
551  const Ipv4Route *re = rt->findBestMatchingRoute(destAddr);
552  if (re) {
553  destIE = re->getInterface();
554  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(destIE->getInterfaceId());
555  packet->addTagIfAbsent<NextHopAddressReq>()->setNextHopAddress(re->getGateway());
556  }
557  }
558 
559  if (!destIE) { // no route found
560  EV_WARN << "unroutable, sending ICMP_DESTINATION_UNREACHABLE, dropping packet\n";
561  numUnroutable++;
562  PacketDropDetails details;
563  details.setReason(NO_ROUTE_FOUND);
564  emit(packetDroppedSignal, packet, &details);
565  sendIcmpError(packet, fromIE ? fromIE->getInterfaceId() : -1, ICMP_DESTINATION_UNREACHABLE, 0);
566  }
567  else { // fragment and send
568  if (fromIE != nullptr) {
570  return;
571  }
572 
573  routeUnicastPacketFinish(packet);
574  }
575 }

Referenced by datagramLocalOut(), and preroutingFinish().

◆ routeUnicastPacketFinish()

void inet::Ipv4::routeUnicastPacketFinish ( Packet packet)
protected
578 {
579  EV_INFO << "output interface = " << getDestInterface(packet)->getInterfaceName() << ", next hop address = " << getNextHop(packet) << "\n";
580  numForwarded++;
581  fragmentPostRouting(packet);
582 }

Referenced by reinjectQueuedDatagram(), and routeUnicastPacket().

◆ sendDatagramToOutput()

void inet::Ipv4::sendDatagramToOutput ( Packet packet)
protectedvirtual

Send datagram on the given interface.

1060 {
1061  const NetworkInterface *ie = ift->getInterfaceById(packet->getTag<InterfaceReq>()->getInterfaceId());
1062  auto nextHopAddressReq = packet->removeTag<NextHopAddressReq>();
1063  Ipv4Address nextHopAddr = nextHopAddressReq->getNextHopAddress().toIpv4();
1064  if (!ie->isBroadcast() || ie->getMacAddress().isUnspecified()) // we can't do ARP
1065  sendPacketToNIC(packet);
1066  else {
1067  MacAddress nextHopMacAddr = resolveNextHopMacAddress(packet, nextHopAddr, ie);
1068  if (nextHopMacAddr.isUnspecified()) {
1069  EV_INFO << "Pending " << packet << " to ARP resolution.\n";
1070  pendingPackets[nextHopAddr].insert(packet);
1071  }
1072  else {
1073  ASSERT2(!containsKey(pendingPackets, nextHopAddr), "Ipv4-ARP error: nextHopAddr found in ARP table, but Ipv4 queue for nextHopAddr not empty");
1074  packet->addTagIfAbsent<MacAddressReq>()->setDestAddress(nextHopMacAddr);
1075  sendPacketToNIC(packet);
1076  }
1077  }
1078 }

Referenced by fragmentAndSend().

◆ sendIcmpError()

void inet::Ipv4::sendIcmpError ( Packet packet,
int  inputInterfaceId,
IcmpType  type,
IcmpCode  code 
)
protectedvirtual
1413 {
1414  icmp->sendErrorMessage(origPacket, inputInterfaceId, type, code);
1415  delete origPacket;
1416 }

Referenced by fragmentAndSend(), handleIncomingDatagram(), reassembleAndDeliverFinish(), and routeUnicastPacket().

◆ sendPacketToNIC()

void inet::Ipv4::sendPacketToNIC ( Packet packet)
protectedvirtual
1137 {
1138  auto networkInterface = ift->getInterfaceById(packet->getTag<InterfaceReq>()->getInterfaceId());
1139  EV_INFO << "Sending " << packet << " to output interface = " << networkInterface->getInterfaceName() << ".\n";
1140  packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::ipv4);
1141  packet->addTagIfAbsent<DispatchProtocolInd>()->setProtocol(&Protocol::ipv4);
1142  auto networkInterfaceProtocol = networkInterface->getProtocol();
1143  auto dispatchProtocol = networkInterfaceProtocol;
1144  if (auto encapsulationProtocolReq = packet->findTagForUpdate<EncapsulationProtocolReq>()) {
1145  dispatchProtocol = encapsulationProtocolReq->getProtocol(0);
1146  encapsulationProtocolReq->eraseProtocol(0);
1147  encapsulationProtocolReq->insertProtocol(encapsulationProtocolReq->getProtocolArraySize(), networkInterfaceProtocol);
1148  }
1149  if (dispatchProtocol == nullptr)
1150  packet->removeTagIfPresent<DispatchProtocolReq>();
1151  else
1152  packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(dispatchProtocol);
1153  ASSERT(packet->findTag<InterfaceReq>() != nullptr);
1154  send(packet, "queueOut");
1155 }

Referenced by arpResolutionCompleted(), and sendDatagramToOutput().

◆ setComputedCrc()

void inet::Ipv4::setComputedCrc ( Ptr< Ipv4Header > &  ipv4Header)
protected
822 {
823  ASSERT(crcMode == CRC_COMPUTED);
824  ipv4Header->setCrc(0);
825  MemoryOutputStream ipv4HeaderStream;
826  Chunk::serialize(ipv4HeaderStream, ipv4Header);
827  // compute the CRC
828  uint16_t crc = TcpIpChecksum::checksum(ipv4HeaderStream.getData());
829  ipv4Header->setCrc(crc);
830 }

Referenced by fragmentAndSend(), and reassembleAndDeliver().

◆ start()

void inet::Ipv4::start ( )
protectedvirtual
1316 {
1317 }

Referenced by handleStartOperation().

◆ stop()

void inet::Ipv4::stop ( )
protectedvirtual
1320 {
1321  flush();
1322  for (auto it : socketIdToSocketDescriptor)
1323  delete it.second;
1325 }

Referenced by handleCrashOperation(), and handleStopOperation().

◆ unregisterHook()

void inet::Ipv4::unregisterHook ( INetfilter::IHook hook)
overridevirtual

unregisters a Hook to be executed during datagram processing

Reimplemented from inet::NetfilterBase.

1166 {
1167  Enter_Method("unregisterHook()");
1169 }

◆ verifyCrc()

bool inet::Ipv4::verifyCrc ( const Ptr< const Ipv4Header > &  ipv4Header)
protected
208 {
209  switch (ipv4Header->getCrcMode()) {
210  case CRC_DECLARED_CORRECT: {
211  // if the CRC mode is declared to be correct, then the check passes if and only if the chunk is correct
212  return ipv4Header->isCorrect();
213  }
215  // if the CRC mode is declared to be incorrect, then the check fails
216  return false;
217  case CRC_COMPUTED: {
218  if (ipv4Header->isCorrect()) {
219  // compute the CRC, the check passes if the result is 0xFFFF (includes the received CRC) and the chunks are correct
220  MemoryOutputStream ipv4HeaderStream;
221  Chunk::serialize(ipv4HeaderStream, ipv4Header);
222  uint16_t computedCrc = TcpIpChecksum::checksum(ipv4HeaderStream.getData());
223  return computedCrc == 0;
224  }
225  else {
226  return false;
227  }
228  }
229  default:
230  throw cRuntimeError("Unknown CRC mode");
231  }
232 }

Referenced by handleIncomingDatagram().

Member Data Documentation

◆ arp

ModuleRefByPar<IArp> inet::Ipv4::arp
protected

◆ crcMode

CrcMode inet::Ipv4::crcMode = CRC_MODE_UNDEFINED
protected

◆ curFragmentId

uint16_t inet::Ipv4::curFragmentId = -1
protected

Referenced by encapsulate(), and initialize().

◆ defaultMCTimeToLive

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

Referenced by encapsulate(), and initialize().

◆ defaultTimeToLive

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

Referenced by encapsulate(), and initialize().

◆ directBroadcastInterfaceMatcher

cPatternMatcher inet::Ipv4::directBroadcastInterfaceMatcher
protected

Referenced by initialize(), and preroutingFinish().

◆ directBroadcastInterfaces

std::string inet::Ipv4::directBroadcastInterfaces = ""
protected

Referenced by initialize().

◆ fragbuf

Ipv4FragBuf inet::Ipv4::fragbuf
protected

Referenced by flush(), and reassembleAndDeliver().

◆ fragmentTimeoutTime

simtime_t inet::Ipv4::fragmentTimeoutTime
protected

Referenced by initialize(), and reassembleAndDeliver().

◆ icmp

ModuleRefByPar<Icmp> inet::Ipv4::icmp
protected

◆ ift

◆ lastCheckTime

simtime_t inet::Ipv4::lastCheckTime
protected

Referenced by initialize(), and reassembleAndDeliver().

◆ limitedBroadcast

bool inet::Ipv4::limitedBroadcast = false
protected

◆ numDropped

◆ numForwarded

int inet::Ipv4::numForwarded = 0
protected

◆ numLocalDeliver

int inet::Ipv4::numLocalDeliver = 0
protected

◆ numMulticast

int inet::Ipv4::numMulticast = 0
protected

◆ numUnroutable

int inet::Ipv4::numUnroutable = 0
protected

◆ pendingPackets

◆ queuedDatagramsForHooks

◆ rt

◆ socketIdToSocketDescriptor

std::map<int, SocketDescriptor *> inet::Ipv4::socketIdToSocketDescriptor
protected

◆ transportInGateBaseId

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

Referenced by initialize().

◆ upperProtocols

std::set<const Protocol *> inet::Ipv4::upperProtocols
protected

The documentation for this class was generated from the following files:
inet::Ipv4::verifyCrc
bool verifyCrc(const Ptr< const Ipv4Header > &ipv4Header)
Definition: Ipv4.cc:207
inet::ipv4DataOnRpfSignal
simsignal_t ipv4DataOnRpfSignal
Definition: Simsignals.cc:58
inet::Ipv4::defaultTimeToLive
int defaultTimeToLive
Definition: Ipv4.h:73
inet::ProtocolGroup::getProtocolNumber
int getProtocolNumber(const Protocol *protocol) const
Definition: ProtocolGroup.cc:46
inet::Ipv4::determineOutgoingInterfaceForMulticastDatagram
virtual const NetworkInterface * determineOutgoingInterfaceForMulticastDatagram(const Ptr< const Ipv4Header > &ipv4Header, const NetworkInterface *multicastIFOption)
Determines the output interface for the given multicast datagram.
Definition: Ipv4.cc:496
protocol
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down protocol
Definition: IUdp-gates.txt:25
inet::NO_INTERFACE_FOUND
@ NO_INTERFACE_FOUND
Definition: Simsignals_m.h:74
inet::ICMP_DESTINATION_UNREACHABLE
@ ICMP_DESTINATION_UNREACHABLE
Definition: IcmpHeader_m.h:77
inet::Ipv4::sendIcmpError
virtual void sendIcmpError(Packet *packet, int inputInterfaceId, IcmpType type, IcmpCode code)
Definition: Ipv4.cc:1412
inet::Ipv4::getDestInterface
virtual const NetworkInterface * getDestInterface(Packet *packet)
Definition: Ipv4.cc:240
inet::ICMP_DU_PROTOCOL_UNREACHABLE
@ ICMP_DU_PROTOCOL_UNREACHABLE
Definition: IcmpHeader_m.h:188
inet::Ipv4::forwardMulticastPacket
virtual void forwardMulticastPacket(Packet *packet)
Forwards packets to all multicast destinations, using fragmentAndSend().
Definition: Ipv4.cc:628
inet::Ipv4::setComputedCrc
void setComputedCrc(Ptr< Ipv4Header > &ipv4Header)
Definition: Ipv4.cc:821
DscpReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DscpReq
Definition: IUdp-gates.txt:25
inet::ModuleStopOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:53
inet::INCORRECTLY_RECEIVED
@ INCORRECTLY_RECEIVED
Definition: Simsignals_m.h:71
inet::Protocol::ipv4
static const Protocol ipv4
Definition: Protocol.h:93
inet::Ipv4::handleIncomingDatagram
virtual void handleIncomingDatagram(Packet *packet)
Handle Ipv4Header messages arriving from lower layer.
Definition: Ipv4.cc:252
inet::Ipv4::datagramLocalInHook
IHook::Result datagramLocalInHook(Packet *datagram)
called before a packet arriving from the network is delivered locally
Definition: Ipv4.cc:1345
inet::Ipv4::routeLocalBroadcastPacket
virtual void routeLocalBroadcastPacket(Packet *packet)
Broadcasts the datagram on the specified interface.
Definition: Ipv4.cc:584
inet::packetReceivedFromUpperSignal
simsignal_t packetReceivedFromUpperSignal
Definition: Simsignals.cc:88
inet::INetfilter::IHook::STOLEN
@ STOLEN
doesn't allow datagram to pass to next hook, but won't be deleted
Definition: INetfilter.h:43
inet::IP_PROT_IGMP
@ IP_PROT_IGMP
Definition: IpProtocolId_m.h:92
inet::Ipv4::numUnroutable
int numUnroutable
Definition: Ipv4.h:95
inet::ICMP_PARAMETER_PROBLEM
@ ICMP_PARAMETER_PROBLEM
Definition: IcmpHeader_m.h:84
inet::Ipv4::arp
ModuleRefByPar< IArp > arp
Definition: Ipv4.h:67
inet::Ipv4::datagramForwardHook
IHook::Result datagramForwardHook(Packet *datagram)
called before a packet arriving from the network is delivered via the network
Definition: Ipv4.cc:1247
inet::OperationalMixin< cSimpleModule >::initialize
virtual void initialize(int stage) override
Definition: OperationalMixinImpl.h:26
inet::CRC_COMPUTED
@ CRC_COMPUTED
Definition: CrcMode_m.h:59
inet::ModuleStartOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:29
InterfaceReq
removed InterfaceReq
Definition: IUdp-gates.txt:11
inet::Chunk::serialize
static void serialize(MemoryOutputStream &stream, const Ptr< const Chunk > &chunk, b offset=b(0), b length=b(-1))
Serializes a chunk into the given stream.
Definition: Chunk.cc:175
inet::Ipv4::decapsulate
virtual void decapsulate(Packet *packet)
Decapsulate packet.
Definition: Ipv4.cc:787
inet::NetworkInterface::getInterfaceName
const char * getInterfaceName() const
Definition: NetworkInterface.h:233
DispatchProtocolReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DispatchProtocolReq
Definition: IUdp-gates.txt:25
inet::INITSTAGE_NETWORK_LAYER
INET_API InitStage INITSTAGE_NETWORK_LAYER
Initialization of network layer protocols.
inet::Ipv4::rt
ModuleRefByPar< IIpv4RoutingTable > rt
Definition: Ipv4.h:65
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
inet::Ipv4::reassembleAndDeliverFinish
virtual void reassembleAndDeliverFinish(Packet *packet)
Definition: Ipv4.cc:747
inet::INetfilter::IHook::FORWARD
@ FORWARD
Definition: INetfilter.h:34
inet::Ipv4::fragmentTimeoutTime
simtime_t fragmentTimeoutTime
Definition: Ipv4.h:75
inet::Ipv4::handlePacketFromHL
virtual void handlePacketFromHL(Packet *packet)
Handle messages (typically packets to be send in Ipv4) from transport or ICMP.
Definition: Ipv4.cc:392
inet::NetfilterBase::registerHook
virtual void registerHook(int priority, INetfilter::IHook *hook) override
Adds the provided hook to the list of registered hooks that will be called by the network layer when ...
Definition: INetfilter.h:137
inet::parseCrcMode
CrcMode parseCrcMode(const char *crcModeString, bool allowDisable)
Definition: CrcMode.cc:14
inet::HOP_LIMIT_REACHED
@ HOP_LIMIT_REACHED
Definition: Simsignals_m.h:70
inet::Ipv4::defaultMCTimeToLive
int defaultMCTimeToLive
Definition: Ipv4.h:74
inet::NO_ROUTE_FOUND
@ NO_ROUTE_FOUND
Definition: Simsignals_m.h:75
inet::Ipv4::pendingPackets
PendingPackets pendingPackets
Definition: Ipv4.h:89
inet::L3Address::IPv4
@ IPv4
Definition: L3Address.h:35
inet::registerService
void registerService(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a service primitive (SDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:14
inet::Ipv4::transportInGateBaseId
int transportInGateBaseId
Definition: Ipv4.h:69
inet::Ipv4::fragbuf
Ipv4FragBuf fragbuf
Definition: Ipv4.h:83
inet::FORWARDING_DISABLED
@ FORWARDING_DISABLED
Definition: Simsignals_m.h:69
inet::insertNetworkProtocolHeader
void insertNetworkProtocolHeader(Packet *packet, const Protocol &protocol, const Ptr< NetworkHeaderBase > &header)
Definition: L3Tools.cc:70
inet::packetDroppedSignal
simsignal_t packetDroppedSignal
Definition: Simsignals.cc:85
inet::Ipv4::sendDatagramToOutput
virtual void sendDatagramToOutput(Packet *packet)
Send datagram on the given interface.
Definition: Ipv4.cc:1059
inet::Ipv4::lastCheckTime
simtime_t lastCheckTime
Definition: Ipv4.h:84
inet::Ipv4::curFragmentId
uint16_t curFragmentId
Definition: Ipv4.h:82
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::ipv4NewMulticastSignal
simsignal_t ipv4NewMulticastSignal
Definition: Simsignals.cc:56
inet::Ipv4Address::ALLONES_ADDRESS
static const Ipv4Address ALLONES_ADDRESS
255.255.255.255
Definition: Ipv4Address.h:94
inet::Ipv4::routeUnicastPacket
virtual void routeUnicastPacket(Packet *packet)
Performs unicast routing.
Definition: Ipv4.cc:523
inet::Ipv4::handleRequest
void handleRequest(Request *request)
Definition: Ipv4.cc:146
ctrl
removed ctrl
Definition: IUdp-gates.txt:7
inet::ipv4MdataRegisterSignal
simsignal_t ipv4MdataRegisterSignal
Definition: Simsignals.cc:59
inet::Ipv4::flush
virtual void flush()
Definition: Ipv4.cc:1327
MulticastReq
removed MulticastReq
Definition: IUdp-gates.txt:11
inet::Ipv4FragBuf::purgeStaleFragments
void purgeStaleFragments(Icmp *icmpModule, simtime_t lastupdate)
Throws out all fragments which are incomplete and their last update (last fragment arrival) was befor...
Definition: Ipv4FragBuf.cc:99
inet::Ipv4FragBuf::flush
void flush()
Clear all state.
Definition: Ipv4FragBuf.cc:27
inet::Ipv4::socketIdToSocketDescriptor
std::map< int, SocketDescriptor * > socketIdToSocketDescriptor
Definition: Ipv4.h:86
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::ICMP_TIME_EXCEEDED
@ ICMP_TIME_EXCEEDED
Definition: IcmpHeader_m.h:83
inet::Ipv4::datagramPreRoutingHook
IHook::Result datagramPreRoutingHook(Packet *datagram)
called before a packet arriving from the network is routed
Definition: Ipv4.cc:1221
inet::INetfilter::IHook::QUEUE
@ QUEUE
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:42
inet::INetfilter::IHook::Result
Result
Definition: INetfilter.h:39
inet::contains
bool contains(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:65
inet::Ipv4::datagramPostRoutingHook
IHook::Result datagramPostRoutingHook(Packet *datagram)
called before a packet is delivered via the network
Definition: Ipv4.cc:1273
inet::NetfilterBase::unregisterHook
virtual void unregisterHook(INetfilter::IHook *hook) override
Removes the provided hook from the list of registered hooks.
Definition: INetfilter.h:142
inet::Ipv4::numForwarded
int numForwarded
Definition: Ipv4.h:96
HopLimitReq
removed HopLimitReq
Definition: IUdp-gates.txt:11
inet::Ipv4::stop
virtual void stop()
Definition: Ipv4.cc:1319
inet::Ipv4::start
virtual void start()
Definition: Ipv4.cc:1315
inet::Ipv4::routeUnicastPacketFinish
void routeUnicastPacketFinish(Packet *packet)
Definition: Ipv4.cc:577
type
removed type
Definition: IUdp-gates.txt:7
inet::Ipv4FragBuf::addFragment
Packet * addFragment(Packet *packet, simtime_t now)
Takes a fragment and inserts it into the reassembly buffer.
Definition: Ipv4FragBuf.cc:34
inet::Ipv4::arpResolutionTimedOut
void arpResolutionTimedOut(IArp::Notification *entry)
Definition: Ipv4.cc:1101
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::Ipv4::datagramLocalOut
virtual void datagramLocalOut(Packet *packet)
Routes and sends datagram received from higher layers.
Definition: Ipv4.cc:417
inet::Ipv4::numMulticast
int numMulticast
Definition: Ipv4.h:92
inet::Ipv4::limitedBroadcast
bool limitedBroadcast
Definition: Ipv4.h:76
inet::IArp::arpResolutionFailedSignal
static const simsignal_t arpResolutionFailedSignal
Definition: IArp.h:43
inet::CrcMode
CrcMode
Enum generated from inet/transportlayer/common/CrcMode.msg:12 by opp_msgtool.
Definition: CrcMode_m.h:54
inet::Ipv4::numLocalDeliver
int numLocalDeliver
Definition: Ipv4.h:93
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::packetReceivedFromLowerSignal
simsignal_t packetReceivedFromLowerSignal
Definition: Simsignals.cc:91
inet::ipv4DataOnNonrpfSignal
simsignal_t ipv4DataOnNonrpfSignal
Definition: Simsignals.cc:57
inet::IPv4_I_SOCKET_CLOSED
@ IPv4_I_SOCKET_CLOSED
Definition: Ipv4SocketCommand_m.h:85
inet::Ipv4::queuedDatagramsForHooks
DatagramQueueForHooks queuedDatagramsForHooks
Definition: Ipv4.h:100
inet::INetfilter::IHook::PREROUTING
@ PREROUTING
Definition: INetfilter.h:32
inet::Ipv4::arpResolutionCompleted
void arpResolutionCompleted(IArp::Notification *entry)
Definition: Ipv4.cc:1080
inet::TcpIpChecksum::checksum
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TcpIpChecksum.h:33
inet::Ipv4::reassembleAndDeliver
virtual void reassembleAndDeliver(Packet *packet)
Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL().
Definition: Ipv4.cc:711
inet::CRC_DECLARED_CORRECT
@ CRC_DECLARED_CORRECT
Definition: CrcMode_m.h:57
inet::Ipv4::getShortestPathInterfaceToSource
virtual const NetworkInterface * getShortestPathInterfaceToSource(const Ptr< const Ipv4Header > &ipv4Header) const
Definition: Ipv4.cc:623
inet::Ipv4::prepareForForwarding
virtual Packet * prepareForForwarding(Packet *packet) const
Definition: Ipv4.cc:304
inet::IPv4_I_DATA
@ IPv4_I_DATA
Definition: Ipv4SocketCommand_m.h:84
inet::Ipv4::fragmentAndSend
virtual void fragmentAndSend(Packet *packet)
Fragment packet if needed, then send it to the selected interface using sendDatagramToOutput().
Definition: Ipv4.cc:860
inet::Ipv4::numDropped
int numDropped
Definition: Ipv4.h:94
inet::Ipv4::sendPacketToNIC
virtual void sendPacketToNIC(Packet *packet)
Definition: Ipv4.cc:1136
inet::Ipv4::icmp
ModuleRefByPar< Icmp > icmp
Definition: Ipv4.h:68
inet::CRC_DECLARED_INCORRECT
@ CRC_DECLARED_INCORRECT
Definition: CrcMode_m.h:58
inet::IPv4_MAX_HEADER_LENGTH
const B IPv4_MAX_HEADER_LENGTH
Definition: Ipv4Header_m.h:71
inet::NetfilterBase::hooks
std::multimap< int, IHook * > hooks
Definition: INetfilter.h:129
inet::Ipv4Address::UNSPECIFIED_ADDRESS
static const Ipv4Address UNSPECIFIED_ADDRESS
0.0.0.0
Definition: Ipv4Address.h:91
inet::INetfilter::IHook::DROP
@ DROP
doesn't allow the datagram to pass to the next hook, will be deleted
Definition: INetfilter.h:41
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::Ipv4::directBroadcastInterfaces
std::string directBroadcastInterfaces
Definition: Ipv4.h:77
inet::MacAddress::BROADCAST_ADDRESS
static const MacAddress BROADCAST_ADDRESS
The broadcast MAC address, ff:ff:ff:ff:ff:ff.
Definition: MacAddress.h:34
inet::IArp::arpResolutionCompletedSignal
static const simsignal_t arpResolutionCompletedSignal
Definition: IArp.h:42
inet::INetfilter::IHook::ACCEPT
@ ACCEPT
allows the datagram to pass to the next hook
Definition: INetfilter.h:40
inet::Ipv4::encapsulate
virtual void encapsulate(Packet *packet)
Encapsulate packet coming from higher layers into Ipv4Header, using the given control info.
Definition: Ipv4.cc:960
inet::ProtocolGroup::ipprotocol
static ProtocolGroup ipprotocol
Definition: ProtocolGroup.h:42
inet::ADDRESS_RESOLUTION_FAILED
@ ADDRESS_RESOLUTION_FAILED
Definition: Simsignals_m.h:68
inet::packetSentToUpperSignal
simsignal_t packetSentToUpperSignal
Definition: Simsignals.cc:87
inet::ProtocolGroup::getProtocol
const Protocol * getProtocol(int protocolNumber) const
Definition: ProtocolGroup.cc:31
inet::Ipv4::resolveNextHopMacAddress
virtual MacAddress resolveNextHopMacAddress(cPacket *packet, Ipv4Address nextHopAddr, const NetworkInterface *destIE)
Definition: Ipv4.cc:1120
inet::Ipv4::getSourceInterface
virtual const NetworkInterface * getSourceInterface(Packet *packet)
Definition: Ipv4.cc:234
inet::IpProtocolId
IpProtocolId
Enum generated from inet/networklayer/common/IpProtocolId.msg:17 by opp_msgtool.
Definition: IpProtocolId_m.h:90
inet::Ipv4::fragmentPostRouting
virtual void fragmentPostRouting(Packet *datagram)
Call PostRouting Hook and continue with fragmentAndSend() if accepted.
Definition: Ipv4.cc:808
inet::OperationalMixin< cSimpleModule >::refreshDisplay
virtual void refreshDisplay() const override
Definition: OperationalMixinImpl.h:200
inet::registerProtocol
void registerProtocol(const Protocol &protocol, cGate *gate, ServicePrimitive servicePrimitive)
Registers a protocol primitive (PDU processing) at the given gate.
Definition: IProtocolRegistrationListener.cc:83
inet::Ipv4::directBroadcastInterfaceMatcher
cPatternMatcher directBroadcastInterfaceMatcher
Definition: Ipv4.h:79
inet::Ipv4::upperProtocols
std::set< const Protocol * > upperProtocols
Definition: Ipv4.h:85
inet::INetfilter::IHook::LOCALIN
@ LOCALIN
Definition: INetfilter.h:33
inet::INetfilter::IHook::POSTROUTING
@ POSTROUTING
Definition: INetfilter.h:35
inet::INetfilter::IHook::LOCALOUT
@ LOCALOUT
Definition: INetfilter.h:36
inet::Ipv4::crcMode
CrcMode crcMode
Definition: Ipv4.h:72
inet::containsKey
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80
inet::Ipv4::datagramLocalOutHook
IHook::Result datagramLocalOutHook(Packet *datagram)
called before a packet arriving locally is delivered
Definition: Ipv4.cc:1374
inet::Ipv4::preroutingFinish
virtual void preroutingFinish(Packet *packet)
Definition: Ipv4.cc:312
inet::Ipv4::ift
ModuleRefByPar< IInterfaceTable > ift
Definition: Ipv4.h:66
inet::Ipv4::getNextHop
virtual Ipv4Address getNextHop(Packet *packet)
Definition: Ipv4.cc:246