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

Ipv6 implementation. More...

#include <Ipv6.h>

Inheritance diagram for inet::Ipv6:
inet::NetfilterBase inet::LifecycleUnsupported inet::INetworkProtocol inet::DefaultProtocolRegistrationListener inet::INetfilter inet::ILifecycle inet::IProtocolRegistrationListener

Classes

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

Public Member Functions

 Ipv6 ()
 
 ~Ipv6 ()
 
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
 Adds the provided hook to the list of registered hooks that will be called by the network layer when it processes datagrams. More...
 
virtual void unregisterHook (IHook *hook) override
 Removes the provided hook from the list of registered hooks. More...
 
virtual void dropQueuedDatagram (const Packet *packet) override
 Requests the network layer to drop the datagram, because it's no longer needed. More...
 
virtual void reinjectQueuedDatagram (const Packet *packet) override
 Requests the network layer to restart the processing of the datagram. More...
 
- Public Member Functions inherited from inet::NetfilterBase
virtual ~NetfilterBase ()
 
- Public Member Functions inherited from inet::INetfilter
virtual ~INetfilter ()
 
- Public Member Functions inherited from inet::LifecycleUnsupported
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 
- 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
 

Protected Types

typedef std::list< QueuedDatagramForHookDatagramQueueForHooks
 

Protected Member Functions

virtual NetworkInterfacegetSourceInterfaceFrom (Packet *msg)
 
virtual void refreshDisplay () const override
 
virtual void encapsulate (Packet *transportPacket)
 Encapsulate packet coming from higher layers into IPv6Datagram. More...
 
virtual void preroutingFinish (Packet *packet, const NetworkInterface *fromIE, const NetworkInterface *destIE, Ipv6Address nextHopAddr)
 
virtual void handleMessage (cMessage *msg) override
 
virtual void handleRequest (Request *request)
 
virtual void handleMessageFromHL (Packet *msg)
 Handle messages (typically packets to be send in Ipv6) from transport or ICMP. More...
 
virtual void datagramLocalOut (Packet *packet, const NetworkInterface *destIE, Ipv6Address requestedNextHopAddress)
 
virtual void handleReceivedIcmp (Packet *msg)
 Handle incoming ICMP messages. More...
 
virtual void routePacket (Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, Ipv6Address requestedNextHopAddress, bool fromHL)
 Performs routing. More...
 
virtual void resolveMACAddressAndSendPacket (Packet *packet, int interfaceID, Ipv6Address nextHop, bool fromHL)
 
virtual void routeMulticastPacket (Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, bool fromHL)
 Forwards packets to all multicast destinations, using fragmentAndSend(). More...
 
virtual void fragmentPostRouting (Packet *packet, const NetworkInterface *ie, const MacAddress &nextHopAddr, bool fromHL)
 
virtual void fragmentAndSend (Packet *packet, const NetworkInterface *destIE, const MacAddress &nextHopAddr, bool fromHL)
 Performs fragmentation if needed, and sends the original datagram or the fragments through the specified interface. More...
 
virtual void localDeliver (Packet *packet, const NetworkInterface *fromIE)
 Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL(). More...
 
virtual void decapsulate (Packet *packet)
 Decapsulate packet. More...
 
virtual void sendDatagramToOutput (Packet *packet, const NetworkInterface *destIE, const MacAddress &macAddr)
 Last hoplimit check, then send datagram on the given interface. More...
 
void sendIcmpError (Packet *origPacket, Icmpv6Type type, int code)
 
IHook::Result datagramPreRoutingHook (Packet *packet)
 called before a packet arriving from the network is routed More...
 
IHook::Result datagramForwardHook (Packet *packet)
 called before a packet arriving from the network is delivered via the network More...
 
IHook::Result datagramPostRoutingHook (Packet *packet, const NetworkInterface *inIE, const NetworkInterface *&outIE, L3Address &nextHopAddr)
 called before a packet is delivered via the network More...
 
IHook::Result datagramLocalInHook (Packet *packet, const NetworkInterface *inIE)
 called before a packet arriving from the network is delivered locally More...
 
IHook::Result datagramLocalOutHook (Packet *packet)
 called before a packet arriving locally is delivered More...
 
virtual void initialize (int stage) override
 Initialization. More...
 
virtual int numInitStages () const override
 
bool determineOutputInterface (const Ipv6Address &destAddress, Ipv6Address &nextHop, int &interfaceId, Packet *packet, bool fromHL)
 Determines the correct interface for the specified destination address. More...
 

Protected Attributes

ModuleRefByPar< IInterfaceTableift
 
ModuleRefByPar< Ipv6RoutingTablert
 
ModuleRefByPar< Ipv6NeighbourDiscoverynd
 
ModuleRefByPar< Icmpv6icmp
 
ModuleRefByPar< Ipv6Tunnelingtunneling
 
unsigned int curFragmentId = -1
 
Ipv6FragBuf fragbuf
 
simtime_t lastCheckTime
 
std::set< const Protocol * > upperProtocols
 
std::map< int, SocketDescriptor * > socketIdToSocketDescriptor
 
int numMulticast = 0
 
int numLocalDeliver = 0
 
int numDropped = 0
 
int numUnroutable = 0
 
int numForwarded = 0
 
DatagramQueueForHooks queuedDatagramsForHooks
 
- Protected Attributes inherited from inet::NetfilterBase
std::multimap< int, IHook * > hooks
 

Detailed Description

Ipv6 implementation.

Member Typedef Documentation

◆ DatagramQueueForHooks

Constructor & Destructor Documentation

◆ Ipv6()

inet::Ipv6::Ipv6 ( )
43  :
44  curFragmentId(0)
45 {
46 }

◆ ~Ipv6()

inet::Ipv6::~Ipv6 ( )
49 {
50  for (auto it : socketIdToSocketDescriptor)
51  delete it.second;
52 
53  for (auto& elem : queuedDatagramsForHooks) {
54  delete elem.packet;
55  }
56 }

Member Function Documentation

◆ datagramForwardHook()

INetfilter::IHook::Result inet::Ipv6::datagramForwardHook ( Packet packet)
protected

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

1156 {
1157  for (auto& elem : hooks) {
1158  IHook::Result r = elem.second->datagramForwardHook(packet);
1159  switch (r) {
1161  break; // continue iteration
1162 
1164  delete packet;
1165  return r;
1166 
1168  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::FORWARD));
1169  return r;
1170 
1172  return r;
1173 
1174  default:
1175  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1176  }
1177  }
1179 }

◆ datagramLocalInHook()

INetfilter::IHook::Result inet::Ipv6::datagramLocalInHook ( Packet packet,
const NetworkInterface inIE 
)
protected

called before a packet arriving from the network is delivered locally

1208 {
1209  for (auto& elem : hooks) {
1210  IHook::Result r = elem.second->datagramLocalInHook(packet);
1211  switch (r) {
1213  break; // continue iteration
1214 
1216  delete packet;
1217  return r;
1218 
1220  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::LOCALIN));
1221  return r;
1222 
1224  return r;
1225 
1226  default:
1227  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1228  }
1229  }
1231 }

◆ datagramLocalOut()

void inet::Ipv6::datagramLocalOut ( Packet packet,
const NetworkInterface destIE,
Ipv6Address  requestedNextHopAddress 
)
protectedvirtual
366 {
367  const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
368  // route packet
369  if (destIE != nullptr)
370  fragmentPostRouting(packet, destIE, MacAddress::BROADCAST_ADDRESS, true); // FIXME what MAC address to use?
371  else if (!ipv6Header->getDestAddress().isMulticast())
372  routePacket(packet, destIE, nullptr, requestedNextHopAddress, true);
373  else
374  routeMulticastPacket(packet, destIE, nullptr, true);
375 }

Referenced by handleMessage(), handleMessageFromHL(), and reinjectQueuedDatagram().

◆ datagramLocalOutHook()

INetfilter::IHook::Result inet::Ipv6::datagramLocalOutHook ( Packet packet)
protected

called before a packet arriving locally is delivered

1234 {
1235  for (auto& elem : hooks) {
1236  IHook::Result r = elem.second->datagramLocalOutHook(packet);
1237  switch (r) {
1239  break; // continue iteration
1240 
1242  delete packet;
1243  return r;
1244 
1246  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::LOCALOUT));
1247  return r;
1248 
1250  return r;
1251 
1252  default:
1253  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1254  }
1255  }
1257 }

Referenced by handleMessage(), and handleMessageFromHL().

◆ datagramPostRoutingHook()

INetfilter::IHook::Result inet::Ipv6::datagramPostRoutingHook ( Packet packet,
const NetworkInterface inIE,
const NetworkInterface *&  outIE,
L3Address nextHopAddr 
)
protected

called before a packet is delivered via the network

1182 {
1183  for (auto& elem : hooks) {
1184  IHook::Result r = elem.second->datagramPostRoutingHook(packet);
1185  switch (r) {
1187  break; // continue iteration
1188 
1190  delete packet;
1191  return r;
1192 
1194  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::POSTROUTING));
1195  return r;
1196 
1198  return r;
1199 
1200  default:
1201  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1202  }
1203  }
1205 }

Referenced by fragmentPostRouting().

◆ datagramPreRoutingHook()

INetfilter::IHook::Result inet::Ipv6::datagramPreRoutingHook ( Packet packet)
protected

called before a packet arriving from the network is routed

1130 {
1131  for (auto& elem : hooks) {
1132  IHook::Result r = elem.second->datagramPreRoutingHook(packet);
1133  switch (r) {
1135  break; // continue iteration
1136 
1138  delete packet;
1139  return r;
1140 
1142  queuedDatagramsForHooks.push_back(QueuedDatagramForHook(packet, INetfilter::IHook::PREROUTING));
1143  return r;
1144 
1146  return r;
1147 
1148  default:
1149  throw cRuntimeError("Unknown Hook::Result value: %d", (int)r);
1150  }
1151  }
1153 }

Referenced by handleMessage().

◆ decapsulate()

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

Decapsulate packet.

758 {
759  // decapsulate transport packet
760  auto ipv6Header = packet->popAtFront<Ipv6Header>();
761 
762  B payloadLength = ipv6Header->getPayloadLength();
763  if (payloadLength != B(0)) { // payloadLength == 0 occured with Jumbo payload
764  ASSERT(payloadLength <= packet->getDataLength());
765  // drop padding behind the payload:
766  if (payloadLength < packet->getDataLength())
767  packet->setBackOffset(packet->getFrontOffset() + payloadLength);
768  }
769 
770  // create and fill in control info
771  packet->addTagIfAbsent<TosInd>()->setTos(ipv6Header->getTrafficClass());
772  packet->addTagIfAbsent<DscpInd>()->setDifferentiatedServicesCodePoint(ipv6Header->getDscp());
773  packet->addTagIfAbsent<EcnInd>()->setExplicitCongestionNotification(ipv6Header->getEcn());
774  packet->addTagIfAbsent<DispatchProtocolInd>()->setProtocol(&Protocol::ipv6);
775  auto payloadProtocol = ipv6Header->getProtocol();
776  packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(payloadProtocol);
777  packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(payloadProtocol);
778  auto networkProtocolInd = packet->addTagIfAbsent<NetworkProtocolInd>();
779  networkProtocolInd->setProtocol(&Protocol::ipv6);
780  networkProtocolInd->setNetworkProtocolHeader(ipv6Header);
781  auto l3AddressInd = packet->addTagIfAbsent<L3AddressInd>();
782  l3AddressInd->setSrcAddress(ipv6Header->getSrcAddress());
783  l3AddressInd->setDestAddress(ipv6Header->getDestAddress());
784  packet->addTagIfAbsent<HopLimitInd>()->setHopLimit(ipv6Header->getHopLimit());
785 }

Referenced by localDeliver().

◆ determineOutputInterface()

bool inet::Ipv6::determineOutputInterface ( const Ipv6Address destAddress,
Ipv6Address nextHop,
int &  interfaceId,
Packet packet,
bool  fromHL 
)
protected

Determines the correct interface for the specified destination address.

The nextHop and interfaceId are output parameter.

973 {
974  // try destination cache
975  nextHop = rt->lookupDestCache(destAddress, interfaceId);
976 
977  if (interfaceId == -1) {
978  // address not in destination cache: do longest prefix match in routing table
979  EV_INFO << "do longest prefix match in routing table" << endl;
980  const Ipv6Route *route = rt->doLongestPrefixMatch(destAddress);
981  EV_INFO << "finished longest prefix match in routing table" << endl;
982  if (!route) {
983  if (rt->isRouter()) {
984  EV_INFO << "unroutable, sending ICMPv6_DESTINATION_UNREACHABLE\n";
985  numUnroutable++;
986  sendIcmpError(packet, ICMPv6_DESTINATION_UNREACHABLE, 0); // FIXME check ICMP 'code'
987  }
988  else { // host
989  EV_INFO << "no match in routing table, passing datagram to Neighbour Discovery module for default router selection\n";
990  Ipv6NdControlInfo *ctrl = new Ipv6NdControlInfo();
991  ctrl->setFromHL(fromHL);
992  ctrl->setNextHop(nextHop);
993  ctrl->setInterfaceId(interfaceId);
994  packet->cMessage::setControlInfo(ctrl);
995  send(packet, "ndOut");
996  }
997  return false;
998  }
999  interfaceId = route->getInterface() ? route->getInterface()->getInterfaceId() : -1;
1000  nextHop = route->getNextHop();
1001  if (nextHop.isUnspecified())
1002  nextHop = destAddress; // next hop is the host itself
1003 
1004  // add result into destination cache
1005  rt->updateDestCache(destAddress, nextHop, interfaceId, route->getExpiryTime());
1006  }
1007 
1008  return true;
1009 }

Referenced by routePacket().

◆ dropQueuedDatagram()

void inet::Ipv6::dropQueuedDatagram ( const Packet daragram)
overridevirtual

Requests the network layer to drop the datagram, because it's no longer needed.

This function may be used by a reactive routing protocol when it cancels the route discovery process.

Implements inet::INetfilter.

1079 {
1080  Enter_Method("dropQueuedDatagram()");
1081  for (auto iter = queuedDatagramsForHooks.begin(); iter != queuedDatagramsForHooks.end(); iter++) {
1082  if (iter->packet == packet) {
1083  delete packet;
1084  queuedDatagramsForHooks.erase(iter);
1085  return;
1086  }
1087  }
1088 }

◆ encapsulate()

void inet::Ipv6::encapsulate ( Packet transportPacket)
protectedvirtual

Encapsulate packet coming from higher layers into IPv6Datagram.

788 {
789  auto ipv6Header = makeShared<Ipv6Header>(); // TODO transportPacket->getName());
790 
791  auto& addresses = transportPacket->removeTag<L3AddressReq>();
792  Ipv6Address src = addresses->getSrcAddress().toIpv6();
793  Ipv6Address dest = addresses->getDestAddress().toIpv6();
794 
795  auto hopLimitReq = transportPacket->removeTagIfPresent<HopLimitReq>();
796  short ttl = (hopLimitReq != nullptr) ? hopLimitReq->getHopLimit() : -1;
797 
798  ipv6Header->setPayloadLength(transportPacket->getDataLength());
799 
800  // set source and destination address
801  ipv6Header->setDestAddress(dest);
802  ipv6Header->setSrcAddress(src);
803 
804  // set other fields
805  if (auto& tosReq = transportPacket->removeTagIfPresent<TosReq>()) {
806  ipv6Header->setTrafficClass(tosReq->getTos());
807  if (transportPacket->findTag<DscpReq>())
808  throw cRuntimeError("TosReq and DscpReq found together");
809  if (transportPacket->findTag<EcnReq>())
810  throw cRuntimeError("TosReq and EcnReq found together");
811  }
812  if (auto& dscpReq = transportPacket->removeTagIfPresent<DscpReq>())
813  ipv6Header->setDscp(dscpReq->getDifferentiatedServicesCodePoint());
814  if (auto& ecnReq = transportPacket->removeTagIfPresent<EcnReq>())
815  ipv6Header->setEcn(ecnReq->getExplicitCongestionNotification());
816 
817  ipv6Header->setHopLimit(ttl != -1 ? ttl : 32); // FIXME use iface hop limit instead of 32?
818  ASSERT(ipv6Header->getHopLimit() > 0);
819  ipv6Header->setProtocolId(static_cast<IpProtocolId>(ProtocolGroup::ipprotocol.getProtocolNumber(transportPacket->getTag<PacketProtocolTag>()->getProtocol())));
820 
821  // #### Move extension headers from ctrlInfo to datagram if present
822  auto extHeadersTag = transportPacket->removeTagIfPresent<Ipv6ExtHeaderReq>();
823  while (extHeadersTag && 0 < extHeadersTag->getExtensionHeaderArraySize()) {
824  Ipv6ExtensionHeader *extHeader = extHeadersTag->removeFirstExtensionHeader();
825  ipv6Header->addExtensionHeader(extHeader);
826 // EV << "Move extension header to datagram." << endl;
827  }
828 
829  ipv6Header->setChunkLength(B(ipv6Header->calculateHeaderByteLength()));
830  transportPacket->trimFront();
831  insertNetworkProtocolHeader(transportPacket, Protocol::ipv6, ipv6Header);
832  // setting IP options is currently not supported
833 }

Referenced by handleMessageFromHL().

◆ fragmentAndSend()

void inet::Ipv6::fragmentAndSend ( Packet packet,
const NetworkInterface destIE,
const MacAddress nextHopAddr,
bool  fromHL 
)
protectedvirtual

Performs fragmentation if needed, and sends the original datagram or the fragments through the specified interface.

862 {
863  auto ipv6Header = packet->peekAtFront<Ipv6Header>();
864  // hop counter check
865  if (ipv6Header->getHopLimit() <= 0) {
866  // drop datagram, destruction responsibility in ICMP
867  EV_INFO << "datagram hopLimit reached zero, sending ICMPv6_TIME_EXCEEDED\n";
868  sendIcmpError(packet, ICMPv6_TIME_EXCEEDED, 0); // FIXME check icmp 'code'
869  return;
870  }
871 
872  // ensure source address is filled
873  if (fromHL && ipv6Header->getSrcAddress().isUnspecified() &&
874  !ipv6Header->getDestAddress().isSolicitedNodeMulticastAddress())
875  {
876  // source address can be unspecified during DAD
877  const Ipv6Address& srcAddr = ie->getProtocolData<Ipv6InterfaceData>()->getPreferredAddress();
878  ASSERT(!srcAddr.isUnspecified()); // FIXME what if we don't have an address yet?
879 
880  // TODO factor out
881  packet->eraseAtFront(ipv6Header->getChunkLength());
882  auto ipv6HeaderCopy = staticPtrCast<Ipv6Header>(ipv6Header->dupShared());
883  // TODO dup or mark ipv4Header->markMutableIfExclusivelyOwned();
884  ipv6HeaderCopy->setSrcAddress(srcAddr);
885  packet->insertAtFront(ipv6HeaderCopy);
886  ipv6Header = ipv6HeaderCopy;
887 
888  #ifdef INET_WITH_xMIPv6
889  // if the datagram has a tentative address as source we have to reschedule it
890  // as it can not be sent before the address' tentative status is cleared - CB
891  if (ie->getProtocolData<Ipv6InterfaceData>()->isTentativeAddress(srcAddr)) {
892  EV_INFO << "Source address is tentative - enqueueing datagram for later resubmission." << endl;
893  ScheduledDatagram *sDgram = new ScheduledDatagram(packet, ipv6Header.get(), ie, nextHopAddr, fromHL);
894 // queue.insert(sDgram);
895  scheduleAfter(1.0, sDgram); // KLUDGE wait 1s for tentative->permanent. MISSING: timeout for drop or send back icmpv6 error, processing signals from IE, need another msg queue for waiting (similar to Ipv4 ARP)
896  return;
897  }
898  #endif /* INET_WITH_xMIPv6 */
899  }
900 
901  int mtu = ie->getMtu();
902 
903  // check if datagram does not require fragmentation
904  if (packet->getTotalLength() <= B(mtu)) {
905  sendDatagramToOutput(packet, ie, nextHopAddr);
906  return;
907  }
908 
909  // routed datagrams are not fragmented
910  if (!fromHL) {
911  // FIXME check for multicast datagrams, how many ICMP error should be sent
912  sendIcmpError(packet, ICMPv6_PACKET_TOO_BIG, 0); // TODO set MTU
913  return;
914  }
915 
916  // create and send fragments
917  ipv6Header = packet->popAtFront<Ipv6Header>();
918  B headerLength = ipv6Header->calculateUnfragmentableHeaderByteLength();
919  B payloadLength = packet->getDataLength();
920  B fragmentLength = ((B(mtu) - headerLength - IPv6_FRAGMENT_HEADER_LENGTH) / 8) * 8;
921  ASSERT(fragmentLength > B(0));
922 
923  int noOfFragments = B(payloadLength + fragmentLength - B(1)).get() / B(fragmentLength).get();
924  EV_INFO << "Breaking datagram into " << noOfFragments << " fragments\n";
925  std::string fragMsgName = packet->getName();
926  fragMsgName += "-frag-";
927 
928  // FIXME is need to remove unfragmentable header extensions? see calculateUnfragmentableHeaderByteLength()
929 
930  unsigned int identification = curFragmentId++;
931  for (B offset = B(0); offset < payloadLength; offset += fragmentLength) {
932  bool lastFragment = (offset + fragmentLength >= payloadLength);
933  B thisFragmentLength = lastFragment ? payloadLength - offset : fragmentLength;
934 
935  std::string curFragName = fragMsgName + std::to_string(offset.get());
936  if (lastFragment)
937  curFragName += "-last";
938  Packet *fragPk = new Packet(curFragName.c_str());
939  const auto& fragHdr = staticPtrCast<Ipv6Header>(ipv6Header->dupShared());
940  auto *fh = new Ipv6FragmentHeader();
941  fh->setIdentification(identification);
942  fh->setFragmentOffset(offset.get());
943  fh->setMoreFragments(!lastFragment);
944  fragHdr->addExtensionHeader(fh);
945  fragHdr->setChunkLength(headerLength + fh->getByteLength()); // KLUDGE
946  fragPk->insertAtFront(fragHdr);
947  fragPk->insertAtBack(packet->peekDataAt(offset, thisFragmentLength));
948 
949  ASSERT(fragPk->getDataLength() == headerLength + fh->getByteLength() + thisFragmentLength);
950 
951  sendDatagramToOutput(fragPk, ie, nextHopAddr);
952  }
953 
954  delete packet;
955 }

Referenced by fragmentPostRouting().

◆ fragmentPostRouting()

void inet::Ipv6::fragmentPostRouting ( Packet packet,
const NetworkInterface ie,
const MacAddress nextHopAddr,
bool  fromHL 
)
protectedvirtual
836 {
837 // const NetworkInterface *destIE = ift->getInterfaceById(packet->getTag<InterfaceReq>()->getInterfaceId());
838  auto ipv6Header = packet->peekAtFront<Ipv6Header>();
839  // ensure source address is filled
840  if (fromHL && ipv6Header->getSrcAddress().isUnspecified() &&
841  !ipv6Header->getDestAddress().isSolicitedNodeMulticastAddress())
842  {
843  // source address can be unspecified during DAD
844  const Ipv6Address& srcAddr = ie->getProtocolData<Ipv6InterfaceData>()->getPreferredAddress();
845  ASSERT(!srcAddr.isUnspecified()); // FIXME what if we don't have an address yet?
846 
847  // TODO factor out
848  ipv6Header = nullptr;
849  auto newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
850  newIpv6Header->setSrcAddress(srcAddr);
851  insertNetworkProtocolHeader(packet, Protocol::ipv6, newIpv6Header);
852  ipv6Header = newIpv6Header;
853  }
854  const NetworkInterface *fromIe = fromHL ? nullptr : ift->getInterfaceById(packet->getTag<InterfaceInd>()->getInterfaceId());
855  L3Address nextHopAddr_(nextHopAddr);
856  if (datagramPostRoutingHook(packet, fromIe, ie, nextHopAddr_) == INetfilter::IHook::ACCEPT) {
857  fragmentAndSend(packet, ie, nextHopAddr_.toMac(), fromHL);
858  }
859 }

Referenced by datagramLocalOut(), handleMessage(), resolveMACAddressAndSendPacket(), and routeMulticastPacket().

◆ getSourceInterfaceFrom()

NetworkInterface * inet::Ipv6::getSourceInterfaceFrom ( Packet msg)
protectedvirtual
277 {
278  const auto& interfaceInd = packet->findTag<InterfaceInd>();
279  return interfaceInd != nullptr ? ift->getInterfaceById(interfaceInd->getInterfaceId()) : nullptr;
280 }

Referenced by handleMessage().

◆ handleMessage()

void inet::Ipv6::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
188 {
189  auto& tags = check_and_cast<ITaggedObject *>(msg)->getTags();
190 
191 #ifdef INET_WITH_xMIPv6
192  // 28.09.07 - CB
193  // support for rescheduling datagrams which are supposed to be sent over
194  // a tentative address.
195  if (msg->isSelfMessage()) {
196  ScheduledDatagram *sDgram = check_and_cast<ScheduledDatagram *>(msg);
197 
198  // take care of datagram which was supposed to be sent over a tentative address
199  if (sDgram->getIE()->getProtocolData<Ipv6InterfaceData>()->isTentativeAddress(sDgram->getSrcAddress())) {
200  // address is still tentative - enqueue again
201 // queue.insert(sDgram);
202  scheduleAfter(1.0, sDgram); // KLUDGE wait 1s for tentative->permanent. MISSING: timeout for drop or send back icmpv6 error, processing signals from IE, need another msg queue for waiting (similar to Ipv4 ARP)
203  }
204  else {
205  // address is not tentative anymore - send out datagram
206  numForwarded++;
207  fragmentPostRouting(sDgram->removeDatagram(), sDgram->getIE(), sDgram->getMacAddress(), sDgram->getFromHL());
208  delete sDgram;
209  }
210  }
211  else
212 #endif /* INET_WITH_xMIPv6 */
213 
214  if (auto request = dynamic_cast<Request *>(msg))
215  handleRequest(request);
216  else if (msg->getArrivalGate()->isName("transportIn")
217  || (msg->arrivedOn("ndIn") && tags.getTag<PacketProtocolTag>()->getProtocol() == &Protocol::icmpv6)
218  || (msg->arrivedOn("upperTunnelingIn")) // for tunneling support-CB
219 #ifdef INET_WITH_xMIPv6
220  || (msg->arrivedOn("xMIPv6In") && tags.getTag<PacketProtocolTag>()->getProtocol() == &Protocol::mobileipv6)
221 #endif /* INET_WITH_xMIPv6 */
222  )
223  {
224  // packet from upper layers, tunnel link-layer output or ND: encapsulate and send out
225  handleMessageFromHL(check_and_cast<Packet *>(msg));
226  }
227  else if (msg->arrivedOn("ndIn") && tags.getTag<PacketProtocolTag>()->getProtocol() == &Protocol::ipv6) {
228  auto packet = check_and_cast<Packet *>(msg);
229  Ipv6NdControlInfo *ctrl = check_and_cast<Ipv6NdControlInfo *>(msg->removeControlInfo());
230  bool fromHL = ctrl->getFromHL();
231  Ipv6Address nextHop = ctrl->getNextHop();
232  int interfaceId = ctrl->getInterfaceId();
233  delete ctrl;
234  resolveMACAddressAndSendPacket(packet, interfaceId, nextHop, fromHL);
235  }
236  else {
237  // datagram from network or from ND: localDeliver and/or route
238  auto packet = check_and_cast<Packet *>(msg);
239  auto ipv6Header = packet->peekAtFront<Ipv6Header>();
240  packet->addTagIfAbsent<NetworkProtocolInd>()->setProtocol(&Protocol::ipv6);
241  packet->addTagIfAbsent<NetworkProtocolInd>()->setNetworkProtocolHeader(ipv6Header);
242  bool fromHL = false;
243  if (packet->getArrivalGate()->isName("ndIn")) {
244  Ipv6NdControlInfo *ctrl = check_and_cast<Ipv6NdControlInfo *>(msg->removeControlInfo());
245  fromHL = ctrl->getFromHL();
246  Ipv6Address nextHop = ctrl->getNextHop();
247  int interfaceId = ctrl->getInterfaceId();
248  delete ctrl;
249  resolveMACAddressAndSendPacket(packet, interfaceId, nextHop, fromHL);
250  }
251  else
253 
254  // Do not handle header biterrors, because
255  // 1. Ipv6 header does not contain checksum for the header fields, each field is
256  // validated when they are processed.
257  // 2. The Ethernet or PPP frame is dropped by the link-layer if there is a transmission error.
258  ASSERT(!packet->hasBitError());
259 
260  const NetworkInterface *fromIE = getSourceInterfaceFrom(packet);
261  const NetworkInterface *destIE = nullptr;
262  L3Address nextHop(Ipv6Address::UNSPECIFIED_ADDRESS);
263  if (fromHL) {
264  // remove control info
265  delete packet->removeControlInfo();
267  datagramLocalOut(packet, destIE, nextHop.toIpv6());
268  }
269  else {
271  preroutingFinish(packet, fromIE, destIE, nextHop.toIpv6());
272  }
273  }
274 }

◆ handleMessageFromHL()

void inet::Ipv6::handleMessageFromHL ( Packet msg)
protectedvirtual

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

Invokes encapsulate(), then routePacket().

297 {
298  emit(packetReceivedFromUpperSignal, packet);
299 
300  // if no interface exists, do not send datagram
301  if (ift->getNumInterfaces() == 0) {
302  EV_WARN << "No interfaces exist, dropping packet\n";
303  PacketDropDetails details;
304  details.setReason(NO_INTERFACE_FOUND);
305  emit(packetDroppedSignal, packet, &details);
306  delete packet;
307  return;
308  }
309 
310  const auto& ifTag = packet->findTag<InterfaceReq>();
311  const NetworkInterface *destIE = ifTag ? ift->getInterfaceById(ifTag->getInterfaceId()) : nullptr;
312 
313  // when source address was given, use it; otherwise it'll get the address
314  // of the outgoing interface after routing
315  Ipv6Address src = packet->getTag<L3AddressReq>()->getSrcAddress().toIpv6();
316  if (!src.isUnspecified()) {
317  // if interface parameter does not match existing interface, do not send datagram
318  if (rt->getInterfaceByAddress(src) == nullptr) {
319 #ifdef INET_WITH_xMIPv6
320  EV_WARN << "Encapsulation failed - dropping packet." << endl;
321  PacketDropDetails details;
322  details.setReason(NO_INTERFACE_FOUND);
323  emit(packetDroppedSignal, packet, &details);
324  delete packet;
325  return;
326 #else /* INET_WITH_xMIPv6 */
327  throw cRuntimeError("Wrong source address %s in (%s)%s: no interface with such address",
328  src.str().c_str(), packet->getClassName(), packet->getFullName());
329 #endif /* INET_WITH_xMIPv6 */
330  }
331  }
332 
333  // encapsulate upper-layer packet into IPv6Datagram
334  encapsulate(packet);
335 
336  auto ipv6Header = packet->peekAtFront<Ipv6Header>();
337  Ipv6Address destAddress = ipv6Header->getDestAddress();
338 
339  // check for local delivery
340  if (!destAddress.isMulticast() && rt->isLocalAddress(destAddress)) {
341  EV_INFO << "local delivery\n";
342  if (ipv6Header->getSrcAddress().isUnspecified()) {
343  // allows two apps on the same host to communicate
344  packet->trim();
345  ipv6Header = nullptr;
346  const auto& newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
347  newIpv6Header->setSrcAddress(destAddress);
348  insertNetworkProtocolHeader(packet, Protocol::ipv6, newIpv6Header);
349  ipv6Header = newIpv6Header;
350  }
351 
352  if (destIE && !destIE->isLoopback()) {
353  EV_INFO << "datagram destination address is local, ignoring destination interface specified in the control info\n";
354  destIE = nullptr;
355  }
356  if (!destIE)
357  destIE = ift->findFirstLoopbackInterface();
358  ASSERT(destIE);
359  }
360  L3Address nextHopAddr(Ipv6Address::UNSPECIFIED_ADDRESS);
362  datagramLocalOut(packet, destIE, nextHopAddr.toIpv6());
363 }

Referenced by handleMessage().

◆ handleReceivedIcmp()

void inet::Ipv6::handleReceivedIcmp ( Packet msg)
protectedvirtual

Handle incoming ICMP messages.

745 {
746  const auto& icmpHeader = msg->peekAtFront<Icmpv6Header>();
747  if (dynamicPtrCast<const Ipv6NdMessage>(icmpHeader) != nullptr) {
748  EV_INFO << "Neighbour Discovery packet: passing it to ND module\n";
749  send(msg, "ndOut");
750  }
751  else {
752  EV_INFO << "ICMPv6 packet: passing it to ICMPv6 module\n";
753  send(msg, "transportOut");
754  }
755 }

Referenced by localDeliver().

◆ handleRegisterProtocol()

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

Reimplemented from inet::DefaultProtocolRegistrationListener.

118 {
119  Enter_Method("handleRegisterProtocol");
120  if (gate->isName("transportOut"))
121  upperProtocols.insert(&protocol);
122 }

◆ handleRegisterService()

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

Reimplemented from inet::DefaultProtocolRegistrationListener.

113 {
114  Enter_Method("handleRegisterService");
115 }

◆ handleRequest()

void inet::Ipv6::handleRequest ( Request request)
protectedvirtual
125 {
126  auto ctrl = request->getControlInfo();
127  if (ctrl == nullptr)
128  throw cRuntimeError("Request '%s' arrived without controlinfo", request->getName());
129  if (auto *command = dynamic_cast<Ipv6SocketBindCommand *>(ctrl)) {
130  int socketId = request->getTag<SocketReq>()->getSocketId();
131  SocketDescriptor *descriptor = new SocketDescriptor(socketId, command->getProtocol()->getId(), command->getLocalAddress());
132  socketIdToSocketDescriptor[socketId] = descriptor;
133  delete request;
134  }
135  else if (auto *command = dynamic_cast<Ipv6SocketConnectCommand *>(ctrl)) {
136  int socketId = request->getTag<SocketReq>()->getSocketId();
137  if (!containsKey(socketIdToSocketDescriptor, socketId))
138  throw cRuntimeError("Ipv6Socket: should use bind() before connect()");
139  socketIdToSocketDescriptor[socketId]->remoteAddress = command->getRemoteAddress();
140  delete request;
141  }
142  else if (dynamic_cast<Ipv6SocketCloseCommand *>(ctrl) != nullptr) {
143  int socketId = 0;
144  request->getTag<SocketReq>()->getSocketId();
145  auto it = socketIdToSocketDescriptor.find(socketId);
146  if (it != socketIdToSocketDescriptor.end()) {
147  delete it->second;
148  socketIdToSocketDescriptor.erase(it);
149  auto indication = new Indication("closed", IPv6_I_SOCKET_CLOSED);
150  auto ctrl = new Ipv6SocketClosedIndication();
151  indication->setControlInfo(ctrl);
152  indication->addTag<SocketInd>()->setSocketId(socketId);
153  send(indication, "transportOut");
154  }
155  delete request;
156  }
157  else if (dynamic_cast<Ipv6SocketDestroyCommand *>(ctrl) != nullptr) {
158  int socketId = 0;
159  request->getTag<SocketReq>()->getSocketId();
160  auto it = socketIdToSocketDescriptor.find(socketId);
161  if (it != socketIdToSocketDescriptor.end()) {
162  delete it->second;
163  socketIdToSocketDescriptor.erase(it);
164  }
165  delete request;
166  }
167  else
168  throw cRuntimeError("Unknown command: '%s' with %s", request->getName(), ctrl->getClassName());
169 }

Referenced by handleMessage().

◆ initialize()

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

Initialization.

76 {
77  if (stage == INITSTAGE_LOCAL) {
78  ift.reference(this, "interfaceTableModule", true);
79  rt.reference(this, "routingTableModule", true);
80  nd.reference(this, "ipv6NeighbourDiscoveryModule", true);
81  icmp.reference(this, "icmpv6Module", true);
82  tunneling.reference(this, "ipv6TunnelingModule", true);
83 
84  curFragmentId = 0;
85  lastCheckTime = SIMTIME_ZERO;
86  fragbuf.init(icmp);
87 
88  // NetFilter:
89  hooks.clear();
91 
93 
94  WATCH(numMulticast);
95  WATCH(numLocalDeliver);
96  WATCH(numDropped);
97  WATCH(numUnroutable);
98  WATCH(numForwarded);
99  }
100  else if (stage == INITSTAGE_NETWORK_LAYER) {
101  cModule *node = findContainingNode(this);
102  NodeStatus *nodeStatus = node ? check_and_cast_nullable<NodeStatus *>(node->getSubmodule("status")) : nullptr;
103  bool isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
104  if (!isOperational)
105  throw cRuntimeError("This module doesn't support starting in node DOWN state");
106 
107  registerService(Protocol::ipv6, gate("transportIn"), gate("transportOut"));
108  registerProtocol(Protocol::ipv6, gate("queueOut"), gate("queueIn"));
109  }
110 }

◆ localDeliver()

void inet::Ipv6::localDeliver ( Packet packet,
const NetworkInterface fromIE 
)
protectedvirtual

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

648 {
649  const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
650 
651  // Defragmentation. skip defragmentation if datagram is not fragmented
652  const Ipv6FragmentHeader *fh = dynamic_cast<const Ipv6FragmentHeader *>(ipv6Header->findExtensionHeaderByType(IP_PROT_IPv6EXT_FRAGMENT));
653  if (fh) {
654  EV_DETAIL << "Datagram fragment: offset=" << fh->getFragmentOffset()
655  << ", MORE=" << (fh->getMoreFragments() ? "true" : "false") << ".\n";
656 
657  // erase timed out fragments in fragmentation buffer; check every 10 seconds max
658  if (simTime() >= lastCheckTime + 10) {
659  lastCheckTime = simTime();
661  }
662 
663  packet = fragbuf.addFragment(packet, ipv6Header.get(), fh, simTime());
664  if (!packet) {
665  EV_DETAIL << "No complete datagram yet.\n";
666  return;
667  }
668  EV_DETAIL << "This fragment completes the datagram.\n";
669  }
670 
671 #ifdef INET_WITH_xMIPv6
672  // #### 29.08.07 - CB
673  // check for extension headers
674  if (!processExtensionHeaders(packet, ipv6Header.get())) {
675  // ext. header processing not yet finished
676  // datagram was sent to another module or dropped
677  // -> interrupt local delivery process
678  return;
679  }
680  // #### end CB
681 #endif /* INET_WITH_xMIPv6 */
682 
683  auto origPacket = packet->dup();
684  const Protocol *protocol = ipv6Header->getProtocol();
685  auto remoteAddress(ipv6Header->getSrcAddress());
686  auto localAddress(ipv6Header->getDestAddress());
687  decapsulate(packet);
688  bool hasSocket = false;
689  for (const auto& elem : socketIdToSocketDescriptor) {
690  if (elem.second->protocolId == protocol->getId()
691  && (elem.second->localAddress.isUnspecified() || elem.second->localAddress == localAddress)
692  && (elem.second->remoteAddress.isUnspecified() || elem.second->remoteAddress == remoteAddress))
693  {
694  auto *packetCopy = packet->dup();
695  packetCopy->setKind(IPv6_I_DATA);
696  packetCopy->addTagIfAbsent<SocketInd>()->setSocketId(elem.second->socketId);
697  EV_INFO << "Passing up to socket " << elem.second->socketId << "\n";
698  emit(packetSentToUpperSignal, packetCopy);
699  send(packetCopy, "transportOut");
700  hasSocket = true;
701  }
702  }
703 
704  if (protocol == &Protocol::icmpv6) {
705  handleReceivedIcmp(packet);
706  } // Added by WEI to forward ICMPv6 msgs to ICMPv6 module.
707 #ifdef INET_WITH_xMIPv6
708  else if (protocol == &Protocol::mobileipv6) {
709  // added check for MIPv6 support to prevent nodes w/o the
710  // xMIP module from processing related messages, 4.9.07 - CB
711  if (rt->hasMipv6Support()) {
712  EV_INFO << "MIPv6 packet: passing it to xMIPv6 module\n";
713  send(packet, "xMIPv6Out");
714  }
715  else {
716  // update 12.9.07 - CB
717  /*RFC3775, 11.3.5
718  Any node that does not recognize the Mobility header will return an
719  ICMP Parameter Problem, Code 1, message to the sender of the packet*/
720  EV_INFO << "No MIPv6 support on this node!\n";
722  }
723  }
724 #endif /* INET_WITH_xMIPv6 */
725  else if (protocol == &Protocol::ipv4 || protocol == &Protocol::ipv6) {
726  EV_INFO << "Tunnelled IP datagram\n";
727  send(packet, "upperTunnelingOut");
728  }
729  else if (contains(upperProtocols, protocol)) {
730  EV_INFO << "Passing up to protocol " << *protocol << "\n";
731  emit(packetSentToUpperSignal, packet);
732  send(packet, "transportOut");
733  }
734  else if (!hasSocket) {
735  // send ICMP Destination Unreacheable error: protocol unavailable
736  EV_INFO << "Transport layer gate not connected - dropping packet!\n";
738  origPacket = nullptr; // for not delete
739  delete packet; // delete decapsulated packet
740  }
741  delete origPacket;
742 }

Referenced by routeMulticastPacket(), and routePacket().

◆ numInitStages()

virtual int inet::Ipv6::numInitStages ( ) const
inlineoverrideprotectedvirtual
227 { return NUM_INIT_STAGES; }

◆ preroutingFinish()

void inet::Ipv6::preroutingFinish ( Packet packet,
const NetworkInterface fromIE,
const NetworkInterface destIE,
Ipv6Address  nextHopAddr 
)
protectedvirtual
283 {
284  const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
285  Ipv6Address destAddr = ipv6Header->getDestAddress();
286  // remove control info
287  delete packet->removeControlInfo();
288 
289  // routepacket
290  if (!destAddr.isMulticast())
291  routePacket(packet, destIE, fromIE, nextHopAddr, false);
292  else
293  routeMulticastPacket(packet, destIE, fromIE, false);
294 }

Referenced by handleMessage(), and reinjectQueuedDatagram().

◆ refreshDisplay()

void inet::Ipv6::refreshDisplay ( ) const
overrideprotectedvirtual
172 {
173  char buf[80] = "";
174  if (numForwarded > 0)
175  sprintf(buf + strlen(buf), "fwd:%d ", numForwarded);
176  if (numLocalDeliver > 0)
177  sprintf(buf + strlen(buf), "up:%d ", numLocalDeliver);
178  if (numMulticast > 0)
179  sprintf(buf + strlen(buf), "mcast:%d ", numMulticast);
180  if (numDropped > 0)
181  sprintf(buf + strlen(buf), "DROP:%d ", numDropped);
182  if (numUnroutable > 0)
183  sprintf(buf + strlen(buf), "UNROUTABLE:%d ", numUnroutable);
184  getDisplayString().setTagArg("t", 0, buf);
185 }

◆ registerHook()

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

Adds the provided hook to the list of registered hooks that will be called by the network layer when it processes datagrams.

Reimplemented from inet::NetfilterBase.

1067 {
1068  Enter_Method("registerHook()");
1069  NetfilterBase::registerHook(priority, hook);
1070 }

◆ reinjectQueuedDatagram()

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

Requests the network layer to restart the processing of the datagram.

This function may be used by a reactive routing protocol when it completes the route discovery process.

Implements inet::INetfilter.

1091 {
1092  Enter_Method("reinjectDatagram()");
1093  for (auto iter = queuedDatagramsForHooks.begin(); iter != queuedDatagramsForHooks.end(); iter++) {
1094  if (iter->packet == packet) {
1095  Packet *datagram = iter->packet;
1096  switch (iter->hookType) {
1098  datagramLocalOut(datagram, iter->outIE, iter->nextHopAddr);
1099  break;
1100 
1102  preroutingFinish(datagram, iter->inIE, iter->outIE, iter->nextHopAddr);
1103  break;
1104 
1106 // fragmentAndSend(datagram, iter->outIE, iter->nextHopAddr);
1107  throw cRuntimeError("Re-injection of datagram queued for POSTROUTING hook not implemented");
1108  break;
1109 
1111 // reassembleAndDeliverFinish(datagram);
1112  throw cRuntimeError("Re-injection of datagram queued for LOCALIN hook not implemented");
1113  break;
1114 
1116  throw cRuntimeError("Re-injection of datagram queued for FORWARD hook not implemented");
1117  break;
1118 
1119  default:
1120  throw cRuntimeError("Unknown hook ID: %d", (int)(iter->hookType));
1121  break;
1122  }
1123  queuedDatagramsForHooks.erase(iter);
1124  return;
1125  }
1126  }
1127 }

◆ resolveMACAddressAndSendPacket()

void inet::Ipv6::resolveMACAddressAndSendPacket ( Packet packet,
int  interfaceID,
Ipv6Address  nextHop,
bool  fromHL 
)
protectedvirtual
477 {
478  const auto& ipv6Header = packet->peekAtFront<Ipv6Header>();
479  NetworkInterface *ie = ift->getInterfaceById(interfaceId);
480  ASSERT(ie != nullptr);
481  ASSERT(!nextHop.isUnspecified());
482  Ipv6Address destAddress = ipv6Header->getDestAddress();
483  EV_INFO << "next hop for " << destAddress << " is " << nextHop << ", interface " << ie->getInterfaceName() << "\n";
484 
485 #ifdef INET_WITH_xMIPv6
486  if (rt->isMobileNode()) {
487  // if the source address is the HoA and we have a CoA then drop the packet
488  // (address is topologically incorrect!)
489  if (ipv6Header->getSrcAddress() == ie->getProtocolData<Ipv6InterfaceData>()->getMNHomeAddress()
490  && !ie->getProtocolData<Ipv6InterfaceData>()->getGlobalAddress(Ipv6InterfaceData::CoA).isUnspecified())
491  {
492  EV_WARN << "Using HoA instead of CoA... dropping datagram" << endl;
493  delete packet;
494  numDropped++;
495  return;
496  }
497  }
498 #endif /* INET_WITH_xMIPv6 */
499 
500  MacAddress macAddr = nd->resolveNeighbour(nextHop, interfaceId); // might initiate NUD
501  if (macAddr.isUnspecified()) {
502  if (!ie->isPointToPoint()) {
503  EV_INFO << "no link-layer address for next hop yet, passing datagram to Neighbour Discovery module\n";
504  Ipv6NdControlInfo *ctrl = new Ipv6NdControlInfo();
505  ctrl->setFromHL(fromHL);
506  ctrl->setNextHop(nextHop);
507  ctrl->setInterfaceId(interfaceId);
508  packet->cMessage::setControlInfo(ctrl);
509  send(packet, "ndOut");
510  return;
511  }
512  }
513  else
514  EV_DETAIL << "link-layer address: " << macAddr << "\n";
515 
516  // send out datagram
517  numForwarded++;
518  fragmentPostRouting(packet, ie, macAddr, fromHL);
519 }

Referenced by handleMessage(), and routePacket().

◆ routeMulticastPacket()

void inet::Ipv6::routeMulticastPacket ( Packet packet,
const NetworkInterface destIE,
const NetworkInterface fromIE,
bool  fromHL 
)
protectedvirtual

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

522 {
523  auto ipv6Header = packet->peekAtFront<Ipv6Header>();
524  const Ipv6Address& destAddr = ipv6Header->getDestAddress();
525 
526  EV_INFO << "destination address " << destAddr << " is multicast, doing multicast routing\n";
527  numMulticast++;
528 
529  // if received from the network...
530  if (fromIE != nullptr) {
531  ASSERT(!fromHL);
532  // deliver locally
533  if (rt->isLocalAddress(destAddr)) {
534  EV_INFO << "local delivery of multicast packet\n";
535  numLocalDeliver++;
536  localDeliver(packet->dup(), fromIE);
537  }
538 
539  // if ipv6Header arrived from input gate and IP forwarding is off, delete datagram
540  if (!rt->isRouter()) {
541  EV_INFO << "forwarding is off\n";
542  delete packet;
543  return;
544  }
545 
546  // make sure scope of multicast address is large enough to be forwarded to other links
547  if (destAddr.getMulticastScope() <= 2) {
548  EV_INFO << "multicast dest address is link-local (or smaller) scope\n";
549  delete packet;
550  return;
551  }
552 
553  // hop counter decrement: only if datagram arrived from network, and will be
554  // sent out to the network (hoplimit check will be done just before sending
555  // out datagram)
556  packet->trim();
557  ipv6Header = nullptr;
558  const auto& newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
559  newIpv6Header->setHopLimit(ipv6Header->getHopLimit() - 1);
560  insertNetworkProtocolHeader(packet, Protocol::ipv6, newIpv6Header);
561  ipv6Header = newIpv6Header;
562  }
563 
564  // for now, we just send it out on every interface except on which it came. FIXME better!!!
565  EV_INFO << "sending out datagram on every interface (except incoming one)\n";
566  for (int i = 0; i < ift->getNumInterfaces(); i++) {
567  NetworkInterface *ie = ift->getInterface(i);
568  if (fromIE != ie && !ie->isLoopback())
569  fragmentPostRouting(packet->dup(), ie, MacAddress::BROADCAST_ADDRESS, fromHL);
570  }
571  delete packet;
572 
573 /* FIXME implement handling of multicast
574 
575  According to Gopi: "multicast routing table" should map
576  srcAddr+multicastDestAddr to a set of next hops (interface+nexthopAddr)
577  Where srcAddr is the multicast server, and destAddr sort of narrows it down to a given stream
578 
579  // FIXME multicast-->tunneling link (present in original IPSuite) missing from here
580 
581  // DVMRP: process datagram only if sent locally or arrived on the shortest
582  // route (provided routing table already contains srcAddr); otherwise
583  // discard and continue.
584  int inputGateIndex = datagram->getArrivalGate() ? datagram->getArrivalGate()->getIndex() : -1;
585  int shortestPathInputGateIndex = rt->outputGateIndexNo(datagram->getSrcAddress());
586  if (inputGateIndex!=-1 && shortestPathInputGateIndex!=-1 && inputGateIndex!=shortestPathInputGateIndex)
587  {
588  // FIXME count dropped
589  EV << "Packet dropped.\n";
590  delete datagram;
591  return;
592  }
593 
594  // check for local delivery
595  Ipv6Address destAddress = datagram->getDestAddress();
596  if (rt->isLocalMulticastAddress(destAddress))
597  {
598  IPv6Datagram *datagramCopy = datagram->dup();
599 
600  // FIXME code from the Mpls model: set packet dest address to routerId (???)
601  datagramCopy->setDestAddress(rt->getRouterId());
602 
603  localDeliver(datagramCopy, fromIE);
604  }
605 
606  // forward datagram only if IP forward is enabled, or sent locally
607  if (inputGateIndex!=-1 && !rt->isRouter())
608  {
609  delete datagram;
610  return;
611  }
612 
613  MulticastRoutes routes = rt->getMulticastRoutesFor(destAddress);
614  if (routes.size()==0)
615  {
616  // no destination: delete datagram
617  delete datagram;
618  }
619  else
620  {
621  // copy original datagram for multiple destinations
622  for (unsigned int i=0; i<routes.size(); i++)
623  {
624  int outputGateIndex = routes[i].interf->outputGateIndex();
625 
626  // don't forward to input port
627  if (outputGateIndex>=0 && outputGateIndex!=inputGateIndex)
628  {
629  IPv6Datagram *datagramCopy = datagram->dup();
630 
631  // set datagram source address if not yet set
632  if (datagramCopy->getSrcAddress().isUnspecified())
633  datagramCopy->setSrcAddress(ift->interfaceByPortNo(outputGateIndex)->getProtocolData<Ipv6InterfaceData>()->getIPAddress());
634 
635  // send
636  Ipv6Address nextHopAddr = routes[i].gateway;
637  fragmentPostRouting(datagramCopy, outputGateIndex, macAddr, fromHL);
638  }
639  }
640 
641  // only copies sent, delete original datagram
642  delete datagram;
643  }
644  */
645 }

Referenced by datagramLocalOut(), and preroutingFinish().

◆ routePacket()

void inet::Ipv6::routePacket ( Packet packet,
const NetworkInterface destIE,
const NetworkInterface fromIE,
Ipv6Address  requestedNextHopAddress,
bool  fromHL 
)
protectedvirtual

Performs routing.

Based on the routing decision, it dispatches to localDeliver() for local packets, to fragmentAndSend() for forwarded packets, to routeMulticastPacket() for multicast packets, or drops the packet if it's unroutable or forwarding is off.

378 {
379  auto ipv6Header = packet->peekAtFront<Ipv6Header>();
380  // TODO add option handling code here
381  Ipv6Address destAddress = ipv6Header->getDestAddress();
382 
383  EV_INFO << "Routing datagram `" << ipv6Header->getName() << "' with dest=" << destAddress << ", requested nexthop is " << requestedNextHopAddress << " on " << (destIE ? destIE->getFullName() : "unspec") << " interface: \n";
384 
385  // local delivery of unicast packets
386  if (rt->isLocalAddress(destAddress)) {
387  if (fromHL)
388  throw cRuntimeError("model error: local unicast packet arrived from HL, but handleMessageFromHL() not detected it");
389  EV_INFO << "local delivery\n";
390 
391  numLocalDeliver++;
392  localDeliver(packet, fromIE);
393  return;
394  }
395 
396  if (!fromHL) {
397  // if datagram arrived from input gate and IP forwarding is off, delete datagram
398  // yes but datagrams from the ND module is getting dropped too!-WEI
399  // so we add a 2nd condition
400  // FIXME rewrite code so that condition is cleaner --Andras
401  //if (!rt->isRouter())
402  if (!rt->isRouter() && !(packet->getArrivalGate()->isName("ndIn"))) {
403  EV_INFO << "forwarding is off, dropping packet\n";
404  numDropped++;
405  delete packet;
406  return;
407  }
408 
409  // don't forward link-local addresses or weaker
410  if (destAddress.isLinkLocal() || destAddress.isLoopback()) {
411  EV_INFO << "dest address is link-local (or weaker) scope, doesn't get forwarded\n";
412  delete packet;
413  return;
414  }
415 
416  // hop counter decrement: only if datagram arrived from network, and will be
417  // sent out to the network (hoplimit check will be done just before sending
418  // out datagram)
419  // TODO: in Ipv4, arrange TTL check like this
420  packet->trim();
421  ipv6Header = nullptr;
422  const auto& newIpv6Header = removeNetworkProtocolHeader<Ipv6Header>(packet);
423  newIpv6Header->setHopLimit(newIpv6Header->getHopLimit() - 1);
424  insertNetworkProtocolHeader(packet, Protocol::ipv6, newIpv6Header);
425  ipv6Header = newIpv6Header;
426  }
427 
428  // routing
429  int interfaceId = -1;
430  Ipv6Address nextHop(requestedNextHopAddress);
431 
432 #ifdef INET_WITH_xMIPv6
433  // tunneling support - CB
434  // check if destination is covered by tunnel lists
435  if ((ipv6Header->getProtocolId() != IP_PROT_IPv6) && // if datagram was already tunneled, don't tunnel again
436  (ipv6Header->getExtensionHeaderArraySize() == 0) && // we do not already have extension headers - FIXME check for RH2 existence
437  ((rt->isMobileNode() && rt->isHomeAddress(ipv6Header->getSrcAddress())) || // for MNs: only if source address is a HoA // 27.08.07 - CB
438  rt->isHomeAgent() || // but always check for tunnel if node is a HA
439  !rt->isMobileNode())) // or if it is a correspondent or non-MIP node
440  {
441  if (ipv6Header->getProtocolId() == IP_PROT_IPv6EXT_MOB)
442  // in case of mobility header we can only search for "real" tunnels
443  // as T2RH or HoA Opt. are not allowed with these messages
444  interfaceId = tunneling->getVIfIndexForDest(destAddress, Ipv6Tunneling::NORMAL); // 10.06.08 - CB
445 // getVIfIndexForDestForXSplitTunnel(destAddress);
446  else
447  // otherwise we can search for everything
448  interfaceId = tunneling->getVIfIndexForDest(destAddress);
449  }
450 #else // ifdef INET_WITH_xMIPv6
451  // FIXME this is not the same as the code above (when INET_WITH_xMIPv6 is defined),
452  // so tunneling examples could not work with xMIPv6
453  interfaceId = tunneling->getVIfIndexForDest(destAddress, Ipv6Tunneling::NORMAL);
454 #endif /* INET_WITH_xMIPv6 */
455 
456  if (interfaceId == -1 && destIE != nullptr)
457  interfaceId = destIE->getInterfaceId(); // set interfaceId to destIE when not tunneling
458 
459  if (interfaceId > ift->getBiggestInterfaceId()) {
460  // a virtual tunnel interface provides a path to the destination: do tunneling
461  EV_INFO << "tunneling: src addr=" << ipv6Header->getSrcAddress() << ", dest addr=" << destAddress << std::endl;
462  send(packet, "lowerTunnelingOut");
463  return;
464  }
465 
466  if (interfaceId == -1)
467  if (!determineOutputInterface(destAddress, nextHop, interfaceId, packet, fromHL))
468  // no interface found; sent to ND or to ICMP for error processing
469 // throw cRuntimeError("No interface found!");//return;
470  return;
471  // don't raise error if sent to ND or ICMP!
472 
473  resolveMACAddressAndSendPacket(packet, interfaceId, nextHop, fromHL);
474 }

Referenced by datagramLocalOut(), and preroutingFinish().

◆ sendDatagramToOutput()

void inet::Ipv6::sendDatagramToOutput ( Packet packet,
const NetworkInterface destIE,
const MacAddress macAddr 
)
protectedvirtual

Last hoplimit check, then send datagram on the given interface.

958 {
959  packet->addTagIfAbsent<MacAddressReq>()->setDestAddress(macAddr);
960  packet->addTagIfAbsent<InterfaceReq>()->setInterfaceId(destIE->getInterfaceId());
961  packet->addTagIfAbsent<PacketProtocolTag>()->setProtocol(&Protocol::ipv6);
962  packet->addTagIfAbsent<DispatchProtocolInd>()->setProtocol(&Protocol::ipv6);
963  auto protocol = destIE->getProtocol();
964  if (protocol != nullptr)
965  packet->addTagIfAbsent<DispatchProtocolReq>()->setProtocol(protocol);
966  else
967  packet->removeTagIfPresent<DispatchProtocolReq>();
968  send(packet, "queueOut");
969 }

Referenced by fragmentAndSend().

◆ sendIcmpError()

void inet::Ipv6::sendIcmpError ( Packet origPacket,
Icmpv6Type  type,
int  code 
)
protected
1260 {
1261  icmp->sendErrorMessage(packet, type, code);
1262  delete packet;
1263 }

Referenced by determineOutputInterface(), fragmentAndSend(), and localDeliver().

◆ unregisterHook()

void inet::Ipv6::unregisterHook ( IHook hook)
overridevirtual

Removes the provided hook from the list of registered hooks.

Reimplemented from inet::NetfilterBase.

1073 {
1074  Enter_Method("unregisterHook()");
1076 }

Member Data Documentation

◆ curFragmentId

unsigned int inet::Ipv6::curFragmentId = -1
protected

Referenced by fragmentAndSend(), and initialize().

◆ fragbuf

Ipv6FragBuf inet::Ipv6::fragbuf
protected

Referenced by initialize(), and localDeliver().

◆ icmp

ModuleRefByPar<Icmpv6> inet::Ipv6::icmp
protected

◆ ift

◆ lastCheckTime

simtime_t inet::Ipv6::lastCheckTime
protected

Referenced by initialize(), and localDeliver().

◆ nd

◆ numDropped

int inet::Ipv6::numDropped = 0
protected

◆ numForwarded

int inet::Ipv6::numForwarded = 0
protected

◆ numLocalDeliver

int inet::Ipv6::numLocalDeliver = 0
protected

◆ numMulticast

int inet::Ipv6::numMulticast = 0
protected

◆ numUnroutable

int inet::Ipv6::numUnroutable = 0
protected

◆ queuedDatagramsForHooks

◆ rt

◆ socketIdToSocketDescriptor

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

Referenced by handleRequest(), localDeliver(), and ~Ipv6().

◆ tunneling

ModuleRefByPar<Ipv6Tunneling> inet::Ipv6::tunneling
protected

Referenced by initialize(), and routePacket().

◆ upperProtocols

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

The documentation for this class was generated from the following files:
inet::findContainingNode
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:31
inet::Ipv6::fragbuf
Ipv6FragBuf fragbuf
Definition: Ipv6.h:72
inet::Ipv6FragBuf::init
void init(Icmpv6 *icmp)
Initialize fragmentation buffer.
Definition: Ipv6FragBuf.cc:32
inet::Ipv6::ift
ModuleRefByPar< IInterfaceTable > ift
Definition: Ipv6.h:64
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::Ipv6::numMulticast
int numMulticast
Definition: Ipv6.h:78
INET_WITH_xMIPv6
#define INET_WITH_xMIPv6
Definition: features.h:221
DscpReq
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down DscpReq
Definition: IUdp-gates.txt:25
inet::Ipv6::icmp
ModuleRefByPar< Icmpv6 > icmp
Definition: Ipv6.h:67
inet::Protocol::ipv4
static const Protocol ipv4
Definition: Protocol.h:93
inet::Protocol::ipv6
static const Protocol ipv6
Definition: Protocol.h:94
inet::Ipv6::encapsulate
virtual void encapsulate(Packet *transportPacket)
Encapsulate packet coming from higher layers into IPv6Datagram.
Definition: Ipv6.cc:787
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
InterfaceReq
removed InterfaceReq
Definition: IUdp-gates.txt:11
inet::Ipv6::datagramLocalOutHook
IHook::Result datagramLocalOutHook(Packet *packet)
called before a packet arriving locally is delivered
Definition: Ipv6.cc:1233
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::Ipv6::datagramPostRoutingHook
IHook::Result datagramPostRoutingHook(Packet *packet, const NetworkInterface *inIE, const NetworkInterface *&outIE, L3Address &nextHopAddr)
called before a packet is delivered via the network
Definition: Ipv6.cc:1181
L3AddressInd
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd L3AddressInd
Definition: IUdp-gates.txt:20
inet::INetfilter::IHook::FORWARD
@ FORWARD
Definition: INetfilter.h:34
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::Ipv6::queuedDatagramsForHooks
DatagramQueueForHooks queuedDatagramsForHooks
Definition: Ipv6.h:109
inet::Ipv6::handleRequest
virtual void handleRequest(Request *request)
Definition: Ipv6.cc:124
inet::Ipv6::sendDatagramToOutput
virtual void sendDatagramToOutput(Packet *packet, const NetworkInterface *destIE, const MacAddress &macAddr)
Last hoplimit check, then send datagram on the given interface.
Definition: Ipv6.cc:957
inet::Ipv6::upperProtocols
std::set< const Protocol * > upperProtocols
Definition: Ipv6.h:74
inet::Ipv6::numUnroutable
int numUnroutable
Definition: Ipv6.h:81
inet::Ipv6FragBuf::addFragment
Packet * addFragment(Packet *packet, const Ipv6Header *dg, const Ipv6FragmentHeader *fh, simtime_t now)
Takes a fragment and inserts it into the reassembly buffer.
Definition: Ipv6FragBuf.cc:37
inet::Ipv6::socketIdToSocketDescriptor
std::map< int, SocketDescriptor * > socketIdToSocketDescriptor
Definition: Ipv6.h:75
inet::Ipv6::fragmentAndSend
virtual void fragmentAndSend(Packet *packet, const NetworkInterface *destIE, const MacAddress &nextHopAddr, bool fromHL)
Performs fragmentation if needed, and sends the original datagram or the fragments through the specif...
Definition: Ipv6.cc:861
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::Ipv6::lastCheckTime
simtime_t lastCheckTime
Definition: Ipv6.h:73
inet::Ipv6::handleMessageFromHL
virtual void handleMessageFromHL(Packet *msg)
Handle messages (typically packets to be send in Ipv6) from transport or ICMP.
Definition: Ipv6.cc:296
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::IPv6_I_DATA
@ IPv6_I_DATA
Definition: Ipv6SocketCommand_m.h:84
PacketProtocolTag
removed DscpReq Ipv4ControlInfo Ipv6ControlInfo up L3AddressInd DispatchProtocolReq L4PortInd Ipv4ControlInfo Ipv6ControlInfo down PacketProtocolTag
Definition: IUdp-gates.txt:25
inet::Ipv6::curFragmentId
unsigned int curFragmentId
Definition: Ipv6.h:71
inet::IP_PROT_IPv6EXT_FRAGMENT
@ IP_PROT_IPv6EXT_FRAGMENT
Definition: IpProtocolId_m.h:114
ctrl
removed ctrl
Definition: IUdp-gates.txt:7
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::Packet::dup
virtual Packet * dup() const override
Definition: Packet.h:171
inet::Ipv6::tunneling
ModuleRefByPar< Ipv6Tunneling > tunneling
Definition: Ipv6.h:68
inet::ICMPv6_PARAMETER_PROBLEM
@ ICMPv6_PARAMETER_PROBLEM
Definition: Icmpv6Header_m.h:88
FRAGMENT_TIMEOUT
#define FRAGMENT_TIMEOUT
Definition: Ipv6.cc:39
inet::INetfilter::IHook::QUEUE
@ QUEUE
queues the datagram for later re-injection (e.g. when route discovery completes)
Definition: INetfilter.h:42
inet::Ipv6Address::UNSPECIFIED_ADDRESS
static const Ipv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: Ipv6Address.h:54
inet::Ipv6::numLocalDeliver
int numLocalDeliver
Definition: Ipv6.h:79
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::NetfilterBase::unregisterHook
virtual void unregisterHook(INetfilter::IHook *hook) override
Removes the provided hook from the list of registered hooks.
Definition: INetfilter.h:142
inet::ICMPv6_TIME_EXCEEDED
@ ICMPv6_TIME_EXCEEDED
Definition: Icmpv6Header_m.h:87
HopLimitReq
removed HopLimitReq
Definition: IUdp-gates.txt:11
type
removed type
Definition: IUdp-gates.txt:7
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::Ipv6::rt
ModuleRefByPar< Ipv6RoutingTable > rt
Definition: Ipv6.h:65
inet::packetReceivedFromLowerSignal
simsignal_t packetReceivedFromLowerSignal
Definition: Simsignals.cc:91
inet::Ipv6::preroutingFinish
virtual void preroutingFinish(Packet *packet, const NetworkInterface *fromIE, const NetworkInterface *destIE, Ipv6Address nextHopAddr)
Definition: Ipv6.cc:282
inet::INetfilter::IHook::PREROUTING
@ PREROUTING
Definition: INetfilter.h:32
inet::Protocol::mobileipv6
static const Protocol mobileipv6
Definition: Protocol.h:100
inet::Ipv6::handleReceivedIcmp
virtual void handleReceivedIcmp(Packet *msg)
Handle incoming ICMP messages.
Definition: Ipv6.cc:744
inet::Protocol::icmpv6
static const Protocol icmpv6
Definition: Protocol.h:72
inet::Ipv6::determineOutputInterface
bool determineOutputInterface(const Ipv6Address &destAddress, Ipv6Address &nextHop, int &interfaceId, Packet *packet, bool fromHL)
Determines the correct interface for the specified destination address.
Definition: Ipv6.cc:971
inet::Ipv6::nd
ModuleRefByPar< Ipv6NeighbourDiscovery > nd
Definition: Ipv6.h:66
inet::NodeStatus::UP
@ UP
Definition: NodeStatus.h:28
inet::UNRECOGNIZED_NEXT_HDR_TYPE
@ UNRECOGNIZED_NEXT_HDR_TYPE
Definition: Icmpv6Header_m.h:169
inet::NetfilterBase::hooks
std::multimap< int, IHook * > hooks
Definition: INetfilter.h:129
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::Ipv6::routeMulticastPacket
virtual void routeMulticastPacket(Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, bool fromHL)
Forwards packets to all multicast destinations, using fragmentAndSend().
Definition: Ipv6.cc:521
inet::Ipv6Tunneling::NORMAL
@ NORMAL
Definition: Ipv6Tunneling.h:44
tags
* tags
Definition: IUdp-gates.txt:3
inet::Ipv6::decapsulate
virtual void decapsulate(Packet *packet)
Decapsulate packet.
Definition: Ipv6.cc:757
inet::Ipv6::datagramPreRoutingHook
IHook::Result datagramPreRoutingHook(Packet *packet)
called before a packet arriving from the network is routed
Definition: Ipv6.cc:1129
inet::MacAddress::BROADCAST_ADDRESS
static const MacAddress BROADCAST_ADDRESS
The broadcast MAC address, ff:ff:ff:ff:ff:ff.
Definition: MacAddress.h:34
inet::INetfilter::IHook::ACCEPT
@ ACCEPT
allows the datagram to pass to the next hook
Definition: INetfilter.h:40
inet::IP_PROT_IPv6
@ IP_PROT_IPv6
Definition: IpProtocolId_m.h:99
inet::Ipv6::numDropped
int numDropped
Definition: Ipv6.h:80
inet::ProtocolGroup::ipprotocol
static ProtocolGroup ipprotocol
Definition: ProtocolGroup.h:42
inet::packetSentToUpperSignal
simsignal_t packetSentToUpperSignal
Definition: Simsignals.cc:87
inet::Ipv6FragBuf::purgeStaleFragments
void purgeStaleFragments(simtime_t lastupdate)
Throws out all fragments which are incomplete and their last update (last fragment arrival) was befor...
Definition: Ipv6FragBuf.cc:143
inet::ICMPv6_PACKET_TOO_BIG
@ ICMPv6_PACKET_TOO_BIG
Definition: Icmpv6Header_m.h:86
inet::Ipv6::fragmentPostRouting
virtual void fragmentPostRouting(Packet *packet, const NetworkInterface *ie, const MacAddress &nextHopAddr, bool fromHL)
Definition: Ipv6.cc:835
inet::Ipv6::resolveMACAddressAndSendPacket
virtual void resolveMACAddressAndSendPacket(Packet *packet, int interfaceID, Ipv6Address nextHop, bool fromHL)
Definition: Ipv6.cc:476
inet::IpProtocolId
IpProtocolId
Enum generated from inet/networklayer/common/IpProtocolId.msg:17 by opp_msgtool.
Definition: IpProtocolId_m.h:90
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::Ipv6::sendIcmpError
void sendIcmpError(Packet *origPacket, Icmpv6Type type, int code)
Definition: Ipv6.cc:1259
inet::IPv6_FRAGMENT_HEADER_LENGTH
const B IPv6_FRAGMENT_HEADER_LENGTH
Definition: Ipv6ExtensionHeaders_m.h:62
inet::IP_PROT_IPv6EXT_MOB
@ IP_PROT_IPv6EXT_MOB
Definition: IpProtocolId_m.h:117
inet::Ipv6::numForwarded
int numForwarded
Definition: Ipv6.h:82
inet::IPv6_I_SOCKET_CLOSED
@ IPv6_I_SOCKET_CLOSED
Definition: Ipv6SocketCommand_m.h:85
inet::INetfilter::IHook::LOCALIN
@ LOCALIN
Definition: INetfilter.h:33
inet::ICMPv6_DESTINATION_UNREACHABLE
@ ICMPv6_DESTINATION_UNREACHABLE
Definition: Icmpv6Header_m.h:85
inet::Ipv6::routePacket
virtual void routePacket(Packet *packet, const NetworkInterface *destIE, const NetworkInterface *fromIE, Ipv6Address requestedNextHopAddress, bool fromHL)
Performs routing.
Definition: Ipv6.cc:377
inet::INetfilter::IHook::POSTROUTING
@ POSTROUTING
Definition: INetfilter.h:35
inet::INetfilter::IHook::LOCALOUT
@ LOCALOUT
Definition: INetfilter.h:36
inet::containsKey
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80
inet::Ipv6::datagramLocalOut
virtual void datagramLocalOut(Packet *packet, const NetworkInterface *destIE, Ipv6Address requestedNextHopAddress)
Definition: Ipv6.cc:365
inet::Ipv6::localDeliver
virtual void localDeliver(Packet *packet, const NetworkInterface *fromIE)
Perform reassembly of fragmented datagrams, then send them up to the higher layers using sendToHL().
Definition: Ipv6.cc:647
inet::Ipv6::getSourceInterfaceFrom
virtual NetworkInterface * getSourceInterfaceFrom(Packet *msg)
Definition: Ipv6.cc:276