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

#include <Ipv4Encap.h>

Inheritance diagram for inet::Ipv4Encap:

Classes

struct  SocketDescriptor
 

Protected Member Functions

virtual int numInitStages () const override
 
virtual void initialize (int stage) override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void handleRequest (Request *request)
 
virtual void encapsulate (Packet *packet)
 
virtual void decapsulate (Packet *packet)
 

Protected Attributes

CrcMode crcMode = CRC_MODE_UNDEFINED
 
int defaultTimeToLive = -1
 
int defaultMCTimeToLive = -1
 
std::set< const Protocol * > upperProtocols
 
std::map< int, SocketDescriptor * > socketIdToSocketDescriptor
 

Member Function Documentation

◆ decapsulate()

void inet::Ipv4Encap::decapsulate ( Packet packet)
protectedvirtual
205 {
206  // decapsulate transport packet
207  const auto& ipv4Header = packet->popAtFront<Ipv4Header>();
208 
209  // create and fill in control info
210  packet->addTagIfAbsent<DscpInd>()->setDifferentiatedServicesCodePoint(ipv4Header->getDscp());
211  packet->addTagIfAbsent<EcnInd>()->setExplicitCongestionNotification(ipv4Header->getEcn());
212  packet->addTagIfAbsent<TosInd>()->setTos(ipv4Header->getTypeOfService());
213 
214  // original Ipv4 datagram might be needed in upper layers to send back ICMP error message
215 
216  auto transportProtocol = ProtocolGroup::ipprotocol.getProtocol(ipv4Header->getProtocolId());
217  packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(transportProtocol);
218  packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(transportProtocol);
219  auto l3AddressInd = packet->addTagIfAbsent<L3AddressInd>();
220  l3AddressInd->setSrcAddress(ipv4Header->getSrcAddress());
221  l3AddressInd->setDestAddress(ipv4Header->getDestAddress());
222  packet->addTagIfAbsent<HopLimitInd>()->setHopLimit(ipv4Header->getTimeToLive());
223 }

Referenced by handleMessage().

◆ encapsulate()

void inet::Ipv4Encap::encapsulate ( Packet packet)
protectedvirtual
126 {
127  const auto& ipv4Header = makeShared<Ipv4Header>();
128 
129  auto l3AddressReq = transportPacket->removeTag<L3AddressReq>();
130  Ipv4Address src = l3AddressReq->getSrcAddress().toIpv4();
131  Ipv4Address dest = l3AddressReq->getDestAddress().toIpv4();
132 
133  ipv4Header->setProtocolId((IpProtocolId)ProtocolGroup::ipprotocol.getProtocolNumber(transportPacket->getTag<PacketProtocolTag>()->getProtocol()));
134 
135  auto hopLimitReq = transportPacket->removeTagIfPresent<HopLimitReq>();
136  short ttl = (hopLimitReq != nullptr) ? hopLimitReq->getHopLimit() : -1;
137  bool dontFragment = false;
138  if (auto dontFragmentReq = transportPacket->removeTagIfPresent<FragmentationReq>())
139  dontFragment = dontFragmentReq->getDontFragment();
140 
141  // set source and destination address
142  ipv4Header->setDestAddress(dest);
143 
144  // when source address was given, use it; otherwise it'll get the address
145  // of the outgoing interface after routing
146  if (!src.isUnspecified())
147  ipv4Header->setSrcAddress(src);
148 
149  // set other fields
150  if (auto& tosReq = transportPacket->removeTagIfPresent<TosReq>()) {
151  ipv4Header->setTypeOfService(tosReq->getTos());
152  if (transportPacket->findTag<DscpReq>())
153  throw cRuntimeError("TosReq and DscpReq found together");
154  if (transportPacket->findTag<EcnReq>())
155  throw cRuntimeError("TosReq and EcnReq found together");
156  }
157  if (auto& dscpReq = transportPacket->removeTagIfPresent<DscpReq>())
158  ipv4Header->setDscp(dscpReq->getDifferentiatedServicesCodePoint());
159  if (auto& ecnReq = transportPacket->removeTagIfPresent<EcnReq>())
160  ipv4Header->setEcn(ecnReq->getExplicitCongestionNotification());
161 
162  ipv4Header->setMoreFragments(false);
163  ipv4Header->setDontFragment(dontFragment);
164  ipv4Header->setFragmentOffset(0);
165 
166  if (ttl != -1) {
167  ASSERT(ttl > 0);
168  }
169  else if (ipv4Header->getDestAddress().isLinkLocalMulticast())
170  ttl = 1;
171  else if (ipv4Header->getDestAddress().isMulticast())
172  ttl = defaultMCTimeToLive;
173  else
174  ttl = defaultTimeToLive;
175  ipv4Header->setTimeToLive(ttl);
176  ipv4Header->setTotalLengthField(ipv4Header->getChunkLength() + transportPacket->getDataLength());
177  ipv4Header->setCrcMode(crcMode);
178  ipv4Header->setCrc(0);
179  switch (crcMode) {
181  // if the CRC mode is declared to be correct, then set the CRC to an easily recognizable value
182  ipv4Header->setCrc(0xC00D);
183  break;
185  // if the CRC mode is declared to be incorrect, then set the CRC to an easily recognizable value
186  ipv4Header->setCrc(0xBAAD);
187  break;
188  case CRC_COMPUTED: {
189  MemoryOutputStream ipv4HeaderStream;
190  Chunk::serialize(ipv4HeaderStream, ipv4Header);
191  // compute the CRC
192  uint16_t crc = TcpIpChecksum::checksum(ipv4HeaderStream.getData());
193  ipv4Header->setCrc(crc);
194  // crc will be calculated in fragmentAndSend()
195  break;
196  }
197  default:
198  throw cRuntimeError("Unknown CRC mode");
199  }
200  insertNetworkProtocolHeader(transportPacket, Protocol::ipv4, ipv4Header);
201  // setting Ipv4 options is currently not supported
202 }

Referenced by handleMessage().

◆ handleMessage()

void inet::Ipv4Encap::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
42 {
43  if (auto request = dynamic_cast<Request *>(msg))
44  handleRequest(request);
45  else if (msg->getArrivalGate()->isName("upperLayerIn")) {
46  auto packet = check_and_cast<Packet *>(msg);
47  EV << "Encapsulating\n";
48  encapsulate(packet);
49  EV << "SEnding\n";
50  send(packet, "lowerLayerOut");
51  }
52  else {
53  auto packet = check_and_cast<Packet *>(msg);
54  auto ipv4HeaderPosition = packet->getFrontOffset();
55  const auto& ipv4Header = packet->peekAtFront<Ipv4Header>();
56  const Protocol *protocol = ipv4Header->getProtocol();
57  auto remoteAddress(ipv4Header->getSrcAddress());
58  auto localAddress(ipv4Header->getDestAddress());
59  EV << "Receiving\n";
60  decapsulate(packet);
61  bool hasSocket = false;
62  for (const auto& elem : socketIdToSocketDescriptor) {
63  if (elem.second->protocolId == protocol->getId() &&
64  (elem.second->localAddress.isUnspecified() || elem.second->localAddress == localAddress) &&
65  (elem.second->remoteAddress.isUnspecified() || elem.second->remoteAddress == remoteAddress))
66  {
67  auto *packetCopy = packet->dup();
68  packetCopy->addTagIfAbsent<SocketInd>()->setSocketId(elem.second->socketId);
69  EV_INFO << "Passing up to socket " << elem.second->socketId << "\n";
70 // emit(packetSentToUpperSignal, packetCopy);
71  send(packetCopy, "upperLayerOut");
72  hasSocket = true;
73  }
74  }
76  EV_INFO << "Passing up to protocol " << protocol << "\n";
77 // emit(packetSentToUpperSignal, packet);
78  send(packet, "upperLayerOut");
79  }
80  else if (hasSocket) {
81  delete packet;
82  }
83  else {
84  EV_ERROR << "Transport protocol '" << protocol->getName() << "' not connected, discarding packet\n";
85  packet->setFrontOffset(ipv4HeaderPosition);
86 // const NetworkInterface* fromIE = getSourceInterface(packet);
87 // sendIcmpError(packet, fromIE ? fromIE->getInterfaceId() : -1, ICMP_DESTINATION_UNREACHABLE, ICMP_DU_PROTOCOL_UNREACHABLE);
88  }
89  send(packet, "upperLayerOut");
90  }
91 }

◆ handleRequest()

void inet::Ipv4Encap::handleRequest ( Request request)
protectedvirtual
94 {
95  auto ctrl = request->getControlInfo();
96  if (ctrl == nullptr)
97  throw cRuntimeError("Request '%s' arrived without controlinfo", request->getName());
98  else if (Ipv4SocketBindCommand *command = dynamic_cast<Ipv4SocketBindCommand *>(ctrl)) {
99  int socketId = request->getTag<SocketReq>()->getSocketId();
100  SocketDescriptor *descriptor = new SocketDescriptor(socketId, command->getProtocol()->getId(), command->getLocalAddress());
101  socketIdToSocketDescriptor[socketId] = descriptor;
102  delete request;
103  }
104  else if (Ipv4SocketConnectCommand *command = dynamic_cast<Ipv4SocketConnectCommand *>(ctrl)) {
105  int socketId = request->getTag<SocketReq>()->getSocketId();
106  if (!containsKey(socketIdToSocketDescriptor, socketId))
107  throw cRuntimeError("Ipv4Socket: should use bind() before connect()");
108  socketIdToSocketDescriptor[socketId]->remoteAddress = command->getRemoteAddress();
109  delete request;
110  }
111  else if (dynamic_cast<Ipv4SocketCloseCommand *>(ctrl) != nullptr) {
112  int socketId = 0;
113  request->getTag<SocketReq>()->getSocketId();
114  auto it = socketIdToSocketDescriptor.find(socketId);
115  if (it != socketIdToSocketDescriptor.end()) {
116  delete it->second;
117  socketIdToSocketDescriptor.erase(it);
118  }
119  delete request;
120  }
121  else
122  throw cRuntimeError("Unknown command: '%s' with %s", request->getName(), ctrl->getClassName());
123 }

Referenced by handleMessage().

◆ initialize()

void inet::Ipv4Encap::initialize ( int  stage)
overrideprotectedvirtual
29 {
30  cSimpleModule::initialize(stage);
31  if (stage == INITSTAGE_LOCAL) {
32  defaultTimeToLive = 16; // par("timeToLive");
33  defaultMCTimeToLive = 16; // par("multicastTimeToLive");
35  }
36  else if (stage == INITSTAGE_NETWORK_LAYER) {
37  registerService(Protocol::ipv4, gate("upperLayerIn"), gate("upperLayerOut"));
38  }
39 }

◆ numInitStages()

virtual int inet::Ipv4Encap::numInitStages ( ) const
inlineoverrideprotectedvirtual
37 { return NUM_INIT_STAGES; }

Member Data Documentation

◆ crcMode

CrcMode inet::Ipv4Encap::crcMode = CRC_MODE_UNDEFINED
protected

Referenced by encapsulate(), and initialize().

◆ defaultMCTimeToLive

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

Referenced by encapsulate(), and initialize().

◆ defaultTimeToLive

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

Referenced by encapsulate(), and initialize().

◆ socketIdToSocketDescriptor

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

Referenced by handleMessage(), and handleRequest().

◆ upperProtocols

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

Referenced by handleMessage().


The documentation for this class was generated from the following files:
inet::ProtocolGroup::getProtocolNumber
int getProtocolNumber(const Protocol *protocol) const
Definition: ProtocolGroup.cc:46
protocol
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down protocol
Definition: IUdp-gates.txt:25
inet::Ipv4Encap::socketIdToSocketDescriptor
std::map< int, SocketDescriptor * > socketIdToSocketDescriptor
Definition: Ipv4Encap.h:34
inet::Ipv4Encap::crcMode
CrcMode crcMode
Definition: Ipv4Encap.h:30
DscpReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DscpReq
Definition: IUdp-gates.txt:25
inet::Protocol::ipv4
static const Protocol ipv4
Definition: Protocol.h:93
inet::Ipv4Encap::upperProtocols
std::set< const Protocol * > upperProtocols
Definition: Ipv4Encap.h:33
inet::CRC_COMPUTED
@ CRC_COMPUTED
Definition: CrcMode_m.h:59
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
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.
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
inet::Ipv4Encap::defaultMCTimeToLive
int defaultMCTimeToLive
Definition: Ipv4Encap.h:32
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::insertNetworkProtocolHeader
void insertNetworkProtocolHeader(Packet *packet, const Protocol &protocol, const Ptr< NetworkHeaderBase > &header)
Definition: L3Tools.cc:70
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
ctrl
removed ctrl
Definition: IUdp-gates.txt:7
inet::contains
bool contains(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:65
HopLimitReq
removed HopLimitReq
Definition: IUdp-gates.txt:11
inet::Ipv4Encap::handleRequest
virtual void handleRequest(Request *request)
Definition: Ipv4Encap.cc:93
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::Ipv4Encap::defaultTimeToLive
int defaultTimeToLive
Definition: Ipv4Encap.h:31
inet::TcpIpChecksum::checksum
static uint16_t checksum(const void *addr, unsigned int count)
Definition: TcpIpChecksum.h:33
inet::CRC_DECLARED_CORRECT
@ CRC_DECLARED_CORRECT
Definition: CrcMode_m.h:57
inet::CRC_DECLARED_INCORRECT
@ CRC_DECLARED_INCORRECT
Definition: CrcMode_m.h:58
inet::Ipv4Encap::decapsulate
virtual void decapsulate(Packet *packet)
Definition: Ipv4Encap.cc:204
inet::ProtocolGroup::ipprotocol
static ProtocolGroup ipprotocol
Definition: ProtocolGroup.h:42
inet::ProtocolGroup::getProtocol
const Protocol * getProtocol(int protocolNumber) const
Definition: ProtocolGroup.cc:31
inet::Ipv4Encap::encapsulate
virtual void encapsulate(Packet *packet)
Definition: Ipv4Encap.cc:125
inet::IpProtocolId
IpProtocolId
Enum generated from inet/networklayer/common/IpProtocolId.msg:17 by opp_msgtool.
Definition: IpProtocolId_m.h:90
inet::containsKey
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80