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

Implements RFC 2461 Neighbor Discovery for IPv6. More...

#include <IPv6NeighbourDiscovery.h>

Inheritance diagram for inet::IPv6NeighbourDiscovery:
inet::ILifecycle

Classes

struct  AdvIfEntry
 
struct  DADEntry
 
struct  DADGlobalEntry
 
struct  RDEntry
 

Public Types

typedef std::vector< cMessage * > MsgPtrVector
 
typedef IPv6NeighbourCache::Key Key
 
typedef IPv6NeighbourCache::Neighbour Neighbour
 
typedef IPv6NeighbourCache::DefaultRouterList DefaultRouterList
 

Public Member Functions

 IPv6NeighbourDiscovery ()
 
virtual ~IPv6NeighbourDiscovery ()
 
const MACAddressresolveNeighbour (const IPv6Address &nextHop, int interfaceId)
 Public method, to be invoked from the IPv6 module to determine link-layer address and the output interface of the next hop. More...
 
virtual void reachabilityConfirmed (const IPv6Address &neighbour, int interfaceId)
 Public method, it can be invoked from the IPv6 module or any other module to let Neighbour Discovery know that the reachability of the given neighbor has just been confirmed (e.g. More...
 
virtual void sendUnsolicitedNA (InterfaceEntry *ie)
 
void invalidateNeigbourCache ()
 RFC2463 Section 3.1: Destination Unreachable Message Send an unreachable message to the IPv6 module. More...
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Types

typedef std::set< cMessage * > RATimerList
 
typedef std::set< DADEntry * > DADList
 
typedef std::set< RDEntry * > RDList
 
typedef std::set< AdvIfEntry * > AdvIfList
 
typedef std::map< InterfaceEntry *, DADGlobalEntryDADGlobalList
 

Protected Member Functions

virtual int numInitStages () const override
 
virtual void initialize (int stage) override
 
virtual void handleMessage (cMessage *msg) override
 
virtual void processNDMessage (ICMPv6Message *msg, IPv6ControlInfo *ctrlInfo)
 
virtual bool handleOperationStage (LifecycleOperation *operation, int stage, IDoneCallback *doneCallback) override
 Perform one stage of a lifecycle operation. More...
 
virtual void finish () override
 
virtual void processIPv6Datagram (IPv6Datagram *datagram)
 
virtual IPv6NeighbourDiscovery::AdvIfEntryfetchAdvIfEntry (InterfaceEntry *ie)
 
virtual IPv6NeighbourDiscovery::RDEntryfetchRDEntry (InterfaceEntry *ie)
 
virtual IPv6Address determineNextHop (const IPv6Address &destAddr, int &outIfID)
 This function accepts the datagram's destination address and attempts to determine the destination's next hop address and interface ID by: (1) looking up the destination cache, (2)looking up the routing table, or (3) selecting a default router. More...
 
virtual void initiateNeighbourUnreachabilityDetection (Neighbour *neighbour)
 
virtual void processNUDTimeout (cMessage *timeoutMsg)
 
virtual IPv6Address selectDefaultRouter (int &outIfID)
 
virtual void timeoutPrefixEntry (const IPv6Address &destPrefix, int prefixLength)
 RFC 2461: Section 6.3.5 Whenever the invalidation timer expires for a Prefix List entry, that entry is discarded. More...
 
virtual void timeoutDefaultRouter (const IPv6Address &addr, int interfaceID)
 RFC 2461: Section 6.3.5 Whenever the Lifetime of an entry in the Default Router List expires, that entry is discarded. More...
 
virtual void initiateAddressResolution (const IPv6Address &dgSrcAddr, Neighbour *nce)
 This method attempts to resolve the given neighbour's link-layer address. More...
 
virtual void processARTimeout (cMessage *arTimeoutMsg)
 Resends a NS packet to the address intended for address resolution. More...
 
virtual void dropQueuedPacketsAwaitingAR (Neighbour *nce)
 Drops specific queued packets for a specific NCE AR-timeout. More...
 
virtual void sendPacketToIPv6Module (cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId)
 Create control info and assigns it to a msg. More...
 
virtual void sendQueuedPacketsToIPv6Module (Neighbour *nce)
 Send off any queued packets within the Neighbour Discovery module awaiting address resolution. More...
 
virtual void initiateDAD (const IPv6Address &tentativeAddr, InterfaceEntry *ie)
 Initiating DAD means to send off a Neighbour Solicitation with its target address set as this node's tentative link-local address. More...
 
virtual void processDADTimeout (cMessage *msg)
 Sends a scheduled DAD NS packet. More...
 
virtual void makeTentativeAddressPermanent (const IPv6Address &tentativeAddr, InterfaceEntry *ie)
 Permanently assign the given address for the given interface entry. More...
 
virtual void assignLinkLocalAddress (cMessage *timerMsg)
 as it is not possbile to explicitly define RFC 2462. More...
 
virtual IPv6RouterSolicitationcreateAndSendRSPacket (InterfaceEntry *ie)
 
virtual void initiateRouterDiscovery (cMessage *msg)
 
virtual void cancelRouterDiscovery (InterfaceEntry *ie)
 RFC 2461: Section 6.3.7 4th paragraph Once the host sends a Router Solicitation, and receives a valid Router Advertisement with a non-zero Router Lifetime, the host MUST desist from sending additional solicitations on that interface,. More...
 
virtual void processRDTimeout (cMessage *msg)
 
virtual void processRSPacket (IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo)
 
virtual bool validateRSPacket (IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo)
 
virtual IPv6RouterAdvertisementcreateAndSendRAPacket (const IPv6Address &destAddr, InterfaceEntry *ie)
 
virtual void processRAPacket (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
 
virtual void processRAForRouterUpdates (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
 
virtual void processRAPrefixInfo (IPv6RouterAdvertisement *ra, InterfaceEntry *ie)
 
virtual void processRAPrefixInfoForAddrAutoConf (IPv6NDPrefixInformation &prefixInfo, InterfaceEntry *ie, bool hFlag=false)
 
virtual void createRATimer (InterfaceEntry *ie)
 Create a timer for the given interface entry that sends periodic Router Advertisements. More...
 
virtual void resetRATimer (InterfaceEntry *ie)
 Reset the given interface entry's Router Advertisement timer. More...
 
virtual void sendPeriodicRA (cMessage *msg)
 
virtual void sendSolicitedRA (cMessage *msg)
 
virtual bool validateRAPacket (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
 
virtual IPv6NeighbourSolicitationcreateAndSendNSPacket (const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie)
 
virtual void processNSPacket (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *naCtrlInfo)
 
virtual bool validateNSPacket (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo)
 
virtual void processNSForTentativeAddress (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo)
 
virtual void processNSForNonTentativeAddress (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie)
 
virtual void processNSWithSpecifiedSrcAddr (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie)
 
IPv6NeighbourAdvertisementcreateAndSendNAPacket (IPv6NeighbourSolicitation *ns, const IPv6Address &nsSrcAddr, const IPv6Address &nsDestAddr, InterfaceEntry *ie)
 
virtual void sendSolicitedNA (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo, InterfaceEntry *ie)
 
virtual void processNAPacket (IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo)
 
virtual bool validateNAPacket (IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo)
 
virtual void processNAForIncompleteNCEState (IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce)
 
virtual void processNAForOtherNCEStates (IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce)
 
virtual IPv6RedirectcreateAndSendRedirectPacket (InterfaceEntry *ie)
 
virtual void processRedirectPacket (IPv6Redirect *redirect, IPv6ControlInfo *ctrlInfo)
 
virtual bool canServeWirelessNodes (InterfaceEntry *ie)
 
void routersUnreachabilityDetection (const InterfaceEntry *ie)
 
bool isWirelessInterface (const InterfaceEntry *ie)
 
bool isWirelessAccessPoint (cModule *module)
 

Protected Attributes

cQueue pendingQueue
 
IInterfaceTableift = nullptr
 
IPv6RoutingTablert6 = nullptr
 
ICMPv6icmpv6 = nullptr
 
xMIPv6mipv6 = nullptr
 
IPv6NeighbourCache neighbourCache
 
RATimerList raTimerList
 
DADList dadList
 
RDList rdList
 
AdvIfList advIfList
 
DADGlobalList dadGlobalList
 

Static Private Attributes

static simsignal_t startDADSignal = registerSignal("startDAD")
 

Detailed Description

Implements RFC 2461 Neighbor Discovery for IPv6.

Member Typedef Documentation

typedef std::set<AdvIfEntry *> inet::IPv6NeighbourDiscovery::AdvIfList
protected
typedef std::set<DADEntry *> inet::IPv6NeighbourDiscovery::DADList
protected
typedef std::vector<cMessage *> inet::IPv6NeighbourDiscovery::MsgPtrVector
typedef std::set<cMessage *> inet::IPv6NeighbourDiscovery::RATimerList
protected
typedef std::set<RDEntry *> inet::IPv6NeighbourDiscovery::RDList
protected

Constructor & Destructor Documentation

inet::IPv6NeighbourDiscovery::IPv6NeighbourDiscovery ( )
50  : neighbourCache(*this)
51 {
52 }
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
inet::IPv6NeighbourDiscovery::~IPv6NeighbourDiscovery ( )
virtual
55 {
56  // FIXME delete the following data structures, cancelAndDelete timers in them etc.
57  // Deleting the data structures my become unnecessary if the lists store the
58  // structs themselves and not pointers.
59 
60  // RATimerList raTimerList;
61  for (const auto & elem : raTimerList) {
62  cancelAndDelete(elem);
63  delete (elem);
64  }
65 
66  // DADList dadList;
67  for (const auto & elem : dadList) {
68  cancelAndDelete((elem)->timeoutMsg);
69  delete (elem);
70  }
71 
72  // RDList rdList;
73  for (const auto & elem : rdList) {
74  cancelAndDelete((elem)->timeoutMsg);
75  delete (elem);
76  }
77 
78  // AdvIfList advIfList;
79  for (const auto & elem : advIfList) {
80  cancelAndDelete((elem)->raTimeoutMsg);
81  delete (elem);
82  }
83 }
RATimerList raTimerList
Definition: IPv6NeighbourDiscovery.h:142
AdvIfList advIfList
Definition: IPv6NeighbourDiscovery.h:151
RDList rdList
Definition: IPv6NeighbourDiscovery.h:148
DADList dadList
Definition: IPv6NeighbourDiscovery.h:145

Member Function Documentation

void inet::IPv6NeighbourDiscovery::assignLinkLocalAddress ( cMessage *  timerMsg)
protectedvirtual

as it is not possbile to explicitly define RFC 2462.

ND is the next best place to do this.

RFC 2462-IPv6 Stateless Address Autoconfiguration: Section 1 The autoconfiguration process specified in this document applies only to hosts and not routers. Since host autoconfiguration uses information advertised by routers, routers will need to be configured by some other means. However, it is expected that routers will generate link-local addresses using the mechanism described in this document. In addition, routers are expected to successfully pass the Duplicate Address Detection procedure described in this document on all addresses prior to assigning them to an interface.

Referenced by handleMessage().

783 {
784  //Node has booted up. Start assigning a link-local address for each
785  //interface in this node.
786  for (int i = 0; i < ift->getNumInterfaces(); i++) {
787  InterfaceEntry *ie = ift->getInterface(i);
788 
789  //Skip the loopback interface.
790  if (ie->isLoopback())
791  continue;
792 
793  IPv6Address linkLocalAddr = ie->ipv6Data()->getLinkLocalAddress();
794  if (linkLocalAddr.isUnspecified()) {
795  //if no link local address exists for this interface, we assign one to it.
796  EV_INFO << "No link local address exists. Forming one" << endl;
797  linkLocalAddr = IPv6Address().formLinkLocalAddress(ie->getInterfaceToken());
798  ie->ipv6Data()->assignAddress(linkLocalAddr, true, SIMTIME_ZERO, SIMTIME_ZERO);
799  }
800 
801  //Before we can use this address, we MUST initiate DAD first.
802  if (ie->ipv6Data()->isTentativeAddress(linkLocalAddr)) {
803  if (ie->ipv6Data()->getDupAddrDetectTransmits() > 0)
804  initiateDAD(linkLocalAddr, ie);
805  else
806  makeTentativeAddressPermanent(linkLocalAddr, ie);
807  }
808  }
809  delete timerMsg;
810 }
virtual void initiateDAD(const IPv6Address &tentativeAddr, InterfaceEntry *ie)
Initiating DAD means to send off a Neighbour Solicitation with its target address set as this node&#39;s ...
Definition: IPv6NeighbourDiscovery.cc:812
const IPv6Address & getLinkLocalAddress() const
Returns the first valid link-local address of the interface, or UNSPECIFIED_ADDRESS if there&#39;s none...
Definition: IPv6InterfaceData.cc:353
static IPv6Address formLinkLocalAddress(const InterfaceToken &ident)
Forms a link-local address using the given interface identifier.
Definition: IPv6Address.cc:357
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
virtual void makeTentativeAddressPermanent(const IPv6Address &tentativeAddr, InterfaceEntry *ie)
Permanently assign the given address for the given interface entry.
Definition: IPv6NeighbourDiscovery.cc:882
IPv6InterfaceData * ipv6Data() const
Definition: InterfaceEntry.h:223
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
void inet::IPv6NeighbourDiscovery::cancelRouterDiscovery ( InterfaceEntry ie)
protectedvirtual

RFC 2461: Section 6.3.7 4th paragraph Once the host sends a Router Solicitation, and receives a valid Router Advertisement with a non-zero Router Lifetime, the host MUST desist from sending additional solicitations on that interface,.

Cancel Router Discovery on the Interface where a RA was received with the given Interface Entry.

Referenced by processRAPacket().

1030 {
1031  //Next we retrieve the rdEntry with the Interface Entry.
1032  RDEntry *rdEntry = fetchRDEntry(ie);
1033  if (rdEntry != nullptr) {
1034  EV_DETAIL << "rdEntry is not nullptr, RD cancelled!" << endl;
1035  cancelAndDelete(rdEntry->timeoutMsg);
1036  rdList.erase(rdEntry);
1037  delete rdEntry;
1038  }
1039  else
1040  EV_DETAIL << "rdEntry is nullptr, not cancelling RD!" << endl;
1041 }
virtual IPv6NeighbourDiscovery::RDEntry * fetchRDEntry(InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:327
RDList rdList
Definition: IPv6NeighbourDiscovery.h:148
bool inet::IPv6NeighbourDiscovery::canServeWirelessNodes ( InterfaceEntry ie)
protectedvirtual

Referenced by createRATimer().

2609 {
2610  if (isWirelessInterface(ie))
2611  return true;
2612 
2613  // check if this interface is directly connected to an AccessPoint.
2614  cModule *node = getContainingNode(this);
2615  cGate *gate = node->gate(ie->getNodeOutputGateId());
2616  ASSERT(gate != nullptr);
2617  cGate *connectedGate = gate->getPathEndGate();
2618  if (connectedGate != gate) {
2619  cModule *connectedNode = getContainingNode(connectedGate->getOwnerModule());
2620  if(!connectedNode)
2621  throw cRuntimeError("The connected module %s is not in a network node.", connectedGate->getOwnerModule()->getFullPath().c_str());
2622  if (isWirelessAccessPoint(connectedNode))
2623  return true;
2624  }
2625 
2626  // FIXME The AccessPoint can be connected to this router via Ethernet switches and/or hubs.
2627 
2628  return false;
2629 }
bool isWirelessAccessPoint(cModule *module)
Definition: IPv6NeighbourDiscovery.cc:2637
bool isWirelessInterface(const InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:2631
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:65
IPv6NeighbourAdvertisement* inet::IPv6NeighbourDiscovery::createAndSendNAPacket ( IPv6NeighbourSolicitation ns,
const IPv6Address nsSrcAddr,
const IPv6Address nsDestAddr,
InterfaceEntry ie 
)
protected
IPv6NeighbourSolicitation * inet::IPv6NeighbourDiscovery::createAndSendNSPacket ( const IPv6Address nsTargetAddr,
const IPv6Address dgDestAddr,
const IPv6Address dgSrcAddr,
InterfaceEntry ie 
)
protectedvirtual

Referenced by initiateAddressResolution(), initiateDAD(), processARTimeout(), processDADTimeout(), and processNUDTimeout().

1818 {
1819 #ifdef WITH_xMIPv6
1820  Enter_Method_Silent();
1821 #endif /* WITH_xMIPv6 */
1822 
1823  MACAddress myMacAddr = ie->getMacAddress();
1824 
1825  //Construct a Neighbour Solicitation message
1826  IPv6NeighbourSolicitation *ns = new IPv6NeighbourSolicitation("NSpacket");
1827  ns->setType(ICMPv6_NEIGHBOUR_SOL);
1828 
1829  //Neighbour Solicitation Specific Information
1830  ns->setTargetAddress(nsTargetAddr);
1831  ns->setByteLength(ICMPv6_HEADER_BYTES + IPv6_ADDRESS_SIZE); // RFC 2461, Section 4.3.
1832 
1833  /*If the solicitation is being sent to a solicited-node multicast
1834  address, the sender MUST include its link-layer address (if it has
1835  one) as a Source Link-Layer Address option.*/
1836  if (dgDestAddr.matches(IPv6Address("FF02::1:FF00:0"), 104) && // FIXME what's this? make constant...
1837  !dgSrcAddr.isUnspecified()) {
1838  ns->setSourceLinkLayerAddress(myMacAddr);
1839  ns->addByteLength(IPv6ND_LINK_LAYER_ADDRESS_OPTION_LENGTH);
1840  }
1841 
1842  sendPacketToIPv6Module(ns, dgDestAddr, dgSrcAddr, ie->getInterfaceId());
1843 
1844  return ns;
1845 }
Definition: IPv6NDMessage_m.h:56
Definition: ICMPv6Message_m.h:82
#define ICMPv6_HEADER_BYTES
Definition: ICMPv6Message_m.h:32
Definition: IPv6Address.h:32
virtual void sendPacketToIPv6Module(cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId)
Create control info and assigns it to a msg.
Definition: IPv6NeighbourDiscovery.cc:752
IPv6RouterAdvertisement * inet::IPv6NeighbourDiscovery::createAndSendRAPacket ( const IPv6Address destAddr,
InterfaceEntry ie 
)
protectedvirtual

Referenced by sendPeriodicRA(), and sendSolicitedRA().

1194 {
1195  EV_INFO << "Create and send RA invoked!\n";
1196  //Must use link-local addr. See: RFC2461 Section 6.1.2
1197  IPv6Address sourceAddr = ie->ipv6Data()->getLinkLocalAddress();
1198 
1199  //This operation includes all options, regardless whether it is solicited or unsolicited.
1200  if (ie->ipv6Data()->getAdvSendAdvertisements()) { //if this is an advertising interface
1201  //Construct a Router Advertisment message
1202  IPv6RouterAdvertisement *ra = new IPv6RouterAdvertisement("RApacket");
1203  ra->setType(ICMPv6_ROUTER_AD);
1204 
1205  //RFC 2461: Section 6.2.3 Router Advertisment Message Content
1206  /*A router sends periodic as well as solicited Router Advertisements out
1207  its advertising interfaces. Outgoing Router Advertisements are filled
1208  with the following values consistent with the message format given in
1209  Section 4.2:*/
1210 
1211  //- In the Router Lifetime field: the interface's configured AdvDefaultLifetime.
1212  ra->setRouterLifetime(SIMTIME_DBL(ie->ipv6Data()->getAdvDefaultLifetime()));
1213 
1214  //- In the M and O flags: the interface's configured AdvManagedFlag and
1215  //AdvOtherConfigFlag, respectively. See [ADDRCONF].
1216  ra->setManagedAddrConfFlag(ie->ipv6Data()->getAdvManagedFlag());
1217  ra->setOtherStatefulConfFlag(ie->ipv6Data()->getAdvOtherConfigFlag());
1218 
1219 #ifdef WITH_xMIPv6
1220  // Configuring the HomeAgentFlag (H-bit) (RFC 3775): Zarrar 25.02.07
1221  if (rt6->isHomeAgent())
1222  ra->setHomeAgentFlag(true); //Set H-bit if the router is a HA
1223  else
1224  ra->setHomeAgentFlag(ie->ipv6Data()->getAdvHomeAgentFlag()); //else unset it, which is default
1225 #endif /* WITH_xMIPv6 */
1226 
1227  //- In the Cur Hop Limit field: the interface's configured CurHopLimit.
1228  ra->setCurHopLimit(ie->ipv6Data()->getAdvCurHopLimit());
1229 
1230  //- In the Reachable Time field: the interface's configured AdvReachableTime.
1231  ra->setReachableTime(ie->ipv6Data()->getAdvReachableTime());
1232 
1233  //- In the Retrans Timer field: the interface's configured AdvRetransTimer.
1234  ra->setRetransTimer(ie->ipv6Data()->getAdvRetransTimer());
1235 
1236  //- In the options:
1237  /*o Source Link-Layer Address option: link-layer address of the sending
1238  interface. (Assumption: We always send this)*/
1239  ra->setSourceLinkLayerAddress(ie->getMacAddress());
1240  ra->setMTU(ie->ipv6Data()->getAdvLinkMTU());
1241 
1242  //Add all Advertising Prefixes to the RA
1243  int numAdvPrefixes = ie->ipv6Data()->getNumAdvPrefixes();
1244  EV_DETAIL << "Number of Adv Prefixes: " << numAdvPrefixes << endl;
1245  ra->setPrefixInformationArraySize(numAdvPrefixes);
1246  for (int i = 0; i < numAdvPrefixes; i++) {
1247  IPv6InterfaceData::AdvPrefix advPrefix = ie->ipv6Data()->getAdvPrefix(i);
1248  IPv6NDPrefixInformation prefixInfo;
1249 
1250 #ifndef WITH_xMIPv6
1251  prefixInfo.setPrefix(advPrefix.prefix);
1252 #else /* WITH_xMIPv6 */
1253  EV_DETAIL << "\n+=+=+=+= Appendign Prefix Info Option to RA +=+=+=+=\n";
1254  EV_DETAIL << "Prefix Value: " << advPrefix.prefix << endl;
1255  EV_DETAIL << "Prefix Length: " << advPrefix.prefixLength << endl;
1256  EV_DETAIL << "L-Flag: " << advPrefix.advOnLinkFlag << endl;
1257  EV_DETAIL << "A-Flag: " << advPrefix.advAutonomousFlag << endl;
1258  EV_DETAIL << "R-Flag: " << advPrefix.advRtrAddr << endl;
1259  EV_DETAIL << "Global Address from Prefix: " << advPrefix.rtrAddress << endl;
1260 
1261  if (rt6->isHomeAgent() && advPrefix.advRtrAddr == true)
1262  prefixInfo.setPrefix(advPrefix.rtrAddress); //add the global-scope address of the HA's interface in the prefix option list of the RA message.
1263  else
1264  prefixInfo.setPrefix(advPrefix.prefix); //adds the prefix only of the router's interface in the prefix option list of the RA message.
1265 #endif /* WITH_xMIPv6 */
1266 
1267  prefixInfo.setPrefixLength(advPrefix.prefixLength);
1268 
1269  //- In the "on-link" flag: the entry's AdvOnLinkFlag.
1270  prefixInfo.setOnlinkFlag(advPrefix.advOnLinkFlag);
1271  //- In the Valid Lifetime field: the entry's AdvValidLifetime.
1272  prefixInfo.setValidLifetime(SIMTIME_DBL(advPrefix.advValidLifetime));
1273  //- In the "Autonomous address configuration" flag: the entry's
1274  //AdvAutonomousFlag.
1275  prefixInfo.setAutoAddressConfFlag(advPrefix.advAutonomousFlag);
1276 
1277 #ifdef WITH_xMIPv6
1278  if (rt6->isHomeAgent())
1279  prefixInfo.setRouterAddressFlag(true); // set the R-bit if the node is a HA
1280 
1281  //- In the Valid Lifetime field: the entry's AdvValidLifetime.
1282  prefixInfo.setValidLifetime(SIMTIME_DBL(advPrefix.advValidLifetime));
1283 #endif /* WITH_xMIPv6 */
1284 
1285  //- In the Preferred Lifetime field: the entry's AdvPreferredLifetime.
1286  prefixInfo.setPreferredLifetime(SIMTIME_DBL(advPrefix.advPreferredLifetime));
1287  //Now we pop the prefix info into the RA.
1288  ra->setPrefixInformation(i, prefixInfo);
1289  }
1290 
1291  ra->setByteLength(ICMPv6_HEADER_BYTES + numAdvPrefixes * IPv6ND_PREFIX_INFORMATION_OPTION_LENGTH);
1292  sendPacketToIPv6Module(ra, destAddr, sourceAddr, ie->getInterfaceId());
1293  return ra;
1294  }
1295 
1296  return nullptr; //XXX is this OK?
1297 }
Definition: ICMPv6Message_m.h:81
Definition: IPv6NDMessage_m.h:57
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
#define ICMPv6_HEADER_BYTES
Definition: ICMPv6Message_m.h:32
virtual void sendPacketToIPv6Module(cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId)
Create control info and assigns it to a msg.
Definition: IPv6NeighbourDiscovery.cc:752
bool isHomeAgent() const
Determine whether normal Router or Home Agent.
Definition: IPv6RoutingTable.h:170
IPv6Redirect * inet::IPv6NeighbourDiscovery::createAndSendRedirectPacket ( InterfaceEntry ie)
protectedvirtual
2403 {
2404  //Construct a Redirect message
2405  IPv6Redirect *redirect = new IPv6Redirect("redirectMsg");
2406  redirect->setType(ICMPv6_REDIRECT);
2407  redirect->setByteLength(ICMPv6_HEADER_BYTES + 2 * IPv6_ADDRESS_SIZE); // RFC 2461, Section 4.5
2408 
2409 //FIXME incomplete code
2410 #if 0
2411  //Redirect Message Specific Information
2412  redirect->setTargetAddress();
2413  redirect->setDestinationAddress();
2414 
2415  //Possible Option
2416  redirect->setTargetLinkLayerAddress();
2417  redirect->addByteLength(IPv6ND_LINK_LAYER_ADDRESS_OPTION_LENGTH);
2418 #endif
2419 
2420  return redirect;
2421 }
Definition: IPv6NDMessage_m.h:56
#define ICMPv6_HEADER_BYTES
Definition: ICMPv6Message_m.h:32
Definition: IPv6Address.h:32
Definition: ICMPv6Message_m.h:84
IPv6RouterSolicitation * inet::IPv6NeighbourDiscovery::createAndSendRSPacket ( InterfaceEntry ie)
protectedvirtual

Referenced by initiateRouterDiscovery(), and processRDTimeout().

963 {
964  ASSERT(ie->ipv6Data()->getAdvSendAdvertisements() == false);
965  //RFC 2461: Section 6.3.7 Sending Router Solicitations
966  //A host sends Router Solicitations to the All-Routers multicast address. The
967  //IP source address is set to either one of the interface's unicast addresses
968  //or the unspecified address.
969  IPv6Address myIPv6Address = ie->ipv6Data()->getPreferredAddress();
970 
971  if (myIPv6Address.isUnspecified())
972  myIPv6Address = ie->ipv6Data()->getLinkLocalAddress(); //so we use the link local address instead
973 
974  if (ie->ipv6Data()->isTentativeAddress(myIPv6Address))
975  myIPv6Address = IPv6Address::UNSPECIFIED_ADDRESS; //set my IPv6 address to unspecified.
976 
977  IPv6Address destAddr = IPv6Address::ALL_ROUTERS_2; //all_routers multicast
978  IPv6RouterSolicitation *rs = new IPv6RouterSolicitation("RSpacket");
979  rs->setType(ICMPv6_ROUTER_SOL);
980  rs->setByteLength(ICMPv6_HEADER_BYTES);
981 
982  //The Source Link-Layer Address option SHOULD be set to the host's link-layer
983  //address, if the IP source address is not the unspecified address.
984  if (!myIPv6Address.isUnspecified()) {
985  rs->setSourceLinkLayerAddress(ie->getMacAddress());
987  }
988 
989  //Construct a Router Solicitation message
990  sendPacketToIPv6Module(rs, destAddr, myIPv6Address, ie->getInterfaceId());
991  return rs;
992 }
Definition: IPv6NDMessage_m.h:56
#define ICMPv6_HEADER_BYTES
Definition: ICMPv6Message_m.h:32
static const IPv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: IPv6Address.h:66
virtual void sendPacketToIPv6Module(cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId)
Create control info and assigns it to a msg.
Definition: IPv6NeighbourDiscovery.cc:752
static const IPv6Address ALL_ROUTERS_2
All-routers multicast address, scope 2 (link-local)
Definition: IPv6Address.h:81
Definition: ICMPv6Message_m.h:80
void inet::IPv6NeighbourDiscovery::createRATimer ( InterfaceEntry ie)
protectedvirtual

Create a timer for the given interface entry that sends periodic Router Advertisements.

Referenced by initialize().

1647 {
1648  cMessage *msg = new cMessage("sendPeriodicRA", MK_SEND_PERIODIC_RTRADV);
1649  msg->setContextPointer(ie);
1650  AdvIfEntry *advIfEntry = new AdvIfEntry();
1651  advIfEntry->interfaceId = ie->getInterfaceId();
1652  advIfEntry->numRASent = 0;
1653 
1654 #ifdef WITH_xMIPv6
1655  // 20.9.07 - CB
1656  /*if ( rt6->isRouter() )
1657  {
1658  ie->ipv6()->setMinRtrAdvInterval(IPv6NeighbourDiscovery::getMinRAInterval()); //should be 0.07 for MIPv6 Support
1659  ie->ipv6()->setMaxRtrAdvInterval(IPv6NeighbourDiscovery::getMaxRAInterval()); //should be 0.03 for MIPv6 Support
1660  }*/
1661  // update 23.10.07 - CB
1662 
1663  if (canServeWirelessNodes(ie)) {
1664  EV_INFO << "This Interface is connected to a WLAN AP, hence using MIPv6 Default Values" << endl;
1665  simtime_t minRAInterval = par("minIntervalBetweenRAs"); //reading from the omnetpp.ini (ZY 23.07.09)
1666  simtime_t maxRAInterval = par("maxIntervalBetweenRAs"); //reading from the omnetpp.ini (ZY 23.07.09
1667  ie->ipv6Data()->setMinRtrAdvInterval(minRAInterval);
1668  ie->ipv6Data()->setMaxRtrAdvInterval(maxRAInterval);
1669  }
1670  else {
1671  EV_INFO << "This Interface is not connected to a WLAN AP, hence using default values" << endl;
1672  //interval = uniform( ie->ipv6()->minRtrAdvInterval(), ie->ipv6()->maxRtrAdvInterval() );
1673  //EV<<"\nThe random calculated RA_ND interval is: "<< interval<<" seconds\n";
1674  }
1675  // end CB
1676 #endif /* WITH_xMIPv6 */
1677 
1678  simtime_t interval = uniform(ie->ipv6Data()->getMinRtrAdvInterval(), ie->ipv6Data()->getMaxRtrAdvInterval());
1679  advIfEntry->raTimeoutMsg = msg;
1680 
1681  simtime_t nextScheduledTime = simTime() + interval;
1682  advIfEntry->nextScheduledRATime = nextScheduledTime;
1683  advIfList.insert(advIfEntry);
1684  EV_DETAIL << "Interval: " << interval << endl;
1685  EV_DETAIL << "Next scheduled time: " << nextScheduledTime << endl;
1686  //now we schedule the msg for whatever time that was derived
1687  scheduleAt(nextScheduledTime, msg);
1688 }
#define MK_SEND_PERIODIC_RTRADV
Definition: IPv6NeighbourDiscovery.cc:37
AdvIfList advIfList
Definition: IPv6NeighbourDiscovery.h:151
virtual bool canServeWirelessNodes(InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:2608
IPv6Address inet::IPv6NeighbourDiscovery::determineNextHop ( const IPv6Address destAddr,
int &  outIfID 
)
protectedvirtual

This function accepts the datagram's destination address and attempts to determine the destination's next hop address and interface ID by: (1) looking up the destination cache, (2)looking up the routing table, or (3) selecting a default router.

It then updates the destination cache. If no default router can be selected than we assume the destination address to be onlink and simply return any available interface.

Referenced by processIPv6Datagram().

437 {
438  IPv6Address nextHopAddr;
439  simtime_t expiryTime;
440 
441  //RFC 2461 Section 5.2
442  //Next-hop determination for a given unicast destination operates as follows.
443 
444  //The sender performs a longest prefix match against the Prefix List to
445  //determine whether the packet's destination is on- or off-link.
446  EV_INFO << "Find out if supplied dest addr is on-link or off-link.\n";
447  const IPv6Route *route = rt6->doLongestPrefixMatch(destAddr);
448 
449  if (route != nullptr) {
450  expiryTime = route->getExpiryTime();
451  outIfID = route->getInterface() ? route->getInterface()->getInterfaceId() : -1;
452 
453  //If the destination is on-link, the next-hop address is the same as the
454  //packet's destination address.
455  if (route->getNextHop().isUnspecified()) {
456  EV_INFO << "Dest is on-link, next-hop addr is same as dest addr.\n";
457  nextHopAddr = destAddr;
458  }
459  else {
460  EV_INFO << "A next-hop address was found with the route, dest is off-link\n";
461  EV_INFO << "Assume next-hop address as the selected default router.\n";
462  nextHopAddr = route->getNextHop();
463  }
464  }
465  else {
466  //Otherwise, the sender selects a router from the Default Router List
467  //(following the rules described in Section 6.3.6).
468 
469  EV_INFO << "No routes were found, Dest addr is off-link.\n";
470  nextHopAddr = selectDefaultRouter(outIfID);
471  expiryTime = 0;
472 
473  if (outIfID == -1)
474  EV_INFO << "No Default Routers were found.";
475  else
476  EV_INFO << "Default router found.\n";
477  }
478 
479  /*the results of next-hop determination computations are saved in the Destination
480  Cache (which also contains updates learned from Redirect messages).*/
481  rt6->updateDestCache(destAddr, nextHopAddr, outIfID, expiryTime);
482  return nextHopAddr;
483 }
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
simtime_t getExpiryTime() const
Definition: IPv6Route.h:112
virtual IPv6Address selectDefaultRouter(int &outIfID)
Definition: IPv6NeighbourDiscovery.cc:549
virtual void updateDestCache(const IPv6Address &dest, const IPv6Address &nextHopAddr, int interfaceId, simtime_t expiryTime)
Add or update a destination cache entry.
Definition: IPv6RoutingTable.cc:510
const IPv6Route * doLongestPrefixMatch(const IPv6Address &dest)
Performs longest prefix match in the routing table and returns the resulting route, or nullptr if there was no match.
Definition: IPv6RoutingTable.cc:475
void inet::IPv6NeighbourDiscovery::dropQueuedPacketsAwaitingAR ( Neighbour nce)
protectedvirtual

Drops specific queued packets for a specific NCE AR-timeout.

TODO: Not implemented yet!

Referenced by processARTimeout().

723 {
724  const Key *nceKey = nce->nceKey;
725  //RFC 2461: Section 7.2.2
726  /*If no Neighbor Advertisement is received after MAX_MULTICAST_SOLICIT
727  solicitations, address resolution has failed. The sender MUST return ICMP
728  destination unreachable indications with code 3 (Address Unreachable) for
729  each packet queued awaiting address resolution.*/
730  MsgPtrVector& pendingPackets = nce->pendingPackets;
731  EV_INFO << "Pending Packets empty:" << pendingPackets.empty() << endl;
732 
733  while (!pendingPackets.empty()) {
734  auto i = pendingPackets.begin();
735  cMessage *msg = (*i);
736  IPv6Datagram *ipv6Msg = check_and_cast<IPv6Datagram *>(msg);
737  //Assume msg is the packet itself. I need the datagram's source addr.
738  //The datagram's src addr will be the destination of the unreachable msg.
739  EV_INFO << "Sending ICMP unreachable destination." << endl;
740  pendingPackets.erase(i);
741  pendingQueue.remove(msg);
743  }
744 
745  //RFC 2461: Section 7.3.3
746  /*If address resolution fails, the entry SHOULD be deleted, so that subsequent
747  traffic to that neighbor invokes the next-hop determination procedure again.*/
748  EV_INFO << "Removing neighbour cache entry" << endl;
749  neighbourCache.remove(nceKey->address, nceKey->interfaceID);
750 }
Definition: ICMPv6Message_m.h:109
std::vector< cMessage * > MsgPtrVector
Definition: IPv6NeighbourDiscovery.h:53
IPv6NeighbourCache::Key Key
Definition: IPv6NeighbourDiscovery.h:54
Definition: ICMPv6Message_m.h:71
virtual void remove(const IPv6Address &addr, int interfaceID)
Deletes the given neighbour from the cache.
Definition: IPv6NeighbourCache.cc:149
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
cQueue pendingQueue
Definition: IPv6NeighbourDiscovery.h:98
ICMPv6 * icmpv6
Definition: IPv6NeighbourDiscovery.h:102
virtual void sendErrorMessage(IPv6Datagram *datagram, ICMPv6Type type, int code)
This method can be called from other modules to send an ICMPv6 error packet.
Definition: ICMPv6.cc:188
IPv6NeighbourDiscovery::AdvIfEntry * inet::IPv6NeighbourDiscovery::fetchAdvIfEntry ( InterfaceEntry ie)
protectedvirtual

Referenced by processRSPacket(), and sendPeriodicRA().

318 {
319  for (auto advIfEntry : advIfList) {
320  if (advIfEntry->interfaceId == ie->getInterfaceId()) {
321  return advIfEntry;
322  }
323  }
324  return nullptr;
325 }
AdvIfList advIfList
Definition: IPv6NeighbourDiscovery.h:151
IPv6NeighbourDiscovery::RDEntry * inet::IPv6NeighbourDiscovery::fetchRDEntry ( InterfaceEntry ie)
protectedvirtual

Referenced by cancelRouterDiscovery(), and processRDTimeout().

328 {
329  for (auto rdEntry : rdList) {
330 
331  if (rdEntry->interfaceId == ie->getInterfaceId()) {
332  return rdEntry;
333  }
334  }
335  return nullptr;
336 }
RDList rdList
Definition: IPv6NeighbourDiscovery.h:148
void inet::IPv6NeighbourDiscovery::finish ( )
overrideprotectedvirtual
227 {
228 }
void inet::IPv6NeighbourDiscovery::handleMessage ( cMessage *  msg)
overrideprotectedvirtual
141 {
142  if (msg->isSelfMessage()) {
143  EV_TRACE << "Self message received!\n";
144 
145  if (msg->getKind() == MK_SEND_PERIODIC_RTRADV) {
146  EV_INFO << "Sending periodic RA\n";
147  sendPeriodicRA(msg);
148  }
149  else if (msg->getKind() == MK_SEND_SOL_RTRADV) {
150  EV_INFO << "Sending solicited RA\n";
151  sendSolicitedRA(msg);
152  }
153  else if (msg->getKind() == MK_ASSIGN_LINKLOCAL_ADDRESS) {
154  EV_INFO << "Assigning Link Local Address\n";
156  }
157  else if (msg->getKind() == MK_DAD_TIMEOUT) {
158  EV_INFO << "DAD Timeout message received\n";
159  processDADTimeout(msg);
160  }
161  else if (msg->getKind() == MK_RD_TIMEOUT) {
162  EV_INFO << "Router Discovery message received\n";
163  processRDTimeout(msg);
164  }
165  else if (msg->getKind() == MK_INITIATE_RTRDIS) {
166  EV_INFO << "initiate router discovery.\n";
168  }
169  else if (msg->getKind() == MK_NUD_TIMEOUT) {
170  EV_INFO << "NUD Timeout message received\n";
171  processNUDTimeout(msg);
172  }
173  else if (msg->getKind() == MK_AR_TIMEOUT) {
174  EV_INFO << "Address Resolution Timeout message received\n";
175  processARTimeout(msg);
176  }
177  else
178  throw cRuntimeError("Unrecognized Timer"); //stops sim w/ error msg.
179  }
180  else if (dynamic_cast<ICMPv6Message *>(msg)) {
181  //This information will serve as input parameters to various processors.
182  IPv6ControlInfo *ctrlInfo = check_and_cast<IPv6ControlInfo *>(msg->removeControlInfo());
183  ICMPv6Message *ndMsg = (ICMPv6Message *)msg;
184  processNDMessage(ndMsg, ctrlInfo);
185  }
186  else if (dynamic_cast<IPv6Datagram *>(msg)) { // not ND message
187  IPv6Datagram *datagram = static_cast<IPv6Datagram *>(msg);
188  processIPv6Datagram(datagram);
189  }
190  else
191  throw cRuntimeError("Unknown message type received.\n");
192 }
#define MK_RD_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:41
virtual void processARTimeout(cMessage *arTimeoutMsg)
Resends a NS packet to the address intended for address resolution.
Definition: IPv6NeighbourDiscovery.cc:697
#define MK_INITIATE_RTRDIS
Definition: IPv6NeighbourDiscovery.cc:39
#define MK_SEND_PERIODIC_RTRADV
Definition: IPv6NeighbourDiscovery.cc:37
virtual void processDADTimeout(cMessage *msg)
Sends a scheduled DAD NS packet.
Definition: IPv6NeighbourDiscovery.cc:853
virtual void processRDTimeout(cMessage *msg)
Definition: IPv6NeighbourDiscovery.cc:1043
#define MK_SEND_SOL_RTRADV
Definition: IPv6NeighbourDiscovery.cc:38
virtual void processNUDTimeout(cMessage *timeoutMsg)
Definition: IPv6NeighbourDiscovery.cc:504
#define MK_NUD_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:42
#define MK_DAD_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:40
virtual void sendPeriodicRA(cMessage *msg)
Definition: IPv6NeighbourDiscovery.cc:1711
#define MK_AR_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:43
virtual void sendSolicitedRA(cMessage *msg)
Definition: IPv6NeighbourDiscovery.cc:1762
virtual void processIPv6Datagram(IPv6Datagram *datagram)
Definition: IPv6NeighbourDiscovery.cc:230
virtual void processNDMessage(ICMPv6Message *msg, IPv6ControlInfo *ctrlInfo)
Definition: IPv6NeighbourDiscovery.cc:194
#define MK_ASSIGN_LINKLOCAL_ADDRESS
Definition: IPv6NeighbourDiscovery.cc:36
virtual void assignLinkLocalAddress(cMessage *timerMsg)
as it is not possbile to explicitly define RFC 2462.
Definition: IPv6NeighbourDiscovery.cc:782
virtual void initiateRouterDiscovery(cMessage *msg)
Definition: IPv6NeighbourDiscovery.cc:994
bool inet::IPv6NeighbourDiscovery::handleOperationStage ( LifecycleOperation operation,
int  stage,
IDoneCallback doneCallback 
)
overrideprotectedvirtual

Perform one stage of a lifecycle operation.

Processing may be done entirely within this method, or may be a longer process that involves nonzero simulation time or several events, and is triggered by this method call.

Return value: true = "done"; false = "not yet done, will invoke doneCallback when done"

Implements inet::ILifecycle.

222 {
223  throw cRuntimeError("Lifecycle operation support not implemented");
224 }
void inet::IPv6NeighbourDiscovery::initialize ( int  stage)
overrideprotectedvirtual
86 {
87  cSimpleModule::initialize(stage);
88 
89  if (stage == INITSTAGE_NETWORK_LAYER) {
90  bool isOperational;
91  NodeStatus *nodeStatus = dynamic_cast<NodeStatus *>(findContainingNode(this)->getSubmodule("status"));
92  isOperational = (!nodeStatus) || nodeStatus->getState() == NodeStatus::UP;
93  if (!isOperational)
94  throw cRuntimeError("This module doesn't support starting in node DOWN state");
95  }
96  else if (stage == INITSTAGE_NETWORK_LAYER_3) {
97  ift = getModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
98  rt6 = getModuleFromPar<IPv6RoutingTable>(par("routingTableModule"), this);
99  icmpv6 = getModuleFromPar<ICMPv6>(par("icmpv6Module"), this);
100 
101 #ifdef WITH_xMIPv6
102  if (rt6->isMobileNode())
103  mipv6 = getModuleFromPar<xMIPv6>(par("xmipv6Module"), this);
104 #endif /* WITH_xMIPv6 */
105 
106  pendingQueue.setName("pendingQueue");
107 
108 #ifdef WITH_xMIPv6
109  //MIPv6Enabled = par("MIPv6Support"); // (Zarrar 14.07.07)
110  /*if(rt6->isRouter()) // 12.9.07 - CB
111  {
112  minRAInterval = par("minIntervalBetweenRAs"); // from the omnetpp.ini file (Zarrar 15.07.07)
113  maxRAInterval = par("maxIntervalBetweenRAs"); // from the omnetpp.ini file (Zarrar 15.07.07)
114  //WATCH (MIPv6Enabled); // (Zarrar 14.07.07)
115  WATCH(minRAInterval); // (Zarrar 15.07.07)
116  WATCH(maxRAInterval); // (Zarrar 15.07.07)
117  }*/
118 #endif /* WITH_xMIPv6 */
119 
120  for (int i = 0; i < ift->getNumInterfaces(); i++) {
121  InterfaceEntry *ie = ift->getInterface(i);
122 
123  if (ie->ipv6Data()->getAdvSendAdvertisements() && !(ie->isLoopback())) {
124  createRATimer(ie);
125  }
126  }
127 
128  //This simulates random node bootup time. Link local address assignment
129  //takes place during this time.
130  cMessage *msg = new cMessage("assignLinkLocalAddr", MK_ASSIGN_LINKLOCAL_ADDRESS);
131 
132  //We want routers to boot up faster!
133  if (rt6->isRouter())
134  scheduleAt(simTime() + uniform(0, 0.3), msg); //Random Router bootup time
135  else
136  scheduleAt(simTime() + uniform(0.4, 1), msg); //Random Host bootup time
137  }
138 }
virtual void createRATimer(InterfaceEntry *ie)
Create a timer for the given interface entry that sends periodic Router Advertisements.
Definition: IPv6NeighbourDiscovery.cc:1646
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
Initialization of network-layer protocols, stage 3.
Definition: InitStages.h:84
xMIPv6 * mipv6
Definition: IPv6NeighbourDiscovery.h:105
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:56
Initialization of network-layer protocols, stage 1.
Definition: InitStages.h:72
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
virtual InterfaceEntry * getInterface(int pos) const =0
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
#define MK_ASSIGN_LINKLOCAL_ADDRESS
Definition: IPv6NeighbourDiscovery.cc:36
cQueue pendingQueue
Definition: IPv6NeighbourDiscovery.h:98
ICMPv6 * icmpv6
Definition: IPv6NeighbourDiscovery.h:102
Definition: NodeStatus.h:40
void inet::IPv6NeighbourDiscovery::initiateAddressResolution ( const IPv6Address dgSrcAddr,
Neighbour nce 
)
protectedvirtual

This method attempts to resolve the given neighbour's link-layer address.

The source address of the packet prompting address resolution is also given in order to decide the source address of the NS to be sent. nceKey stores 2 pieces of information (Neighbour address and Interface ID) which is needed for addr resolution and access to the corresponding nce.

Referenced by processIPv6Datagram().

647 {
648  const Key *nceKey = nce->nceKey;
649  InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
650  IPv6Address neighbourAddr = nceKey->address;
651  int ifID = nceKey->interfaceID;
652 
653  //RFC2461: Section 7.2.2
654  //When a node has a unicast packet to send to a neighbor, but does not
655  //know the neighbor's link-layer address, it performs address
656  //resolution. For multicast-capable interfaces this entails creating a
657  //Neighbor Cache entry in the INCOMPLETE state(already created if not done yet)
658  //WEI-If entry already exists, we still have to ensure that its state is INCOMPLETE.
659  nce->reachabilityState = IPv6NeighbourCache::INCOMPLETE;
660 
661  //and transmitting a Neighbor Solicitation message targeted at the
662  //neighbor. The solicitation is sent to the solicited-node multicast
663  //address "corresponding to"(or "derived from") the target address.
664  //(in this case, the target address is the address we are trying to resolve)
665  EV_INFO << "Preparing to send NS to solicited-node multicast group\n";
666  EV_INFO << "on the next hop interface\n";
667  IPv6Address nsDestAddr = neighbourAddr.formSolicitedNodeMulticastAddress(); //for NS datagram
668  IPv6Address nsTargetAddr = neighbourAddr; //for the field within the NS
669  IPv6Address nsSrcAddr;
670 
671  /*If the source address of the packet prompting the solicitation is the
672  same as one of the addresses assigned to the outgoing interface,*/
673  if (ie->ipv6Data()->hasAddress(dgSrcAddr))
674  /*that address SHOULD be placed in the IP Source Address of the outgoing
675  solicitation.*/
676  nsSrcAddr = dgSrcAddr;
677  else
678  /*Otherwise, any one of the addresses assigned to the interface
679  should be used.*/
680  nsSrcAddr = ie->ipv6Data()->getPreferredAddress();
681  ASSERT(ifID != -1);
682  //Sending NS on specified interface.
683  createAndSendNSPacket(nsTargetAddr, nsDestAddr, nsSrcAddr, ie);
684  nce->numOfARNSSent = 1;
685  nce->nsSrcAddr = nsSrcAddr;
686 
687  /*While awaiting a response, the sender SHOULD retransmit Neighbor Solicitation
688  messages approximately every RetransTimer milliseconds, even in the absence
689  of additional traffic to the neighbor. Retransmissions MUST be rate-limited
690  to at most one solicitation per neighbor every RetransTimer milliseconds.*/
691  cMessage *msg = new cMessage("arTimeout", MK_AR_TIMEOUT); //AR msg timer
692  nce->arTimer = msg;
693  msg->setContextPointer(nce);
694  scheduleAt(simTime() + ie->ipv6Data()->_getRetransTimer(), msg);
695 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual IPv6NeighbourSolicitation * createAndSendNSPacket(const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1816
IPv6NeighbourCache::Key Key
Definition: IPv6NeighbourDiscovery.h:54
Definition: IPv6NeighbourCache.h:53
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
#define MK_AR_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:43
void inet::IPv6NeighbourDiscovery::initiateDAD ( const IPv6Address tentativeAddr,
InterfaceEntry ie 
)
protectedvirtual

Initiating DAD means to send off a Neighbour Solicitation with its target address set as this node's tentative link-local address.

Referenced by assignLinkLocalAddress(), and processRAPrefixInfoForAddrAutoConf().

813 {
814 #ifdef WITH_xMIPv6
815  Enter_Method_Silent();
816  EV_INFO << "----------INITIATING DUPLICATE ADDRESS DISCOVERY----------" << endl;
817  ie->ipv6Data()->setDADInProgress(true);
818 #endif /* WITH_xMIPv6 */
819 
820  DADEntry *dadEntry = new DADEntry();
821  dadEntry->interfaceId = ie->getInterfaceId();
822  dadEntry->address = tentativeAddr;
823  dadEntry->numNSSent = 0;
824  dadList.insert(dadEntry);
825  /*
826  RFC2462: Section 5.4.2
827  To check an address, a node sends DupAddrDetectTransmits Neighbor
828  Solicitations, each separated by RetransTimer milliseconds. The
829  solicitation's Target Address is set to the address being checked,
830  the IP source is set to the unspecified address and the IP
831  destination is set to the solicited-node multicast address of the
832  target address.*/
833  IPv6Address destAddr = tentativeAddr.formSolicitedNodeMulticastAddress();
834  //Send a NS
835  createAndSendNSPacket(tentativeAddr, destAddr,
837  dadEntry->numNSSent++;
838 
839  cMessage *msg = new cMessage("dadTimeout", MK_DAD_TIMEOUT);
840  msg->setContextPointer(dadEntry);
841 
842 #ifndef WITH_xMIPv6
843  scheduleAt(simTime() + ie->ipv6Data()->getRetransTimer(), msg);
844 #else /* WITH_xMIPv6 */
845  // update: added uniform(0, IPv6_MAX_RTR_SOLICITATION_DELAY) to account for joining the solicited-node multicast
846  // group which is delay up to one 1 second (RFC 4862, 5.4.2) - 16.01.08, CB
847  scheduleAt(simTime() + ie->ipv6Data()->getRetransTimer() + uniform(0, IPv6_MAX_RTR_SOLICITATION_DELAY), msg);
848 #endif /* WITH_xMIPv6 */
849 
850  emit(startDADSignal, 1);
851 }
virtual IPv6NeighbourSolicitation * createAndSendNSPacket(const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1816
#define IPv6_MAX_RTR_SOLICITATION_DELAY
Definition: IPv6InterfaceData.h:55
static const IPv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: IPv6Address.h:66
#define MK_DAD_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:40
static simsignal_t startDADSignal
Definition: IPv6NeighbourDiscovery.h:63
DADList dadList
Definition: IPv6NeighbourDiscovery.h:145
void inet::IPv6NeighbourDiscovery::initiateNeighbourUnreachabilityDetection ( Neighbour neighbour)
protectedvirtual

Referenced by processIPv6Datagram(), and resolveNeighbour().

486 {
487  ASSERT(nce->reachabilityState == IPv6NeighbourCache::STALE);
488  ASSERT(nce->nudTimeoutEvent == nullptr);
489  const Key *nceKey = nce->nceKey;
490  EV_INFO << "Initiating Neighbour Unreachability Detection";
491  InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
492  EV_INFO << "Setting NCE state to DELAY.\n";
493  /*The first time a node sends a packet to a neighbor whose entry is
494  STALE, the sender changes the state to DELAY*/
495  nce->reachabilityState = IPv6NeighbourCache::DELAY;
496 
497  /*and sets a timer to expire in DELAY_FIRST_PROBE_TIME seconds.*/
498  cMessage *msg = new cMessage("NUDTimeout", MK_NUD_TIMEOUT);
499  msg->setContextPointer(nce);
500  nce->nudTimeoutEvent = msg;
501  scheduleAt(simTime() + ie->ipv6Data()->_getDelayFirstProbeTime(), msg);
502 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
IPv6NeighbourCache::Key Key
Definition: IPv6NeighbourDiscovery.h:54
Definition: IPv6NeighbourCache.h:53
#define MK_NUD_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:42
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
Definition: IPv6NeighbourCache.h:53
void inet::IPv6NeighbourDiscovery::initiateRouterDiscovery ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

995 {
996  EV_INFO << "Initiating Router Discovery" << endl;
997  InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
998  delete msg;
999  //RFC2461: Section 6.3.7
1000  /*When an interface becomes enabled, a host may be unwilling to wait for the
1001  next unsolicited Router Advertisement to locate default routers or learn
1002  prefixes. To obtain Router Advertisements quickly, a host SHOULD transmit up
1003  to MAX_RTR_SOLICITATIONS Router Solicitation messages each separated by at
1004  least RTR_SOLICITATION_INTERVAL seconds.(FIXME:Therefore this should be invoked
1005  at the beginning of the simulation-WEI)*/
1006  RDEntry *rdEntry = new RDEntry();
1007  rdEntry->interfaceId = ie->getInterfaceId();
1008  rdEntry->numRSSent = 0;
1010  rdEntry->numRSSent++;
1011 
1012  //Create and schedule a message for retransmission to this module
1013  cMessage *rdTimeoutMsg = new cMessage("processRDTimeout", MK_RD_TIMEOUT);
1014  rdTimeoutMsg->setContextPointer(ie);
1015  rdEntry->timeoutMsg = rdTimeoutMsg;
1016  rdList.insert(rdEntry);
1017  /*Before a host sends an initial solicitation, it SHOULD delay the
1018  transmission for a random amount of time between 0 and
1019  MAX_RTR_SOLICITATION_DELAY. This serves to alleviate congestion when
1020  many hosts start up on a link at the same time, such as might happen
1021  after recovery from a power failure. If a host has already performed
1022  a random delay since the interface became (re)enabled (e.g., as part
1023  of Duplicate Address Detection [ADDRCONF]) there is no need to delay
1024  again before sending the first Router Solicitation message.*/
1025  //simtime_t rndInterval = uniform(0, ie->ipv6Data()->_getMaxRtrSolicitationDelay());
1026  scheduleAt(simTime() + ie->ipv6Data()->_getRtrSolicitationInterval(), rdTimeoutMsg);
1027 }
#define MK_RD_TIMEOUT
Definition: IPv6NeighbourDiscovery.cc:41
virtual IPv6RouterSolicitation * createAndSendRSPacket(InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:962
RDList rdList
Definition: IPv6NeighbourDiscovery.h:148
void inet::IPv6NeighbourDiscovery::invalidateNeigbourCache ( )

RFC2463 Section 3.1: Destination Unreachable Message Send an unreachable message to the IPv6 module.

TODO: Relocate to ICMPv6 module

2603 {
2604  //Enter_Method("Invalidating Neigbour Cache Entries");
2606 }
virtual void invalidateAllEntries()
Set status of all neighbours to state PROBE.
Definition: IPv6NeighbourCache.cc:179
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
bool inet::IPv6NeighbourDiscovery::isWirelessAccessPoint ( cModule *  module)
protected

Referenced by canServeWirelessNodes().

2638 {
2639  // AccessPoint is defined as a node containing "relayUnit" and
2640  // "wlan" submodules
2641  return isNetworkNode(module) && module->getSubmodule("relayUnit") &&
2642  (module->getSubmodule("wlan", 0) || module->getSubmodule("wlan"));
2643 }
bool isNetworkNode(const cModule *mod)
Returns true if the given module is a network node, i.e.
Definition: ModuleAccess.cc:28
bool inet::IPv6NeighbourDiscovery::isWirelessInterface ( const InterfaceEntry ie)
protected

Referenced by canServeWirelessNodes().

2632 {
2633  // TODO should be a flag in the InterfaceEntry
2634  return strncmp("wlan", ie->getName(), 4) == 0;
2635 }
void inet::IPv6NeighbourDiscovery::makeTentativeAddressPermanent ( const IPv6Address tentativeAddr,
InterfaceEntry ie 
)
protectedvirtual

Permanently assign the given address for the given interface entry.

To be called after successful DAD.

Referenced by assignLinkLocalAddress(), and processDADTimeout().

883 {
884  ie->ipv6Data()->permanentlyAssign(tentativeAddr);
885 
886 #ifdef WITH_xMIPv6
887  ie->ipv6Data()->setDADInProgress(false);
888 
889  // update 28.09.07 - CB
890  // after the link-local address was verified to be unique
891  // we can assign the address and initiate the MIPv6 protocol
892  // in case there are any pending entries in the list
893  auto it = dadGlobalList.find(ie);
894  if (it != dadGlobalList.end()) {
895  DADGlobalEntry& entry = it->second;
896 
897  ie->ipv6Data()->assignAddress(entry.addr, false, simTime() + entry.validLifetime,
898  simTime() + entry.preferredLifetime, entry.hFlag);
899 
900  // moved from processRAPrefixInfoForAddrAutoConf()
901  // we can remove the old CoA now
902  if (!entry.CoA.isUnspecified())
903  ie->ipv6Data()->removeAddress(entry.CoA);
904 
905  // set addresses on this interface to tentative=false
906  for (int i = 0; i < ie->ipv6Data()->getNumAddresses(); i++) {
907  // TODO improve this code so that only addresses are permanently assigned
908  // which are formed based on the new prefix from the RA
909  IPv6Address addr = ie->ipv6Data()->getAddress(i);
910  ie->ipv6Data()->permanentlyAssign(addr);
911  }
912 
913  // if we have MIPv6 protocols on this node we will eventually have to
914  // call some appropriate methods
915  if (rt6->isMobileNode()) {
916  if (entry.hFlag == false) // if we are not in the home network, send BUs
917  mipv6->initiateMIPv6Protocol(ie, tentativeAddr);
918  /*
919  else if ( entry.returnedHome ) // if we are again in the home network
920  {
921  ASSERT(entry.CoA.isUnspecified() == false);
922  mipv6->returningHome(entry.CoA, ie); // initiate the returning home procedure
923  }*/
924  }
925 
926  dadGlobalList.erase(it->first);
927  }
928 
929  // an optimization to make sure that the access router on the link gets our L2 address
930  //sendUnsolicitedNA(ie);
931 
932  // =================================Start: Zarrar Yousaf 08.07.07 ===============================================
933  /* == Calling the routine to assign global scope adddresses to the the routers only. At present during the simulation initialization, the FlatNetworkConfigurator6 assigns a 64 bit prefix to the routers but for xMIPv6 operation, we need full 128bit global scope address, only for routers. The call to autoConfRouterGlobalScopeAddress() will autoconfigure the full 128 bit global scope address, which will be used by the MN in its BU message destination address, especially for home registeration.
934  */
935  if (rt6->isRouter() && !(ie->isLoopback())) {
936  for (int i = 0; i < ie->ipv6Data()->getNumAdvPrefixes(); i++) {
937  IPv6Address globalAddress = ie->ipv6Data()->autoConfRouterGlobalScopeAddress(i);
938  ie->ipv6Data()->assignAddress(globalAddress, false, 0, 0);
939  // ie->ipv6Data()->deduceAdvPrefix(); //commented out but the above two statements can be replaced with this single statement. But i am using the above two statements for clarity reasons.
940  }
941  }
942  // ==================================End: Zarrar Yousaf 08.07.07===========================================
943 #endif /* WITH_xMIPv6 */
944 
945  /*RFC 2461: Section 6.3.7 2nd Paragraph
946  Before a host sends an initial solicitation, it SHOULD delay the
947  transmission for a random amount of time between 0 and
948  MAX_RTR_SOLICITATION_DELAY. This serves to alleviate congestion when
949  many hosts start up on a link at the same time, such as might happen
950  after recovery from a power failure.*/
951  //TODO: Placing these operations here means fast router solicitation is
952  //not adopted. Will relocate.
953  if (ie->ipv6Data()->getAdvSendAdvertisements() == false) {
954  EV_INFO << "creating router discovery message timer\n";
955  cMessage *rtrDisMsg = new cMessage("initiateRTRDIS", MK_INITIATE_RTRDIS);
956  rtrDisMsg->setContextPointer(ie);
957  simtime_t interval = uniform(0, ie->ipv6Data()->_getMaxRtrSolicitationDelay()); // random delay
958  scheduleAt(simTime() + interval, rtrDisMsg);
959  }
960 }
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
#define MK_INITIATE_RTRDIS
Definition: IPv6NeighbourDiscovery.cc:39
bool isMobileNode() const
Determine whether a node is a Mobile Node or Correspondent Node: MN if TRUE or else a CN...
Definition: IPv6RoutingTable.h:181
xMIPv6 * mipv6
Definition: IPv6NeighbourDiscovery.h:105
void initiateMIPv6Protocol(InterfaceEntry *ie, const IPv6Address &CoA)
Initiates the Mobile IP protocol.
Definition: xMIPv6.cc:244
DADGlobalList dadGlobalList
Definition: IPv6NeighbourDiscovery.h:167
virtual bool isRouter() const
IP forwarding on/off.
Definition: IPv6RoutingTable.h:155
virtual int inet::IPv6NeighbourDiscovery::numInitStages ( ) const
inlineoverrideprotectedvirtual
172 { return NUM_INIT_STAGES; }
The number of initialization stages.
Definition: InitStages.h:116
void inet::IPv6NeighbourDiscovery::processARTimeout ( cMessage *  arTimeoutMsg)
protectedvirtual

Resends a NS packet to the address intended for address resolution.

TODO: Not implemented yet!

Referenced by handleMessage().

698 {
699  //AR timeouts are cancelled when a valid solicited NA is received.
700  Neighbour *nce = (Neighbour *)arTimeoutMsg->getContextPointer();
701  const Key *nceKey = nce->nceKey;
702  IPv6Address nsTargetAddr = nceKey->address;
703  InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
704  EV_INFO << "Num Of NS Sent:" << nce->numOfARNSSent << endl;
705  EV_INFO << "Max Multicast Solicitation:" << ie->ipv6Data()->_getMaxMulticastSolicit() << endl;
706 
707  if (nce->numOfARNSSent < ie->ipv6Data()->_getMaxMulticastSolicit()) {
708  EV_INFO << "Sending another Address Resolution NS message" << endl;
709  IPv6Address nsDestAddr = nsTargetAddr.formSolicitedNodeMulticastAddress();
710  createAndSendNSPacket(nsTargetAddr, nsDestAddr, nce->nsSrcAddr, ie);
711  nce->numOfARNSSent++;
712  scheduleAt(simTime() + ie->ipv6Data()->_getRetransTimer(), arTimeoutMsg);
713  return;
714  }
715 
716  EV_WARN << "Address Resolution has failed." << endl;
718  EV_INFO << "Deleting AR timeout msg\n";
719  delete arTimeoutMsg;
720 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
IPv6Address address
Definition: IPv6NeighbourCache.h:62
virtual IPv6NeighbourSolicitation * createAndSendNSPacket(const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1816
IPv6NeighbourCache::Key Key
Definition: IPv6NeighbourDiscovery.h:54
uint _getMaxMulticastSolicit() const
Definition: IPv6InterfaceData.h:631
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual void dropQueuedPacketsAwaitingAR(Neighbour *nce)
Drops specific queued packets for a specific NCE AR-timeout.
Definition: IPv6NeighbourDiscovery.cc:722
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
IPv6InterfaceData * ipv6Data() const
Definition: InterfaceEntry.h:223
void inet::IPv6NeighbourDiscovery::processDADTimeout ( cMessage *  msg)
protectedvirtual

Sends a scheduled DAD NS packet.

If number of sends is equals or more than dupAddrDetectTransmits, then permantly assign target link local address as permanent address for given interface entry.

Referenced by handleMessage().

854 {
855  DADEntry *dadEntry = (DADEntry *)msg->getContextPointer();
856  InterfaceEntry *ie = (InterfaceEntry *)ift->getInterfaceById(dadEntry->interfaceId);
857  IPv6Address tentativeAddr = dadEntry->address;
858  //Here, we need to check how many DAD messages for the interface entry were
859  //sent vs. DupAddrDetectTransmits
860  EV_DETAIL << "numOfDADMessagesSent is: " << dadEntry->numNSSent << endl;
861  EV_DETAIL << "dupAddrDetectTrans is: " << ie->ipv6Data()->getDupAddrDetectTransmits() << endl;
862 
863  if (dadEntry->numNSSent < ie->ipv6Data()->getDupAddrDetectTransmits()) {
864  bubble("Sending another DAD NS message.");
865  IPv6Address destAddr = tentativeAddr.formSolicitedNodeMulticastAddress();
866  createAndSendNSPacket(dadEntry->address, destAddr, IPv6Address::UNSPECIFIED_ADDRESS, ie);
867  dadEntry->numNSSent++;
868  //Reuse the received msg
869  scheduleAt(simTime() + ie->ipv6Data()->getRetransTimer(), msg);
870  }
871  else {
872  bubble("Max number of DAD messages for interface sent. Address is unique.");
873  dadList.erase(dadEntry);
874  EV_DETAIL << "delete dadEntry and msg\n";
875  delete dadEntry;
876  delete msg;
877 
878  makeTentativeAddressPermanent(tentativeAddr, ie);
879  }
880 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual IPv6NeighbourSolicitation * createAndSendNSPacket(const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1816
static const IPv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: IPv6Address.h:66
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual void makeTentativeAddressPermanent(const IPv6Address &tentativeAddr, InterfaceEntry *ie)
Permanently assign the given address for the given interface entry.
Definition: IPv6NeighbourDiscovery.cc:882
int getDupAddrDetectTransmits() const
Definition: IPv6InterfaceData.h:653
IPv6InterfaceData * ipv6Data() const
Definition: InterfaceEntry.h:223
DADList dadList
Definition: IPv6NeighbourDiscovery.h:145
void inet::IPv6NeighbourDiscovery::processIPv6Datagram ( IPv6Datagram datagram)
protectedvirtual

Referenced by handleMessage().

231 {
232  EV_INFO << "Packet " << msg << " arrived from IPv6 module.\n";
233 
234  IPv6NDControlInfo *ctrl = check_and_cast<IPv6NDControlInfo *>(msg->getControlInfo());
235  int nextHopIfID = ctrl->getInterfaceId();
236  IPv6Address nextHopAddr = ctrl->getNextHop();
237  //bool fromHL = ctrl->getFromHL();
238 
239  if (nextHopIfID == -1 || nextHopAddr.isUnspecified()) {
240  EV_INFO << "Determining Next Hop" << endl;
241  nextHopAddr = determineNextHop(msg->getDestAddress(), nextHopIfID);
242  ctrl->setInterfaceId(nextHopIfID);
243  ctrl->setNextHop(nextHopAddr);
244  }
245 
246  if (nextHopIfID == -1) {
247  //draft-ietf-ipv6-2461bis-04 has omitted on-link assumption.
248  //draft-ietf-v6ops-onlinkassumption-03 explains why.
249  delete msg->removeControlInfo();
251  return;
252  }
253 
254  EV_INFO << "Next Hop Address is: " << nextHopAddr << " on interface: " << nextHopIfID << endl;
255 
256  //RFC2461: Section 5.2 Conceptual Sending Algorithm
257  //Once the IP address of the next-hop node is known, the sender examines the
258  //Neighbor Cache for link-layer information about that neighbor.
259  Neighbour *nce = neighbourCache.lookup(nextHopAddr, nextHopIfID);
260 
261  if (nce == nullptr) {
262  EV_INFO << "No Entry exists in the Neighbour Cache.\n";
263  InterfaceEntry *ie = ift->getInterfaceById(nextHopIfID);
264  if (ie->isPointToPoint()) {
265  //the sender creates one, sets its state to STALE,
266  EV_DETAIL << "Creating an STALE entry in the neighbour cache.\n";
267  nce = neighbourCache.addNeighbour(nextHopAddr, nextHopIfID, MACAddress::UNSPECIFIED_ADDRESS);
268  }
269  else {
270  //the sender creates one, sets its state to INCOMPLETE,
271  EV_DETAIL << "Creating an INCOMPLETE entry in the neighbour cache.\n";
272  nce = neighbourCache.addNeighbour(nextHopAddr, nextHopIfID);
273 
274  //initiates Address Resolution,
275  EV_DETAIL << "Initiating Address Resolution for:" << nextHopAddr
276  << " on Interface:" << nextHopIfID << endl;
277  initiateAddressResolution(msg->getSrcAddress(), nce);
278  }
279  }
280 
281  /*
282  * A host is capable of sending packets to a destination in all states except INCOMPLETE
283  * or when there is no corresponding NC entry. In INCOMPLETE state the data packets are
284  * queued pending completion of address resolution.
285  */
286  switch (nce->reachabilityState) {
288  EV_INFO << "Reachability State is INCOMPLETE. Address Resolution already initiated.\n";
289  EV_INFO << "Add packet to entry's queue until Address Resolution is complete.\n";
290  bubble("Packet added to queue until Address Resolution is complete.");
291  nce->pendingPackets.push_back(msg);
292  pendingQueue.insert(msg);
293  break;
295  EV_INFO << "Reachability State is STALE.\n";
296  send(msg, "ipv6Out");
298  break;
300  EV_INFO << "Next hop is REACHABLE, sending packet to next-hop address.";
301  send(msg, "ipv6Out");
302  break;
304  EV_INFO << "Next hop is in DELAY state, sending packet to next-hop address.";
305  send(msg, "ipv6Out");
306  break;
308  EV_INFO << "Next hop is in PROBE state, sending packet to next-hop address.";
309  send(msg, "ipv6Out");
310  break;
311  default:
312  throw cRuntimeError("Unknown Neighbour cache entry state.");
313  break;
314  }
315 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
Definition: IPv6NeighbourCache.h:53
Definition: IPv6NeighbourCache.h:53
virtual void initiateAddressResolution(const IPv6Address &dgSrcAddr, Neighbour *nce)
This method attempts to resolve the given neighbour&#39;s link-layer address.
Definition: IPv6NeighbourDiscovery.cc:645
virtual void initiateNeighbourUnreachabilityDetection(Neighbour *neighbour)
Definition: IPv6NeighbourDiscovery.cc:485
virtual IPv6Address determineNextHop(const IPv6Address &destAddr, int &outIfID)
This function accepts the datagram&#39;s destination address and attempts to determine the destination&#39;s ...
Definition: IPv6NeighbourDiscovery.cc:436
Definition: ICMPv6Message_m.h:71
virtual Neighbour * lookup(const IPv6Address &addr, int interfaceID)
Returns a neighbour entry, or nullptr.
Definition: IPv6NeighbourCache.cc:85
Definition: IPv6NeighbourCache.h:53
Definition: IPv6NeighbourCache.h:53
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
Definition: IPv6NeighbourCache.h:53
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
virtual Neighbour * addNeighbour(const IPv6Address &addr, int interfaceID)
Creates and initializes a neighbour entry with isRouter=false, state=INCOMPLETE.
Definition: IPv6NeighbourCache.cc:98
Definition: ICMPv6Message_m.h:107
cQueue pendingQueue
Definition: IPv6NeighbourDiscovery.h:98
static const MACAddress UNSPECIFIED_ADDRESS
The unspecified MAC address, 00:00:00:00:00:00.
Definition: MACAddress.h:57
ICMPv6 * icmpv6
Definition: IPv6NeighbourDiscovery.h:102
virtual void sendErrorMessage(IPv6Datagram *datagram, ICMPv6Type type, int code)
This method can be called from other modules to send an ICMPv6 error packet.
Definition: ICMPv6.cc:188
void inet::IPv6NeighbourDiscovery::processNAForIncompleteNCEState ( IPv6NeighbourAdvertisement na,
IPv6NeighbourCache::Neighbour nce 
)
protectedvirtual

Referenced by processNAPacket().

2255 {
2256  MACAddress naMacAddr = na->getTargetLinkLayerAddress();
2257  bool naRouterFlag = na->getRouterFlag();
2258  bool naSolicitedFlag = na->getSolicitedFlag();
2259  const Key *nceKey = nce->nceKey;
2260  InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
2261 
2262  /*If the target's neighbour Cache entry is in the INCOMPLETE state when the
2263  advertisement is received, one of two things happens.*/
2264  if (naMacAddr.isUnspecified()) {
2265  /*If the link layer has addresses and no Target Link-Layer address option
2266  is included, the receiving node SHOULD silently discard the received
2267  advertisement.*/
2268  EV_INFO << "No MAC Address specified in NA. Ignoring NA\n";
2269  return;
2270  }
2271  else {
2272  //Otherwise, the receiving node performs the following steps:
2273  //- It records the link-layer address in the neighbour Cache entry.
2274  EV_INFO << "ND is updating Neighbour Cache Entry.\n";
2275  nce->macAddress = naMacAddr;
2276 
2277  //- If the advertisement's Solicited flag is set, the state of the
2278  // entry is set to REACHABLE, otherwise it is set to STALE.
2279  if (naSolicitedFlag == true) {
2280  nce->reachabilityState = IPv6NeighbourCache::REACHABLE;
2281  EV_INFO << "Reachability confirmed through successful Addr Resolution.\n";
2282  nce->reachabilityExpires = simTime() + ie->ipv6Data()->_getReachableTime();
2283  }
2284  else
2285  nce->reachabilityState = IPv6NeighbourCache::STALE;
2286 
2287  //- It sets the IsRouter flag in the cache entry based on the Router
2288  // flag in the received advertisement.
2289  nce->isRouter = naRouterFlag;
2290  if (nce->isDefaultRouter() && !nce->isRouter)
2292 
2293  //- It sends any packets queued for the neighbour awaiting address
2294  // resolution.
2296  cancelAndDelete(nce->arTimer);
2297  nce->arTimer = nullptr;
2298  }
2299 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
DefaultRouterList & getDefaultRouterList()
Definition: IPv6NeighbourCache.h:175
Definition: IPv6NeighbourCache.h:53
void remove(Neighbour &router)
Definition: IPv6NeighbourCache.cc:41
IPv6NeighbourCache::Key Key
Definition: IPv6NeighbourDiscovery.h:54
Definition: IPv6NeighbourCache.h:53
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
virtual void sendQueuedPacketsToIPv6Module(Neighbour *nce)
Send off any queued packets within the Neighbour Discovery module awaiting address resolution...
Definition: IPv6NeighbourDiscovery.cc:768
void inet::IPv6NeighbourDiscovery::processNAForOtherNCEStates ( IPv6NeighbourAdvertisement na,
IPv6NeighbourCache::Neighbour nce 
)
protectedvirtual

Referenced by processNAPacket().

2302 {
2303  bool naRouterFlag = na->getRouterFlag();
2304  bool naSolicitedFlag = na->getSolicitedFlag();
2305  bool naOverrideFlag = na->getOverrideFlag();
2306  MACAddress naMacAddr = na->getTargetLinkLayerAddress();
2307  const Key *nceKey = nce->nceKey;
2308  InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
2309 
2310  /*draft-ietf-ipv6-2461bis-04
2311  Section 7.2.5: Receipt of Neighbour Advertisements
2312  If the target's Neighbor Cache entry is in any state other than INCOMPLETE
2313  when the advertisement is received, the following actions take place:*/
2314 
2315  if (naOverrideFlag == false && !(naMacAddr.equals(nce->macAddress))
2316  && !(naMacAddr.isUnspecified()))
2317  {
2318  EV_INFO << "NA override is FALSE and NA MAC addr is different.\n";
2319 
2320  //I. If the Override flag is clear and the supplied link-layer address
2321  // differs from that in the cache, then one of two actions takes place:
2322  //(Note: An unspecified MAC should not be compared with the NCE's mac!)
2323  //a. If the state of the entry is REACHABLE,
2324  if (nce->reachabilityState == IPv6NeighbourCache::REACHABLE) {
2325  EV_INFO << "NA mac is different. Change NCE state from REACHABLE to STALE\n";
2326  //set it to STALE, but do not update the entry in any other way.
2327  nce->reachabilityState = IPv6NeighbourCache::STALE;
2328  }
2329  else
2330  //b. Otherwise, the received advertisement should be ignored and
2331  //MUST NOT update the cache.
2332  EV_INFO << "NCE is not in REACHABLE state. Ignore NA.\n";
2333  }
2334  else if (naOverrideFlag == true || naMacAddr.equals(nce->macAddress)
2335  || naMacAddr.isUnspecified())
2336  {
2337  EV_INFO << "NA override flag is TRUE. or Advertised MAC is same as NCE's. or"
2338  << " NA MAC is not specified.\n";
2339  /*II. If the Override flag is set, or the supplied link-layer address
2340  is the same as that in the cache, or no Target Link-layer address
2341  option was supplied, the received advertisement MUST update the
2342  Neighbor Cache entry as follows:*/
2343 
2344  /*- The link-layer address in the Target Link-Layer Address option
2345  MUST be inserted in the cache (if one is supplied and is
2346  Different than the already recorded address).*/
2347  if (!(naMacAddr.isUnspecified()) && !(naMacAddr.equals(nce->macAddress))) {
2348  EV_INFO << "Updating NCE's MAC addr with NA's.\n";
2349  nce->macAddress = naMacAddr;
2350  }
2351 
2352  //- If the Solicited flag is set,
2353  if (naSolicitedFlag == true) {
2354  EV_INFO << "Solicited Flag is TRUE. Set NCE state to REACHABLE.\n";
2355  //the state of the entry MUST be set to REACHABLE.
2356  nce->reachabilityState = IPv6NeighbourCache::REACHABLE;
2357  //We have to cancel the NUD self timer message if there is one.
2358 
2359  cMessage *msg = nce->nudTimeoutEvent;
2360  if (msg != nullptr) {
2361  EV_INFO << "NUD in progress. Cancelling NUD Timer\n";
2362  bubble("Reachability Confirmed via NUD.");
2363  nce->reachabilityExpires = simTime() + ie->ipv6Data()->_getReachableTime();
2364  cancelAndDelete(msg);
2365  nce->nudTimeoutEvent = nullptr;
2366  }
2367  }
2368  else {
2369  //If the Solicited flag is zero
2370  EV_INFO << "Solicited Flag is FALSE.\n";
2371  //and the link layer address was updated with a different address
2372 
2373  if (!(naMacAddr.equals(nce->macAddress))) {
2374  EV_INFO << "NA's MAC is different from NCE's.Set NCE state to STALE\n";
2375  //the state MUST be set to STALE.
2376  nce->reachabilityState = IPv6NeighbourCache::STALE;
2377  }
2378  else
2379  //Otherwise, the entry's state remains unchanged.
2380  EV_INFO << "NA's MAC is the same as NCE's. State remains unchanged.\n";
2381  }
2382  //(Next paragraph with explanation is omitted.-WEI)
2383 
2384  /*- The IsRouter flag in the cache entry MUST be set based on the
2385  Router flag in the received advertisement.*/
2386  EV_INFO << "Updating NCE's router flag to " << naRouterFlag << endl;
2387  nce->isRouter = naRouterFlag;
2388 
2389  /*In those cases where the IsRouter flag changes from TRUE to FALSE as a
2390  result of this update, the node MUST remove that router from the Default
2391  Router List and update the Destination Cache entries for all destinations
2392  using that neighbor as a router as specified in Section 7.3.3. This is
2393  needed to detect when a node that is used as a router stops forwarding
2394  packets due to being configured as a host.*/
2395  if (nce->isDefaultRouter() && !nce->isRouter)
2397 
2398  //TODO: remove destination cache entries
2399  }
2400 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
DefaultRouterList & getDefaultRouterList()
Definition: IPv6NeighbourCache.h:175
Definition: IPv6NeighbourCache.h:53
void remove(Neighbour &router)
Definition: IPv6NeighbourCache.cc:41
IPv6NeighbourCache::Key Key
Definition: IPv6NeighbourDiscovery.h:54
Definition: IPv6NeighbourCache.h:53
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
void inet::IPv6NeighbourDiscovery::processNAPacket ( IPv6NeighbourAdvertisement na,
IPv6ControlInfo naCtrlInfo 
)
protectedvirtual

Referenced by processNDMessage().

2176 {
2177  if (validateNAPacket(na, naCtrlInfo) == false) {
2178  delete naCtrlInfo;
2179  delete na;
2180  return;
2181  }
2182 
2183  //Neighbour Advertisement Information
2184  IPv6Address naTargetAddr = na->getTargetAddress();
2185 
2186  //First, we check if the target address in NA is found in the interface it
2187  //was received on is tentative.
2188  InterfaceEntry *ie = ift->getInterfaceById(naCtrlInfo->getInterfaceId());
2189  if (ie->ipv6Data()->isTentativeAddress(naTargetAddr)) {
2190  throw cRuntimeError("Duplicate Address Detected! Manual attention needed!");
2191  }
2192  //Logic as defined in Section 7.2.5
2193  Neighbour *neighbourEntry = neighbourCache.lookup(naTargetAddr, ie->getInterfaceId());
2194 
2195  if (neighbourEntry == nullptr) {
2196  EV_INFO << "NA received. Target Address not found in Neighbour Cache\n";
2197  EV_INFO << "Dropping NA packet.\n";
2198  delete naCtrlInfo;
2199  delete na;
2200  return;
2201  }
2202 
2203  //Target Address has entry in Neighbour Cache
2204  EV_INFO << "NA received. Target Address found in Neighbour Cache\n";
2205 
2206  if (neighbourEntry->reachabilityState == IPv6NeighbourCache::INCOMPLETE)
2207  processNAForIncompleteNCEState(na, neighbourEntry);
2208  else
2209  processNAForOtherNCEStates(na, neighbourEntry);
2210 
2211  delete naCtrlInfo;
2212  delete na;
2213 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual Neighbour * lookup(const IPv6Address &addr, int interfaceID)
Returns a neighbour entry, or nullptr.
Definition: IPv6NeighbourCache.cc:85
Definition: IPv6NeighbourCache.h:53
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual bool validateNAPacket(IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:2215
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
virtual void processNAForIncompleteNCEState(IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce)
Definition: IPv6NeighbourDiscovery.cc:2254
virtual void processNAForOtherNCEStates(IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce)
Definition: IPv6NeighbourDiscovery.cc:2301
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
void inet::IPv6NeighbourDiscovery::processNDMessage ( ICMPv6Message msg,
IPv6ControlInfo ctrlInfo 
)
protectedvirtual

Referenced by handleMessage().

195 {
196  if (dynamic_cast<IPv6RouterSolicitation *>(msg)) {
197  IPv6RouterSolicitation *rs = (IPv6RouterSolicitation *)msg;
198  processRSPacket(rs, ctrlInfo);
199  }
200  else if (dynamic_cast<IPv6RouterAdvertisement *>(msg)) {
201  IPv6RouterAdvertisement *ra = (IPv6RouterAdvertisement *)msg;
202  processRAPacket(ra, ctrlInfo);
203  }
204  else if (dynamic_cast<IPv6NeighbourSolicitation *>(msg)) {
205  IPv6NeighbourSolicitation *ns = (IPv6NeighbourSolicitation *)msg;
206  processNSPacket(ns, ctrlInfo);
207  }
208  else if (dynamic_cast<IPv6NeighbourAdvertisement *>(msg)) {
209  IPv6NeighbourAdvertisement *na = (IPv6NeighbourAdvertisement *)msg;
210  processNAPacket(na, ctrlInfo);
211  }
212  else if (dynamic_cast<IPv6Redirect *>(msg)) {
213  IPv6Redirect *redirect = (IPv6Redirect *)msg;
214  processRedirectPacket(redirect, ctrlInfo);
215  }
216  else {
217  throw cRuntimeError("Unrecognized ND message!");
218  }
219 }
virtual void processNAPacket(IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:2174
virtual void processRSPacket(IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1075
virtual void processRedirectPacket(IPv6Redirect *redirect, IPv6ControlInfo *ctrlInfo)
Definition: IPv6NeighbourDiscovery.cc:2423
virtual void processRAPacket(IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1299
virtual void processNSPacket(IPv6NeighbourSolicitation *ns, IPv6ControlInfo *naCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1847
void inet::IPv6NeighbourDiscovery::processNSForNonTentativeAddress ( IPv6NeighbourSolicitation ns,
IPv6ControlInfo ctrlInfo,
InterfaceEntry ie 
)
protectedvirtual

Referenced by processNSPacket().

1957 {
1958  //Neighbour Solicitation Information
1959  //MACAddress nsMacAddr = ns->getSourceLinkLayerAddress();
1960 
1961  //target addr is not tentative addr
1962  //solicitation processed as described in RFC2461:section 7.2.3
1963  if (nsCtrlInfo->getSrcAddr().isUnspecified()) {
1964  EV_INFO << "Address is duplicate! Inform Sender of duplicate address!\n";
1965  sendSolicitedNA(ns, nsCtrlInfo, ie);
1966  }
1967  else {
1968  processNSWithSpecifiedSrcAddr(ns, nsCtrlInfo, ie);
1969  }
1970 }
virtual void sendSolicitedNA(IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:2011
virtual void processNSWithSpecifiedSrcAddr(IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1972
void inet::IPv6NeighbourDiscovery::processNSForTentativeAddress ( IPv6NeighbourSolicitation ns,
IPv6ControlInfo ctrlInfo 
)
protectedvirtual

Referenced by processNSPacket().

1929 {
1930  //Control Information
1931  IPv6Address nsSrcAddr = nsCtrlInfo->getSrcAddr();
1932  //IPv6Address nsDestAddr = nsCtrlInfo->getDestAddr();
1933 
1934  ASSERT(nsSrcAddr.isUnicast() || nsSrcAddr.isUnspecified());
1935  //solicitation is processed as described in RFC2462:section 5.4.3
1936 
1937  if (nsSrcAddr.isUnspecified()) {
1938  EV_INFO << "Source Address is UNSPECIFIED. Sender is performing DAD\n";
1939 
1940  //Sender performing Duplicate Address Detection
1941  if (rt6->isLocalAddress(nsSrcAddr)) // FIXME: isLocalAddress(UNSPECIFIED) is always false!!! Must write another check for detecting source is myself/foreign node!!!
1942  EV_INFO << "NS comes from myself. Ignoring NS\n";
1943  else {
1944  EV_INFO << "NS comes from another node. Address is duplicate!\n";
1945  throw cRuntimeError("Duplicate Address Detected! Manual Attention Required!");
1946  }
1947  }
1948  else if (nsSrcAddr.isUnicast()) {
1949  //Sender performing address resolution
1950  EV_INFO << "Sender is performing Address Resolution\n";
1951  EV_INFO << "Target Address is tentative. Ignoring NS.\n";
1952  }
1953 }
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
virtual bool isLocalAddress(const IPv6Address &dest) const
Checks if the address is one of the host&#39;s addresses, i.e.
Definition: IPv6RoutingTable.cc:423
void inet::IPv6NeighbourDiscovery::processNSPacket ( IPv6NeighbourSolicitation ns,
IPv6ControlInfo naCtrlInfo 
)
protectedvirtual

Referenced by processNDMessage().

1849 {
1850  //Control Information
1851  InterfaceEntry *ie = ift->getInterfaceById(nsCtrlInfo->getInterfaceId());
1852 
1853  IPv6Address nsTargetAddr = ns->getTargetAddress();
1854 
1855  //RFC 2461:Section 7.2.3
1856  //If target address is not a valid "unicast" or anycast address assigned to the
1857  //receiving interface, we should silently discard the packet.
1858  if (validateNSPacket(ns, nsCtrlInfo) == false
1859  || ie->ipv6Data()->hasAddress(nsTargetAddr) == false)
1860  {
1861  bubble("NS validation failed\n");
1862  delete nsCtrlInfo;
1863  delete ns;
1864  return;
1865  }
1866 
1867  bubble("NS validation passed.\n");
1868 
1869  if (ie->ipv6Data()->isTentativeAddress(nsTargetAddr)) {
1870  //If the Target Address is tentative, the Neighbor Solicitation should
1871  //be processed as described in [ADDRCONF].
1872  EV_INFO << "Process NS for Tentative target address.\n";
1873  processNSForTentativeAddress(ns, nsCtrlInfo);
1874  }
1875  else {
1876  //Otherwise, the following description applies.
1877  EV_INFO << "Process NS for Non-Tentative target address.\n";
1878  processNSForNonTentativeAddress(ns, nsCtrlInfo, ie);
1879  }
1880 
1881  delete nsCtrlInfo;
1882  delete ns;
1883 }
virtual bool validateNSPacket(IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1885
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual void processNSForNonTentativeAddress(IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1955
virtual void processNSForTentativeAddress(IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1927
void inet::IPv6NeighbourDiscovery::processNSWithSpecifiedSrcAddr ( IPv6NeighbourSolicitation ns,
IPv6ControlInfo ctrlInfo,
InterfaceEntry ie 
)
protectedvirtual

Referenced by processNSForNonTentativeAddress().

1974 {
1975  //RFC 2461, Section 7.2.3
1976  /*If the Source Address is not the unspecified address and, on link layers
1977  that have addresses, the solicitation includes a Source Link-Layer Address
1978  option, then the recipient SHOULD create or update the Neighbor Cache entry
1979  for the IP Source Address of the solicitation.*/
1980 
1981  //Neighbour Solicitation Information
1982  MACAddress nsMacAddr = ns->getSourceLinkLayerAddress();
1983 
1984  int ifID = ie->getInterfaceId();
1985 
1986  //Look for the Neighbour Cache Entry
1987  Neighbour *entry = neighbourCache.lookup(nsCtrlInfo->getSrcAddr(), ifID);
1988 
1989  if (entry == nullptr) {
1990  /*If an entry does not already exist, the node SHOULD create a new one
1991  and set its reachability state to STALE as specified in Section 7.3.3.*/
1992  EV_INFO << "Neighbour Entry not found. Create a Neighbour Cache Entry.\n";
1993  neighbourCache.addNeighbour(nsCtrlInfo->getSrcAddr(), ifID, nsMacAddr);
1994  }
1995  else {
1996  /*If an entry already exists, and the cached link-layer address differs from
1997  the one in the received Source Link-Layer option,*/
1998  if (!(entry->macAddress.equals(nsMacAddr)) && !nsMacAddr.isUnspecified()) {
1999  //the cached address should be replaced by the received address
2000  entry->macAddress = nsMacAddr;
2001  //and the entry's reachability state MUST be set to STALE.
2002  entry->reachabilityState = IPv6NeighbourCache::STALE;
2003  }
2004  }
2005 
2006  /*After any updates to the Neighbor Cache, the node sends a Neighbor
2007  Advertisement response as described in the next section.*/
2008  sendSolicitedNA(ns, nsCtrlInfo, ie);
2009 }
virtual void sendSolicitedNA(IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:2011
MACAddress macAddress
Definition: IPv6NeighbourCache.h:76
virtual Neighbour * lookup(const IPv6Address &addr, int interfaceID)
Returns a neighbour entry, or nullptr.
Definition: IPv6NeighbourCache.cc:85
Definition: IPv6NeighbourCache.h:53
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
virtual Neighbour * addNeighbour(const IPv6Address &addr, int interfaceID)
Creates and initializes a neighbour entry with isRouter=false, state=INCOMPLETE.
Definition: IPv6NeighbourCache.cc:98
void inet::IPv6NeighbourDiscovery::processNUDTimeout ( cMessage *  timeoutMsg)
protectedvirtual

Referenced by handleMessage().

505 {
506  EV_INFO << "NUD has timed out\n";
507  Neighbour *nce = (Neighbour *)timeoutMsg->getContextPointer();
508 
509  const Key *nceKey = nce->nceKey;
510  if (nceKey == nullptr)
511  throw cRuntimeError("The nceKey is nullptr at nce->MAC=%s, isRouter=%d",
512  nce->macAddress.str().c_str(), nce->isRouter);
513 
514  InterfaceEntry *ie = ift->getInterfaceById(nceKey->interfaceID);
515 
516  if (nce->reachabilityState == IPv6NeighbourCache::DELAY) {
517  /*If the entry is still in the DELAY state when the timer expires, the
518  entry's state changes to PROBE. If reachability confirmation is received,
519  the entry's state changes to REACHABLE.*/
520  EV_DETAIL << "Neighbour Entry is still in DELAY state.\n";
521  EV_DETAIL << "Entering PROBE state. Sending NS probe.\n";
522  nce->reachabilityState = IPv6NeighbourCache::PROBE;
523  nce->numProbesSent = 0;
524  }
525 
526  /*If no response is received after waiting RetransTimer milliseconds
527  after sending the MAX_UNICAST_SOLICIT solicitations, retransmissions cease
528  and the entry SHOULD be deleted. Subsequent traffic to that neighbor will
529  recreate the entry and performs address resolution again.*/
530  if (nce->numProbesSent == (int)ie->ipv6Data()->_getMaxUnicastSolicit()) {
531  EV_DETAIL << "Max number of probes have been sent." << endl;
532  EV_DETAIL << "Neighbour is Unreachable, removing NCE." << endl;
533  neighbourCache.remove(nceKey->address, nceKey->interfaceID); // remove nce from cache, cancel and delete timeoutMsg;
534  return;
535  }
536 
537  /*Upon entering the PROBE state, a node sends a unicast Neighbor Solicitation
538  message to the neighbor using the cached link-layer address.*/
539  createAndSendNSPacket(nceKey->address, nceKey->address,
540  ie->ipv6Data()->getPreferredAddress(), ie);
541  nce->numProbesSent++;
542  /*While in the PROBE state, a node retransmits Neighbor Solicitation messages
543  every RetransTimer milliseconds until reachability confirmation is obtained.
544  Probes are retransmitted even if no additional packets are sent to the
545  neighbor.*/
546  scheduleAt(simTime() + ie->ipv6Data()->_getRetransTimer(), timeoutMsg);
547 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
Definition: IPv6NeighbourCache.h:53
virtual IPv6NeighbourSolicitation * createAndSendNSPacket(const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1816
IPv6NeighbourCache::Key Key
Definition: IPv6NeighbourDiscovery.h:54
virtual void remove(const IPv6Address &addr, int interfaceID)
Deletes the given neighbour from the cache.
Definition: IPv6NeighbourCache.cc:149
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
Definition: IPv6NeighbourCache.h:53
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
void inet::IPv6NeighbourDiscovery::processRAForRouterUpdates ( IPv6RouterAdvertisement ra,
IPv6ControlInfo raCtrlInfo 
)
protectedvirtual

Referenced by processRAPacket().

1366 {
1367  EV_INFO << "Processing RA for Router Updates\n";
1368  //RFC2461: Section 6.3.4
1369  //Paragraphs 1 and 2 omitted.
1370 
1371  //On receipt of a valid Router Advertisement, a host extracts the source
1372  //address of the packet and does the following:
1373  IPv6Address raSrcAddr = raCtrlInfo->getSrcAddr();
1374  InterfaceEntry *ie = ift->getInterfaceById(raCtrlInfo->getInterfaceId());
1375  int ifID = ie->getInterfaceId();
1376 
1377  /*- If the address is not already present in the host's Default Router List,
1378  and the advertisement's Router Lifetime is non-zero, create a new entry in
1379  the list, and initialize its invalidation timer value from the advertisement's
1380  Router Lifetime field.*/
1381  Neighbour *neighbour = neighbourCache.lookup(raSrcAddr, ifID);
1382 
1383 #ifdef WITH_xMIPv6
1384  // update 3.9.07 - CB // if (neighbour == nullptr && (ra->homeAgentFlag() == true)) //the RA is from a Router acting as a Home Agent as well
1385 #endif /* WITH_xMIPv6 */
1386 
1387  if (neighbour == nullptr) {
1388  EV_INFO << "Neighbour Cache Entry does not contain RA's source address\n";
1389  if (ra->getRouterLifetime() != 0) {
1390  EV_INFO << "RA's router lifetime is non-zero, creating an entry in the "
1391  << "Host's default router list with lifetime=" << ra->getRouterLifetime() << "\n";
1392 
1393 #ifdef WITH_xMIPv6
1394  // initiate neighbour unreachability detection for existing routers and remove default route(r), 3.9.07 - CB
1395  // TODO improve this code
1397 #endif /* WITH_xMIPv6 */
1398 
1399  //If a Neighbor Cache entry is created for the router its reachability
1400  //state MUST be set to STALE as specified in Section 7.3.3.
1401  neighbour = neighbourCache.addRouter(raSrcAddr, ifID,
1402 #ifndef WITH_xMIPv6
1403  ra->getSourceLinkLayerAddress(), simTime() + ra->getRouterLifetime());
1404 #else /* WITH_xMIPv6 */
1405  ra->getSourceLinkLayerAddress(), simTime() + ra->getRouterLifetime(), ra->getHomeAgentFlag());
1406 #endif /* WITH_xMIPv6 */
1407  //According to Greg, we should add a default route for hosts as well!
1408  rt6->addDefaultRoute(raSrcAddr, ifID, simTime() + ra->getRouterLifetime());
1409  }
1410  else {
1411  EV_INFO << "Router Lifetime is 0, adding NON-default router.\n";
1412  //WEI-The router is advertising itself, BUT not as a default router.
1413  if (ra->getSourceLinkLayerAddress().isUnspecified())
1414  neighbour = neighbourCache.addNeighbour(raSrcAddr, ifID);
1415  else
1416  neighbour = neighbourCache.addNeighbour(raSrcAddr, ifID,
1417  ra->getSourceLinkLayerAddress());
1418  neighbour->isRouter = true;
1419  }
1420  }
1421  else {
1422  //If no Source Link-Layer Address is included, but a corresponding Neighbor
1423  //Cache entry exists, its IsRouter flag MUST be set to TRUE.
1424  neighbour->isRouter = true;
1425 
1426  //If a cache entry already exists and is updated with a different link-
1427  //layer address the reachability state MUST also be set to STALE.
1428  if (ra->getSourceLinkLayerAddress().isUnspecified() == false &&
1429  neighbour->macAddress.equals(ra->getSourceLinkLayerAddress()) == false)
1430  neighbour->macAddress = ra->getSourceLinkLayerAddress();
1431 
1432  /*- If the address is already present in the host's Default Router List
1433  as a result of a previously-received advertisement, reset its invalidation
1434  timer to the Router Lifetime value in the newly-received advertisement.*/
1435  neighbour->routerExpiryTime = simTime() + ra->getRouterLifetime();
1436 
1437  /*- If the address is already present in the host's Default Router List
1438  and the received Router Lifetime value is zero, immediately time-out the
1439  entry as specified in Section 6.3.5.*/
1440  if (ra->getRouterLifetime() == 0) {
1441  EV_INFO << "RA's router lifetime is ZERO. Timing-out entry.\n";
1442  timeoutDefaultRouter(raSrcAddr, ifID);
1443  }
1444  }
1445 
1446  //Paragraph Omitted.
1447 
1448  //If the received Cur Hop Limit value is non-zero the host SHOULD set
1449  //its CurHopLimit variable to the received value.
1450  if (ra->getCurHopLimit() != 0) {
1451  EV_INFO << "RA's Cur Hop Limit is non-zero. Setting host's Cur Hop Limit to "
1452  << "received value.\n";
1453  ie->ipv6Data()->setCurHopLimit(ra->getCurHopLimit());
1454  }
1455 
1456  //If the received Reachable Time value is non-zero the host SHOULD set its
1457  //BaseReachableTime variable to the received value.
1458  if (ra->getReachableTime() != 0) {
1459  EV_INFO << "RA's reachable time is non-zero ";
1460 
1461  if (ra->getReachableTime() != SIMTIME_DBL(ie->ipv6Data()->getReachableTime())) {
1462  EV_INFO << " and RA's and Host's reachable time differ, \nsetting host's base"
1463  << " reachable time to received value.\n";
1464  ie->ipv6Data()->setBaseReachableTime(ra->getReachableTime());
1465  //If the new value differs from the previous value, the host SHOULD
1466  //recompute a new random ReachableTime value.
1467  ie->ipv6Data()->setReachableTime(ie->ipv6Data()->generateReachableTime());
1468  }
1469 
1470  EV_INFO << endl;
1471  }
1472 
1473  //The RetransTimer variable SHOULD be copied from the Retrans Timer field,
1474  //if the received value is non-zero.
1475  if (ra->getRetransTimer() != 0) {
1476  EV_INFO << "RA's retrans timer is non-zero, copying retrans timer variable.\n";
1477  ie->ipv6Data()->setRetransTimer(ra->getRetransTimer());
1478  }
1479 
1480  /*If the MTU option is present, hosts SHOULD copy the option's value into
1481  LinkMTU so long as the value is greater than or equal to the minimum link MTU
1482  [IPv6] and does not exceed the default LinkMTU value specified in the link
1483  type specific document (e.g., [IPv6-ETHER]).*/
1484  //TODO: not done yet
1485 
1486  processRAPrefixInfo(ra, ie);
1487 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
int getInterfaceId() const
Definition: InterfaceEntry.h:185
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
virtual void addDefaultRoute(const IPv6Address &raSrcAddr, unsigned int ifID, simtime_t routerLifetime)
Adds a default route for a host.
Definition: IPv6RoutingTable.cc:643
virtual void timeoutDefaultRouter(const IPv6Address &addr, int interfaceID)
RFC 2461: Section 6.3.5 Whenever the Lifetime of an entry in the Default Router List expires...
Definition: IPv6NeighbourDiscovery.cc:630
void routersUnreachabilityDetection(const InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:2571
virtual Neighbour * lookup(const IPv6Address &addr, int interfaceID)
Returns a neighbour entry, or nullptr.
Definition: IPv6NeighbourCache.cc:85
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual Neighbour * addRouter(const IPv6Address &addr, int interfaceID, MACAddress macAddress, simtime_t expiryTime, bool isHomeAgent=false)
Creates and initializes a router entry (isRouter=isDefaultRouter=true), MAC address and state=STALE...
Definition: IPv6NeighbourCache.cc:130
bool isRouter
Definition: IPv6NeighbourCache.h:77
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
virtual void processRAPrefixInfo(IPv6RouterAdvertisement *ra, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1489
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
virtual Neighbour * addNeighbour(const IPv6Address &addr, int interfaceID)
Creates and initializes a neighbour entry with isRouter=false, state=INCOMPLETE.
Definition: IPv6NeighbourCache.cc:98
void inet::IPv6NeighbourDiscovery::processRAPacket ( IPv6RouterAdvertisement ra,
IPv6ControlInfo raCtrlInfo 
)
protectedvirtual

Referenced by processNDMessage().

1301 {
1302  InterfaceEntry *ie = ift->getInterfaceById(raCtrlInfo->getInterfaceId());
1303 
1304  if (ie->ipv6Data()->getAdvSendAdvertisements()) {
1305  EV_INFO << "Interface is an advertising interface, dropping RA message.\n";
1306  delete raCtrlInfo;
1307  delete ra;
1308  return;
1309  }
1310  else {
1311  if (validateRAPacket(ra, raCtrlInfo) == false) {
1312  delete raCtrlInfo;
1313  delete ra;
1314  return;
1315  }
1316 
1317 #ifdef WITH_xMIPv6
1318  if (ie->ipv6Data()->isDADInProgress()) {
1319  // in case we are currently performing DAD we ignore this RA
1320  // TODO improve this procedure in order to allow reinitiating DAD
1321  // (which means cancel current DAD, start new DAD)
1322  delete raCtrlInfo;
1323  delete ra;
1324  return;
1325  }
1326 #endif /* WITH_xMIPv6 */
1327 
1328  cancelRouterDiscovery(ie); //Cancel router discovery if it is in progress.
1329  EV_INFO << "Interface is a host, processing RA.\n";
1330 
1331  processRAForRouterUpdates(ra, raCtrlInfo); //See RFC2461: Section 6.3.4
1332 
1333  //Possible options
1334  //MACAddress macAddress = ra->getSourceLinkLayerAddress();
1335  //uint mtu = ra->getMTU();
1336  for (int i = 0; i < (int)ra->getPrefixInformationArraySize(); i++) {
1337  IPv6NDPrefixInformation& prefixInfo = ra->getPrefixInformation(i);
1338  if (prefixInfo.getAutoAddressConfFlag() == true) { //If auto addr conf is set
1339 #ifndef WITH_xMIPv6
1340  processRAPrefixInfoForAddrAutoConf(prefixInfo, ie); //We process prefix Info and form an addr
1341 #else /* WITH_xMIPv6 */
1342  processRAPrefixInfoForAddrAutoConf(prefixInfo, ie, ra->getHomeAgentFlag()); // then calling the overloaded function for address configuration. The address conf for MN is different from other nodes as it needs to classify the newly formed address as HoA or CoA, depending on the status of the H-Flag. (Zarrar Yousaf 20.07.07)
1343 #endif /* WITH_xMIPv6 */
1344  }
1345 
1346 #ifdef WITH_xMIPv6
1347  // When in foreign network(s), the MN needs info about its HA address and its own Home Address (HoA), when sending BU to HA and CN(s). Therefore while in the home network I intialise struct HomeNetworkInfo{} with HoA and HA address, which will eventually be used by the MN while sending BUs from within visit networks. (Zarrar Yousaf 12.07.07)
1348  if (ra->getHomeAgentFlag() && (prefixInfo.getRouterAddressFlag() == true)) { //If R-Flag is set and RA is from HA
1349  // homeNetworkInfo now carries HoA, global unicast HA address and the home network prefix
1350  // update 4.9.07 - CB
1351  IPv6Address HoA = ie->ipv6Data()->getGlobalAddress(); //MN's home address
1352  IPv6Address HA = raCtrlInfo->getSrcAddr().setPrefix(prefixInfo.getPrefix(), prefixInfo.getPrefixLength());
1353  EV_DETAIL << "The HoA of MN is: " << HoA << ", MN's HA Address is: " << HA
1354  << " and the home prefix is " << prefixInfo.getPrefix() << endl;
1355  ie->ipv6Data()->updateHomeNetworkInfo(HoA, HA, prefixInfo.getPrefix(), prefixInfo.getPrefixLength()); //populate the HoA of MN, the HA global scope address and the home network prefix
1356  }
1357 #endif /* WITH_xMIPv6 */
1358  }
1359  }
1360  delete raCtrlInfo;
1361  delete ra;
1362 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual void processRAPrefixInfoForAddrAutoConf(IPv6NDPrefixInformation &prefixInfo, InterfaceEntry *ie, bool hFlag=false)
Definition: IPv6NeighbourDiscovery.cc:2439
virtual bool validateRAPacket(IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1772
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual void processRAForRouterUpdates(IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1364
virtual void cancelRouterDiscovery(InterfaceEntry *ie)
RFC 2461: Section 6.3.7 4th paragraph Once the host sends a Router Solicitation, and receives a valid...
Definition: IPv6NeighbourDiscovery.cc:1029
void inet::IPv6NeighbourDiscovery::processRAPrefixInfo ( IPv6RouterAdvertisement ra,
InterfaceEntry ie 
)
protectedvirtual

Referenced by processRAForRouterUpdates().

1491 {
1492  //Continued from section 6.3.4
1493  /*Prefix Information options that have the "on-link" (L) flag set indicate a
1494  prefix identifying a range of addresses that should be considered on-link.
1495  Note, however, that a Prefix Information option with the on-link flag set to
1496  zero conveys no information concerning on-link determination and MUST NOT be
1497  interpreted to mean that addresses covered by the prefix are off-link. The
1498  only way to cancel a previous on-link indication is to advertise that prefix
1499  with the L-bit set and the Lifetime set to zero. The default behavior (see
1500  Section 5.2) when sending a packet to an address for which no information is
1501  known about the on-link status of the address is to forward the packet to a
1502  default router; the reception of a Prefix Information option with the "on-link "
1503  (L) flag set to zero does not change this behavior. The reasons for an address
1504  being treated as on-link is specified in the definition of "on-link" in
1505  Section 2.1. Prefixes with the on-link flag set to zero would normally have
1506  the autonomous flag set and be used by [ADDRCONF].*/
1507  IPv6NDPrefixInformation prefixInfo;
1508  //For each Prefix Information option
1509  for (int i = 0; i < (int)ra->getPrefixInformationArraySize(); i++) {
1510  prefixInfo = ra->getPrefixInformation(i);
1511  if (!prefixInfo.getOnlinkFlag())
1512  break; //skip to next prefix option
1513 
1514  //with the on-link flag set, a host does the following:
1515  EV_INFO << "Fetching Prefix Information:" << i + 1 << " of "
1516  << ra->getPrefixInformationArraySize() << endl;
1517  uint prefixLength = prefixInfo.getPrefixLength();
1518  simtime_t validLifetime = prefixInfo.getValidLifetime();
1519  //uint preferredLifetime = prefixInfo.getPreferredLifetime();
1520  IPv6Address prefix = prefixInfo.getPrefix();
1521 
1522  //- If the prefix is the link-local prefix, silently ignore the Prefix
1523  //Information option.
1524  if (prefix.isLinkLocal()) {
1525  EV_INFO << "Prefix is link-local, ignoring prefix.\n";
1526  return;
1527  }
1528 
1529  //- If the prefix is not already present in the Prefix List,
1530  if (!rt6->isPrefixPresent(prefix)) {
1531  //and the Prefix Information option's Valid Lifetime field is non-zero,
1532  if (validLifetime != 0) {
1533  /*create a new entry for the prefix and initialize its invalidation
1534  timer to the Valid Lifetime value in the Prefix Information option.*/
1535  rt6->addOrUpdateOnLinkPrefix(prefix, prefixLength, ie->getInterfaceId(),
1536  simTime() + validLifetime);
1537  }
1538  /*- If the Prefix Information option's Valid Lifetime field is zero,
1539  and the prefix is not present in the host's Prefix List,
1540  silently ignore the option.*/
1541  }
1542  else {
1543  /* If the new Lifetime value is zero, time-out the prefix immediately
1544  (see Section 6.3.5).*/
1545  if (validLifetime == 0) {
1546  EV_INFO << "Prefix Info's valid lifetime is 0, time-out prefix\n";
1547  rt6->deleteOnLinkPrefix(prefix, prefixLength);
1548  return;
1549  }
1550 
1551  /*- If the prefix is already present in the host's Prefix List as
1552  the result of a previously-received advertisement, reset its
1553  invalidation timer to the Valid Lifetime value in the Prefix
1554  Information option.*/
1555  rt6->addOrUpdateOnLinkPrefix(prefix, prefixLength, ie->getInterfaceId(),
1556  simTime() + validLifetime);
1557  }
1558 
1559  /*Stateless address autoconfiguration [ADDRCONF] may in some
1560  circumstances increase the Valid Lifetime of a prefix or ignore it
1561  completely in order to prevent a particular denial of service attack.
1562  However, since the effect of the same denial of service targeted at
1563  the on-link prefix list is not catastrophic (hosts would send packets
1564  to a default router and receive a redirect rather than sending
1565  packets directly to a neighbor) the Neighbor Discovery protocol does
1566  not impose such a check on the prefix lifetime values.*/
1567  }
1568 }
virtual bool isPrefixPresent(const IPv6Address &prefix) const
Checks if the given prefix already exists in the routing table (prefix list)
Definition: IPv6RoutingTable.cc:501
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
unsigned int uint
Definition: INETDefs.h:63
virtual void addOrUpdateOnLinkPrefix(const IPv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
Add on-link prefix (route of type FROM_RA), or update existing one.
Definition: IPv6RoutingTable.cc:549
virtual void deleteOnLinkPrefix(const IPv6Address &destPrefix, int prefixLength)
Remove an on-link prefix.
Definition: IPv6RoutingTable.cc:615
void inet::IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf ( IPv6NDPrefixInformation prefixInfo,
InterfaceEntry ie,
bool  hFlag = false 
)
protectedvirtual

Referenced by processRAPacket(), and processRAPrefixInfo().

2440 {
2441  EV_INFO << "Processing Prefix Info for address auto-configuration.\n";
2442  IPv6Address prefix = prefixInfo.getPrefix();
2443  uint prefixLength = prefixInfo.getPrefixLength();
2444  simtime_t preferredLifetime = prefixInfo.getPreferredLifetime();
2445  simtime_t validLifetime = prefixInfo.getValidLifetime();
2446 
2447  //EV << "/// prefix: " << prefix << std::endl; // CB
2448 
2449  //RFC 2461: Section 5.5.3
2450  //First condition tested, the autonomous flag is already set
2451 
2452  //b) If the prefix is the link-local prefix, silently ignore the Prefix
2453  //Information option.
2454  if (prefixInfo.getPrefix().isLinkLocal() == true) {
2455  EV_INFO << "Prefix is link-local, ignore Prefix Information Option\n";
2456  return;
2457  }
2458 
2459  //c) If the preferred lifetime is greater than the valid lifetime, silently
2460  //ignore the Prefix Information option. A node MAY wish to log a system
2461  //management error in this case.
2462  if (preferredLifetime > validLifetime) {
2463  EV_INFO << "Preferred lifetime is greater than valid lifetime, ignore Prefix Information\n";
2464  return;
2465  }
2466 
2467  // changed structure of code below, 12.9.07 - CB
2468  bool isPrefixAssignedToInterface = false;
2469  bool returnedHome = false; // 4.9.07 - CB
2470 
2471  for (int i = 0; i < ie->ipv6Data()->getNumAddresses(); i++) {
2472  if (ie->ipv6Data()->getAddress(i).getScope() == IPv6Address::LINK)
2473  // skip the link local address - it's not relevant for movement detection
2474  continue;
2475 
2476  /*RFC 3775, 11.5.4
2477  A mobile node detects that it has returned to its home link through
2478  the movement detection algorithm in use (Section 11.5.1), when the
2479  mobile node detects that its home subnet prefix is again on-link.
2480  */
2481  if (ie->ipv6Data()->getAddress(i).matches(prefix, prefixLength) == true) {
2482  // A MN can have the following address combinations:
2483  // * only a link-local address -> at home
2484  // * link-local plus a HoA -> at home
2485  // * link-local, HoA plus CoA -> at foreign network
2486  // The prefix of the home network can only match the HoA
2487  // address, and if it does (=we received a RA from the HA),
2488  // and we have a CoA as well (three addresses) then we have
2489  // returned home
2490  // TODO the MN can have several global scope addresses configured from
2491  // different prefixes advertised via a RA -> not supported with this code
2492  if (rt6->isMobileNode() && ie->ipv6Data()->getAddressType(i) == IPv6InterfaceData::HoA && ie->ipv6Data()->getNumAddresses() > 2)
2493  returnedHome = true;
2494  else {
2495  isPrefixAssignedToInterface = true;
2496  EV_INFO << "The received Prefix is already assigned to the interface" << endl; //Zarrar Yousaf 19.07.07
2497  break;
2498  }
2499  }
2500  }
2501  /*d) If the prefix advertised does not match the prefix of an address already
2502  in the list, and the Valid Lifetime is not 0, form an address (and add
2503  it to the list) by combining the advertised prefix with the link's
2504  interface identifier as follows:
2505  */
2506  if ((isPrefixAssignedToInterface == false) && (validLifetime != 0)) {
2507  EV_INFO << "Prefix not assigned to interface. Possible new router detected. Auto-configuring new address.\n";
2508  IPv6Address linkLocalAddress = ie->ipv6Data()->getLinkLocalAddress();
2509  ASSERT(linkLocalAddress.isUnspecified() == false);
2510  IPv6Address newAddr = linkLocalAddress.setPrefix(prefix, prefixLength);
2511  IPv6Address CoA;
2512  //TODO: for now we leave the newly formed address as not tentative,
2513  //according to Greg, we have to always perform DAD for a newly formed address.
2514  EV_INFO << "Assigning new address to: " << ie->getName() << endl;
2515 
2516  // we are for sure either in the home network or in a new foreign network
2517  // -> remove CoA
2518  //CoA = ie->ipv6()->removeCoAAddr();
2519  // moved code from above to processDADTimeout()
2520 
2521  // 27.9.07 - CB
2522  if (returnedHome) {
2523  // we have to remove the CoA before we create a new one
2524  EV_INFO << "Node returning home - removing CoA...\n";
2525  CoA = ie->ipv6Data()->removeAddress(IPv6InterfaceData::CoA);
2526 
2527  // nothing to do more wrt managing addresses, as we are at home and a HoA is
2528  // already existing at the interface
2529 
2530  // initiate the returning home procedure
2531  ASSERT(!CoA.isUnspecified());
2532  mipv6->returningHome(CoA, ie);
2533  }
2534  else { // non-mobile nodes will never have returnedHome == true, so they will always assign a new address
2535  CoA = ie->ipv6Data()->getGlobalAddress(IPv6InterfaceData::CoA);
2536 
2537  // form new address and initiate DAD, as we are in a foreign network
2538 
2539  if (ie->ipv6Data()->getNumAddresses() == 1) {
2540  // we only have a link-layer and no unicast address of scope > link-local
2541  // this means DAD is already running or has already been completed
2542  // create a unicast address with scope > link-local
2543  bool isLinkLocalTentative = ie->ipv6Data()->isTentativeAddress(linkLocalAddress);
2544  // if the link local address is tentative, then we make the global unicast address tentative as well
2545  ie->ipv6Data()->assignAddress(newAddr, isLinkLocalTentative,
2546  simTime() + validLifetime, simTime() + preferredLifetime, hFlag);
2547  }
2548  else {
2549  // set tentative flag for all addresses on this interface
2550  for (int j = 0; j < ie->ipv6Data()->getNumAddresses(); j++) {
2551  // TODO improve this code so that only addresses are set to tentative which are
2552  // formed based on the link-local address from above
2553  ie->ipv6Data()->tentativelyAssign(j);
2554  EV_INFO << "Setting address " << ie->ipv6Data()->getAddress(j) << " to tentative.\n";
2555  }
2556 
2557  initiateDAD(ie->ipv6Data()->getLinkLocalAddress(), ie);
2558 
2559  // set MIPv6Init structure that will later on be used for initiating MIPv6 protocol after DAD was performed
2560  dadGlobalList[ie].hFlag = hFlag;
2561  dadGlobalList[ie].validLifetime = validLifetime;
2562  dadGlobalList[ie].preferredLifetime = preferredLifetime;
2563  dadGlobalList[ie].addr = newAddr;
2564  //dadGlobalList[ie].returnedHome = returnedHome;
2565  dadGlobalList[ie].CoA = CoA;
2566  }
2567  }
2568  }
2569 }
virtual void initiateDAD(const IPv6Address &tentativeAddr, InterfaceEntry *ie)
Initiating DAD means to send off a Neighbour Solicitation with its target address set as this node&#39;s ...
Definition: IPv6NeighbourDiscovery.cc:812
Definition: IPv6InterfaceData.h:211
void returningHome(const IPv6Address &CoA, InterfaceEntry *ie)
This method destroys all tunnels associated to the previous CoA and sends appropriate BU(s) to HA and...
Definition: xMIPv6.cc:278
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
unsigned int uint
Definition: INETDefs.h:63
bool isMobileNode() const
Determine whether a node is a Mobile Node or Correspondent Node: MN if TRUE or else a CN...
Definition: IPv6RoutingTable.h:181
Definition: IPv6Address.h:58
xMIPv6 * mipv6
Definition: IPv6NeighbourDiscovery.h:105
DADGlobalList dadGlobalList
Definition: IPv6NeighbourDiscovery.h:167
Definition: IPv6InterfaceData.h:211
void inet::IPv6NeighbourDiscovery::processRDTimeout ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

1044 {
1045  InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
1046  RDEntry *rdEntry = fetchRDEntry(ie);
1047 
1048  if (rdEntry->numRSSent < ie->ipv6Data()->_getMaxRtrSolicitations()) {
1049  bubble("Sending another RS message.");
1051  rdEntry->numRSSent++;
1052 
1053  //Need to find out if this is the last RS we are sending out.
1054  if (rdEntry->numRSSent == ie->ipv6Data()->_getMaxRtrSolicitations())
1055  scheduleAt(simTime() + ie->ipv6Data()->_getMaxRtrSolicitationDelay(), msg);
1056  else
1057  scheduleAt(simTime() + ie->ipv6Data()->_getRtrSolicitationInterval(), msg);
1058  }
1059  else {
1060  //RFC 2461, Section 6.3.7
1061  /*If a host sends MAX_RTR_SOLICITATIONS solicitations, and receives no Router
1062  Advertisements after having waited MAX_RTR_SOLICITATION_DELAY seconds after
1063  sending the last solicitation, the host concludes that there are no routers
1064  on the link for the purpose of [ADDRCONF]. However, the host continues to
1065  receive and process Router Advertisements messages in the event that routers
1066  appear on the link.*/
1067  bubble("Max number of RS messages sent");
1068  EV_INFO << "No RA messages were received. Assume no routers are on-link";
1069  delete rdEntry;
1070  rdList.erase(rdEntry);
1071  delete msg;
1072  }
1073 }
virtual IPv6RouterSolicitation * createAndSendRSPacket(InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:962
virtual IPv6NeighbourDiscovery::RDEntry * fetchRDEntry(InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:327
RDList rdList
Definition: IPv6NeighbourDiscovery.h:148
void inet::IPv6NeighbourDiscovery::processRedirectPacket ( IPv6Redirect redirect,
IPv6ControlInfo ctrlInfo 
)
protectedvirtual

Referenced by processNDMessage().

2425 {
2426 //FIXME incomplete code
2427 #if 0
2428  //First we need to extract information from the redirect message
2429  IPv6Address targetAddr = redirect->getTargetAddress(); //Addressed to me
2430  IPv6Address destAddr = redirect->getDestinationAddress(); //new dest addr
2431 
2432  //Optional
2433  MACAddress macAddr = redirect->getTargetLinkLayerAddress();
2434 #endif
2435 }
void inet::IPv6NeighbourDiscovery::processRSPacket ( IPv6RouterSolicitation rs,
IPv6ControlInfo rsCtrlInfo 
)
protectedvirtual

Referenced by processNDMessage().

1077 {
1078  if (validateRSPacket(rs, rsCtrlInfo) == false) {
1079  delete rsCtrlInfo;
1080  delete rs;
1081  return;
1082  }
1083 
1084  //Find out which interface the RS message arrived on.
1085  InterfaceEntry *ie = ift->getInterfaceById(rsCtrlInfo->getInterfaceId());
1086  AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie); //fetch advertising interface entry.
1087 
1088  //RFC 2461: Section 6.2.6
1089  //A host MUST silently discard any received Router Solicitation messages.
1090  if (ie->ipv6Data()->getAdvSendAdvertisements()) {
1091  EV_INFO << "This is an advertising interface, processing RS\n";
1092 
1093  if (validateRSPacket(rs, rsCtrlInfo) == false) {
1094  delete rsCtrlInfo;
1095  delete rs;
1096  return;
1097  }
1098 
1099  EV_INFO << "RS message validated\n";
1100 
1101  //First we extract RS specific information from the received message
1102  MACAddress macAddr = rs->getSourceLinkLayerAddress();
1103  EV_INFO << "MAC Address '" << macAddr << "' extracted\n";
1104  delete rsCtrlInfo;
1105  delete rs;
1106 
1107  /*A router MAY choose to unicast the response directly to the soliciting
1108  host's address (if the solicitation's source address is not the unspecified
1109  address), but the usual case is to multicast the response to the
1110  all-nodes group. In the latter case, the interface's interval timer is
1111  reset to a new random value, as if an unsolicited advertisement had just
1112  been sent(see Section 6.2.4).*/
1113 
1114  /*In all cases, Router Advertisements sent in response to a Router
1115  Solicitation MUST be delayed by a random time between 0 and
1116  MAX_RA_DELAY_TIME seconds. (If a single advertisement is sent in
1117  response to multiple solicitations, the delay is relative to the
1118  first solicitation.) In addition, consecutive Router Advertisements
1119  sent to the all-nodes multicast address MUST be rate limited to no
1120  more than one advertisement every MIN_DELAY_BETWEEN_RAS seconds.*/
1121 
1122  /*A router might process Router Solicitations as follows:
1123  - Upon receipt of a Router Solicitation, compute a random delay
1124  within the range 0 through MAX_RA_DELAY_TIME. If the computed
1125  value corresponds to a time later than the time the next multicast
1126  Router Advertisement is scheduled to be sent, ignore the random
1127  delay and send the advertisement at the already-scheduled time.*/
1128  cMessage *msg = new cMessage("sendSolicitedRA", MK_SEND_SOL_RTRADV);
1129  msg->setContextPointer(ie);
1130  simtime_t interval = uniform(0, ie->ipv6Data()->_getMaxRADelayTime());
1131 
1132  if (interval < advIfEntry->nextScheduledRATime) {
1133  simtime_t nextScheduledTime;
1134  nextScheduledTime = simTime() + interval;
1135  scheduleAt(nextScheduledTime, msg);
1136  advIfEntry->nextScheduledRATime = nextScheduledTime;
1137  }
1138  //else we ignore the generate interval and send it at the next scheduled time.
1139 
1140  //We need to keep a log here each time an RA is sent. Not implemented yet.
1141  //Assume the first course of action.
1142  /*- If the router sent a multicast Router Advertisement (solicited or
1143  unsolicited) within the last MIN_DELAY_BETWEEN_RAS seconds,
1144  schedule the advertisement to be sent at a time corresponding to
1145  MIN_DELAY_BETWEEN_RAS plus the random value after the previous
1146  advertisement was sent. This ensures that the multicast Router
1147  Advertisements are rate limited.
1148 
1149  - Otherwise, schedule the sending of a Router Advertisement at the
1150  time given by the random value.*/
1151  }
1152  else {
1153  EV_INFO << "This interface is a host, discarding RA message\n";
1154  delete rsCtrlInfo;
1155  delete rs;
1156  }
1157 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
#define MK_SEND_SOL_RTRADV
Definition: IPv6NeighbourDiscovery.cc:38
IInterfaceTable * ift
Definition: IPv6NeighbourDiscovery.h:100
virtual bool validateRSPacket(IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo)
Definition: IPv6NeighbourDiscovery.cc:1159
virtual IPv6NeighbourDiscovery::AdvIfEntry * fetchAdvIfEntry(InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:317
void inet::IPv6NeighbourDiscovery::reachabilityConfirmed ( const IPv6Address neighbour,
int  interfaceId 
)
virtual

Public method, it can be invoked from the IPv6 module or any other module to let Neighbour Discovery know that the reachability of the given neighbor has just been confirmed (e.g.

TCP received ACK of new data from it). Neighbour Discovery can then update the neighbour cache with this information, and cancel the Neighbour Unreachability Detection procedure if it is currently running.

369 {
370  Enter_Method("reachabilityConfirmed(%s,if=%d)", neighbour.str().c_str(), interfaceId);
371  //hmmm... this should only be invoked if a TCP ACK was received and NUD is
372  //currently being performed on the neighbour where the TCP ACK was received from.
373 
374  Neighbour *nce = neighbourCache.lookup(neighbour, interfaceId);
375  if (!nce)
376  throw cRuntimeError("Model error: not found in cache");
377 
378  cMessage *msg = nce->nudTimeoutEvent;
379  if (msg != nullptr) {
380  EV_INFO << "NUD in progress. Cancelling NUD Timer\n";
381  bubble("Reachability Confirmed via NUD.");
382  cancelAndDelete(msg);
383  nce->nudTimeoutEvent = nullptr;
384  }
385 
386  // TODO (see header file for description)
387  /*A neighbor is considered reachable if the node has recently received
388  a confirmation that packets sent recently to the neighbor were
389  received by its IP layer. Positive confirmation can be gathered in
390  two ways: hints from upper layer protocols that indicate a connection
391  is making "forward progress", or receipt of a Neighbor Advertisement
392  message that is a response to a Neighbor Solicitation message.
393 
394  A connection makes "forward progress" if the packets received from a
395  remote peer can only be arriving if recent packets sent to that peer
396  are actually reaching it. In TCP, for example, receipt of a (new)
397  acknowledgement indicates that previously sent data reached the peer.
398  Likewise, the arrival of new (non-duplicate) data indicates that
399 
400  earlier acknowledgements are being delivered to the remote peer. If
401  packets are reaching the peer, they must also be reaching the
402  sender's next-hop neighbor; thus "forward progress" is a confirmation
403  that the next-hop neighbor is reachable. For off-link destinations,
404  forward progress implies that the first-hop router is reachable.
405  When available, this upper-layer information SHOULD be used.
406 
407  In some cases (e.g., UDP-based protocols and routers forwarding
408  packets to hosts) such reachability information may not be readily
409  available from upper-layer protocols. When no hints are available
410  and a node is sending packets to a neighbor, the node actively probes
411  the neighbor using unicast Neighbor Solicitation messages to verify
412  that the forward path is still working.
413 
414  The receipt of a solicited Neighbor Advertisement serves as
415  reachability confirmation, since advertisements with the Solicited
416  flag set to one are sent only in response to a Neighbor Solicitation.
417  Receipt of other Neighbor Discovery messages such as Router
418  Advertisements and Neighbor Advertisement with the Solicited flag set
419  to zero MUST NOT be treated as a reachability confirmation. Receipt
420  of unsolicited messages only confirm the one-way path from the sender
421  to the recipient node. In contrast, Neighbor Unreachability
422  Detection requires that a node keep track of the reachability of the
423  forward path to a neighbor from the its perspective, not the
424  neighbor's perspective. Note that receipt of a solicited
425  advertisement indicates that a path is working in both directions.
426  The solicitation must have reached the neighbor, prompting it to
427  generate an advertisement. Likewise, receipt of an advertisement
428  indicates that the path from the sender to the recipient is working.
429  However, the latter fact is known only to the recipient; the
430  advertisement's sender has no direct way of knowing that the
431  advertisement it sent actually reached a neighbor. From the
432  perspective of Neighbor Unreachability Detection, only the
433  reachability of the forward path is of interest.*/
434 }
virtual Neighbour * lookup(const IPv6Address &addr, int interfaceID)
Returns a neighbour entry, or nullptr.
Definition: IPv6NeighbourCache.cc:85
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
void inet::IPv6NeighbourDiscovery::resetRATimer ( InterfaceEntry ie)
protectedvirtual

Reset the given interface entry's Router Advertisement timer.

This is usually done when a router interface responds (by replying with a Router Advertisement sent to the All-Node multicast group)to a router solicitation Also see: RFC 2461, Section 6.2.6

1691 { //Not used yet but could be useful later on.-WEI
1692  //Iterate through all RA timers within the Neighbour Discovery module.
1693 /*
1694  for (auto it =raTimerList.begin(); it != raTimerList.end(); it++)
1695  {
1696  cMessage *msg = (*it);
1697  InterfaceEntry *msgIE = (InterfaceEntry *)msg->getContextPointer();
1698  //Find the timer that matches the given Interface Entry.
1699  if (msgIE->outputPort() == ie->outputPort())
1700  {
1701  EV << "Resetting RA timer for port: " << ie->outputPort();
1702  cancelEvent(msg);//Cancel the next scheduled msg.
1703  simtime_t interval
1704  = uniform(ie->ipv6Data()->getMinRtrAdvInterval(),ie->ipv6Data()->getMaxRtrAdvInterval());
1705  scheduleAt(simTime()+interval, msg);
1706  }
1707  }
1708  */
1709 }
const MACAddress & inet::IPv6NeighbourDiscovery::resolveNeighbour ( const IPv6Address nextHop,
int  interfaceId 
)

Public method, to be invoked from the IPv6 module to determine link-layer address and the output interface of the next hop.

If the neighbor cache does not contain this address or it's in the state INCOMPLETE, this method will return the nullptr address, and the IPv6 module should then send the datagram here to IPv6NeighbourDiscovery where it will be stored until neighbour resolution completes.

If the neighbour cache entry is STALE (or REACHABLE but more than reachableTime elapsed since reachability was last confirmed), the link-layer address is still returned and IPv6 can send the datagram, but simultaneously, this call should trigger the Neighbour Unreachability Detection procedure to start in the IPv6NeighbourDiscovery module.

Referenced by inet::IPv6::resolveMACAddressAndSendPacket().

339 {
340  Enter_Method("resolveNeighbor(%s,if=%d)", nextHop.str().c_str(), interfaceId);
341 
342  Neighbour *nce = neighbourCache.lookup(nextHop, interfaceId);
343  //InterfaceEntry *ie = ift->getInterfaceById(interfaceId);
344 
345  if (!nce || nce->reachabilityState == IPv6NeighbourCache::INCOMPLETE)
347 
348  if (nce->reachabilityState == IPv6NeighbourCache::STALE) {
350  }
351  else if (nce->reachabilityState == IPv6NeighbourCache::REACHABLE &&
352  simTime() > nce->reachabilityExpires)
353  {
354  nce->reachabilityState = IPv6NeighbourCache::STALE;
356  }
357  else if (nce->reachabilityState != IPv6NeighbourCache::REACHABLE) {
358  //reachability state must be either in DELAY or PROBE
359  ASSERT(nce->reachabilityState == IPv6NeighbourCache::DELAY ||
360  nce->reachabilityState == IPv6NeighbourCache::PROBE);
361  EV_INFO << "NUD in progress.\n";
362  }
363 
364  //else the entry is REACHABLE and no further action is required here.
365  return nce->macAddress;
366 }
Definition: IPv6NeighbourCache.h:53
Definition: IPv6NeighbourCache.h:53
virtual void initiateNeighbourUnreachabilityDetection(Neighbour *neighbour)
Definition: IPv6NeighbourDiscovery.cc:485
virtual Neighbour * lookup(const IPv6Address &addr, int interfaceID)
Returns a neighbour entry, or nullptr.
Definition: IPv6NeighbourCache.cc:85
Definition: IPv6NeighbourCache.h:53
Definition: IPv6NeighbourCache.h:53
Definition: IPv6NeighbourCache.h:53
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
static const MACAddress UNSPECIFIED_ADDRESS
The unspecified MAC address, 00:00:00:00:00:00.
Definition: MACAddress.h:57
void inet::IPv6NeighbourDiscovery::routersUnreachabilityDetection ( const InterfaceEntry ie)
protected

Referenced by processRAForRouterUpdates().

2572 {
2573  // remove all entries from the destination cache for this interface
2574  //rt6->purgeDestCacheForInterfaceID( ie->interfaceId() );
2575  // invalidate entries in the destination cache for this interface
2576  //neighbourCache.invalidateEntriesForInterfaceID( ie->interfaceId() );
2577  // remove default routes on this interface
2578  rt6->deleteDefaultRoutes(ie->getInterfaceId());
2579  rt6->deletePrefixes(ie->getInterfaceId());
2580 
2581  for (auto it = neighbourCache.begin(); it != neighbourCache.end(); ) {
2582  if ((*it).first.interfaceID == ie->getInterfaceId() && it->second.isDefaultRouter()) {
2583  // update 14.9.07 - CB
2584  IPv6Address rtrLnkAddress = (*it).first.address;
2585  EV_INFO << "Setting router (address=" << rtrLnkAddress << ", ifID="
2586  << (*it).first.interfaceID << ") to unreachable" << endl;
2587  ++it;
2588 
2589  //if ( rtrLnkAddress.isLinkLocal() )
2590  timeoutDefaultRouter(rtrLnkAddress, ie->getInterfaceId());
2591 
2592  // reset reachability state of this router
2593  //Neighbour* nbor = neighbourCache.lookup( (*it).first.address, (*it).first.interfaceID );
2594  //nbor->reachabilityState = IPv6NeighbourCache::STALE;
2595  //initiateNeighbourUnreachabilityDetection(nbor);
2596  }
2597  else
2598  ++it;
2599  }
2600 }
NeighbourMap::iterator begin()
For iteration on the internal std::map.
Definition: IPv6NeighbourCache.h:178
NeighbourMap::iterator end()
For iteration on the internal std::map.
Definition: IPv6NeighbourCache.h:181
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
virtual void timeoutDefaultRouter(const IPv6Address &addr, int interfaceID)
RFC 2461: Section 6.3.5 Whenever the Lifetime of an entry in the Default Router List expires...
Definition: IPv6NeighbourDiscovery.cc:630
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
void deletePrefixes(int interfaceID)
Deletes all prefixes registered for the given interface.
Definition: IPv6RoutingTable.cc:821
void deleteDefaultRoutes(int interfaceID)
Deletes the current default routes for the given interface.
Definition: IPv6RoutingTable.cc:790
IPv6Address inet::IPv6NeighbourDiscovery::selectDefaultRouter ( int &  outIfID)
protectedvirtual

Referenced by determineNextHop().

550 {
551  EV_INFO << "Selecting default router...\n";
552  //draft-ietf-ipv6-2461bis-04.txt Section 6.3.6
553  /*The algorithm for selecting a router depends in part on whether or not a
554  router is known to be reachable. The exact details of how a node keeps track
555  of a neighbor's reachability state are covered in Section 7.3. The algorithm
556  for selecting a default router is invoked during next-hop determination when
557  no Destination Cache entry exists for an off-link destination or when
558  communication through an existing router appears to be failing. Under normal
559  conditions, a router would be selected the first time traffic is sent to a
560  destination, with subsequent traffic for that destination using the same router
561  as indicated in the Destination Cache modulo any changes to the Destination
562  Cache caused by Redirect messages.
563 
564  The policy for selecting routers from the Default Router List is as
565  follows:*/
566 
567  /*1) Routers that are reachable or probably reachable (i.e., in any state
568  other than INCOMPLETE) SHOULD be preferred over routers whose reachability
569  is unknown or suspect (i.e., in the INCOMPLETE state, or for which no Neighbor
570  Cache entry exists). An implementation may choose to always return the same
571  router or cycle through the router list in a round-robin fashion as long as
572  it always returns a reachable or a probably reachable router when one is
573  available.*/
575  for (auto it = defaultRouters.begin(); it != defaultRouters.end(); ) {
576  Neighbour& nce = *it;
577  if (simTime() > nce.routerExpiryTime) {
578  EV_INFO << "Found an expired default router. Deleting entry...\n";
579  ++it;
580  neighbourCache.remove(nce.nceKey->address, nce.nceKey->interfaceID);
581  continue;
582  }
583  if (nce.reachabilityState != IPv6NeighbourCache::INCOMPLETE) {
584  EV_INFO << "Found a probably reachable router in the default router list.\n";
585  defaultRouters.setHead(*nce.nextDefaultRouter);
586  outIfID = nce.nceKey->interfaceID;
587  return nce.nceKey->address;
588  }
589  ++it;
590  }
591 
592  /*2) When no routers on the list are known to be reachable or probably
593  reachable, routers SHOULD be selected in a round-robin fashion, so that
594  subsequent requests for a default router do not return the same router until
595  all other routers have been selected.
596 
597  Cycling through the router list in this case ensures that all available
598  routers are actively probed by the Neighbor Unreachability Detection algorithm.
599  A request for a default router is made in conjunction with the sending of a
600  packet to a router, and the selected router will be probed for reachability
601  as a side effect.*/
602  Neighbour *defaultRouter = defaultRouters.getHead();
603  if (defaultRouter != nullptr) {
604  EV_INFO << "Found a router in the neighbour cache (default router list).\n";
605  defaultRouters.setHead(*defaultRouter->nextDefaultRouter);
606  outIfID = defaultRouter->nceKey->interfaceID;
607  return defaultRouter->nceKey->address;
608  }
609 
610  EV_INFO << "No suitable routers found.\n";
611  outIfID = -1;
613 }
int interfaceID
Definition: IPv6NeighbourCache.h:63
DefaultRouterList & getDefaultRouterList()
Definition: IPv6NeighbourCache.h:175
const Key * nceKey
Definition: IPv6NeighbourCache.h:75
IPv6NeighbourCache::DefaultRouterList DefaultRouterList
Definition: IPv6NeighbourDiscovery.h:56
Definition: IPv6NeighbourCache.h:53
static const IPv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: IPv6Address.h:66
virtual void remove(const IPv6Address &addr, int interfaceID)
Deletes the given neighbour from the cache.
Definition: IPv6NeighbourCache.cc:149
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
IPv6NeighbourCache::Neighbour Neighbour
Definition: IPv6NeighbourDiscovery.h:55
void inet::IPv6NeighbourDiscovery::sendPacketToIPv6Module ( cMessage *  msg,
const IPv6Address destAddr,
const IPv6Address srcAddr,
int  interfaceId 
)
protectedvirtual

Create control info and assigns it to a msg.

Returns a copy of the msg with the control info.

Referenced by createAndSendNSPacket(), createAndSendRAPacket(), createAndSendRSPacket(), sendSolicitedNA(), and sendUnsolicitedNA().

754 {
755  IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
756  controlInfo->setProtocol(IP_PROT_IPv6_ICMP);
757  controlInfo->setDestAddr(destAddr);
758  controlInfo->setSrcAddr(srcAddr);
759  controlInfo->setHopLimit(255);
760  controlInfo->setInterfaceId(interfaceId);
761  msg->setControlInfo(controlInfo);
762 
763  send(msg, "ipv6Out");
764 }
Definition: IPProtocolId_m.h:87
void inet::IPv6NeighbourDiscovery::sendPeriodicRA ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

1712 {
1713  InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
1714  AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie);
1715  IPv6Address destAddr = IPv6Address("FF02::1");
1716  createAndSendRAPacket(destAddr, ie);
1717  advIfEntry->numRASent++;
1718  simtime_t nextScheduledTime;
1719 
1720  //RFC 2461, Section 6.2.4
1721  /*Whenever a multicast advertisement is sent from an interface, the timer is
1722  reset to a uniformly-distributed random value between the interface's
1723  configured MinRtrAdvInterval and MaxRtrAdvInterval; expiration of the timer
1724  causes the next advertisement to be sent and a new random value to be chosen.*/
1725 
1726  simtime_t interval;
1727 
1728 #ifdef WITH_xMIPv6
1729  EV_DEBUG << "\n+=+=+= MIPv6 Feature: " << rt6->hasMIPv6Support() << " +=+=+=\n";
1730 #endif /* WITH_xMIPv6 */
1731 
1732  interval = uniform(ie->ipv6Data()->getMinRtrAdvInterval(), ie->ipv6Data()->getMaxRtrAdvInterval());
1733 
1734 #ifdef WITH_xMIPv6
1735  EV_DETAIL << "\n +=+=+= The random calculated interval is: " << interval << " +=+=+=\n";
1736 #endif /* WITH_xMIPv6 */
1737 
1738  nextScheduledTime = simTime() + interval;
1739 
1740  /*For the first few advertisements (up to MAX_INITIAL_RTR_ADVERTISEMENTS)
1741  sent from an interface when it becomes an advertising interface,*/
1742  EV_DETAIL << "Num RA sent is: " << advIfEntry->numRASent << endl;
1743  EV_DETAIL << "maxInitialRtrAdvertisements is: " << ie->ipv6Data()->_getMaxInitialRtrAdvertisements() << endl;
1744 
1745  if (advIfEntry->numRASent <= ie->ipv6Data()->_getMaxInitialRtrAdvertisements()) {
1746  if (interval > ie->ipv6Data()->_getMaxInitialRtrAdvertInterval()) {
1747  //if the randomly chosen interval is greater than MAX_INITIAL_RTR_ADVERT_INTERVAL,
1748  //the timer SHOULD be set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead.
1749  nextScheduledTime = simTime() + ie->ipv6Data()->_getMaxInitialRtrAdvertInterval();
1750  EV_INFO << "Sending initial RA but interval is too long. Using default value." << endl;
1751  }
1752  else
1753  EV_INFO << "Sending initial RA. Using randomly generated interval." << endl;
1754  }
1755 
1756  EV_DETAIL << "Next scheduled time: " << nextScheduledTime << endl;
1757  advIfEntry->nextScheduledRATime = nextScheduledTime;
1758  ASSERT(nextScheduledTime > simTime());
1759  scheduleAt(nextScheduledTime, msg);
1760 }
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
virtual IPv6RouterAdvertisement * createAndSendRAPacket(const IPv6Address &destAddr, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1193
bool hasMIPv6Support()
Can be used to check whether this node supports MIPv6 or not (MN, MR, HA or CN).
Definition: IPv6RoutingTable.h:365
virtual IPv6NeighbourDiscovery::AdvIfEntry * fetchAdvIfEntry(InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:317
void inet::IPv6NeighbourDiscovery::sendQueuedPacketsToIPv6Module ( Neighbour nce)
protectedvirtual

Send off any queued packets within the Neighbour Discovery module awaiting address resolution.

Not used yet-unsure if we really need it.

–DELETED, Andras

Referenced by processNAForIncompleteNCEState().

769 {
770  MsgPtrVector& pendingPackets = nce->pendingPackets;
771 
772  while (!pendingPackets.empty()) {
773  auto i = pendingPackets.begin();
774  cMessage *msg = (*i);
775  pendingPackets.erase(i);
776  pendingQueue.remove(msg);
777  EV_INFO << "Sending queued packet " << msg << endl;
778  send(msg, "ipv6Out");
779  }
780 }
std::vector< cMessage * > MsgPtrVector
Definition: IPv6NeighbourDiscovery.h:53
cQueue pendingQueue
Definition: IPv6NeighbourDiscovery.h:98
void inet::IPv6NeighbourDiscovery::sendSolicitedNA ( IPv6NeighbourSolicitation ns,
IPv6ControlInfo nsCtrlInfo,
InterfaceEntry ie 
)
protectedvirtual

Referenced by processNSForNonTentativeAddress(), and processNSWithSpecifiedSrcAddr().

2013 {
2014  IPv6NeighbourAdvertisement *na = new IPv6NeighbourAdvertisement("NApacket");
2015  na->setByteLength(ICMPv6_HEADER_BYTES + IPv6_ADDRESS_SIZE); // FIXME set correct length
2016 
2017  //RFC 2461: Section 7.2.4
2018  /*A node sends a Neighbor Advertisement in response to a valid Neighbor
2019  Solicitation targeting one of the node's assigned addresses. The
2020  Target Address of the advertisement is copied from the Target Address
2021  of the solicitation.*/
2022  na->setTargetAddress(ns->getTargetAddress());
2023 
2024  /*If the solicitation's IP Destination Address is not a multicast address,
2025  the Target Link-Layer Address option MAY be omitted; the neighboring node's
2026  cached value must already be current in order for the solicitation to have
2027  been received. If the solicitation's IP Destination Address is a multicast
2028  address, the Target Link-Layer option MUST be included in the advertisement.*/
2029  na->setTargetLinkLayerAddress(ie->getMacAddress()); //here, we always include the MAC addr.
2030  na->addByteLength(IPv6ND_LINK_LAYER_ADDRESS_OPTION_LENGTH);
2031 
2032  /*Furthermore, if the node is a router, it MUST set the Router flag to one;
2033  otherwise it MUST set the flag to zero.*/
2034  na->setRouterFlag(rt6->isRouter());
2035 
2036  /*If the (NS)Target Address is either an anycast address or a unicast
2037  address for which the node is providing proxy service, or the Target
2038  Link-Layer Address option is not included,*/
2039  //TODO:ANYCAST will not be implemented here!
2040 
2041  if (ns->getSourceLinkLayerAddress().isUnspecified())
2042  //the Override flag SHOULD be set to zero.
2043  na->setOverrideFlag(false);
2044  else
2045  //Otherwise, the Override flag SHOULD be set to one.
2046  na->setOverrideFlag(true);
2047 
2048  /*Proper setting of the Override flag ensures that nodes give preference to
2049  non-proxy advertisements, even when received after proxy advertisements, and
2050  also ensures that the first advertisement for an anycast address "wins".*/
2051 
2052  IPv6Address naDestAddr;
2053  //If the source of the solicitation is the unspecified address,
2054  if (nsCtrlInfo->getSrcAddr().isUnspecified()) {
2055  /*the node MUST set the Solicited flag to zero and multicast the advertisement
2056  to the all-nodes address.*/
2057  na->setSolicitedFlag(false);
2058  naDestAddr = IPv6Address::ALL_NODES_2;
2059  }
2060  else {
2061  /*Otherwise, the node MUST set the Solicited flag to one and unicast
2062  the advertisement to the Source Address of the solicitation.*/
2063  na->setSolicitedFlag(true);
2064  naDestAddr = nsCtrlInfo->getSrcAddr();
2065  }
2066 
2067  /*If the Target Address is an anycast address the sender SHOULD delay sending
2068  a response for a random time between 0 and MAX_ANYCAST_DELAY_TIME seconds.*/
2069  /*TODO: More associated complexity for this one. We will have to delay
2070  sending off the solicitation. Perhaps the self message could have a context
2071  pointer pointing to a struct with enough info to create and send a NA packet.*/
2072 
2073  /*Because unicast Neighbor Solicitations are not required to include a
2074  Source Link-Layer Address, it is possible that a node sending a
2075  solicited Neighbor Advertisement does not have a corresponding link-
2076  layer address for its neighbor in its Neighbor Cache. In such
2077  situations, a node will first have to use Neighbor Discovery to
2078  determine the link-layer address of its neighbor (i.e, send out a
2079  multicast Neighbor Solicitation).*/
2080  //TODO: if above mentioned happens, can addr resolution be performed for ND messages?
2081  //if no link-layer addr exists for unicast addr when sending solicited NA, we should
2082  //add the NA to the list of queued packets. What if we have a list of queued
2083  //packets for different unicast solicitations? each time addr resolution is
2084  //done we should check the destinations of the list of queued packets and send
2085  //off the respective ones.
2086  IPv6Address myIPv6Addr = ie->ipv6Data()->getPreferredAddress();
2087  sendPacketToIPv6Module(na, naDestAddr, myIPv6Addr, ie->getInterfaceId());
2088 }
Definition: IPv6NDMessage_m.h:56
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
#define ICMPv6_HEADER_BYTES
Definition: ICMPv6Message_m.h:32
virtual bool isRouter() const
IP forwarding on/off.
Definition: IPv6RoutingTable.h:155
Definition: IPv6Address.h:32
virtual void sendPacketToIPv6Module(cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId)
Create control info and assigns it to a msg.
Definition: IPv6NeighbourDiscovery.cc:752
static const IPv6Address ALL_NODES_2
All-nodes multicast address, scope 2 (link-local)
Definition: IPv6Address.h:75
void inet::IPv6NeighbourDiscovery::sendSolicitedRA ( cMessage *  msg)
protectedvirtual

Referenced by handleMessage().

1763 {
1764  EV_INFO << "Send Solicited RA invoked!\n";
1765  InterfaceEntry *ie = (InterfaceEntry *)msg->getContextPointer();
1766  IPv6Address destAddr = IPv6Address("FF02::1");
1767  EV_DETAIL << "Testing condition!\n";
1768  createAndSendRAPacket(destAddr, ie);
1769  delete msg;
1770 }
virtual IPv6RouterAdvertisement * createAndSendRAPacket(const IPv6Address &destAddr, InterfaceEntry *ie)
Definition: IPv6NeighbourDiscovery.cc:1193
void inet::IPv6NeighbourDiscovery::sendUnsolicitedNA ( InterfaceEntry ie)
virtual

Referenced by inet::xMIPv6::processBAMessage().

2091 {
2092  //RFC 2461
2093  //Section 7.2.6: Sending Unsolicited Neighbor Advertisements
2094 #ifdef WITH_xMIPv6
2095  Enter_Method_Silent();
2096 #endif /* WITH_xMIPv6 */
2097 
2098 #ifndef WITH_xMIPv6
2099  // In some cases a node may be able to determine that its link-layer
2100  // address has changed (e.g., hot-swap of an interface card) and may
2101  // wish to inform its neighbors of the new link-layer address quickly.
2102  // In such cases a node MAY send up to MAX_NEIGHBOR_ADVERTISEMENT
2103  // unsolicited Neighbor Advertisement messages to the all-nodes
2104  // multicast address. These advertisements MUST be separated by at
2105  // least RetransTimer seconds.
2106 #else /* WITH_xMIPv6 */
2107  IPv6NeighbourAdvertisement *na = new IPv6NeighbourAdvertisement("NApacket");
2108  IPv6Address myIPv6Addr = ie->ipv6Data()->getPreferredAddress();
2109  na->setByteLength(ICMPv6_HEADER_BYTES + IPv6_ADDRESS_SIZE);
2110 #endif /* WITH_xMIPv6 */
2111 
2112  // The Target Address field in the unsolicited advertisement is set to
2113  // an IP address of the interface, and the Target Link-Layer Address
2114  // option is filled with the new link-layer address.
2115 #ifdef WITH_xMIPv6
2116  na->setTargetAddress(myIPv6Addr);
2117  na->setTargetLinkLayerAddress(ie->getMacAddress());
2118  na->addByteLength(IPv6ND_LINK_LAYER_ADDRESS_OPTION_LENGTH);
2119 #endif /* WITH_xMIPv6 */
2120 
2121  // The Solicited flag MUST be set to zero, in order to avoid confusing
2122  // the Neighbor Unreachability Detection algorithm.
2123 #ifdef WITH_xMIPv6
2124  na->setSolicitedFlag(false);
2125 #endif /* WITH_xMIPv6 */
2126 
2127  // If the node is a router, it MUST set the Router flag to one;
2128  // otherwise it MUST set it to zero.
2129 #ifdef WITH_xMIPv6
2130  na->setRouterFlag(rt6->isRouter());
2131 #endif /* WITH_xMIPv6 */
2132 
2133  // The Override flag MAY be set to either zero or one. In either case,
2134  // neighboring nodes will immediately change the state of their Neighbor
2135  // Cache entries for the Target Address to STALE, prompting them to
2136  // verify the path for reachability. If the Override flag is set to
2137  // one, neighboring nodes will install the new link-layer address in
2138  // their caches. Otherwise, they will ignore the new link-layer
2139  // address, choosing instead to probe the cached address.
2140 #ifdef WITH_xMIPv6
2141  na->setOverrideFlag(true);
2142 #endif /* WITH_xMIPv6 */
2143 
2144  // A node that has multiple IP addresses assigned to an interface MAY
2145  // multicast a separate Neighbor Advertisement for each address. In
2146  // such a case the node SHOULD introduce a small delay between the
2147  // sending of each advertisement to reduce the probability of the
2148  // advertisements being lost due to congestion.
2149 
2150  // A proxy MAY multicast Neighbor Advertisements when its link-layer
2151  // address changes or when it is configured (by system management or
2152  // other mechanisms) to proxy for an address. If there are multiple
2153  // nodes that are providing proxy services for the same set of addresses
2154  // the proxies SHOULD provide a mechanism that prevents multiple proxies
2155  // from multicasting advertisements for any one address, in order to
2156  // reduce the risk of excessive multicast traffic.
2157 
2158  // Also, a node belonging to an anycast address MAY multicast
2159  // unsolicited Neighbor Advertisements for the anycast address when the
2160  // node's link-layer address changes.
2161 
2162  // Note that because unsolicited Neighbor Advertisements do not reliably
2163  // update caches in all nodes (the advertisements might not be received
2164  // by all nodes), they should only be viewed as a performance
2165  // optimization to quickly update the caches in most neighbors. The
2166  // Neighbor Unreachability Detection algorithm ensures that all nodes
2167  // obtain a reachable link-layer address, though the delay may be
2168  // slightly longer.
2169 #ifdef WITH_xMIPv6
2170  sendPacketToIPv6Module(na, IPv6Address::ALL_NODES_2, myIPv6Addr, ie->getInterfaceId());
2171 #endif /* WITH_xMIPv6 */
2172 }
Definition: IPv6NDMessage_m.h:56
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
#define ICMPv6_HEADER_BYTES
Definition: ICMPv6Message_m.h:32
virtual bool isRouter() const
IP forwarding on/off.
Definition: IPv6RoutingTable.h:155
Definition: IPv6Address.h:32
virtual void sendPacketToIPv6Module(cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId)
Create control info and assigns it to a msg.
Definition: IPv6NeighbourDiscovery.cc:752
static const IPv6Address ALL_NODES_2
All-nodes multicast address, scope 2 (link-local)
Definition: IPv6Address.h:75
void inet::IPv6NeighbourDiscovery::timeoutDefaultRouter ( const IPv6Address addr,
int  interfaceID 
)
protectedvirtual

RFC 2461: Section 6.3.5 Whenever the Lifetime of an entry in the Default Router List expires, that entry is discarded.

When removing a router from the Default Router list, the node MUST update the Destination Cache in such a way that all entries using the router perform next-hop determination again rather than continue sending traffic to the (deleted) router.

Referenced by processRAForRouterUpdates(), and routersUnreachabilityDetection().

632 {
633  //RFC 2461: Section 6.3.5
634  /*Whenever the Lifetime of an entry in the Default Router List expires,
635  that entry is discarded.*/
636  neighbourCache.remove(addr, interfaceID);
637 
638  /*When removing a router from the Default Router list, the node MUST update
639  the Destination Cache in such a way that all entries using the router perform
640  next-hop determination again rather than continue sending traffic to the
641  (deleted) router.*/
642  rt6->purgeDestCacheEntriesToNeighbour(addr, interfaceID);
643 }
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
virtual void remove(const IPv6Address &addr, int interfaceID)
Deletes the given neighbour from the cache.
Definition: IPv6NeighbourCache.cc:149
IPv6NeighbourCache neighbourCache
Definition: IPv6NeighbourDiscovery.h:108
virtual void purgeDestCacheEntriesToNeighbour(const IPv6Address &nextHopAddr, int interfaceId)
Discard all entries in destination cache where next hop is the given address on the given interface...
Definition: IPv6RoutingTable.cc:523
void inet::IPv6NeighbourDiscovery::timeoutPrefixEntry ( const IPv6Address destPrefix,
int  prefixLength 
)
protectedvirtual

RFC 2461: Section 6.3.5 Whenever the invalidation timer expires for a Prefix List entry, that entry is discarded.

No existing Destination Cache entries need be updated, however. Should a reachability problem arise with an existing Neighbor Cache entry, Neighbor Unreachability Detection will perform any needed recovery.

617 {
618  //RFC 2461: Section 6.3.5
619  /*Whenever the invalidation timer expires for a Prefix List entry, that
620  entry is discarded.*/
621  rt6->deleteOnLinkPrefix(destPrefix, prefixLength);
622  //hmmm... should the unicast address associated with this prefix be deleted
623  //as well?-TODO: The address should be timeout/deleted as well!!
624 
625  /*No existing Destination Cache entries need be updated, however. Should a
626  reachability problem arise with an existing Neighbor Cache entry, Neighbor
627  Unreachability Detection will perform any needed recovery.*/
628 }
IPv6RoutingTable * rt6
Definition: IPv6NeighbourDiscovery.h:101
virtual void deleteOnLinkPrefix(const IPv6Address &destPrefix, int prefixLength)
Remove an on-link prefix.
Definition: IPv6RoutingTable.cc:615
bool inet::IPv6NeighbourDiscovery::validateNAPacket ( IPv6NeighbourAdvertisement na,
IPv6ControlInfo naCtrlInfo 
)
protectedvirtual

Referenced by processNAPacket().

2217 {
2218  bool result = true; //adopt optimistic approach
2219 
2220  //RFC 2461:7.1.2 Validation of Neighbor Advertisments(some checks are omitted)
2221  //A node MUST silently discard any received Neighbor Advertisment messages
2222  //that do not satisfy all of the following validity checks:
2223 
2224  //- The IP Hop Limit field has a value of 255, i.e., the packet
2225  // could not possibly have been forwarded by a router.
2226  if (naCtrlInfo->getHopLimit() != 255) {
2227  EV_WARN << "Hop Limit is not 255! NA validation failed!\n";
2228  result = false;
2229  }
2230 
2231  //- Target Address is not a multicast address.
2232  if (na->getTargetAddress().isMulticast() == true) {
2233  EV_WARN << "Target Address is a multicast address! NA validation failed!\n";
2234  result = false;
2235  }
2236 
2237  //- If the IP Destination Address is a multicast address the Solicited flag
2238  // is zero.
2239  if (naCtrlInfo->getDestAddr().isMulticast()) {
2240  if (na->getSolicitedFlag() == true) {
2241  EV_WARN << "Dest Address is multicast address but solicted flag is 0!\n";
2242  result = false;
2243  }
2244  }
2245 
2246  if (result == true)
2247  bubble("NA validation passed.");
2248  else
2249  bubble("NA validation failed.");
2250 
2251  return result;
2252 }
bool inet::IPv6NeighbourDiscovery::validateNSPacket ( IPv6NeighbourSolicitation ns,
IPv6ControlInfo nsCtrlInfo 
)
protectedvirtual

Referenced by processNSPacket().

1887 {
1888  bool result = true;
1889 
1890  /*RFC 2461:7.1.1. Validation of Neighbor Solicitations(some checks are omitted)
1891  A node MUST silently discard any received Neighbor Solicitation
1892  messages that do not satisfy all of the following validity checks:*/
1893  //- The IP Hop Limit field has a value of 255, i.e., the packet
1894  //could not possibly have been forwarded by a router.
1895  if (nsCtrlInfo->getHopLimit() != 255) {
1896  EV_WARN << "Hop limit is not 255! NS validation failed!\n";
1897  result = false;
1898  }
1899 
1900  //- Target Address is not a multicast address.
1901  if (ns->getTargetAddress().isMulticast() == true) {
1902  EV_WARN << "Target address is a multicast address! NS validation failed!\n";
1903  result = false;
1904  }
1905 
1906  //- If the IP source address is the unspecified address,
1907  if (nsCtrlInfo->getSrcAddr().isUnspecified()) {
1908  EV_WARN << "Source Address is unspecified\n";
1909 
1910  //the IP destination address is a solicited-node multicast address.
1911  if (nsCtrlInfo->getDestAddr().matches(IPv6Address::SOLICITED_NODE_PREFIX, 104) == false) {
1912  EV_WARN << " but IP dest address is not a solicited-node multicast address! NS validation failed!\n";
1913  result = false;
1914  }
1915  //there is no source link-layer address option in the message.
1916  else if (ns->getSourceLinkLayerAddress().isUnspecified() == false) {
1917  EV_WARN << " but Source link-layer address is not empty! NS validation failed!\n";
1918  result = false;
1919  }
1920  else
1921  EV_WARN << "NS Validation Passed\n";
1922  }
1923 
1924  return result;
1925 }
static const IPv6Address SOLICITED_NODE_PREFIX
The solicited-node multicast address prefix (prefix length = 104)
Definition: IPv6Address.h:87
bool inet::IPv6NeighbourDiscovery::validateRAPacket ( IPv6RouterAdvertisement ra,
IPv6ControlInfo raCtrlInfo 
)
protectedvirtual

Referenced by processRAPacket().

1774 {
1775  bool result = true;
1776 
1777  //RFC 2461: Section 6.1.2 Validation of Router Advertisement Messages
1778  /*A node MUST silently discard any received Router Advertisement
1779  messages that do not satisfy all of the following validity checks:*/
1780  raCtrlInfo->getSrcAddr();
1781 
1782  //- IP Source Address is a link-local address. Routers must use
1783  // their link-local address as the source for Router Advertisement
1784  // and Redirect messages so that hosts can uniquely identify
1785  // routers.
1786  if (raCtrlInfo->getSrcAddr().isLinkLocal() == false) {
1787  EV_WARN << "RA source address is not link-local. RA validation failed!\n";
1788  result = false;
1789  }
1790 
1791  //- The IP Hop Limit field has a value of 255, i.e., the packet
1792  // could not possibly have been forwarded by a router.
1793  if (raCtrlInfo->getHopLimit() != 255) {
1794  EV_WARN << "Hop limit is not 255! RA validation failed!\n";
1795  result = false;
1796  }
1797 
1798  //- ICMP Code is 0.
1799  if (raCtrlInfo->getProtocol() != IP_PROT_IPv6_ICMP) {
1800  EV_WARN << "ICMP Code is not 0! RA validation failed!\n";
1801  result = false;
1802  }
1803 
1804 #ifdef WITH_xMIPv6
1805  // - All included options have a length that is greater than zero.
1806  // CB
1807  if (ra->getPrefixInformationArraySize() == 0) {
1808  EV_WARN << "No prefix information available! RA validation failed\n";
1809  result = false;
1810  }
1811 #endif /* WITH_xMIPv6 */
1812 
1813  return result;
1814 }
Definition: IPProtocolId_m.h:87
bool inet::IPv6NeighbourDiscovery::validateRSPacket ( IPv6RouterSolicitation rs,
IPv6ControlInfo rsCtrlInfo 
)
protectedvirtual

Referenced by processRSPacket().

1161 {
1162  bool result = true;
1163  /*6.1.1. Validation of Router Solicitation Messages
1164  A router MUST silently discard any received Router Solicitation
1165  messages that do not satisfy all of the following validity checks:
1166 
1167  - The IP Hop Limit field has a value of 255, i.e., the packet
1168  could not possibly have been forwarded by a router.*/
1169  if (rsCtrlInfo->getHopLimit() != 255) {
1170  EV_WARN << "Hop limit is not 255! RS validation failed!\n";
1171  result = false;
1172  }
1173 
1174  //- ICMP Code is 0.
1175  if (rsCtrlInfo->getProtocol() != IP_PROT_IPv6_ICMP) {
1176  EV_WARN << "ICMP Code is not 0! RS validation failed!\n";
1177  result = false;
1178  }
1179 
1180  //- If the IP source address is the unspecified address, there is no
1181  //source link-layer address option in the message.
1182  if (rsCtrlInfo->getSrcAddr().isUnspecified()) {
1183  EV_WARN << "IP source address is unspecified\n";
1184 
1185  if (rs->getSourceLinkLayerAddress().isUnspecified() == false) {
1186  EV_WARN << " but source link layer address is provided. RS validation failed!\n";
1187  }
1188  }
1189 
1190  return result;
1191 }
Definition: IPProtocolId_m.h:87

Member Data Documentation

AdvIfList inet::IPv6NeighbourDiscovery::advIfList
protected
DADGlobalList inet::IPv6NeighbourDiscovery::dadGlobalList
protected
DADList inet::IPv6NeighbourDiscovery::dadList
protected
ICMPv6* inet::IPv6NeighbourDiscovery::icmpv6 = nullptr
protected
xMIPv6* inet::IPv6NeighbourDiscovery::mipv6 = nullptr
protected
cQueue inet::IPv6NeighbourDiscovery::pendingQueue
protected
RATimerList inet::IPv6NeighbourDiscovery::raTimerList
protected

Referenced by ~IPv6NeighbourDiscovery().

RDList inet::IPv6NeighbourDiscovery::rdList
protected
simsignal_t inet::IPv6NeighbourDiscovery::startDADSignal = registerSignal("startDAD")
staticprivate

Referenced by initiateDAD().


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