#include <IPv6NeighbourDiscovery.h>
typedef std::set<AdvIfEntry*> IPv6NeighbourDiscovery::AdvIfList [protected] |
typedef std::set<DADEntry*> IPv6NeighbourDiscovery::DADList [protected] |
typedef std::vector<cMessage*> IPv6NeighbourDiscovery::MsgPtrVector |
typedef std::set<cMessage*> IPv6NeighbourDiscovery::RATimerList [protected] |
typedef std::set<RDEntry*> IPv6NeighbourDiscovery::RDList [protected] |
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 }
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::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] |
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] |
01978 { 01979 MACAddress naMacAddr = na->targetLinkLayerAddress(); 01980 bool naRouterFlag = na->routerFlag(); 01981 bool naSolicitedFlag = na->solicitedFlag(); 01982 const Key *nceKey = nce->nceKey; 01983 InterfaceEntry *ie = ift->interfaceAt(nceKey->interfaceID); 01984 01985 /*If the target's neighbour Cache entry is in the INCOMPLETE state when the 01986 advertisement is received, one of two things happens.*/ 01987 if (naMacAddr.isUnspecified()) 01988 { 01989 /*If the link layer has addresses and no Target Link-Layer address option 01990 is included, the receiving node SHOULD silently discard the received 01991 advertisement.*/ 01992 EV << "No MAC Address specified in NA. Ignoring NA\n"; 01993 return; 01994 } 01995 else 01996 { 01997 //Otherwise, the receiving node performs the following steps: 01998 //- It records the link-layer address in the neighbour Cache entry. 01999 EV << "ND is updating Neighbour Cache Entry.\n"; 02000 nce->macAddress = naMacAddr; 02001 02002 //- If the advertisement's Solicited flag is set, the state of the 02003 // entry is set to REACHABLE, otherwise it is set to STALE. 02004 if (naSolicitedFlag == true) 02005 { 02006 nce->reachabilityState = IPv6NeighbourCache::REACHABLE; 02007 EV << "Reachability confirmed through successful Addr Resolution.\n"; 02008 nce->reachabilityExpires = simTime() + ie->ipv6()->_reachableTime(); 02009 } 02010 else 02011 nce->reachabilityState = IPv6NeighbourCache::STALE; 02012 02013 //- It sets the IsRouter flag in the cache entry based on the Router 02014 // flag in the received advertisement. 02015 nce->isRouter = naRouterFlag; 02016 02017 //- It sends any packets queued for the neighbour awaiting address 02018 // resolution. 02019 sendQueuedPacketsToIPv6Module(nce); 02020 cancelEvent(nce->arTimer); 02021 } 02022 }
void IPv6NeighbourDiscovery::processNAForOtherNCEStates | ( | IPv6NeighbourAdvertisement * | na, | |
IPv6NeighbourCache::Neighbour * | nce | |||
) | [protected] |
02026 { 02027 bool naRouterFlag = na->routerFlag(); 02028 bool naSolicitedFlag = na->solicitedFlag(); 02029 bool naOverrideFlag = na->overrideFlag(); 02030 MACAddress naMacAddr = na->targetLinkLayerAddress(); 02031 const Key *nceKey = nce->nceKey; 02032 InterfaceEntry *ie = ift->interfaceAt(nceKey->interfaceID); 02033 02034 /*draft-ietf-ipv6-2461bis-04 02035 Section 7.2.5: Receipt of Neighbour Advertisements 02036 If the target's Neighbor Cache entry is in any state other than INCOMPLETE 02037 when the advertisement is received, the following actions take place:*/ 02038 02039 if (naOverrideFlag == false && !(naMacAddr.equals(nce->macAddress)) 02040 && !(naMacAddr.isUnspecified())) 02041 { 02042 EV << "NA override is FALSE and NA MAC addr is different.\n"; 02043 //I. If the Override flag is clear and the supplied link-layer address 02044 // differs from that in the cache, then one of two actions takes place: 02045 //(Note: An unspecified MAC should not be compared with the NCE's mac!) 02046 //a. If the state of the entry is REACHABLE, 02047 if (nce->reachabilityState == IPv6NeighbourCache::REACHABLE) 02048 { 02049 EV << "NA mac is different. Change NCE state from REACHABLE to STALE\n"; 02050 //set it to STALE, but do not update the entry in any other way. 02051 nce->reachabilityState = IPv6NeighbourCache::STALE; 02052 } 02053 else 02054 //b. Otherwise, the received advertisement should be ignored and 02055 //MUST NOT update the cache. 02056 EV << "NCE is not in REACHABLE state. Ignore NA.\n"; 02057 } 02058 else if (naOverrideFlag == true || naMacAddr.equals(nce->macAddress) 02059 || naMacAddr.isUnspecified()) 02060 { 02061 EV << "NA override flag is TRUE. or Advertised MAC is same as NCE's. or" 02062 << " NA MAC is not specified.\n"; 02063 /*II. If the Override flag is set, or the supplied link-layer address 02064 is the same as that in the cache, or no Target Link-layer address 02065 option was supplied, the received advertisement MUST update the 02066 Neighbor Cache entry as follows:*/ 02067 02068 /*- The link-layer address in the Target Link-Layer Address option 02069 MUST be inserted in the cache (if one is supplied and is 02070 Different than the already recorded address).*/ 02071 if (!(naMacAddr.isUnspecified()) && 02072 !(naMacAddr.equals(nce->macAddress))) 02073 { 02074 EV << "Updating NCE's MAC addr with NA's.\n"; 02075 nce->macAddress = naMacAddr; 02076 } 02077 02078 //- If the Solicited flag is set, 02079 if (naSolicitedFlag == true) 02080 { 02081 EV << "Solicited Flag is TRUE. Set NCE state to REACHABLE.\n"; 02082 //the state of the entry MUST be set to REACHABLE. 02083 nce->reachabilityState = IPv6NeighbourCache::REACHABLE; 02084 //We have to cancel the NUD self timer message if there is one. 02085 cMessage *msg = nce->nudTimeoutEvent; 02086 if (msg != NULL) 02087 { 02088 EV << "NUD in progress. Cancelling NUD Timer\n"; 02089 bubble("Reachability Confirmed via NUD."); 02090 nce->reachabilityExpires = simTime() + ie->ipv6()->_reachableTime(); 02091 cancelEvent(msg); 02092 delete msg; 02093 } 02094 } 02095 else 02096 { 02097 //If the Solicited flag is zero 02098 EV << "Solicited Flag is FALSE.\n"; 02099 //and the link layer address was updated with a different address 02100 if (!(naMacAddr.equals(nce->macAddress))) 02101 { 02102 EV << "NA's MAC is different from NCE's.Set NCE state to STALE\n"; 02103 //the state MUST be set to STALE. 02104 nce->reachabilityState = IPv6NeighbourCache::STALE; 02105 } 02106 else 02107 //Otherwise, the entry's state remains unchanged. 02108 EV << "NA's MAC is the same as NCE's. State remains unchanged.\n"; 02109 } 02110 //(Next paragraph with explanation is omitted.-WEI) 02111 02112 /*- The IsRouter flag in the cache entry MUST be set based on the 02113 Router flag in the received advertisement.*/ 02114 EV << "Updating NCE's router flag to " << naRouterFlag << endl; 02115 nce->isRouter = naRouterFlag; 02116 02117 //TODO: To be implemented 02118 /*In those cases where the IsRouter flag changes from TRUE to FALSE as a 02119 result of this update, the node MUST remove that router from the Default 02120 Router List and update the Destination Cache entries for all destinations 02121 using that neighbor as a router as specified in Section 7.3.3. This is 02122 needed to detect when a node that is used as a router stops forwarding 02123 packets due to being configured as a host.*/ 02124 } 02125 }
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 }
AdvIfList IPv6NeighbourDiscovery::advIfList [protected] |
DADList IPv6NeighbourDiscovery::dadList [protected] |
ICMPv6* IPv6NeighbourDiscovery::icmpv6 [protected] |
InterfaceTable* IPv6NeighbourDiscovery::ift [protected] |
cQueue IPv6NeighbourDiscovery::pendingQueue [protected] |
RATimerList IPv6NeighbourDiscovery::raTimerList [protected] |
RDList IPv6NeighbourDiscovery::rdList [protected] |
RoutingTable6* IPv6NeighbourDiscovery::rt6 [protected] |