Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

IPv6NeighbourDiscovery Class Reference

#include <IPv6NeighbourDiscovery.h>

List of all members.


Detailed Description

Implements RFC 2461 Neighbor Discovery for IPv6.


Public Types

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

Public Member Functions

 IPv6NeighbourDiscovery ()
virtual ~IPv6NeighbourDiscovery ()
const MACAddressresolveNeighbour (const IPv6Address &nextHop, int interfaceId)
void reachabilityConfirmed (const IPv6Address &neighbour, int interfaceId)

Protected Types

typedef std::set< cMessage * > RATimerList
typedef std::set< DADEntry * > DADList
typedef std::set< RDEntry * > RDList
typedef std::set< AdvIfEntry * > AdvIfList

Protected Member Functions

virtual int numInitStages () const
virtual void initialize (int stage)
virtual void handleMessage (cMessage *msg)
void processNDMessage (ICMPv6Message *msg, IPv6ControlInfo *ctrlInfo)
virtual void finish ()
void processIPv6Datagram (IPv6Datagram *datagram)
IPv6NeighbourDiscovery::AdvIfEntryfetchAdvIfEntry (InterfaceEntry *ie)
IPv6NeighbourDiscovery::RDEntryfetchRDEntry (InterfaceEntry *ie)
IPv6Address determineNextHop (const IPv6Address &destAddr, int &outIfID)
void initiateNeighbourUnreachabilityDetection (Neighbour *neighbour)
void processNUDTimeout (cMessage *timeoutMsg)
IPv6Address selectDefaultRouter (int &outIfID)
void timeoutPrefixEntry (const IPv6Address &destPrefix, int prefixLength)
void timeoutDefaultRouter (const IPv6Address &addr, int interfaceID)
void initiateAddressResolution (const IPv6Address &dgSrcAddr, Neighbour *nce)
void processARTimeout (cMessage *arTimeoutMsg)
void dropQueuedPacketsAwaitingAR (Neighbour *nce)
void sendPacketToIPv6Module (cMessage *msg, const IPv6Address &destAddr, const IPv6Address &srcAddr, int interfaceId)
void sendQueuedPacketsToIPv6Module (Neighbour *nce)
void initiateDAD (const IPv6Address &tentativeAddr, InterfaceEntry *ie)
void processDADTimeout (cMessage *msg)
void assignLinkLocalAddress (cMessage *timerMsg)
IPv6RouterSolicitationcreateAndSendRSPacket (InterfaceEntry *ie)
void initiateRouterDiscovery (cMessage *msg)
void cancelRouterDiscovery (InterfaceEntry *ie)
void processRDTimeout (cMessage *msg)
void processRSPacket (IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo)
bool validateRSPacket (IPv6RouterSolicitation *rs, IPv6ControlInfo *rsCtrlInfo)
IPv6RouterAdvertisementcreateAndSendRAPacket (const IPv6Address &destAddr, InterfaceEntry *ie)
void processRAPacket (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
void processRAForRouterUpdates (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
void processRAPrefixInfo (IPv6RouterAdvertisement *ra, InterfaceEntry *ie)
void processRAPrefixInfoForAddrAutoConf (IPv6NDPrefixInformation &prefixInfo, InterfaceEntry *ie)
void createRATimer (InterfaceEntry *ie)
void resetRATimer (InterfaceEntry *ie)
void sendPeriodicRA (cMessage *msg)
void sendSolicitedRA (cMessage *msg)
bool validateRAPacket (IPv6RouterAdvertisement *ra, IPv6ControlInfo *raCtrlInfo)
IPv6NeighbourSolicitationcreateAndSendNSPacket (const IPv6Address &nsTargetAddr, const IPv6Address &dgDestAddr, const IPv6Address &dgSrcAddr, InterfaceEntry *ie)
void processNSPacket (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *naCtrlInfo)
bool validateNSPacket (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo)
void processNSForTentativeAddress (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo)
void processNSForNonTentativeAddress (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie)
void processNSWithSpecifiedSrcAddr (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *ctrlInfo, InterfaceEntry *ie)
IPv6NeighbourAdvertisementcreateAndSendNAPacket (IPv6NeighbourSolicitation *ns, const IPv6Address &nsSrcAddr, const IPv6Address &nsDestAddr, InterfaceEntry *ie)
void sendSolicitedNA (IPv6NeighbourSolicitation *ns, IPv6ControlInfo *nsCtrlInfo, InterfaceEntry *ie)
void sendUnsolicitedNA (InterfaceEntry *ie)
void processNAPacket (IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo)
bool validateNAPacket (IPv6NeighbourAdvertisement *na, IPv6ControlInfo *naCtrlInfo)
void processNAForIncompleteNCEState (IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce)
void processNAForOtherNCEStates (IPv6NeighbourAdvertisement *na, IPv6NeighbourCache::Neighbour *nce)
IPv6RedirectcreateAndSendRedirectPacket (InterfaceEntry *ie)
void processRedirectPacket (IPv6Redirect *redirect, IPv6ControlInfo *ctrlInfo)

Protected Attributes

cQueue pendingQueue
InterfaceTableift
RoutingTable6rt6
ICMPv6icmpv6
IPv6NeighbourCache neighbourCache
RATimerList raTimerList
DADList dadList
RDList rdList
AdvIfList advIfList

Classes

struct  AdvIfEntry
struct  DADEntry
struct  RDEntry


Member Typedef Documentation

typedef std::set<AdvIfEntry*> IPv6NeighbourDiscovery::AdvIfList [protected]
 

typedef std::set<DADEntry*> IPv6NeighbourDiscovery::DADList [protected]
 

typedef IPv6NeighbourCache::Key IPv6NeighbourDiscovery::Key
 

typedef std::vector<cMessage*> IPv6NeighbourDiscovery::MsgPtrVector
 

typedef IPv6NeighbourCache::Neighbour IPv6NeighbourDiscovery::Neighbour
 

typedef std::set<cMessage*> IPv6NeighbourDiscovery::RATimerList [protected]
 

typedef std::set<RDEntry*> IPv6NeighbourDiscovery::RDList [protected]
 


Constructor & Destructor Documentation

IPv6NeighbourDiscovery::IPv6NeighbourDiscovery  ) 
 

00036 {
00037 }

IPv6NeighbourDiscovery::~IPv6NeighbourDiscovery  )  [virtual]
 

00040 {
00041     // FIXME delete the following data structures, cancelAndDelete timers in them etc.
00042     // Deleting the data structures my become unnecessary if the lists store the
00043     // structs themselves and not pointers.
00044     //   RATimerList raTimerList;
00045     //   DADList dadList;
00046     //   RDList rdList;
00047     //   AdvIfList advIfList;
00048 }


Member Function Documentation

void IPv6NeighbourDiscovery::assignLinkLocalAddress cMessage *  timerMsg  )  [protected]
 

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.

00732 {
00733     //Node has booted up. Start assigning a link-local address for each
00734     //interface in this node.
00735     for (int i=0; i < ift->numInterfaces(); i++)
00736 {
00737         InterfaceEntry *ie = ift->interfaceAt(i);
00738 
00739         //Skip the loopback interface.
00740         if (ie->isLoopback()) continue;
00741 
00742     IPv6Address linkLocalAddr = ie->ipv6()->linkLocalAddress();
00743     if (linkLocalAddr.isUnspecified())
00744     {
00745         //if no link local address exists for this interface, we assign one to it.
00746             EV << "No link local address exists. Forming one" << endl;
00747         linkLocalAddr = IPv6Address().formLinkLocalAddress(ie->interfaceToken());
00748         ie->ipv6()->assignAddress(linkLocalAddr, true, 0, 0);
00749     }
00750 
00751         //Before we can use this address, we MUST initiate DAD first.
00752         initiateDAD(linkLocalAddr, ie);
00753     }
00754     delete timerMsg;
00755 }

void IPv6NeighbourDiscovery::cancelRouterDiscovery InterfaceEntry ie  )  [protected]
 

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.

00891 {
00892     //Next we retrieve the rdEntry with the Interface Entry.
00893     RDEntry *rdEntry = fetchRDEntry(ie);
00894     if (rdEntry != NULL)
00895     {
00896         EV << "rdEntry is not NULL, RD cancelled!" << endl;
00897         cancelEvent(rdEntry->timeoutMsg);
00898         rdList.erase(rdEntry);
00899         delete rdEntry;
00900     }
00901     else
00902         EV << "rdEntry is NULL, not cancelling RD!" << endl;
00903 }

IPv6NeighbourAdvertisement* IPv6NeighbourDiscovery::createAndSendNAPacket IPv6NeighbourSolicitation ns,
const IPv6Address nsSrcAddr,
const IPv6Address nsDestAddr,
InterfaceEntry ie
[protected]
 

IPv6NeighbourSolicitation * IPv6NeighbourDiscovery::createAndSendNSPacket const IPv6Address nsTargetAddr,
const IPv6Address dgDestAddr,
const IPv6Address dgSrcAddr,
InterfaceEntry ie
[protected]
 

01571 {
01572     MACAddress myMacAddr = ie->macAddress();
01573 
01574     //Construct a Neighbour Solicitation message
01575     IPv6NeighbourSolicitation *ns = new IPv6NeighbourSolicitation("NSpacket");
01576     ns->setType(ICMPv6_NEIGHBOUR_SOL);
01577 
01578     //Neighbour Solicitation Specific Information
01579     ns->setTargetAddress(nsTargetAddr);
01580 
01581     /*If the solicitation is being sent to a solicited-node multicast
01582     address, the sender MUST include its link-layer address (if it has
01583     one) as a Source Link-Layer Address option.*/
01584     if (dgDestAddr.matches(IPv6Address("FF02::1:FF00:0"),104) && // FIXME what's this? make constant...
01585         !dgSrcAddr.isUnspecified())
01586         ns->setSourceLinkLayerAddress(myMacAddr);
01587 
01588     sendPacketToIPv6Module(ns, dgDestAddr, dgSrcAddr, ie->interfaceId());
01589 
01590     return ns;
01591 }

IPv6RouterAdvertisement * IPv6NeighbourDiscovery::createAndSendRAPacket const IPv6Address destAddr,
InterfaceEntry ie
[protected]
 

01047 {
01048     EV << "Create and send RA invoked!\n";
01049     //Must use link-local addr. See: RFC2461 Section 6.1.2
01050     IPv6Address sourceAddr = ie->ipv6()->linkLocalAddress();
01051 
01052     //This operation includes all options, regardless whether it is solicited or unsolicited.
01053     if (ie->ipv6()->advSendAdvertisements()) //if this is an advertising interface
01054     {
01055         //Construct a Router Advertisment message
01056         IPv6RouterAdvertisement *ra = new IPv6RouterAdvertisement("RApacket");
01057         ra->setType(ICMPv6_ROUTER_AD);
01058 
01059         //RFC 2461: Section 6.2.3 Router Advertisment Message Content
01060         /*A router sends periodic as well as solicited Router Advertisements out
01061         its advertising interfaces.  Outgoing Router Advertisements are filled
01062         with the following values consistent with the message format given in
01063         Section 4.2:*/
01064 
01065         //- In the Router Lifetime field: the interface's configured AdvDefaultLifetime.
01066         ra->setRouterLifetime(ie->ipv6()->advDefaultLifetime());
01067 
01068         //- In the M and O flags: the interface's configured AdvManagedFlag and
01069         //AdvOtherConfigFlag, respectively.  See [ADDRCONF].
01070         ra->setManagedAddrConfFlag(ie->ipv6()->advManagedFlag());
01071         ra->setOtherStatefulConfFlag(ie->ipv6()->advOtherConfigFlag());
01072 
01073         //- In the Cur Hop Limit field: the interface's configured CurHopLimit.
01074         ra->setCurHopLimit(ie->ipv6()->advCurHopLimit());
01075 
01076         //- In the Reachable Time field: the interface's configured AdvReachableTime.
01077         ra->setReachableTime(ie->ipv6()->advReachableTime());
01078 
01079         //- In the Retrans Timer field: the interface's configured AdvRetransTimer.
01080         ra->setRetransTimer(ie->ipv6()->advRetransTimer());
01081 
01082         //- In the options:
01083         /*o Source Link-Layer Address option: link-layer address of the sending
01084             interface.  (Assumption: We always send this)*/
01085         ra->setSourceLinkLayerAddress(ie->macAddress());
01086         ra->setMTU(ie->ipv6()->advLinkMTU());
01087 
01088         //Add all Advertising Prefixes to the RA
01089         int numAdvPrefixes = ie->ipv6()->numAdvPrefixes();
01090         EV << "Number of Adv Prefixes: " << numAdvPrefixes << endl;
01091         ra->setPrefixInformationArraySize(numAdvPrefixes);
01092         for (int i = 0; i < numAdvPrefixes; i++)
01093         {
01094             IPv6InterfaceData::AdvPrefix advPrefix = ie->ipv6()->advPrefix(i);
01095             IPv6NDPrefixInformation prefixInfo;
01096             prefixInfo.setPrefix(advPrefix.prefix);
01097             prefixInfo.setPrefixLength(advPrefix.prefixLength);
01098 
01099             //- In the "on-link" flag: the entry's AdvOnLinkFlag.
01100             prefixInfo.setOnlinkFlag(advPrefix.advOnLinkFlag);
01101             //- In the Valid Lifetime field: the entry's AdvValidLifetime.
01102             prefixInfo.setValidLifetime(advPrefix.advValidLifetime);
01103             //- In the "Autonomous address configuration" flag: the entry's
01104             //AdvAutonomousFlag.
01105             prefixInfo.setAutoAddressConfFlag(advPrefix.advAutonomousFlag);
01106             //- In the Preferred Lifetime field: the entry's AdvPreferredLifetime.
01107             prefixInfo.setPreferredLifetime(advPrefix.advPreferredLifetime);
01108             //Now we pop the prefix info into the RA.
01109             ra->setPrefixInformation(i, prefixInfo);
01110         }
01111         sendPacketToIPv6Module(ra, destAddr, sourceAddr, ie->interfaceId());
01112         return ra;
01113     }
01114 }

IPv6Redirect * IPv6NeighbourDiscovery::createAndSendRedirectPacket InterfaceEntry ie  )  [protected]
 

02128 {
02129     //Construct a Redirect message
02130     IPv6Redirect *redirect = new IPv6Redirect("redirectMsg");
02131     redirect->setType(ICMPv6_REDIRECT);
02132 
02133     //Redirect Message Specific Information
02134     //redirect->setTargetAddress();
02135     //redirect->setDestinationAddress();
02136 
02137     //Possible Option
02138     //redirect->setTargetLinkLayerAddress();
02139 
02140     return redirect;
02141 }

IPv6RouterSolicitation * IPv6NeighbourDiscovery::createAndSendRSPacket InterfaceEntry ie  )  [protected]
 

00830 {
00831     ASSERT(ie->ipv6()->advSendAdvertisements() == false);
00832     //RFC 2461: Section 6.3.7 Sending Router Solicitations
00833     //A host sends Router Solicitations to the All-Routers multicast address. The
00834     //IP source address is set to either one of the interface's unicast addresses
00835     //or the unspecified address.
00836     IPv6Address myIPv6Address = ie->ipv6()->preferredAddress();
00837     if (myIPv6Address.isUnspecified())
00838         myIPv6Address = ie->ipv6()->linkLocalAddress();//so we use the link local address instead
00839     if (ie->ipv6()->isTentativeAddress(myIPv6Address))
00840         myIPv6Address = IPv6Address::UNSPECIFIED_ADDRESS;//set my IPv6 address to unspecified.
00841     IPv6Address destAddr = IPv6Address::ALL_ROUTERS_2;//all_routers multicast
00842     IPv6RouterSolicitation *rs = new IPv6RouterSolicitation("RSpacket");
00843     rs->setType(ICMPv6_ROUTER_SOL);
00844 
00845     //The Source Link-Layer Address option SHOULD be set to the host's link-layer
00846     //address, if the IP source address is not the unspecified address.
00847     if (!myIPv6Address.isUnspecified())
00848         rs->setSourceLinkLayerAddress(ie->macAddress());
00849 
00850     //Construct a Router Solicitation message
00851     sendPacketToIPv6Module(rs, destAddr, myIPv6Address, ie->interfaceId());
00852     return rs;
00853 }

void IPv6NeighbourDiscovery::createRATimer InterfaceEntry ie  )  [protected]
 

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

01441 {
01442     cMessage *msg = new cMessage("sendPeriodicRA", MK_SEND_PERIODIC_RTRADV);
01443     msg->setContextPointer(ie);
01444     AdvIfEntry *advIfEntry = new AdvIfEntry();
01445     advIfEntry->interfaceId = ie->interfaceId();
01446     advIfEntry->numRASent = 0;
01447     simtime_t interval
01448         = uniform(ie->ipv6()->minRtrAdvInterval(),ie->ipv6()->maxRtrAdvInterval());
01449     advIfEntry->raTimeoutMsg = msg;
01450 
01451     simtime_t nextScheduledTime = simTime() + interval;
01452     advIfEntry->nextScheduledRATime = nextScheduledTime;
01453     advIfList.insert(advIfEntry);
01454     EV << "Interval: " << interval << endl;
01455     EV << "Next scheduled time: " << nextScheduledTime << endl;
01456     //now we schedule the msg for whatever time that was derived
01457     scheduleAt(nextScheduledTime, msg);
01458 }

IPv6Address IPv6NeighbourDiscovery::determineNextHop const IPv6Address destAddr,
int &  outIfID
[protected]
 

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.

00384 {
00385     IPv6Address nextHopAddr;
00386 
00387     //RFC 2461 Section 5.2
00388     //Next-hop determination for a given unicast destination operates as follows.
00389 
00390     //The sender performs a longest prefix match against the Prefix List to
00391     //determine whether the packet's destination is on- or off-link.
00392     EV << "Find out if supplied dest addr is on-link or off-link.\n";
00393     const IPv6Route *route = rt6->doLongestPrefixMatch(destAddr);
00394 
00395     if (route != NULL)
00396     {
00397         //If the destination is on-link, the next-hop address is the same as the
00398         //packet's destination address.
00399         if (route->nextHop().isUnspecified())
00400         {
00401             EV << "Dest is on-link, next-hop addr is same as dest addr.\n";
00402             outIfID = route->interfaceID();
00403             nextHopAddr = destAddr;
00404         }
00405         else
00406         {
00407             EV << "A next-hop address was found with the route, dest is off-link\n";
00408             EV << "Assume next-hop address as the selected default router.\n";
00409             outIfID = route->interfaceID();
00410             nextHopAddr = route->nextHop();
00411         }
00412     }
00413     else
00414     {
00415         //Otherwise, the sender selects a router from the Default Router List
00416         //(following the rules described in Section 6.3.6).
00417 
00418         EV << "No routes were found, Dest addr is off-link.\n";
00419         nextHopAddr = selectDefaultRouter(outIfID);
00420 
00421         if (outIfID == -1) EV << "No Default Routers were found.";
00422         else EV << "Default router found.\n";
00423     }
00424 
00425     /*the results of next-hop determination computations are saved in the Destination
00426     Cache (which also contains updates learned from Redirect messages).*/
00427     rt6->updateDestCache(destAddr, nextHopAddr, outIfID);
00428     return nextHopAddr;
00429 }

void IPv6NeighbourDiscovery::dropQueuedPacketsAwaitingAR Neighbour nce  )  [protected]
 

Drops specific queued packets for a specific NCE AR-timeout. TODO: Not implemented yet!

00672 {
00673     const Key *nceKey = nce->nceKey;
00674     //RFC 2461: Section 7.2.2
00675     /*If no Neighbor Advertisement is received after MAX_MULTICAST_SOLICIT
00676     solicitations, address resolution has failed. The sender MUST return ICMP
00677     destination unreachable indications with code 3 (Address Unreachable) for
00678     each packet queued awaiting address resolution.*/
00679     MsgPtrVector pendingPackets = nce->pendingPackets;
00680     EV << "Pending Packets empty:" << pendingPackets.empty() << endl;
00681     while (!pendingPackets.empty())
00682     {
00683         MsgPtrVector::iterator i = pendingPackets.begin();
00684         cMessage *msg = (*i);
00685         IPv6Datagram *ipv6Msg = (IPv6Datagram *)msg;
00686         //Assume msg is the packet itself. I need the datagram's source addr.
00687         //The datagram's src addr will be the destination of the unreachable msg.
00688         EV << "Sending ICMP unreachable destination." << endl;
00689         pendingPackets.erase(i);
00690         pendingQueue.remove(msg);
00691         icmpv6->sendErrorMessage(ipv6Msg, ICMPv6_DESTINATION_UNREACHABLE, ADDRESS_UNREACHABLE);
00692     }
00693 
00694     //RFC 2461: Section 7.3.3
00695     /*If address resolution fails, the entry SHOULD be deleted, so that subsequent
00696     traffic to that neighbor invokes the next-hop determination procedure again.*/
00697     EV << "Removing neighbour cache entry" << endl;
00698     neighbourCache.remove(nceKey->address, nceKey->interfaceID);
00699 }

IPv6NeighbourDiscovery::AdvIfEntry * IPv6NeighbourDiscovery::fetchAdvIfEntry InterfaceEntry ie  )  [protected]
 

00262 {
00263    for (AdvIfList::iterator it=advIfList.begin(); it!=advIfList.end(); it++)
00264    {
00265        AdvIfEntry *advIfEntry = (*it);
00266        if (advIfEntry->interfaceId == ie->interfaceId())
00267        {
00268            return advIfEntry;
00269        }
00270    }
00271    return NULL;
00272 }

IPv6NeighbourDiscovery::RDEntry * IPv6NeighbourDiscovery::fetchRDEntry InterfaceEntry ie  )  [protected]
 

00275 {
00276    for (RDList::iterator it=rdList.begin(); it!=rdList.end(); it++)
00277    {
00278        RDEntry *rdEntry = (*it);
00279        if (rdEntry->interfaceId == ie->interfaceId())
00280        {
00281            return rdEntry;
00282        }
00283    }
00284    return NULL;
00285 }

void IPv6NeighbourDiscovery::finish  )  [protected, virtual]
 

00183 {
00184 }

void IPv6NeighbourDiscovery::handleMessage cMessage *  msg  )  [protected, virtual]
 

00083 {
00084     if (msg->isSelfMessage())
00085     {
00086         EV << "Self message received!\n";
00087         if (msg->kind()==MK_SEND_PERIODIC_RTRADV)
00088         {
00089             EV << "Sending periodic RA\n";
00090             sendPeriodicRA(msg);
00091         }
00092         else if (msg->kind()==MK_SEND_SOL_RTRADV)
00093         {
00094             EV << "Sending solicited RA\n";
00095             sendSolicitedRA(msg);
00096         }
00097         else if (msg->kind()==MK_ASSIGN_LINKLOCAL_ADDRESS)
00098         {
00099             EV << "Assigning Link Local Address\n";
00100             assignLinkLocalAddress(msg);
00101         }
00102         else if (msg->kind()==MK_DAD_TIMEOUT)
00103         {
00104             EV << "DAD Timeout message received\n";
00105             processDADTimeout(msg);
00106         }
00107         else if (msg->kind()==MK_RD_TIMEOUT)
00108         {
00109             EV << "Router Discovery message received\n";
00110             processRDTimeout(msg);
00111         }
00112         else if (msg->kind()==MK_INITIATE_RTRDIS)
00113         {
00114             EV << "initiate router discovery.\n";
00115             initiateRouterDiscovery(msg);
00116         }
00117         else if (msg->kind()==MK_NUD_TIMEOUT)
00118         {
00119             EV << "NUD Timeout message received\n";
00120             processNUDTimeout(msg);
00121         }
00122         else if (msg->kind()==MK_AR_TIMEOUT)
00123         {
00124             EV << "Address Resolution Timeout message received\n";
00125             processARTimeout(msg);
00126         }
00127         else
00128             error("Unrecognized Timer");//stops sim w/ error msg.
00129     }
00130     else if (dynamic_cast<ICMPv6Message *>(msg))
00131     {
00132         //This information will serve as input parameters to various processors.
00133         IPv6ControlInfo *ctrlInfo
00134             = check_and_cast<IPv6ControlInfo*>(msg->removeControlInfo());
00135         ICMPv6Message *ndMsg = (ICMPv6Message *)msg;
00136         processNDMessage(ndMsg, ctrlInfo);
00137     }
00138     else if (dynamic_cast<IPv6Datagram *>(msg))// not ND message
00139     {
00140         IPv6Datagram *datagram = (IPv6Datagram *)msg;
00141         processIPv6Datagram(datagram);
00142     }
00143     else
00144         error("Unknown message type received.\n");
00145 }

void IPv6NeighbourDiscovery::initialize int  stage  )  [protected, virtual]
 

00051 {
00052     // We have to wait until the 3rd stage (stage 2) with scheduling messages,
00053     // because interface registration and IPv6 configuration takes places
00054     // in the first two stages.
00055     if (stage==3)
00056     {
00057         ift = InterfaceTableAccess().get();
00058         rt6 = RoutingTable6Access().get();
00059         icmpv6 = ICMPv6Access().get();
00060         pendingQueue.setName("pendingQueue");
00061 
00062         for (int i=0; i < ift->numInterfaces(); i++)
00063         {
00064             InterfaceEntry *ie = ift->interfaceAt(i);
00065 
00066             if (ie->ipv6()->advSendAdvertisements() && !(ie->isLoopback()))
00067             {
00068                 createRATimer(ie);
00069             }
00070         }
00071         //This simulates random node bootup time. Link local address assignment
00072         //takes place during this time.
00073         cMessage *msg = new cMessage("assignLinkLocalAddr", MK_ASSIGN_LINKLOCAL_ADDRESS);
00074         //We want routers to boot up faster!
00075         if (rt6->isRouter())
00076             scheduleAt(uniform(0,0.3), msg);//Random Router bootup time
00077         else
00078             scheduleAt(uniform(0.4,1), msg);//Random Host bootup time
00079     }
00080 }

void IPv6NeighbourDiscovery::initiateAddressResolution const IPv6Address dgSrcAddr,
Neighbour nce
[protected]
 

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.

00596 {
00597     const Key *nceKey = nce->nceKey;
00598     InterfaceEntry *ie = ift->interfaceAt(nceKey->interfaceID);
00599     IPv6Address neighbourAddr = nceKey->address;
00600     int ifID = nceKey->interfaceID;
00601 
00602     //RFC2461: Section 7.2.2
00603     //When a node has a unicast packet to send to a neighbor, but does not
00604     //know the neighbor's link-layer address, it performs address
00605     //resolution.  For multicast-capable interfaces this entails creating a
00606     //Neighbor Cache entry in the INCOMPLETE state(already created if not done yet)
00607     //WEI-If entry already exists, we still have to ensure that its state is INCOMPLETE.
00608     nce->reachabilityState = IPv6NeighbourCache::INCOMPLETE;
00609 
00610     //and transmitting a Neighbor Solicitation message targeted at the
00611     //neighbor.  The solicitation is sent to the solicited-node multicast
00612     //address "corresponding to"(or "derived from") the target address.
00613     //(in this case, the target address is the address we are trying to resolve)
00614     EV << "Preparing to send NS to solicited-node multicast group\n";
00615     EV << "on the next hop interface\n";
00616     IPv6Address nsDestAddr = neighbourAddr.formSolicitedNodeMulticastAddress();//for NS datagram
00617     IPv6Address nsTargetAddr = neighbourAddr;//for the field within the NS
00618     IPv6Address nsSrcAddr;
00619 
00620     /*If the source address of the packet prompting the solicitation is the
00621     same as one of the addresses assigned to the outgoing interface,*/
00622     if (ie->ipv6()->hasAddress(dgSrcAddr))
00623         /*that address SHOULD be placed in the IP Source Address of the outgoing
00624         solicitation.*/
00625         nsSrcAddr = dgSrcAddr;
00626     else
00627         /*Otherwise, any one of the addresses assigned to the interface
00628         should be used.*/
00629         nsSrcAddr = ie->ipv6()->preferredAddress();
00630     ASSERT(ifID != -1);
00631     //Sending NS on specified interface.
00632     createAndSendNSPacket(nsTargetAddr, nsDestAddr, nsSrcAddr, ie);
00633     nce->numOfARNSSent = 1;
00634     nce->nsSrcAddr = nsSrcAddr;
00635 
00636     /*While awaiting a response, the sender SHOULD retransmit Neighbor Solicitation
00637     messages approximately every RetransTimer milliseconds, even in the absence
00638     of additional traffic to the neighbor. Retransmissions MUST be rate-limited
00639     to at most one solicitation per neighbor every RetransTimer milliseconds.*/
00640     cMessage *msg = new cMessage("arTimeout", MK_AR_TIMEOUT);//AR msg timer
00641     nce->arTimer = msg;
00642     msg->setContextPointer(nce);
00643     scheduleAt(simTime()+ie->ipv6()->_retransTimer(), msg);
00644 }

void IPv6NeighbourDiscovery::initiateDAD const IPv6Address tentativeAddr,
InterfaceEntry ie
[protected]
 

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

00759 {
00760     DADEntry *dadEntry = new DADEntry();
00761     dadEntry->interfaceId = ie->interfaceId();
00762     dadEntry->address = tentativeAddr;
00763     dadEntry->numNSSent = 0;
00764     dadList.insert(dadEntry);
00765     /*
00766     RFC2462: Section 5.4.2
00767     To check an address, a node sends DupAddrDetectTransmits Neighbor
00768     Solicitations, each separated by RetransTimer milliseconds. The
00769     solicitation's Target Address is set to the address being checked,
00770     the IP source is set to the unspecified address and the IP
00771     destination is set to the solicited-node multicast address of the
00772     target address.*/
00773     IPv6Address destAddr = tentativeAddr.formSolicitedNodeMulticastAddress();
00774     //Send a NS
00775     createAndSendNSPacket(tentativeAddr, destAddr,
00776         IPv6Address::UNSPECIFIED_ADDRESS, ie);
00777     dadEntry->numNSSent++;
00778 
00779     cMessage *msg = new cMessage("dadTimeout", MK_DAD_TIMEOUT);
00780     msg->setContextPointer(dadEntry);
00781     scheduleAt(simTime()+ie->ipv6()->retransTimer(), msg);
00782 }

void IPv6NeighbourDiscovery::initiateNeighbourUnreachabilityDetection Neighbour neighbour  )  [protected]
 

00433 {
00434     ASSERT(nce->reachabilityState==IPv6NeighbourCache::STALE);
00435     const Key *nceKey = nce->nceKey;
00436     EV << "Initiating Neighbour Unreachability Detection";
00437     InterfaceEntry *ie = ift->interfaceAt(nceKey->interfaceID);
00438     EV << "Setting NCE state to DELAY.\n";
00439     /*The first time a node sends a packet to a neighbor whose entry is
00440     STALE, the sender changes the state to DELAY*/
00441     nce->reachabilityState = IPv6NeighbourCache::DELAY;
00442 
00443     /*and sets a timer to expire in DELAY_FIRST_PROBE_TIME seconds.*/
00444     cMessage *msg = new cMessage("NUDTimeout", MK_NUD_TIMEOUT);
00445     msg->setContextPointer(nce);
00446     nce->nudTimeoutEvent = msg;
00447     scheduleAt(simTime()+ie->ipv6()->_delayFirstProbeTime(), msg);
00448 }

void IPv6NeighbourDiscovery::initiateRouterDiscovery cMessage *  msg  )  [protected]
 

00856 {
00857     EV << "Initiating Router Discovery" << endl;
00858     InterfaceEntry *ie = (InterfaceEntry *)msg->contextPointer();
00859     delete msg;
00860     //RFC2461: Section 6.3.7
00861     /*When an interface becomes enabled, a host may be unwilling to wait for the
00862     next unsolicited Router Advertisement to locate default routers or learn
00863     prefixes.  To obtain Router Advertisements quickly, a host SHOULD transmit up
00864     to MAX_RTR_SOLICITATIONS Router Solicitation messages each separated by at
00865     least RTR_SOLICITATION_INTERVAL seconds.(FIXME:Therefore this should be invoked
00866     at the beginning of the simulation-WEI)*/
00867     RDEntry *rdEntry = new RDEntry();
00868     rdEntry->interfaceId = ie->interfaceId();
00869     rdEntry->numRSSent = 0;
00870     createAndSendRSPacket(ie);
00871     rdEntry->numRSSent++;
00872 
00873     //Create and schedule a message for retransmission to this module
00874     cMessage *rdTimeoutMsg = new cMessage("processRDTimeout", MK_RD_TIMEOUT);
00875     rdTimeoutMsg->setContextPointer(ie);
00876     rdEntry->timeoutMsg = rdTimeoutMsg;
00877     rdList.insert(rdEntry);
00878     /*Before a host sends an initial solicitation, it SHOULD delay the
00879     transmission for a random amount of time between 0 and
00880     MAX_RTR_SOLICITATION_DELAY.  This serves to alleviate congestion when
00881     many hosts start up on a link at the same time, such as might happen
00882     after recovery from a power failure.  If a host has already performed
00883     a random delay since the interface became (re)enabled (e.g., as part
00884     of Duplicate Address Detection [ADDRCONF]) there is no need to delay
00885     again before sending the first Router Solicitation message.*/
00886     //simtime_t rndInterval = uniform(0, ie->ipv6()->_maxRtrSolicitationDelay());
00887     scheduleAt(simTime()+ie->ipv6()->_rtrSolicitationInterval(), rdTimeoutMsg);
00888 }

virtual int IPv6NeighbourDiscovery::numInitStages  )  const [inline, protected, virtual]
 

00135 {return 4;}

void IPv6NeighbourDiscovery::processARTimeout cMessage *  arTimeoutMsg  )  [protected]
 

Resends a NS packet to the address intended for address resolution. TODO: Not implemented yet!

00648 {
00649     //AR timeouts are cancelled when a valid solicited NA is received.
00650     Neighbour *nce = (Neighbour *)arTimeoutMsg->contextPointer();
00651     const Key *nceKey = nce->nceKey;
00652     IPv6Address nsTargetAddr = nceKey->address;
00653     InterfaceEntry *ie = ift->interfaceAt(nceKey->interfaceID);
00654     EV << "Num Of NS Sent:" << nce->numOfARNSSent << endl;
00655     EV << "Max Multicast Solicitation:" << ie->ipv6()->_maxMulticastSolicit() << endl;
00656     if (nce->numOfARNSSent < ie->ipv6()->_maxMulticastSolicit())
00657     {
00658         EV << "Sending another Address Resolution NS message" << endl;
00659         IPv6Address nsDestAddr = nsTargetAddr.formSolicitedNodeMulticastAddress();
00660         createAndSendNSPacket(nsTargetAddr, nsDestAddr, nce->nsSrcAddr, ie);
00661         nce->numOfARNSSent++;
00662         scheduleAt(simTime()+ie->ipv6()->_retransTimer(), arTimeoutMsg);
00663         return;
00664     }
00665     EV << "Address Resolution has failed." << endl;
00666     dropQueuedPacketsAwaitingAR(nce);
00667     EV << "Deleting AR timeout msg\n";
00668     delete arTimeoutMsg;
00669 }

void IPv6NeighbourDiscovery::processDADTimeout cMessage *  msg  )  [protected]
 

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.

00785 {
00786     DADEntry *dadEntry = (DADEntry *)msg->contextPointer();
00787     InterfaceEntry *ie = (InterfaceEntry *)ift->interfaceAt(dadEntry->interfaceId);
00788     IPv6Address tentativeAddr = dadEntry->address;
00789     //Here, we need to check how many DAD messages for the interface entry were
00790     //sent vs. DupAddrDetectTransmits
00791     EV << "numOfDADMessagesSent is: " << dadEntry->numNSSent << endl;
00792     EV << "dupAddrDetectTrans is: " << ie->ipv6()->dupAddrDetectTransmits() << endl;
00793     if (dadEntry->numNSSent < ie->ipv6()->dupAddrDetectTransmits())
00794     {
00795         bubble("Sending another DAD NS message.");
00796         IPv6Address destAddr = tentativeAddr.formSolicitedNodeMulticastAddress();
00797         createAndSendNSPacket(dadEntry->address, destAddr, IPv6Address::UNSPECIFIED_ADDRESS, ie);
00798         dadEntry->numNSSent++;
00799         //Reuse the received msg
00800         scheduleAt(simTime()+ie->ipv6()->retransTimer(), msg);
00801     }
00802     else
00803     {
00804         bubble("Max number of DAD messages for interface sent. Address is unique.");
00805         ie->ipv6()->permanentlyAssign(tentativeAddr);
00806         dadList.erase(dadEntry);
00807         EV << "delete dadEntry and msg\n";
00808         delete dadEntry;
00809         delete msg;
00810         /*RFC 2461: Section 6.3.7 2nd Paragraph
00811         Before a host sends an initial solicitation, it SHOULD delay the
00812         transmission for a random amount of time between 0 and
00813         MAX_RTR_SOLICITATION_DELAY.  This serves to alleviate congestion when
00814         many hosts start up on a link at the same time, such as might happen
00815         after recovery from a power failure.*/
00816         //TODO: Placing these operations here means fast router solicitation is
00817         //not adopted. Will relocate.
00818         if (ie->ipv6()->advSendAdvertisements() == false)
00819         {
00820             EV << "creating router discovery message timer\n";
00821             cMessage *rtrDisMsg = new cMessage("initiateRTRDIS",MK_INITIATE_RTRDIS);
00822             rtrDisMsg->setContextPointer(ie);
00823             simtime_t interval = uniform(0,ie->ipv6()->_maxRtrSolicitationDelay());//random delay
00824             scheduleAt(simTime()+interval, rtrDisMsg);
00825         }
00826     }
00827 }

void IPv6NeighbourDiscovery::processIPv6Datagram IPv6Datagram datagram  )  [protected]
 

00187 {
00188     EV << "Packet " << msg << " arrived from IPv6 module.\n";
00189 
00190     int nextHopIfID;
00191     EV << "Determining Next Hop" << endl;
00192     IPv6Address nextHopAddr = determineNextHop(msg->destAddress(), nextHopIfID);
00193     if (nextHopIfID == -1)
00194     {
00195         //draft-ietf-ipv6-2461bis-04 has omitted on-link assumption.
00196         //draft-ietf-v6ops-onlinkassumption-03 explains why.
00197         icmpv6->sendErrorMessage(msg, ICMPv6_DESTINATION_UNREACHABLE, NO_ROUTE_TO_DEST);
00198         return;
00199     }
00200     EV << "Next Hop Address is: " << nextHopAddr << " on interface: " << nextHopIfID << endl;
00201 
00202     //RFC2461: Section 5.2 Conceptual Sending Algorithm
00203     //Once the IP address of the next-hop node is known, the sender examines the
00204     //Neighbor Cache for link-layer information about that neighbor.
00205     Neighbour *nce = neighbourCache.lookup(nextHopAddr, nextHopIfID);
00206 
00207     if (nce==NULL)
00208     {
00209         //If no entry exists,
00210         EV << "No Entry exists in the Neighbour Cache.\n";
00211 
00212         //the sender creates one, sets its state to INCOMPLETE,
00213         EV << "Creating an INCOMPLETE entry in the neighbour cache.\n";
00214         nce = neighbourCache.addNeighbour(nextHopAddr, nextHopIfID);
00215 
00216         //initiates Address Resolution,
00217         EV << "Initiating Address Resolution for:" << nextHopAddr
00218            << " on Interface:" << nextHopIfID << endl;
00219         initiateAddressResolution(msg->srcAddress(), nce);
00220 
00221         //and then queues the data packet pending completion of address resolution.
00222         EV << "Add packet to entry's queue until Address Resolution is complete.\n";
00223         nce->pendingPackets.push_back(msg);
00224         pendingQueue.insert(msg);
00225     }
00226     else if (nce->reachabilityState == IPv6NeighbourCache::INCOMPLETE)
00227     {
00228         EV << "Reachability State is INCOMPLETE.Address Resolution already initiated.\n";
00229         bubble("Packet added to queue until Address Resolution is complete.");
00230         nce->pendingPackets.push_back(msg);
00231         pendingQueue.insert(msg);
00232     }
00233     else if (nce->macAddress.isUnspecified())
00234     {
00235         EV << "NCE's MAC address is unspecified.\n";
00236         EV << "Initiate Address Resolution and add packet to queue.\n";
00237         initiateAddressResolution(msg->srcAddress(), nce);
00238         nce->pendingPackets.push_back(msg);
00239         pendingQueue.insert(msg);
00240     }
00241     else if (nce->reachabilityState == IPv6NeighbourCache::STALE)
00242     {
00243         EV << "Reachability State is STALE.\n";
00244         send(msg,"toIPv6");
00245         initiateNeighbourUnreachabilityDetection(nce);
00246     }
00247     else if (nce->reachabilityState == IPv6NeighbourCache::REACHABLE)
00248     {
00249         EV << "Next hop is REACHABLE, sending packet to next-hop address.";
00250         sendPacketToIPv6Module(msg, nextHopAddr, msg->srcAddress(), nextHopIfID);
00251     }
00252     else if (nce->reachabilityState == IPv6NeighbourCache::DELAY)//TODO: What if NCE is in PROBE state?
00253     {
00254         EV << "Next hop is in DELAY state, sending packet to next-hop address.";
00255         sendPacketToIPv6Module(msg, nextHopAddr, msg->srcAddress(), nextHopIfID);
00256     }
00257     else
00258         error("Unknown Neighbour cache entry state.");
00259 }

void IPv6NeighbourDiscovery::processNAForIncompleteNCEState IPv6NeighbourAdvertisement na,
IPv6NeighbourCache::Neighbour nce
[protected]
 

void IPv6NeighbourDiscovery::processNAForOtherNCEStates IPv6NeighbourAdvertisement na,
IPv6NeighbourCache::Neighbour nce
[protected]
 

void IPv6NeighbourDiscovery::processNAPacket IPv6NeighbourAdvertisement na,
IPv6ControlInfo naCtrlInfo
[protected]
 

01895 {
01896     if (validateNAPacket(na, naCtrlInfo) == false)
01897     {
01898         delete naCtrlInfo;
01899         delete na;
01900         return;
01901     }
01902 
01903     //Neighbour Advertisement Information
01904     IPv6Address naTargetAddr = na->targetAddress();
01905 
01906     //First, we check if the target address in NA is found in the interface it
01907     //was received on is tentative.
01908     InterfaceEntry *ie = ift->interfaceAt(naCtrlInfo->interfaceId());
01909     if (ie->ipv6()->isTentativeAddress(naTargetAddr))
01910     {
01911         error("Duplicate Address Detected! Manual attention needed!");
01912     }
01913     //Logic as defined in Section 7.2.5
01914     Neighbour *neighbourEntry = neighbourCache.lookup(naTargetAddr, ie->interfaceId());
01915 
01916     if (neighbourEntry == NULL)
01917     {
01918         EV << "NA received. Target Address not found in Neighbour Cache\n";
01919         EV << "Dropping NA packet.\n";
01920         delete naCtrlInfo;
01921         delete na;
01922         return;
01923     }
01924 
01925     //Target Address has entry in Neighbour Cache
01926     EV << "NA received. Target Address found in Neighbour Cache\n";
01927 
01928     if (neighbourEntry->reachabilityState == IPv6NeighbourCache::INCOMPLETE)
01929         processNAForIncompleteNCEState(na, neighbourEntry);
01930     else
01931         processNAForOtherNCEStates(na, neighbourEntry);
01932     delete naCtrlInfo;
01933     delete na;
01934 }

void IPv6NeighbourDiscovery::processNDMessage ICMPv6Message msg,
IPv6ControlInfo ctrlInfo
[protected]
 

00149 {
00150 
00151     if (dynamic_cast<IPv6RouterSolicitation *>(msg))
00152     {
00153         IPv6RouterSolicitation *rs = (IPv6RouterSolicitation *)msg;
00154         processRSPacket(rs, ctrlInfo);
00155     }
00156     else if (dynamic_cast<IPv6RouterAdvertisement *>(msg))
00157     {
00158         IPv6RouterAdvertisement *ra = (IPv6RouterAdvertisement *)msg;
00159         processRAPacket(ra, ctrlInfo);
00160     }
00161     else if (dynamic_cast<IPv6NeighbourSolicitation *>(msg))
00162     {
00163         IPv6NeighbourSolicitation *ns = (IPv6NeighbourSolicitation *)msg;
00164         processNSPacket(ns, ctrlInfo);
00165     }
00166     else if (dynamic_cast<IPv6NeighbourAdvertisement *>(msg))
00167     {
00168         IPv6NeighbourAdvertisement *na = (IPv6NeighbourAdvertisement *)msg;
00169         processNAPacket(na, ctrlInfo);
00170     }
00171     else if (dynamic_cast<IPv6Redirect *>(msg))
00172     {
00173         IPv6Redirect *redirect = (IPv6Redirect *)msg;
00174         processRedirectPacket(redirect, ctrlInfo);
00175     }
00176     else
00177     {
00178         error("Unrecognized ND message!");
00179     }
00180 }

void IPv6NeighbourDiscovery::processNSForNonTentativeAddress IPv6NeighbourSolicitation ns,
IPv6ControlInfo ctrlInfo,
InterfaceEntry ie
[protected]
 

01703 {
01704     //Neighbour Solicitation Information
01705     MACAddress nsMacAddr = ns->sourceLinkLayerAddress();
01706 
01707     int ifID = ie->interfaceId();
01708 
01709     //target addr is not tentative addr
01710     //solicitation processed as described in RFC2461:section 7.2.3
01711     if (nsCtrlInfo->srcAddr().isUnspecified())
01712     {
01713         EV << "Address is duplicate! Inform Sender of duplicate address!\n";
01714         sendSolicitedNA(ns, nsCtrlInfo, ie);
01715     }
01716     else
01717     {
01718         processNSWithSpecifiedSrcAddr(ns, nsCtrlInfo, ie);
01719     }
01720 }

void IPv6NeighbourDiscovery::processNSForTentativeAddress IPv6NeighbourSolicitation ns,
IPv6ControlInfo ctrlInfo
[protected]
 

01675 {
01676     //Control Information
01677     IPv6Address nsSrcAddr = nsCtrlInfo->srcAddr();
01678     IPv6Address nsDestAddr = nsCtrlInfo->destAddr();
01679 
01680     ASSERT(nsSrcAddr.isUnicast() || nsSrcAddr.isUnspecified());
01681     //solicitation is processed as described in RFC2462:section 5.4.3
01682 
01683     if (nsSrcAddr.isUnspecified())
01684     {
01685         EV << "Source Address is UNSPECIFIED. Sender is performing DAD\n";
01686         //Sender performing Duplicate Address Detection
01687         if (rt6->localDeliver(nsSrcAddr))
01688             EV << "NS comes from myself. Ignoring NS\n";
01689         else
01690             EV << "NS comes from another node. Address is duplicate!\n";
01691             error("Duplicate Address Detected! Manual Attention Required!");
01692     }
01693     else if (nsSrcAddr.isUnicast())
01694     {
01695         //Sender performing address resolution
01696         EV << "Sender is performing Address Resolution\n";
01697         EV << "Target Address is tentative. Ignoring NS.\n";
01698     }
01699 }

void IPv6NeighbourDiscovery::processNSPacket IPv6NeighbourSolicitation ns,
IPv6ControlInfo naCtrlInfo
[protected]
 

01595 {
01596     //Control Information
01597     InterfaceEntry *ie = ift->interfaceAt(nsCtrlInfo->interfaceId());
01598 
01599     IPv6Address nsTargetAddr = ns->targetAddress();
01600 
01601     //RFC 2461:Section 7.2.3
01602     //If target address is not a valid "unicast" or anycast address assigned to the
01603     //receiving interface, we should silently discard the packet.
01604     if (validateNSPacket(ns, nsCtrlInfo) == false
01605         || ie->ipv6()->hasAddress(nsTargetAddr) == false)
01606     {
01607         bubble("NS validation failed\n");
01608         delete nsCtrlInfo;
01609         delete ns;
01610         return;
01611     }
01612     bubble("NS validation passed.\n");
01613     if (ie->ipv6()->isTentativeAddress(nsTargetAddr))
01614     {
01615         //If the Target Address is tentative, the Neighbor Solicitation should
01616         //be processed as described in [ADDRCONF].
01617         EV << "Process NS for Tentative target address.\n";
01618         processNSForTentativeAddress(ns, nsCtrlInfo);
01619     }
01620     else
01621     {
01622         //Otherwise, the following description applies.
01623         EV << "Process NS for Non-Tentative target address.\n";
01624         processNSForNonTentativeAddress(ns, nsCtrlInfo, ie);
01625     }
01626     delete nsCtrlInfo;
01627     delete ns;
01628 }

void IPv6NeighbourDiscovery::processNSWithSpecifiedSrcAddr IPv6NeighbourSolicitation ns,
IPv6ControlInfo ctrlInfo,
InterfaceEntry ie
[protected]
 

01724 {
01725     //RFC 2461, Section 7.2.3
01726     /*If the Source Address is not the unspecified address and, on link layers
01727     that have addresses, the solicitation includes a Source Link-Layer Address
01728     option, then the recipient SHOULD create or update the Neighbor Cache entry
01729     for the IP Source Address of the solicitation.*/
01730 
01731     //Neighbour Solicitation Information
01732     MACAddress nsMacAddr = ns->sourceLinkLayerAddress();
01733 
01734     int ifID = ie->interfaceId();
01735 
01736     //Look for the Neighbour Cache Entry
01737     Neighbour *entry = neighbourCache.lookup(nsCtrlInfo->srcAddr(), ifID);
01738 
01739     if (entry == NULL)
01740     {
01741         /*If an entry does not already exist, the node SHOULD create a new one
01742         and set its reachability state to STALE as specified in Section 7.3.3.*/
01743         EV << "Neighbour Entry not found. Create a Neighbour Cache Entry.\n";
01744         neighbourCache.addNeighbour(nsCtrlInfo->srcAddr(), ifID, nsMacAddr);
01745     }
01746     else
01747     {
01748         /*If an entry already exists, and the cached link-layer address differs from
01749         the one in the received Source Link-Layer option,*/
01750         if (!(entry->macAddress.equals(nsMacAddr)) && !nsMacAddr.isUnspecified())
01751         {
01752             //the cached address should be replaced by the received address
01753             entry->macAddress = nsMacAddr;
01754             //and the entry's reachability state MUST be set to STALE.
01755             entry->reachabilityState = IPv6NeighbourCache::STALE;
01756         }
01757     }
01758     /*After any updates to the Neighbor Cache, the node sends a Neighbor
01759     Advertisement response as described in the next section.*/
01760     sendSolicitedNA(ns, nsCtrlInfo, ie);
01761 }

void IPv6NeighbourDiscovery::processNUDTimeout cMessage *  timeoutMsg  )  [protected]
 

00451 {
00452     EV << "NUD has timed out\n";
00453     Neighbour *nce = (Neighbour *) timeoutMsg->contextPointer();
00454     const Key *nceKey = nce->nceKey;
00455     InterfaceEntry *ie = ift->interfaceAt(nceKey->interfaceID);
00456 
00457     if (nce->reachabilityState == IPv6NeighbourCache::DELAY)
00458     {
00459         /*If the entry is still in the DELAY state when the timer expires, the
00460         entry's state changes to PROBE. If reachability confirmation is received,
00461         the entry's state changes to REACHABLE.*/
00462         EV << "Neighbour Entry is still in DELAY state.\n";
00463         EV << "Entering PROBE state. Sending NS probe.\n";
00464         nce->reachabilityState = IPv6NeighbourCache::PROBE;
00465         nce->numProbesSent = 0;
00466     }
00467 
00468     /*If no response is received after waiting RetransTimer milliseconds
00469     after sending the MAX_UNICAST_SOLICIT solicitations, retransmissions cease
00470     and the entry SHOULD be deleted. Subsequent traffic to that neighbor will
00471     recreate the entry and performs address resolution again.*/
00472     if (nce->numProbesSent == ie->ipv6()->_maxUnicastSolicit())
00473     {
00474         EV << "Max number of probes have been sent." << endl;
00475         EV << "Neighbour is Unreachable, removing NCE." << endl;
00476         neighbourCache.remove(nceKey->address, nceKey->interfaceID);
00477         return;
00478     }
00479 
00480     /*Upon entering the PROBE state, a node sends a unicast Neighbor Solicitation
00481     message to the neighbor using the cached link-layer address.*/
00482     createAndSendNSPacket(nceKey->address, nceKey->address,
00483         ie->ipv6()->preferredAddress(), ie);
00484     nce->numProbesSent++;
00485     /*While in the PROBE state, a node retransmits Neighbor Solicitation messages
00486     every RetransTimer milliseconds until reachability confirmation is obtained.
00487     Probes are retransmitted even if no additional packets are sent to the
00488     neighbor.*/
00489     scheduleAt(simTime()+ie->ipv6()->_retransTimer(), timeoutMsg);
00490 }

void IPv6NeighbourDiscovery::processRAForRouterUpdates IPv6RouterAdvertisement ra,
IPv6ControlInfo raCtrlInfo
[protected]
 

01155 {
01156     EV << "Processing RA for Router Updates\n";
01157     //RFC2461: Section 6.3.4
01158     //Paragraphs 1 and 2 omitted.
01159 
01160     //On receipt of a valid Router Advertisement, a host extracts the source
01161     //address of the packet and does the following:
01162     IPv6Address raSrcAddr = raCtrlInfo->srcAddr();
01163     InterfaceEntry *ie = ift->interfaceAt(raCtrlInfo->interfaceId());
01164     int ifID = ie->interfaceId();
01165 
01166     /*- If the address is not already present in the host's Default Router List,
01167     and the advertisement's Router Lifetime is non-zero, create a new entry in
01168     the list, and initialize its invalidation timer value from the advertisement's
01169     Router Lifetime field.*/
01170     Neighbour *neighbour = neighbourCache.lookup(raSrcAddr, ifID);
01171     if (neighbour == NULL)
01172     {
01173         EV << "Neighbour Cache Entry does not contain RA's source address\n";
01174         if (ra->routerLifetime() != 0)
01175         {
01176             EV << "RA's router lifetime is non-zero, creating an entry in the "
01177                << "Host's default router list.\n" << ra->routerLifetime();
01178             //If a Neighbor Cache entry is created for the router its reachability
01179             //state MUST be set to STALE as specified in Section 7.3.3.
01180             if (ra->sourceLinkLayerAddress().isUnspecified())
01181             {
01182                 neighbour = neighbourCache.addRouter(raSrcAddr, ifID,
01183                     simTime()+ra->routerLifetime());
01184                 //Note:invalidation timers are not explicitly defined.
01185             }
01186             else
01187             {
01188                 neighbour = neighbourCache.addRouter(raSrcAddr, ifID,
01189                     ra->sourceLinkLayerAddress(), simTime()+ra->routerLifetime());
01190                 //According to Greg, we should add a default route for hosts as well!
01191                 rt6->addDefaultRoute(raSrcAddr, ifID, simTime()+ra->routerLifetime());
01192             }
01193         }
01194         else
01195         {
01196             EV << "Router Lifetime is 0, adding NON-default router.\n";
01197             //WEI-The router is advertising itself, BUT not as a default router.
01198             if (ra->sourceLinkLayerAddress().isUnspecified())
01199                 neighbour = neighbourCache.addNeighbour(raSrcAddr, ifID);
01200             else
01201                 neighbour = neighbourCache.addNeighbour(raSrcAddr, ifID,
01202                     ra->sourceLinkLayerAddress());
01203             neighbour->isRouter = true;
01204         }
01205     }
01206     else
01207     {
01208         //If no Source Link-Layer Address is included, but a corresponding Neighbor
01209         //Cache entry exists, its IsRouter flag MUST be set to TRUE.
01210         neighbour->isRouter = true;
01211 
01212         //If a cache entry already exists and is updated with a different link-
01213         //layer address the reachability state MUST also be set to STALE.
01214         if (ra->sourceLinkLayerAddress().isUnspecified() == false &&
01215             neighbour->macAddress.equals(ra->sourceLinkLayerAddress()) == false)
01216             neighbour->macAddress = ra->sourceLinkLayerAddress();
01217 
01218         /*- If the address is already present in the host's Default Router List
01219         as a result of a previously-received advertisement, reset its invalidation
01220         timer to the Router Lifetime value in the newly-received advertisement.*/
01221         neighbour->routerExpiryTime = simTime()+ra->routerLifetime();
01222 
01223         /*- If the address is already present in the host's Default Router List
01224         and the received Router Lifetime value is zero, immediately time-out the
01225         entry as specified in Section 6.3.5.*/
01226         if (ra->routerLifetime() == 0)
01227         {
01228             EV << "RA's router lifetime is ZERO. Timing-out entry.\n";
01229             timeoutDefaultRouter(raSrcAddr, ifID);
01230         }
01231     }
01232 
01233     //Paragraph Omitted.
01234 
01235     //If the received Cur Hop Limit value is non-zero the host SHOULD set
01236     //its CurHopLimit variable to the received value.
01237     if (ra->curHopLimit() != 0)
01238     {
01239         EV << "RA's Cur Hop Limit is non-zero. Setting host's Cur Hop Limit to "
01240            << "received value.\n";
01241         ie->ipv6()->setCurHopLimit(ra->curHopLimit());
01242     }
01243 
01244     //If the received Reachable Time value is non-zero the host SHOULD set its
01245     //BaseReachableTime variable to the received value.
01246     if (ra->reachableTime() != 0)
01247     {
01248         EV << "RA's reachable time is non-zero ";
01249         if (ra->reachableTime() != ie->ipv6()->reachableTime())
01250         {
01251             EV << " and RA's and Host's reachable time differ, \nsetting host's base"
01252                << " reachable time to received value.\n";
01253             ie->ipv6()->setBaseReachableTime(ra->reachableTime());
01254             //If the new value differs from the previous value, the host SHOULD
01255             //recompute a new random ReachableTime value.
01256             ie->ipv6()->setReachableTime(ie->ipv6()->generateReachableTime());
01257         }
01258         EV << endl;
01259     }
01260 
01261     //The RetransTimer variable SHOULD be copied from the Retrans Timer field,
01262     //if the received value is non-zero.
01263     if (ra->retransTimer() != 0)
01264     {
01265         EV << "RA's retrans timer is non-zero, copying retrans timer variable.\n";
01266         ie->ipv6()->setRetransTimer(ra->retransTimer());
01267     }
01268 
01269     /*If the MTU option is present, hosts SHOULD copy the option's value into
01270     LinkMTU so long as the value is greater than or equal to the minimum link MTU
01271     [IPv6] and does not exceed the default LinkMTU value specified in the link
01272     type specific document (e.g., [IPv6-ETHER]).*/
01273     //TODO: not done yet
01274 
01275     processRAPrefixInfo(ra, ie);
01276 }

void IPv6NeighbourDiscovery::processRAPacket IPv6RouterAdvertisement ra,
IPv6ControlInfo raCtrlInfo
[protected]
 

01118 {
01119     InterfaceEntry *ie = ift->interfaceAt(raCtrlInfo->interfaceId());
01120 
01121     if (ie->ipv6()->advSendAdvertisements())
01122     {
01123         EV << "Interface is an advertising interface, dropping RA message.\n";
01124         delete ra;
01125         return;
01126     }
01127     else
01128     {
01129         if (validateRAPacket(ra, raCtrlInfo) == false)
01130         {
01131             delete ra;
01132             return;
01133         }
01134         cancelRouterDiscovery(ie);//Cancel router discovery if it is in progress.
01135         EV << "Interface is a host, processing RA.\n";
01136 
01137         processRAForRouterUpdates(ra, raCtrlInfo);//See RFC2461: Section 6.3.4
01138 
01139         //Possible options
01140         MACAddress macAddress = ra->sourceLinkLayerAddress();
01141         uint mtu = ra->MTU();
01142         for (int i = 0; i < ra->prefixInformationArraySize(); i++)
01143         {
01144             IPv6NDPrefixInformation& prefixInfo = ra->prefixInformation(i);
01145             if (prefixInfo.autoAddressConfFlag() == true)//If auto addr conf is set
01146                 processRAPrefixInfoForAddrAutoConf(prefixInfo, ie);//We process prefix Info and form an addr
01147         }
01148     }
01149     delete raCtrlInfo;
01150     delete ra;
01151 }

void IPv6NeighbourDiscovery::processRAPrefixInfo IPv6RouterAdvertisement ra,
InterfaceEntry ie
[protected]
 

01280 {
01281     //Continued from section 6.3.4
01282     /*Prefix Information options that have the "on-link" (L) flag set indicate a
01283     prefix identifying a range of addresses that should be considered on-link.
01284     Note, however, that a Prefix Information option with the on-link flag set to
01285     zero conveys no information concerning on-link determination and MUST NOT be
01286     interpreted to mean that addresses covered by the prefix are off-link. The
01287     only way to cancel a previous on-link indication is to advertise that prefix
01288     with the L-bit set and the Lifetime set to zero. The default behavior (see
01289     Section 5.2) when sending a packet to an address for which no information is
01290     known about the on-link status of the address is to forward the packet to a
01291     default router; the reception of a Prefix Information option with the "on-link "
01292     (L) flag set to zero does not change this behavior. The reasons for an address
01293     being treated as on-link is specified in the definition of "on-link" in
01294     Section 2.1. Prefixes with the on-link flag set to zero would normally have
01295     the autonomous flag set and be used by [ADDRCONF].*/
01296     IPv6NDPrefixInformation prefixInfo;
01297     //For each Prefix Information option
01298     for (int i = 0; i < ra->prefixInformationArraySize(); i++)
01299     {
01300         prefixInfo = ra->prefixInformation(i);
01301         if (!prefixInfo.onlinkFlag()) break;//skip to next prefix option
01302 
01303         //with the on-link flag set, a host does the following:
01304         EV << "Fetching Prefix Information:" << i+1 << " of "
01305            << ra->prefixInformationArraySize() << endl;
01306         uint prefixLength = prefixInfo.prefixLength();
01307         simtime_t validLifetime = prefixInfo.validLifetime();
01308         uint preferredLifetime = prefixInfo.preferredLifetime();
01309         IPv6Address prefix = prefixInfo.prefix();
01310 
01311         //- If the prefix is the link-local prefix, silently ignore the Prefix
01312         //Information option.
01313         if (prefix.isLinkLocal())
01314         {
01315             EV << "Prefix is link-local, ignoring prefix.\n";
01316             return;
01317         }
01318 
01319         //- If the prefix is not already present in the Prefix List,
01320         if (!rt6->isPrefixPresent(prefix)) {
01321             //and the Prefix Information option's Valid Lifetime field is non-zero,
01322             if (validLifetime != 0)
01323             {
01324                 /*create a new entry for the prefix and initialize its invalidation
01325                 timer to the Valid Lifetime value in the Prefix Information option.*/
01326                 rt6->addOrUpdateOnLinkPrefix(prefix, prefixLength, ie->interfaceId(),
01327                     simTime()+validLifetime);
01328             }
01329             /*- If the Prefix Information option's Valid Lifetime field is zero,
01330             and the prefix is not present in the host's Prefix List,
01331             silently ignore the option.*/
01332         }
01333         else
01334         {
01335             /* If the new Lifetime value is zero, time-out the prefix immediately
01336             (see Section 6.3.5).*/
01337             if (validLifetime == 0)
01338             {
01339                 EV << "Prefix Info's valid lifetime is 0, time-out prefix\n";
01340                 rt6->removeOnLinkPrefix(prefix, prefixLength);
01341                 return;
01342             }
01343             /*- If the prefix is already present in the host's Prefix List as
01344             the result of a previously-received advertisement, reset its
01345             invalidation timer to the Valid Lifetime value in the Prefix
01346             Information option.*/
01347             rt6->addOrUpdateOnLinkPrefix(prefix, prefixLength, ie->interfaceId(),
01348                 simTime()+validLifetime);
01349         }
01350 
01351         /*Stateless address autoconfiguration [ADDRCONF] may in some
01352         circumstances increase the Valid Lifetime of a prefix or ignore it
01353         completely in order to prevent a particular denial of service attack.
01354         However, since the effect of the same denial of service targeted at
01355         the on-link prefix list is not catastrophic (hosts would send packets
01356         to a default router and receive a redirect rather than sending
01357         packets directly to a neighbor) the Neighbor Discovery protocol does
01358         not impose such a check on the prefix lifetime values.*/
01359     }
01360 }

void IPv6NeighbourDiscovery::processRAPrefixInfoForAddrAutoConf IPv6NDPrefixInformation prefixInfo,
InterfaceEntry ie
[protected]
 

01364 {
01365     EV << "Processing Prefix Info for address auto-configuration.\n";
01366     IPv6Address prefix = prefixInfo.prefix();
01367     uint prefixLength = prefixInfo.prefixLength();
01368     simtime_t preferredLifetime = prefixInfo.preferredLifetime();
01369     simtime_t validLifetime = prefixInfo.validLifetime();
01370 
01371     //RFC 2461: Section 5.5.3
01372     //First condition tested, the autonomous flag is already set
01373 
01374     //b) If the prefix is the link-local prefix, silently ignore the Prefix
01375     //Information option.
01376     if (prefixInfo.prefix().isLinkLocal() == true)
01377     {
01378         EV << "Prefix is link-local, ignore Prefix Information Option\n";
01379         return;
01380     }
01381 
01382     //c) If the preferred lifetime is greater than the valid lifetime, silently
01383     //ignore the Prefix Information option. A node MAY wish to log a system
01384     //management error in this case.
01385     if (preferredLifetime > validLifetime)
01386     {
01387         EV << "Preferred lifetime is greater than valid lifetime, ignore Prefix Information\n";
01388         return;
01389     }
01390 
01391     bool isPrefixAssignedToInterface = false;
01392     for (int i = 0; i < ie->ipv6()->numAddresses(); i++)
01393     {
01394         if (ie->ipv6()->address(i).matches(prefix, prefixLength) == true)
01395             isPrefixAssignedToInterface = true;
01396     }
01397     /*d) If the prefix advertised does not match the prefix of an address already
01398          in the list, and the Valid Lifetime is not 0, form an address (and add
01399          it to the list) by combining the advertised prefix with the link’s
01400          interface identifier as follows:*/
01401     if (isPrefixAssignedToInterface == false && validLifetime != 0)
01402     {
01403         IPv6Address linkLocalAddress = ie->ipv6()->linkLocalAddress();
01404         ASSERT(linkLocalAddress.isUnspecified() == false);
01405         IPv6Address newAddr = linkLocalAddress.setPrefix(prefix, prefixLength);
01406         //TODO: for now we leave the newly formed address as not tentative,
01407         //according to Greg, we have to always perform DAD for a newly formed address.
01408         EV << "Assigning new address to: " << ie->name() << endl;
01409         ie->ipv6()->assignAddress(newAddr, false, simTime()+validLifetime,
01410             simTime()+preferredLifetime);
01411     }
01412 
01413     //TODO: this is the simplified version.
01414     /*e) If the advertised prefix matches the prefix of an autoconfigured
01415        address (i.e., one obtained via stateless or stateful address
01416        autoconfiguration) in the list of addresses associated with the
01417        interface, the specific action to perform depends on the Valid
01418        Lifetime in the received advertisement and the Lifetime
01419        associated with the previously autoconfigured address (which we
01420        call StoredLifetime in the discussion that follows):
01421 
01422        1) If the received Lifetime is greater than 2 hours or greater
01423           than StoredLifetime, update the stored Lifetime of the
01424           corresponding address.
01425 
01426        2) If the StoredLifetime is less than or equal to 2 hours and the
01427           received Lifetime is less than or equal to StoredLifetime,
01428           ignore the prefix, unless the Router Advertisement from which
01429 
01430           this Prefix Information option was obtained has been
01431           authenticated (e.g., via IPSec [RFC2402]). If the Router
01432           Advertisment was authenticated, the StoredLifetime should be
01433           set to the Lifetime in the received option.
01434 
01435        3) Otherwise, reset the stored Lifetime in the corresponding
01436           address to two hours.*/
01437 
01438 }

void IPv6NeighbourDiscovery::processRDTimeout cMessage *  msg  )  [protected]
 

00906 {
00907     InterfaceEntry *ie = (InterfaceEntry *)msg->contextPointer();
00908     RDEntry *rdEntry = fetchRDEntry(ie);
00909     if (rdEntry->numRSSent < ie->ipv6()->_maxRtrSolicitations())
00910     {
00911         bubble("Sending another RS message.");
00912         createAndSendRSPacket(ie);
00913         rdEntry->numRSSent++;
00914         //Need to find out if this is the last RS we are sending out.
00915         if (rdEntry->numRSSent == ie->ipv6()->_maxRtrSolicitations())
00916             scheduleAt(simTime()+ie->ipv6()->_maxRtrSolicitationDelay(), msg);
00917         else
00918             scheduleAt(simTime()+ie->ipv6()->_rtrSolicitationInterval(), msg);
00919     }
00920     else
00921     {
00922         //RFC 2461, Section 6.3.7
00923         /*If a host sends MAX_RTR_SOLICITATIONS solicitations, and receives no Router
00924         Advertisements after having waited MAX_RTR_SOLICITATION_DELAY seconds after
00925         sending the last solicitation, the host concludes that there are no routers
00926         on the link for the purpose of [ADDRCONF]. However, the host continues to
00927         receive and process Router Advertisements messages in the event that routers
00928         appear on the link.*/
00929         bubble("Max number of RS messages sent");
00930         EV << "No RA messages were received. Assume no routers are on-link";
00931         delete rdEntry;
00932         delete msg;
00933     }
00934 }

void IPv6NeighbourDiscovery::processRedirectPacket IPv6Redirect redirect,
IPv6ControlInfo ctrlInfo
[protected]
 

02145 {
02146     //First we need to extract information from the redirect message
02147     IPv6Address targetAddr = redirect->targetAddress();//Addressed to me
02148     IPv6Address destAddr = redirect->destinationAddress();//new dest addr
02149 
02150     //Optional
02151     MACAddress macAddr = redirect->targetLinkLayerAddress();
02152 }

void IPv6NeighbourDiscovery::processRSPacket IPv6RouterSolicitation rs,
IPv6ControlInfo rsCtrlInfo
[protected]
 

00938 {
00939     if (validateRSPacket(rs, rsCtrlInfo) == false) return;
00940     //Find out which interface the RS message arrived on.
00941     InterfaceEntry *ie = ift->interfaceAt(rsCtrlInfo->interfaceId());
00942     AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie);//fetch advertising interface entry.
00943 
00944     //RFC 2461: Section 6.2.6
00945     //A host MUST silently discard any received Router Solicitation messages.
00946     if (ie->ipv6()->advSendAdvertisements())
00947     {
00948         EV << "This is an advertising interface, processing RS\n";
00949 
00950         if (validateRSPacket(rs, rsCtrlInfo) == false) return;
00951         EV << "RS message validated\n";
00952 
00953         //First we extract RS specific information from the received message
00954         MACAddress macAddr = rs->sourceLinkLayerAddress();
00955         EV << "MAC Address extracted\n";
00956         delete rs;
00957 
00958         /*A router MAY choose to unicast the response directly to the soliciting
00959         host's address (if the solicitation's source address is not the unspecified
00960         address), but the usual case is to multicast the response to the
00961         all-nodes group. In the latter case, the interface's interval timer is
00962         reset to a new random value, as if an unsolicited advertisement had just
00963         been sent(see Section 6.2.4).*/
00964 
00965         /*In all cases, Router Advertisements sent in response to a Router
00966         Solicitation MUST be delayed by a random time between 0 and
00967         MAX_RA_DELAY_TIME seconds. (If a single advertisement is sent in
00968         response to multiple solicitations, the delay is relative to the
00969         first solicitation.)  In addition, consecutive Router Advertisements
00970         sent to the all-nodes multicast address MUST be rate limited to no
00971         more than one advertisement every MIN_DELAY_BETWEEN_RAS seconds.*/
00972 
00973         /*A router might process Router Solicitations as follows:
00974         - Upon receipt of a Router Solicitation, compute a random delay
00975         within the range 0 through MAX_RA_DELAY_TIME. If the computed
00976         value corresponds to a time later than the time the next multicast
00977         Router Advertisement is scheduled to be sent, ignore the random
00978         delay and send the advertisement at the already-scheduled time.*/
00979         cMessage *msg = new cMessage("sendSolicitedRA", MK_SEND_SOL_RTRADV);
00980         msg->setContextPointer(ie);
00981         simtime_t interval = uniform(0,ie->ipv6()->_maxRADelayTime());
00982 
00983         if (interval < advIfEntry->nextScheduledRATime)
00984         {
00985             simtime_t nextScheduledTime;
00986             nextScheduledTime = simTime()+interval;
00987             scheduleAt(nextScheduledTime, msg);
00988             advIfEntry->nextScheduledRATime = nextScheduledTime;
00989         }
00990         //else we ignore the generate interval and send it at the next scheduled time.
00991 
00992         //We need to keep a log here each time an RA is sent. Not implemented yet.
00993         //Assume the first course of action.
00994         /*- If the router sent a multicast Router Advertisement (solicited or
00995         unsolicited) within the last MIN_DELAY_BETWEEN_RAS seconds,
00996         schedule the advertisement to be sent at a time corresponding to
00997         MIN_DELAY_BETWEEN_RAS plus the random value after the previous
00998         advertisement was sent. This ensures that the multicast Router
00999         Advertisements are rate limited.
01000 
01001         - Otherwise, schedule the sending of a Router Advertisement at the
01002         time given by the random value.*/
01003     }
01004     else
01005     {
01006         EV << "This interface is a host, discarding RA message\n";
01007         delete rs;
01008     }
01009 }

void IPv6NeighbourDiscovery::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. 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.

00316 {
00317     Enter_Method("reachabilityConfirmed(%s,if=%d)", neighbour.str().c_str(), interfaceId);
00318     //hmmm... this should only be invoked if a TCP ACK was received and NUD is
00319     //currently being performed on the neighbour where the TCP ACK was received from.
00320 
00321     Neighbour *nce = neighbourCache.lookup(neighbour, interfaceId);
00322 
00323     cMessage *msg = nce->nudTimeoutEvent;
00324     if (msg != NULL)
00325     {
00326         EV << "NUD in progress. Cancelling NUD Timer\n";
00327         bubble("Reachability Confirmed via NUD.");
00328         cancelEvent(msg);
00329         delete msg;
00330     }
00331 
00332     // TODO (see header file for description)
00333     /*A neighbor is considered reachable if the node has recently received
00334     a confirmation that packets sent recently to the neighbor were
00335     received by its IP layer.  Positive confirmation can be gathered in
00336     two ways: hints from upper layer protocols that indicate a connection
00337     is making "forward progress", or receipt of a Neighbor Advertisement
00338     message that is a response to a Neighbor Solicitation message.
00339 
00340     A connection makes "forward progress" if the packets received from a
00341     remote peer can only be arriving if recent packets sent to that peer
00342     are actually reaching it.  In TCP, for example, receipt of a (new)
00343     acknowledgement indicates that previously sent data reached the peer.
00344     Likewise, the arrival of new (non-duplicate) data indicates that
00345 
00346     earlier acknowledgements are being delivered to the remote peer.  If
00347     packets are reaching the peer, they must also be reaching the
00348     sender's next-hop neighbor; thus "forward progress" is a confirmation
00349     that the next-hop neighbor is reachable.  For off-link destinations,
00350     forward progress implies that the first-hop router is reachable.
00351     When available, this upper-layer information SHOULD be used.
00352 
00353     In some cases (e.g., UDP-based protocols and routers forwarding
00354     packets to hosts) such reachability information may not be readily
00355     available from upper-layer protocols.  When no hints are available
00356     and a node is sending packets to a neighbor, the node actively probes
00357     the neighbor using unicast Neighbor Solicitation messages to verify
00358     that the forward path is still working.
00359 
00360     The receipt of a solicited Neighbor Advertisement serves as
00361     reachability confirmation, since advertisements with the Solicited
00362     flag set to one are sent only in response to a Neighbor Solicitation.
00363     Receipt of other Neighbor Discovery messages such as Router
00364     Advertisements and Neighbor Advertisement with the Solicited flag set
00365     to zero MUST NOT be treated as a reachability confirmation.  Receipt
00366     of unsolicited messages only confirm the one-way path from the sender
00367     to the recipient node.  In contrast, Neighbor Unreachability
00368     Detection requires that a node keep track of the reachability of the
00369     forward path to a neighbor from the its perspective, not the
00370     neighbor's perspective.  Note that receipt of a solicited
00371     advertisement indicates that a path is working in both directions.
00372     The solicitation must have reached the neighbor, prompting it to
00373     generate an advertisement.  Likewise, receipt of an advertisement
00374     indicates that the path from the sender to the recipient is working.
00375     However, the latter fact is known only to the recipient; the
00376     advertisement's sender has no direct way of knowing that the
00377     advertisement it sent actually reached a neighbor.  From the
00378     perspective of Neighbor Unreachability Detection, only the
00379     reachability of the forward path is of interest.*/
00380 }

void IPv6NeighbourDiscovery::resetRATimer InterfaceEntry ie  )  [protected]
 

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

01461 {//Not used yet but could be useful later on.-WEI
01462     //Iterate through all RA timers within the Neighbour Discovery module.
01463 /*
01464     for (RATimerList::iterator it=raTimerList.begin(); it != raTimerList.end(); it++)
01465     {
01466         cMessage *msg = (*it);
01467         InterfaceEntry *msgIE = (InterfaceEntry *)msg->contextPointer();
01468         //Find the timer that matches the given Interface Entry.
01469         if (msgIE->outputPort() == ie->outputPort())
01470         {
01471             EV << "Resetting RA timer for port: " << ie->outputPort();
01472             cancelEvent(msg);//Cancel the next scheduled msg.
01473             simtime_t interval
01474                 = uniform(ie->ipv6()->minRtrAdvInterval(),ie->ipv6()->maxRtrAdvInterval());
01475             scheduleAt(simTime()+interval, msg);
01476         }
01477     }
01478 */
01479 }

const MACAddress & 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 NULL 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.

00288 {
00289     Enter_Method("resolveNeighbor(%s,if=%d)", nextHop.str().c_str(), interfaceId);
00290 
00291     Neighbour *nce = neighbourCache.lookup(nextHop, interfaceId);
00292     //InterfaceEntry *ie = ift->interfaceAt(interfaceId);
00293 
00294     if (!nce || nce->reachabilityState==IPv6NeighbourCache::INCOMPLETE)
00295         return MACAddress::UNSPECIFIED_ADDRESS;
00296     else if (nce->reachabilityState==IPv6NeighbourCache::STALE)
00297         initiateNeighbourUnreachabilityDetection(nce);
00298     else if (nce->reachabilityState==IPv6NeighbourCache::REACHABLE &&
00299         simTime() > nce->reachabilityExpires)
00300     {
00301         nce->reachabilityState = IPv6NeighbourCache::STALE;
00302         initiateNeighbourUnreachabilityDetection(nce);
00303     }
00304     else if (nce->reachabilityState!=IPv6NeighbourCache::REACHABLE)
00305     {
00306         //reachability state must be either in DELAY or PROBE
00307         ASSERT(nce->reachabilityState==IPv6NeighbourCache::DELAY ||
00308                nce->reachabilityState==IPv6NeighbourCache::PROBE);
00309         EV << "NUD in progress.\n";
00310     }
00311     //else the entry is REACHABLE and no further action is required here.
00312     return nce->macAddress;
00313 }

IPv6Address IPv6NeighbourDiscovery::selectDefaultRouter int &  outIfID  )  [protected]
 

00493 {
00494     EV << "Selecting default router...\n";
00495     //draft-ietf-ipv6-2461bis-04.txt Section 6.3.6
00496     /*The algorithm for selecting a router depends in part on whether or not a
00497     router is known to be reachable. The exact details of how a node keeps track
00498     of a neighbor's reachability state are covered in Section 7.3.  The algorithm
00499     for selecting a default router is invoked during next-hop determination when
00500     no Destination Cache entry exists for an off-link destination or when
00501     communication through an existing router appears to be failing.  Under normal
00502     conditions, a router would be selected the first time traffic is sent to a
00503     destination, with subsequent traffic for that destination using the same router
00504     as indicated in the Destination Cache modulo any changes to the Destination
00505     Cache caused by Redirect messages.
00506 
00507     The policy for selecting routers from the Default Router List is as
00508     follows:*/
00509 
00510     IPv6Address routerAddr;
00511     //Cycle through all entries in the neighbour cache entry.
00512     for(IPv6NeighbourCache::iterator it=neighbourCache.begin(); it != neighbourCache.end(); it++)
00513     {
00514         Key key = it->first;
00515         Neighbour nce = it->second;
00516         bool routerExpired = false;
00517         if (nce.isDefaultRouter)
00518         {
00519             if (simTime()>nce.routerExpiryTime)
00520             {
00521                 EV << "Found an expired default router. Deleting entry...\n";
00522                 neighbourCache.remove(key.address,key.interfaceID);
00523                 routerExpired = true;
00524             }
00525         }
00526 
00527         if (routerExpired == false)
00528         {
00529             if (nce.reachabilityState == IPv6NeighbourCache::REACHABLE ||
00530                 nce.reachabilityState == IPv6NeighbourCache::STALE ||
00531                 nce.reachabilityState == IPv6NeighbourCache::DELAY)//TODO: Need to improve this algorithm!
00532             {
00533                 EV << "Found a router in the neighbour cache(default router list).\n";
00534                 outIfID = key.interfaceID;
00535                 if (routerExpired == false) return key.address;
00536             }
00537         }
00538     }
00539     EV << "No suitable routers found.\n";
00540 
00541     /*1) Routers that are reachable or probably reachable (i.e., in any state
00542     other than INCOMPLETE) SHOULD be preferred over routers whose reachability
00543     is unknown or suspect (i.e., in the INCOMPLETE state, or for which no Neighbor
00544     Cache entry exists). An implementation may choose to always return the same
00545     router or cycle through the router list in a round-robin fashion as long as
00546     it always returns a reachable or a probably reachable router when one is
00547     available.*/
00548 
00549     /*2) When no routers on the list are known to be reachable or probably
00550     reachable, routers SHOULD be selected in a round-robin fashion, so that
00551     subsequent requests for a default router do not return the same router until
00552     all other routers have been selected.
00553 
00554     Cycling through the router list in this case ensures that all available
00555     routers are actively probed by the Neighbor Unreachability Detection algorithm.
00556     A request for a default router is made in conjunction with the sending of a
00557     packet to a router, and the selected router will be probed for reachability
00558     as a side effect.*/
00559 
00560     outIfID = -1;//nothing found yet
00561     return IPv6Address();
00562 }

void IPv6NeighbourDiscovery::sendPacketToIPv6Module cMessage *  msg,
const IPv6Address destAddr,
const IPv6Address srcAddr,
int  interfaceId
[protected]
 

Create control info and assigns it to a msg. Returns a copy of the msg with the control info.

00703 {
00704     IPv6ControlInfo *controlInfo = new IPv6ControlInfo();
00705     controlInfo->setProtocol(IP_PROT_IPv6_ICMP);
00706     controlInfo->setDestAddr(destAddr);
00707     controlInfo->setSrcAddr(srcAddr);
00708     controlInfo->setHopLimit(255);
00709     controlInfo->setInterfaceId(interfaceId);
00710     msg->setControlInfo(controlInfo);
00711 
00712     send(msg,"toIPv6");
00713 }

void IPv6NeighbourDiscovery::sendPeriodicRA cMessage *  msg  )  [protected]
 

01482 {
01483     InterfaceEntry *ie = (InterfaceEntry *)msg->contextPointer();
01484     AdvIfEntry *advIfEntry = fetchAdvIfEntry(ie);
01485     IPv6Address destAddr = IPv6Address("FF02::1");
01486     createAndSendRAPacket(destAddr, ie);
01487     advIfEntry->numRASent++;
01488     simtime_t nextScheduledTime;
01489 
01490     //RFC 2461, Section 6.2.4
01491     /*Whenever a multicast advertisement is sent from an interface, the timer is
01492     reset to a uniformly-distributed random value between the interface's
01493     configured MinRtrAdvInterval and MaxRtrAdvInterval; expiration of the timer
01494     causes the next advertisement to be sent and a new random value to be chosen.*/
01495     simtime_t interval
01496         = uniform(ie->ipv6()->minRtrAdvInterval(),ie->ipv6()->maxRtrAdvInterval());
01497     nextScheduledTime = simTime() + interval;
01498 
01499     /*For the first few advertisements (up to MAX_INITIAL_RTR_ADVERTISEMENTS)
01500     sent from an interface when it becomes an advertising interface,*/
01501     EV << "Num RA sent is: " << advIfEntry->numRASent << endl;
01502     EV << "maxInitialRtrAdvertisements is: " << ie->ipv6()->_maxInitialRtrAdvertisements() << endl;
01503     if(advIfEntry->numRASent <= ie->ipv6()->_maxInitialRtrAdvertisements())
01504     {
01505         if (interval > ie->ipv6()->_maxInitialRtrAdvertInterval())
01506         {
01507             //if the randomly chosen interval is greater than MAX_INITIAL_RTR_ADVERT_INTERVAL,
01508             //the timer SHOULD be set to MAX_INITIAL_RTR_ADVERT_INTERVAL instead.
01509             nextScheduledTime = simTime() + ie->ipv6()->_maxInitialRtrAdvertInterval();
01510             EV << "Sending initial RA but interval is too long. Using default value." << endl;
01511         }
01512         else
01513             EV << "Sending initial RA. Using randomly generated interval." << endl;
01514     }
01515     EV << "Next scheduled time: " << nextScheduledTime << endl;
01516     advIfEntry->nextScheduledRATime = nextScheduledTime;
01517     ASSERT(nextScheduledTime > simTime());
01518     scheduleAt(nextScheduledTime, msg);
01519 }

void IPv6NeighbourDiscovery::sendQueuedPacketsToIPv6Module Neighbour nce  )  [protected]
 

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

00718 {
00719     MsgPtrVector& pendingPackets = nce->pendingPackets;
00720     while(!pendingPackets.empty())//FIXME: pendingPackets are always empty!!!!
00721     {
00722         MsgPtrVector::iterator i = pendingPackets.begin();
00723         cMessage *msg = (*i);
00724         pendingPackets.erase(i);
00725         pendingQueue.remove(msg);
00726         EV << "Sending queued packet " << msg << endl;
00727         send(msg,"toIPv6");
00728     }
00729 }

void IPv6NeighbourDiscovery::sendSolicitedNA IPv6NeighbourSolicitation ns,
IPv6ControlInfo nsCtrlInfo,
InterfaceEntry ie
[protected]
 

01765 {
01766     IPv6NeighbourAdvertisement *na = new IPv6NeighbourAdvertisement("NApacket");
01767     //RFC 2461: Section 7.2.4
01768     /*A node sends a Neighbor Advertisement in response to a valid Neighbor
01769     Solicitation targeting one of the node's assigned addresses.  The
01770     Target Address of the advertisement is copied from the Target Address
01771     of the solicitation.*/
01772     na->setTargetAddress(ns->targetAddress());
01773 
01774     /*If the solicitation's IP Destination Address is not a multicast address,
01775     the Target Link-Layer Address option MAY be omitted; the neighboring node's
01776     cached value must already be current in order for the solicitation to have
01777     been received. If the solicitation's IP Destination Address is a multicast
01778     address, the Target Link-Layer option MUST be included in the advertisement.*/
01779     na->setTargetLinkLayerAddress(ie->macAddress());//here, we always include the MAC addr.
01780 
01781     /*Furthermore, if the node is a router, it MUST set the Router flag to one;
01782     otherwise it MUST set the flag to zero.*/
01783     na->setRouterFlag(rt6->isRouter());
01784 
01785     /*If the (NS)Target Address is either an anycast address or a unicast
01786     address for which the node is providing proxy service, or the Target
01787     Link-Layer Address option is not included,*/
01788     //TODO:ANYCAST will not be implemented here!
01789     if (ns->sourceLinkLayerAddress().isUnspecified())
01790         //the Override flag SHOULD be set to zero.
01791         na->setOverrideFlag(false);
01792     else
01793         //Otherwise, the Override flag SHOULD be set to one.
01794         na->setOverrideFlag(true);
01795     /*Proper setting of the Override flag ensures that nodes give preference to
01796     non-proxy advertisements, even when received after proxy advertisements, and
01797     also ensures that the first advertisement for an anycast address "wins".*/
01798 
01799     IPv6Address naDestAddr;
01800     //If the source of the solicitation is the unspecified address,
01801     if(nsCtrlInfo->srcAddr().isUnspecified())
01802     {
01803         /*the node MUST set the Solicited flag to zero and multicast the advertisement
01804         to the all-nodes address.*/
01805         na->setSolicitedFlag(false);
01806         naDestAddr = IPv6Address::ALL_NODES_2;
01807     }
01808     else
01809     {
01810         /*Otherwise, the node MUST set the Solicited flag to one and unicast
01811         the advertisement to the Source Address of the solicitation.*/
01812         na->setSolicitedFlag(true);
01813         naDestAddr = nsCtrlInfo->srcAddr();
01814     }
01815 
01816     /*If the Target Address is an anycast address the sender SHOULD delay sending
01817     a response for a random time between 0 and MAX_ANYCAST_DELAY_TIME seconds.*/
01818     /*TODO: More associated complexity for this one. We will have to delay
01819     sending off the solicitation. Perhaps the self message could have a context
01820     pointer pointing to a struct with enough info to create and send a NA packet.*/
01821 
01822     /*Because unicast Neighbor Solicitations are not required to include a
01823     Source Link-Layer Address, it is possible that a node sending a
01824     solicited Neighbor Advertisement does not have a corresponding link-
01825     layer address for its neighbor in its Neighbor Cache.  In such
01826     situations, a node will first have to use Neighbor Discovery to
01827     determine the link-layer address of its neighbor (i.e, send out a
01828     multicast Neighbor Solicitation).*/
01829     //TODO: if above mentioned happens, can addr resolution be performed for ND messages?
01830     //if no link-layer addr exists for unicast addr when sending solicited NA, we should
01831     //add the NA to the list of queued packets. What if we have a list of queued
01832     //packets for different unicast solicitations? each time addr resolution is
01833     //done we should check the destinations of the list of queued packets and send
01834     //off the respective ones.
01835     IPv6Address myIPv6Addr = ie->ipv6()->preferredAddress();
01836     sendPacketToIPv6Module(na, naDestAddr, myIPv6Addr, ie->interfaceId());
01837 }

void IPv6NeighbourDiscovery::sendSolicitedRA cMessage *  msg  )  [protected]
 

01522 {
01523     EV << "Send Solicited RA invoked!\n";
01524     InterfaceEntry *ie = (InterfaceEntry *)msg->contextPointer();
01525     IPv6Address destAddr = IPv6Address("FF02::1");
01526     EV << "Testing condition!\n";
01527     createAndSendRAPacket(destAddr, ie);
01528     delete msg;
01529 }

void IPv6NeighbourDiscovery::sendUnsolicitedNA InterfaceEntry ie  )  [protected]
 

01840 {
01841     //RFC 2461
01842     //Section 7.2.6: Sending Unsolicited Neighbor Advertisements
01843 
01844     /*In some cases a node may be able to determine that its link-layer
01845     address has changed (e.g., hot-swap of an interface card) and may
01846     wish to inform its neighbors of the new link-layer address quickly.
01847     In such cases a node MAY send up to MAX_NEIGHBOR_ADVERTISEMENT
01848     unsolicited Neighbor Advertisement messages to the all-nodes
01849     multicast address.  These advertisements MUST be separated by at
01850     least RetransTimer seconds.
01851 
01852     The Target Address field in the unsolicited advertisement is set to
01853     an IP address of the interface, and the Target Link-Layer Address
01854     option is filled with the new link-layer address.  The Solicited flag
01855     MUST be set to zero, in order to avoid confusing the Neighbor
01856     Unreachability Detection algorithm.  If the node is a router, it MUST
01857     set the Router flag to one; otherwise it MUST set it to zero.  The
01858     Override flag MAY be set to either zero or one.  In either case,
01859     neighboring nodes will immediately change the state of their Neighbor
01860     Cache entries for the Target Address to STALE, prompting them to
01861     verify the path for reachability.  If the Override flag is set to
01862     one, neighboring nodes will install the new link-layer address in
01863     their caches.  Otherwise, they will ignore the new link-layer
01864     address, choosing instead to probe the cached address.
01865 
01866     A node that has multiple IP addresses assigned to an interface MAY
01867     multicast a separate Neighbor Advertisement for each address.  In
01868     such a case the node SHOULD introduce a small delay between the
01869     sending of each advertisement to reduce the probability of the
01870     advertisements being lost due to congestion.
01871 
01872     A proxy MAY multicast Neighbor Advertisements when its link-layer
01873     address changes or when it is configured (by system management or
01874     other mechanisms) to proxy for an address.  If there are multiple
01875     nodes that are providing proxy services for the same set of addresses
01876     the proxies SHOULD provide a mechanism that prevents multiple proxies
01877     from multicasting advertisements for any one address, in order to
01878     reduce the risk of excessive multicast traffic.
01879 
01880     Also, a node belonging to an anycast address MAY multicast
01881     unsolicited Neighbor Advertisements for the anycast address when the
01882     node's link-layer address changes.
01883 
01884     Note that because unsolicited Neighbor Advertisements do not reliably
01885     update caches in all nodes (the advertisements might not be received
01886     by all nodes), they should only be viewed as a performance
01887     optimization to quickly update the caches in most neighbors.  The
01888     Neighbor Unreachability Detection algorithm ensures that all nodes
01889     obtain a reachable link-layer address, though the delay may be
01890     slightly longer.*/
01891 }

void IPv6NeighbourDiscovery::timeoutDefaultRouter const IPv6Address addr,
int  interfaceID
[protected]
 

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.

00581 {
00582     //RFC 2461: Section 6.3.5
00583     /*Whenever the Lifetime of an entry in the Default Router List expires,
00584     that entry is discarded.*/
00585     neighbourCache.remove(addr, interfaceID);
00586 
00587     /*When removing a router from the Default Router list, the node MUST update
00588     the Destination Cache in such a way that all entries using the router perform
00589     next-hop determination again rather than continue sending traffic to the
00590     (deleted) router.*/
00591     rt6->purgeDestCacheEntriesToNeighbour(addr, interfaceID);
00592 }

void IPv6NeighbourDiscovery::timeoutPrefixEntry const IPv6Address destPrefix,
int  prefixLength
[protected]
 

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.

00566 {
00567     //RFC 2461: Section 6.3.5
00568     /*Whenever the invalidation timer expires for a Prefix List entry, that
00569     entry is discarded.*/
00570     rt6->removeOnLinkPrefix(destPrefix, prefixLength);
00571     //hmmm... should the unicast address associated with this prefix be deleted
00572     //as well?-TODO: The address should be timeout/deleted as well!!
00573 
00574     /*No existing Destination Cache entries need be updated, however. Should a
00575     reachability problem arise with an existing Neighbor Cache entry, Neighbor
00576     Unreachability Detection will perform any needed recovery.*/
00577 }

bool IPv6NeighbourDiscovery::validateNAPacket IPv6NeighbourAdvertisement na,
IPv6ControlInfo naCtrlInfo
[protected]
 

01938 {
01939     bool result = true;//adopt optimistic approach
01940 
01941     //RFC 2461:7.1.2 Validation of Neighbor Advertisments(some checks are omitted)
01942     //A node MUST silently discard any received Neighbor Advertisment messages
01943     //that do not satisfy all of the following validity checks:
01944 
01945     //- The IP Hop Limit field has a value of 255, i.e., the packet
01946     //  could not possibly have been forwarded by a router.
01947     if (naCtrlInfo->hopLimit() != 255)
01948     {
01949         EV << "Hop Limit is not 255! NA validation failed!\n";
01950         result = false;
01951     }
01952 
01953     //- Target Address is not a multicast address.
01954     if (na->targetAddress().isMulticast() == true)
01955     {
01956         EV << "Target Address is a multicast address! NA validation failed!\n";
01957         result = false;
01958     }
01959 
01960     //- If the IP Destination Address is a multicast address the Solicited flag
01961     //  is zero.
01962     if (naCtrlInfo->destAddr().isMulticast())
01963     {
01964         if (na->solicitedFlag() == true)
01965         {
01966             EV << "Dest Address is multicast address but solicted flag is 0!\n";
01967             result = false;
01968         }
01969     }
01970 
01971     if (result == true) bubble("NA validation passed.");
01972     else bubble("NA validation failed.");
01973     return result;
01974 }

bool IPv6NeighbourDiscovery::validateNSPacket IPv6NeighbourSolicitation ns,
IPv6ControlInfo nsCtrlInfo
[protected]
 

01632 {
01633     bool result = true;
01634     /*RFC 2461:7.1.1. Validation of Neighbor Solicitations(some checks are omitted)
01635     A node MUST silently discard any received Neighbor Solicitation
01636     messages that do not satisfy all of the following validity checks:*/
01637     //- The IP Hop Limit field has a value of 255, i.e., the packet
01638     //could not possibly have been forwarded by a router.
01639     if (nsCtrlInfo->hopLimit() != 255)
01640     {
01641         EV << "Hop limit is not 255! NS validation failed!\n";
01642         result = false;
01643     }
01644     //- Target Address is not a multicast address.
01645     if (ns->targetAddress().isMulticast() == true)
01646     {
01647         EV << "Target address is a multicast address! NS validation failed!\n";
01648         result = false;
01649     }
01650     //- If the IP source address is the unspecified address,
01651     if (nsCtrlInfo->srcAddr().isUnspecified())
01652     {
01653         EV << "Source Address is unspecified\n";
01654         //the IP destination address is a solicited-node multicast address.
01655         if (nsCtrlInfo->destAddr().matches(IPv6Address::SOLICITED_NODE_PREFIX,104) == false)
01656         {
01657             EV << " but IP dest address is not a solicited-node multicast address! NS validation failed!\n";
01658             result = false;
01659         }
01660         //there is no source link-layer address option in the message.
01661         else if (ns->sourceLinkLayerAddress().isUnspecified() == false)
01662         {
01663             EV << " but Source link-layer address is not empty! NS validation failed!\n";
01664             result = false;
01665         }
01666         else
01667             EV << "NS Validation Passed\n";
01668     }
01669 
01670     return result;
01671 }

bool IPv6NeighbourDiscovery::validateRAPacket IPv6RouterAdvertisement ra,
IPv6ControlInfo raCtrlInfo
[protected]
 

01533 {
01534     bool result = true;
01535 
01536     //RFC 2461: Section 6.1.2 Validation of Router Advertisement Messages
01537     /*A node MUST silently discard any received Router Advertisement
01538     messages that do not satisfy all of the following validity checks:*/
01539     raCtrlInfo->srcAddr();
01540     //- IP Source Address is a link-local address.  Routers must use
01541     //  their link-local address as the source for Router Advertisement
01542     //  and Redirect messages so that hosts can uniquely identify
01543     //  routers.
01544     if (raCtrlInfo->srcAddr().isLinkLocal() == false)
01545     {
01546         EV << "RA source address is not link-local. RA validation failed!\n";
01547         result = false;
01548     }
01549 
01550     //- The IP Hop Limit field has a value of 255, i.e., the packet
01551     //  could not possibly have been forwarded by a router.
01552     if (raCtrlInfo->hopLimit() != 255)
01553     {
01554         EV << "Hop limit is not 255! RA validation failed!\n";
01555         result = false;
01556     }
01557 
01558     //- ICMP Code is 0.
01559     if (raCtrlInfo->protocol() != IP_PROT_IPv6_ICMP)
01560     {
01561         EV << "ICMP Code is not 0! RA validation failed!\n";
01562         result = false;
01563     }
01564 
01565     return result;
01566 }

bool IPv6NeighbourDiscovery::validateRSPacket IPv6RouterSolicitation rs,
IPv6ControlInfo rsCtrlInfo
[protected]
 

01013 {
01014     bool result = true;
01015     /*6.1.1.  Validation of Router Solicitation Messages
01016     A router MUST silently discard any received Router Solicitation
01017     messages that do not satisfy all of the following validity checks:
01018 
01019     - The IP Hop Limit field has a value of 255, i.e., the packet
01020     could not possibly have been forwarded by a router.*/
01021     if (rsCtrlInfo->hopLimit() != 255)
01022     {
01023         EV << "Hop limit is not 255! RS validation failed!\n";
01024         result = false;
01025     }
01026     //- ICMP Code is 0.
01027     if (rsCtrlInfo->protocol() != IP_PROT_IPv6_ICMP)
01028     {
01029         EV << "ICMP Code is not 0! RS validation failed!\n";
01030         result = false;
01031     }
01032     //- If the IP source address is the unspecified address, there is no
01033     //source link-layer address option in the message.
01034     if (rsCtrlInfo->srcAddr().isUnspecified())
01035     {
01036         EV << "IP source address is unspecified\n";
01037         if (rs->sourceLinkLayerAddress().isUnspecified() == false)
01038         {
01039             EV << " but source link layer address is provided. RS validation failed!\n";
01040         }
01041     }
01042     return result;
01043 }


Member Data Documentation

AdvIfList IPv6NeighbourDiscovery::advIfList [protected]
 

DADList IPv6NeighbourDiscovery::dadList [protected]
 

ICMPv6* IPv6NeighbourDiscovery::icmpv6 [protected]
 

InterfaceTable* IPv6NeighbourDiscovery::ift [protected]
 

IPv6NeighbourCache IPv6NeighbourDiscovery::neighbourCache [protected]
 

cQueue IPv6NeighbourDiscovery::pendingQueue [protected]
 

RATimerList IPv6NeighbourDiscovery::raTimerList [protected]
 

RDList IPv6NeighbourDiscovery::rdList [protected]
 

RoutingTable6* IPv6NeighbourDiscovery::rt6 [protected]
 


The documentation for this class was generated from the following files:
Generated on Thu Oct 19 18:22:26 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0