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

OSPF::HelloHandler Class Reference

#include <HelloHandler.h>

Inheritance diagram for OSPF::HelloHandler:

OSPF::IMessageHandler List of all members.

Public Member Functions

 HelloHandler (Router *containingRouter)
void ProcessPacket (OSPFPacket *packet, Interface *intf, Neighbor *unused=NULL)

Constructor & Destructor Documentation

OSPF::HelloHandler::HelloHandler Router containingRouter  ) 
 

00008                                                             :
00009     OSPF::IMessageHandler (containingRouter)
00010 {
00011 }


Member Function Documentation

void OSPF::HelloHandler::ProcessPacket OSPFPacket *  packet,
Interface intf,
Neighbor unused = NULL
 

00014 {
00015     OSPFHelloPacket* helloPacket         = check_and_cast<OSPFHelloPacket*> (packet);
00016     bool             rebuildRoutingTable = false;
00017 
00018     /* The values of the Network Mask, HelloInterval,
00019        and RouterDeadInterval fields in the received Hello packet must
00020        be checked against the values configured for the receiving
00021        interface.  Any mismatch causes processing to stop and the
00022        packet to be dropped.
00023      */
00024     if ((intf->GetHelloInterval () == helloPacket->getHelloInterval ()) &&
00025         (intf->GetRouterDeadInterval () == helloPacket->getRouterDeadInterval ()))
00026     {
00027         OSPF::Interface::OSPFInterfaceType interfaceType = intf->GetType ();
00028         /* There is one exception to the above rule: on point-to-point
00029            networks and on virtual links, the Network Mask in the received
00030            Hello Packet should be ignored.
00031          */
00032         if (!((interfaceType != OSPF::Interface::PointToPoint) &&
00033               (interfaceType != OSPF::Interface::Virtual) &&
00034               (intf->GetAddressRange ().mask != IPv4AddressFromULong (helloPacket->getNetworkMask ().getInt ()))
00035              )
00036            )
00037         {
00038             /* The setting of the E-bit found in the Hello Packet's Options field must match this area's
00039                ExternalRoutingCapability.
00040              */
00041             if (intf->GetArea ()->GetExternalRoutingCapability () == helloPacket->getOptions ().E_ExternalRoutingCapability) {
00042                 IPControlInfo*      controlInfo             = check_and_cast<IPControlInfo *> (helloPacket->controlInfo ());
00043                 OSPF::IPv4Address   srcAddress              = IPv4AddressFromULong (controlInfo->srcAddr ().getInt ());
00044                 bool                neighborChanged         = false;
00045                 bool                neighborsDRStateChanged = false;
00046                 bool                drChanged               = false;
00047                 bool                backupSeen              = false;
00048                 OSPF::Neighbor*     neighbor;
00049 
00050                 /* If the receiving interface connects to a broadcast, Point-to-
00051                    MultiPoint or NBMA network the source is identified by the IP
00052                    source address found in the Hello's IP header.
00053                  */
00054                 if ((interfaceType == OSPF::Interface::Broadcast) ||
00055                     (interfaceType == OSPF::Interface::PointToMultiPoint) ||
00056                     (interfaceType == OSPF::Interface::NBMA))
00057                 {
00058                     neighbor = intf->GetNeighborByAddress (srcAddress);
00059                 } else {
00060                     /* If the receiving interface connects to a point-to-point link or a virtual link,
00061                        the source is identified by the Router ID found in the Hello's OSPF packet header.
00062                      */
00063                     neighbor = intf->GetNeighborByID (helloPacket->getRouterID ().getInt ());
00064                 }
00065 
00066                 if (neighbor != NULL) {
00067                     router->GetMessageHandler ()->PrintEvent ("Hello packet received", intf, neighbor);
00068 
00069                     IPv4Address                 designatedAddress   = neighbor->GetDesignatedRouter ().ipInterfaceAddress;
00070                     IPv4Address                 backupAddress       = neighbor->GetBackupDesignatedRouter ().ipInterfaceAddress;
00071                     char                        newPriority         = helloPacket->getRouterPriority ();
00072                     unsigned long               source              = controlInfo->srcAddr ().getInt ();
00073                     unsigned long               newDesignatedRouter = helloPacket->getDesignatedRouter ().getInt ();
00074                     unsigned long               newBackupRouter     = helloPacket->getBackupDesignatedRouter ().getInt ();
00075                     OSPF::DesignatedRouterID    dRouterID;
00076 
00077                     if ((interfaceType == OSPF::Interface::Virtual) &&
00078                         (neighbor->GetState () == OSPF::Neighbor::DownState))
00079                     {
00080                         neighbor->SetPriority (helloPacket->getRouterPriority ());
00081                         neighbor->SetRouterDeadInterval (helloPacket->getRouterDeadInterval ());
00082                     }
00083 
00084                     /* If a change in the neighbor's Router Priority field
00085                        was noted, the receiving interface's state machine is
00086                        scheduled with the event NeighborChange.
00087                      */
00088                     if (neighbor->GetPriority () != newPriority) {
00089                         neighborChanged = true;
00090                     }
00091 
00092                     /* If the neighbor is both declaring itself to be Designated
00093                        Router (Hello Packet's Designated Router field = Neighbor IP
00094                        address) and the Backup Designated Router field in the
00095                        packet is equal to 0.0.0.0 and the receiving interface is in
00096                        state Waiting, the receiving interface's state machine is
00097                        scheduled with the event BackupSeen.
00098                      */
00099                     if ((newDesignatedRouter == source) &&
00100                         (newBackupRouter == 0) &&
00101                         (intf->GetState () == OSPF::Interface::WaitingState))
00102                     {
00103                         backupSeen = true;
00104                     } else {
00105                         /* Otherwise, if the neighbor is declaring itself to be Designated Router and it
00106                            had not previously, or the neighbor is not declaring itself
00107                            Designated Router where it had previously, the receiving
00108                            interface's state machine is scheduled with the event
00109                            NeighborChange.
00110                          */
00111                         if (((newDesignatedRouter == source) &&
00112                              (newDesignatedRouter != ULongFromIPv4Address (designatedAddress))) ||
00113                             ((newDesignatedRouter != source) &&
00114                              (source == ULongFromIPv4Address (designatedAddress))))
00115                         {
00116                             neighborChanged = true;
00117                             neighborsDRStateChanged = true;
00118                         }
00119                     }
00120 
00121                     /* If the neighbor is declaring itself to be Backup Designated
00122                        Router (Hello Packet's Backup Designated Router field =
00123                        Neighbor IP address) and the receiving interface is in state
00124                        Waiting, the receiving interface's state machine is
00125                        scheduled with the event BackupSeen.
00126                      */
00127                     if ((newBackupRouter == source) &&
00128                         (intf->GetState () == OSPF::Interface::WaitingState))
00129                     {
00130                         backupSeen = true;
00131                     } else {
00132                         /* Otherwise, if the neighbor is declaring itself to be Backup Designated Router
00133                            and it had not previously, or the neighbor is not declaring
00134                            itself Backup Designated Router where it had previously, the
00135                            receiving interface's state machine is scheduled with the
00136                            event NeighborChange.
00137                          */
00138                         if (((newBackupRouter == source) &&
00139                              (newBackupRouter != ULongFromIPv4Address (backupAddress))) ||
00140                             ((newBackupRouter != source) &&
00141                              (source == ULongFromIPv4Address (backupAddress))))
00142                         {
00143                             neighborChanged = true;
00144                         }
00145                     }
00146 
00147                     neighbor->SetNeighborID (helloPacket->getRouterID ().getInt ());
00148                     neighbor->SetPriority (newPriority);
00149                     neighbor->SetAddress (srcAddress);
00150                     dRouterID.routerID = newDesignatedRouter;
00151                     dRouterID.ipInterfaceAddress = IPv4AddressFromULong (newDesignatedRouter);
00152                     if (newDesignatedRouter != ULongFromIPv4Address (designatedAddress)) {
00153                         designatedAddress = dRouterID.ipInterfaceAddress;
00154                         drChanged = true;
00155                     }
00156                     neighbor->SetDesignatedRouter (dRouterID);
00157                     dRouterID.routerID = newBackupRouter;
00158                     dRouterID.ipInterfaceAddress = IPv4AddressFromULong (newBackupRouter);
00159                     if (newBackupRouter != ULongFromIPv4Address (backupAddress)) {
00160                         backupAddress = dRouterID.ipInterfaceAddress;
00161                         drChanged = true;
00162                     }
00163                     neighbor->SetBackupDesignatedRouter (dRouterID);
00164                     if (drChanged) {
00165                         neighbor->SetUpDesignatedRouters (false);
00166                     }
00167 
00168                     /* If the neighbor router's Designated or Backup Designated Router
00169                        has changed it's necessary to look up the Router IDs belonging to the
00170                        new addresses.
00171                      */
00172                     if (!neighbor->DesignatedRoutersAreSetUp ()) {
00173                         OSPF::Neighbor* designated = intf->GetNeighborByAddress (designatedAddress);
00174                         OSPF::Neighbor* backup     = intf->GetNeighborByAddress (backupAddress);
00175 
00176                         if (designated != NULL) {
00177                             dRouterID.routerID = designated->GetNeighborID ();
00178                             dRouterID.ipInterfaceAddress = designated->GetAddress ();
00179                             neighbor->SetDesignatedRouter (dRouterID);
00180                         }
00181                         if (backup != NULL) {
00182                             dRouterID.routerID = backup->GetNeighborID ();
00183                             dRouterID.ipInterfaceAddress = backup->GetAddress ();
00184                             neighbor->SetBackupDesignatedRouter (dRouterID);
00185                         }
00186                         if ((designated != NULL) && (backup != NULL)) {
00187                             neighbor->SetUpDesignatedRouters (true);
00188                         }
00189                     }
00190                 } else {
00191                     OSPF::DesignatedRouterID    dRouterID;
00192                     bool                        designatedSetUp = false;
00193                     bool                        backupSetUp     = false;
00194 
00195                     neighbor = new OSPF::Neighbor (helloPacket->getRouterID ().getInt ());
00196                     neighbor->SetPriority (helloPacket->getRouterPriority ());
00197                     neighbor->SetAddress (srcAddress);
00198                     neighbor->SetRouterDeadInterval (helloPacket->getRouterDeadInterval ());
00199 
00200                     router->GetMessageHandler ()->PrintEvent ("Hello packet received", intf, neighbor);
00201 
00202                     dRouterID.routerID = helloPacket->getDesignatedRouter ().getInt ();
00203                     dRouterID.ipInterfaceAddress = IPv4AddressFromULong (dRouterID.routerID);
00204 
00205                     OSPF::Neighbor* designated = intf->GetNeighborByAddress (dRouterID.ipInterfaceAddress);
00206 
00207                     // Get the Designated Router ID from the corresponding Neighbor Object.
00208                     if (designated != NULL) {
00209                         if (designated->GetNeighborID () != dRouterID.routerID) {
00210                             dRouterID.routerID = designated->GetNeighborID ();
00211                         }
00212                         designatedSetUp = true;
00213                     }
00214                     neighbor->SetDesignatedRouter (dRouterID);
00215 
00216                     dRouterID.routerID = helloPacket->getBackupDesignatedRouter ().getInt ();
00217                     dRouterID.ipInterfaceAddress = IPv4AddressFromULong (dRouterID.routerID);
00218 
00219                     OSPF::Neighbor* backup = intf->GetNeighborByAddress (dRouterID.ipInterfaceAddress);
00220 
00221                     // Get the Backup Designated Router ID from the corresponding Neighbor Object.
00222                     if (backup != NULL) {
00223                         if (backup->GetNeighborID () != dRouterID.routerID) {
00224                             dRouterID.routerID = backup->GetNeighborID ();
00225                         }
00226                         backupSetUp = true;
00227                     }
00228                     neighbor->SetBackupDesignatedRouter (dRouterID);
00229                     if (designatedSetUp && backupSetUp) {
00230                         neighbor->SetUpDesignatedRouters (true);
00231                     }
00232                     intf->AddNeighbor (neighbor);
00233                 }
00234 
00235                 neighbor->ProcessEvent (OSPF::Neighbor::HelloReceived);
00236                 if ((interfaceType == OSPF::Interface::NBMA) &&
00237                     (intf->GetRouterPriority () == 0) &&
00238                     (neighbor->GetState () >= OSPF::Neighbor::InitState))
00239                 {
00240                     intf->SendHelloPacket (neighbor->GetAddress ());
00241                 }
00242 
00243                 unsigned long   interfaceAddress       = ULongFromIPv4Address (intf->GetAddressRange ().address);
00244                 unsigned int    neighborsNeighborCount = helloPacket->getNeighborArraySize ();
00245                 unsigned int    i;
00246                 /* The list of neighbors contained in the Hello Packet is
00247                    examined.  If the router itself appears in this list, the
00248                    neighbor state machine should be executed with the event TwoWayReceived.
00249                  */
00250                 for (i = 0; i < neighborsNeighborCount; i++) {
00251                     if (helloPacket->getNeighbor (i).getInt () == interfaceAddress) {
00252                         neighbor->ProcessEvent (OSPF::Neighbor::TwoWayReceived);
00253                         break;
00254                     }
00255                 }
00256                 /* Otherwise, the neighbor state machine should
00257                    be executed with the event OneWayReceived, and the processing
00258                    of the packet stops.
00259                  */
00260                 if (i == neighborsNeighborCount) {
00261                     neighbor->ProcessEvent (OSPF::Neighbor::OneWayReceived);
00262                 }
00263 
00264                 if (neighborChanged) {
00265                     intf->ProcessEvent (OSPF::Interface::NeighborChange);
00266                     /* In some cases neighbors get stuck in TwoWay state after a DR
00267                        or Backup change. (CalculateDesignatedRouter runs before the
00268                        neighbors' signal of DR change + this router does not become
00269                        neither DR nor backup -> IsAdjacencyOK does not get called.)
00270                        So to make it work (workaround) we'll call IsAdjacencyOK for
00271                        all neighbors in TwoWay state from here. This shouldn't break
00272                        anything because if the neighbor state doesn't have to change
00273                        then NeedAdjacency returns false and nothing happnes in
00274                        IsAdjacencyOK.
00275                      */
00276                     unsigned int neighborCount = intf->GetNeighborCount ();
00277                     for (i = 0; i < neighborCount; i++) {
00278                         OSPF::Neighbor* stuckNeighbor = intf->GetNeighbor (i);
00279                         if (stuckNeighbor->GetState () == OSPF::Neighbor::TwoWayState) {
00280                             stuckNeighbor->ProcessEvent (OSPF::Neighbor::IsAdjacencyOK);
00281                         }
00282                     }
00283 
00284                     if (neighborsDRStateChanged) {
00285                         OSPF::RouterLSA* routerLSA = intf->GetArea ()->FindRouterLSA (router->GetRouterID ());
00286 
00287                         if (routerLSA != NULL) {
00288                             long sequenceNumber = routerLSA->getHeader ().getLsSequenceNumber ();
00289                             if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00290                                 routerLSA->getHeader ().setLsAge (MAX_AGE);
00291                                 intf->GetArea ()->FloodLSA (routerLSA);
00292                                 routerLSA->IncrementInstallTime ();
00293                             } else {
00294                                 OSPF::RouterLSA* newLSA = intf->GetArea ()->OriginateRouterLSA ();
00295 
00296                                 newLSA->getHeader ().setLsSequenceNumber (sequenceNumber + 1);
00297                                 newLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
00298                                 rebuildRoutingTable |= routerLSA->Update (newLSA);
00299                                 delete newLSA;
00300 
00301                                 intf->GetArea ()->FloodLSA (routerLSA);
00302                             }
00303                         }
00304                     }
00305                 }
00306 
00307                 if (backupSeen) {
00308                     intf->ProcessEvent (OSPF::Interface::BackupSeen);
00309                 }
00310             }
00311         }
00312     }
00313 
00314     if (rebuildRoutingTable) {
00315         router->RebuildRoutingTable ();
00316     }
00317 }


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:25 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1