Public Member Functions | Private Member Functions | Private Attributes

OSPF::Area Class Reference

#include <OSPFArea.h>

List of all members.

Public Member Functions

 Area (AreaID id=BackboneAreaID)
virtual ~Area (void)
void SetAreaID (AreaID areaId)
AreaID GetAreaID (void) const
void AddAddressRange (IPv4AddressRange addressRange, bool advertise)
unsigned int GetAddressRangeCount (void) const
IPv4AddressRange GetAddressRange (unsigned int index) const
void AddHostRoute (HostRouteParameters &hostRouteParameters)
void SetTransitCapability (bool transit)
bool GetTransitCapability (void) const
void SetExternalRoutingCapability (bool flooded)
bool GetExternalRoutingCapability (void) const
void SetStubDefaultCost (Metric cost)
Metric GetStubDefaultCost (void) const
void SetSPFTreeRoot (RouterLSA *root)
RouterLSAGetSPFTreeRoot (void)
const RouterLSAGetSPFTreeRoot (void) const
void SetRouter (Router *router)
RouterGetRouter (void)
const RouterGetRouter (void) const
unsigned long GetRouterLSACount (void) const
RouterLSAGetRouterLSA (unsigned long i)
const RouterLSAGetRouterLSA (unsigned long i) const
unsigned long GetNetworkLSACount (void) const
NetworkLSAGetNetworkLSA (unsigned long i)
const NetworkLSAGetNetworkLSA (unsigned long i) const
unsigned long GetSummaryLSACount (void) const
SummaryLSAGetSummaryLSA (unsigned long i)
const SummaryLSAGetSummaryLSA (unsigned long i) const
bool ContainsAddress (IPv4Address address) const
bool HasAddressRange (IPv4AddressRange addressRange) const
IPv4AddressRange GetContainingAddressRange (IPv4AddressRange addressRange, bool *advertise=NULL) const
void AddInterface (Interface *intf)
InterfaceGetInterface (unsigned char ifIndex)
InterfaceGetInterface (IPv4Address address)
bool HasVirtualLink (AreaID withTransitArea) const
InterfaceFindVirtualLink (RouterID routerID)
bool InstallRouterLSA (OSPFRouterLSA *lsa)
bool InstallNetworkLSA (OSPFNetworkLSA *lsa)
bool InstallSummaryLSA (OSPFSummaryLSA *lsa)
RouterLSAFindRouterLSA (LinkStateID linkStateID)
const RouterLSAFindRouterLSA (LinkStateID linkStateID) const
NetworkLSAFindNetworkLSA (LinkStateID linkStateID)
const NetworkLSAFindNetworkLSA (LinkStateID linkStateID) const
SummaryLSAFindSummaryLSA (LSAKeyType lsaKey)
const SummaryLSAFindSummaryLSA (LSAKeyType lsaKey) const
void AgeDatabase (void)
bool HasAnyNeighborInStates (int states) const
void RemoveFromAllRetransmissionLists (LSAKeyType lsaKey)
bool IsOnAnyRetransmissionList (LSAKeyType lsaKey) const
bool FloodLSA (OSPFLSA *lsa, Interface *intf=NULL, Neighbor *neighbor=NULL)
bool IsLocalAddress (IPv4Address address) const
RouterLSAOriginateRouterLSA (void)
NetworkLSAOriginateNetworkLSA (const Interface *intf)
SummaryLSAOriginateSummaryLSA (const RoutingTableEntry *entry, const std::map< LSAKeyType, bool, LSAKeyType_Less > &originatedLSAs, SummaryLSA *&lsaToReoriginate)
void CalculateShortestPathTree (std::vector< RoutingTableEntry * > &newRoutingTable)
void CalculateInterAreaRoutes (std::vector< RoutingTableEntry * > &newRoutingTable)
void ReCheckSummaryLSAs (std::vector< RoutingTableEntry * > &newRoutingTable)
void info (char *buffer)
std::string detailedInfo (void) const

Private Member Functions

SummaryLSAOriginateSummaryLSA (const OSPF::SummaryLSA *summaryLSA)
bool HasLink (OSPFLSA *fromLSA, OSPFLSA *toLSA) const
std::vector< NextHop > * CalculateNextHops (OSPFLSA *destination, OSPFLSA *parent) const
std::vector< NextHop > * CalculateNextHops (Link &destination, OSPFLSA *parent) const
LinkStateID GetUniqueLinkStateID (IPv4AddressRange destination, Metric destinationCost, SummaryLSA *&lsaToReoriginate) const
bool FindSameOrWorseCostRoute (const std::vector< OSPF::RoutingTableEntry * > &newRoutingTable, const OSPF::SummaryLSA &currentLSA, unsigned short currentCost, bool &destinationInRoutingTable, std::list< OSPF::RoutingTableEntry * > &sameOrWorseCost) const
RoutingTableEntryCreateRoutingTableEntryFromSummaryLSA (const OSPF::SummaryLSA &summaryLSA, unsigned short entryCost, const OSPF::RoutingTableEntry &borderRouterEntry) const

Private Attributes

AreaID areaID
std::map< IPv4AddressRange,
bool, IPv4AddressRange_Less
advertiseAddressRanges
std::vector< IPv4AddressRangeareaAddressRanges
std::vector< Interface * > associatedInterfaces
std::vector< HostRouteParametershostRoutes
std::map< LinkStateID,
RouterLSA * > 
routerLSAsByID
std::vector< RouterLSA * > routerLSAs
std::map< LinkStateID,
NetworkLSA * > 
networkLSAsByID
std::vector< NetworkLSA * > networkLSAs
std::map< LSAKeyType,
SummaryLSA *, LSAKeyType_Less
summaryLSAsByID
std::vector< SummaryLSA * > summaryLSAs
bool transitCapability
bool externalRoutingCapability
Metric stubDefaultCost
RouterLSAspfTreeRoot
RouterparentRouter

Detailed Description

Definition at line 32 of file OSPFArea.h.


Constructor & Destructor Documentation

OSPF::Area::Area ( OSPF::AreaID  id = BackboneAreaID  ) 

Definition at line 22 of file OSPFArea.cc.

OSPF::Area::~Area ( void   )  [virtual]

Definition at line 32 of file OSPFArea.cc.

{
    int interfaceNum = associatedInterfaces.size();
    for (int i = 0; i < interfaceNum; i++) {
        delete(associatedInterfaces[i]);
    }
    long lsaCount = routerLSAs.size();
    for (long j = 0; j < lsaCount; j++) {
        delete routerLSAs[j];
    }
    routerLSAs.clear();
    lsaCount = networkLSAs.size();
    for (long k = 0; k < lsaCount; k++) {
        delete networkLSAs[k];
    }
    networkLSAs.clear();
    lsaCount = summaryLSAs.size();
    for (long m = 0; m < lsaCount; m++) {
        delete summaryLSAs[m];
    }
    summaryLSAs.clear();
}


Member Function Documentation

void OSPF::Area::AddAddressRange ( IPv4AddressRange  addressRange,
bool  advertise 
) [inline]

Definition at line 57 of file OSPFArea.h.

Referenced by OSPFRouting::LoadAreaFromXML().

{ areaAddressRanges.push_back(addressRange); advertiseAddressRanges[addressRange] = advertise; }

void OSPF::Area::AddHostRoute ( HostRouteParameters hostRouteParameters  )  [inline]

Definition at line 60 of file OSPFArea.h.

Referenced by OSPFRouting::LoadHostRoute().

{ hostRoutes.push_back(hostRouteParameters); }

void OSPF::Area::AddInterface ( OSPF::Interface intf  ) 

Definition at line 55 of file OSPFArea.cc.

Referenced by OSPFRouting::LoadInterfaceParameters(), and OSPFRouting::LoadVirtualLink().

{
    intf->SetArea(this);
    associatedInterfaces.push_back(intf);
}

void OSPF::Area::AgeDatabase ( void   ) 

Definition at line 341 of file OSPFArea.cc.

{
    long            lsaCount            = routerLSAs.size();
    bool            rebuildRoutingTable = false;
    long            i;

    for (i = 0; i < lsaCount; i++) {
        unsigned short   lsAge          = routerLSAs[i]->getHeader().getLsAge();
        bool             selfOriginated = (routerLSAs[i]->getHeader().getAdvertisingRouter().getInt() == parentRouter->GetRouterID());
        bool             unreachable    = parentRouter->IsDestinationUnreachable(routerLSAs[i]);
        OSPF::RouterLSA* lsa            = routerLSAs[i];

        if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
            lsa->getHeader().setLsAge(lsAge + 1);
            if ((lsAge + 1) % CHECK_AGE == 0) {
                if (!lsa->ValidateLSChecksum()) {
                    EV << "Invalid LS checksum. Memory error detected!\n";
                }
            }
            lsa->IncrementInstallTime();
        }
        if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
            if (unreachable) {
                lsa->getHeader().setLsAge(MAX_AGE);
                FloodLSA(lsa);
                lsa->IncrementInstallTime();
            } else {
                long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
                if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
                    lsa->getHeader().setLsAge(MAX_AGE);
                    FloodLSA(lsa);
                    lsa->IncrementInstallTime();
                } else {
                    OSPF::RouterLSA* newLSA = OriginateRouterLSA();

                    newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
                    newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                    rebuildRoutingTable |= lsa->Update(newLSA);
                    delete newLSA;

                    FloodLSA(lsa);
                }
            }
        }
        if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
            lsa->getHeader().setLsAge(MAX_AGE);
            FloodLSA(lsa);
            lsa->IncrementInstallTime();
        }
        if (lsAge == MAX_AGE) {
            OSPF::LSAKeyType lsaKey;

            lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
            lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

            if (!IsOnAnyRetransmissionList(lsaKey) &&
                !HasAnyNeighborInStates(OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
            {
                if (!selfOriginated || unreachable) {
                    routerLSAsByID.erase(lsa->getHeader().getLinkStateID());
                    delete lsa;
                    routerLSAs[i] = NULL;
                    rebuildRoutingTable = true;
                } else {
                    OSPF::RouterLSA* newLSA              = OriginateRouterLSA();
                    long             sequenceNumber      = lsa->getHeader().getLsSequenceNumber();

                    newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
                    newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                    rebuildRoutingTable |= lsa->Update(newLSA);
                    delete newLSA;

                    FloodLSA(lsa);
                }
            }
        }
    }

    std::vector<RouterLSA*>::iterator routerIt = routerLSAs.begin();
    while (routerIt != routerLSAs.end()) {
        if ((*routerIt) == NULL) {
            routerIt = routerLSAs.erase(routerIt);
        } else {
            routerIt++;
        }
    }

    lsaCount = networkLSAs.size();
    for (i = 0; i < lsaCount; i++) {
        unsigned short    lsAge          = networkLSAs[i]->getHeader().getLsAge();
        bool              unreachable    = parentRouter->IsDestinationUnreachable(networkLSAs[i]);
        OSPF::NetworkLSA* lsa            = networkLSAs[i];
        OSPF::Interface*  localIntf      = GetInterface(IPv4AddressFromULong(lsa->getHeader().getLinkStateID()));
        bool              selfOriginated = false;

        if ((localIntf != NULL) &&
            (localIntf->GetState() == OSPF::Interface::DesignatedRouterState) &&
            (localIntf->GetNeighborCount() > 0) &&
            (localIntf->HasAnyNeighborInStates(OSPF::Neighbor::FullState)))
        {
            selfOriginated = true;
        }

        if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
            lsa->getHeader().setLsAge(lsAge + 1);
            if ((lsAge + 1) % CHECK_AGE == 0) {
                if (!lsa->ValidateLSChecksum()) {
                    EV << "Invalid LS checksum. Memory error detected!\n";
                }
            }
            lsa->IncrementInstallTime();
        }
        if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
            if (unreachable) {
                lsa->getHeader().setLsAge(MAX_AGE);
                FloodLSA(lsa);
                lsa->IncrementInstallTime();
            } else {
                long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
                if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
                    lsa->getHeader().setLsAge(MAX_AGE);
                    FloodLSA(lsa);
                    lsa->IncrementInstallTime();
                } else {
                    OSPF::NetworkLSA* newLSA = OriginateNetworkLSA(localIntf);

                    if (newLSA != NULL) {
                        newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
                        newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                        rebuildRoutingTable |= lsa->Update(newLSA);
                        delete newLSA;
                    } else {    // no neighbors on the network -> old NetworkLSA must be flushed
                        lsa->getHeader().setLsAge(MAX_AGE);
                        lsa->IncrementInstallTime();
                    }

                    FloodLSA(lsa);
                }
            }
        }
        if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
            lsa->getHeader().setLsAge(MAX_AGE);
            FloodLSA(lsa);
            lsa->IncrementInstallTime();
        }
        if (lsAge == MAX_AGE) {
            OSPF::LSAKeyType lsaKey;

            lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
            lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

            if (!IsOnAnyRetransmissionList(lsaKey) &&
                !HasAnyNeighborInStates(OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
            {
                if (!selfOriginated || unreachable) {
                    networkLSAsByID.erase(lsa->getHeader().getLinkStateID());
                    delete lsa;
                    networkLSAs[i] = NULL;
                    rebuildRoutingTable = true;
                } else {
                    OSPF::NetworkLSA* newLSA              = OriginateNetworkLSA(localIntf);
                    long              sequenceNumber      = lsa->getHeader().getLsSequenceNumber();

                    if (newLSA != NULL) {
                        newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
                        newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                        rebuildRoutingTable |= lsa->Update(newLSA);
                        delete newLSA;

                        FloodLSA(lsa);
                    } else {    // no neighbors on the network -> old NetworkLSA must be deleted
                        delete networkLSAs[i];
                    }
                }
            }
        }
    }

    std::vector<NetworkLSA*>::iterator networkIt = networkLSAs.begin();
    while (networkIt != networkLSAs.end()) {
        if ((*networkIt) == NULL) {
            networkIt = networkLSAs.erase(networkIt);
        } else {
            networkIt++;
        }
    }

    lsaCount = summaryLSAs.size();
    for (i = 0; i < lsaCount; i++) {
        unsigned short    lsAge          = summaryLSAs[i]->getHeader().getLsAge();
        bool              selfOriginated = (summaryLSAs[i]->getHeader().getAdvertisingRouter().getInt() == parentRouter->GetRouterID());
        bool              unreachable    = parentRouter->IsDestinationUnreachable(summaryLSAs[i]);
        OSPF::SummaryLSA* lsa            = summaryLSAs[i];

        if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
            lsa->getHeader().setLsAge(lsAge + 1);
            if ((lsAge + 1) % CHECK_AGE == 0) {
                if (!lsa->ValidateLSChecksum()) {
                    EV << "Invalid LS checksum. Memory error detected!\n";
                }
            }
            lsa->IncrementInstallTime();
        }
        if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
            if (unreachable) {
                lsa->getHeader().setLsAge(MAX_AGE);
                FloodLSA(lsa);
                lsa->IncrementInstallTime();
            } else {
                long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
                if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
                    lsa->getHeader().setLsAge(MAX_AGE);
                    FloodLSA(lsa);
                    lsa->IncrementInstallTime();
                } else {
                    OSPF::SummaryLSA* newLSA = OriginateSummaryLSA(lsa);

                    if (newLSA != NULL) {
                        newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
                        newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                        rebuildRoutingTable |= lsa->Update(newLSA);
                        delete newLSA;

                        FloodLSA(lsa);
                    } else {
                        lsa->getHeader().setLsAge(MAX_AGE);
                        FloodLSA(lsa);
                        lsa->IncrementInstallTime();
                    }
                }
            }
        }
        if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
            lsa->getHeader().setLsAge(MAX_AGE);
            FloodLSA(lsa);
            lsa->IncrementInstallTime();
        }
        if (lsAge == MAX_AGE) {
            OSPF::LSAKeyType lsaKey;

            lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
            lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

            if (!IsOnAnyRetransmissionList(lsaKey) &&
                !HasAnyNeighborInStates(OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
            {
                if (!selfOriginated || unreachable) {
                    summaryLSAsByID.erase(lsaKey);
                    delete lsa;
                    summaryLSAs[i] = NULL;
                    rebuildRoutingTable = true;
                } else {
                    OSPF::SummaryLSA* newLSA = OriginateSummaryLSA(lsa);
                    if (newLSA != NULL) {
                        long sequenceNumber = lsa->getHeader().getLsSequenceNumber();

                        newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
                        newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                        rebuildRoutingTable |= lsa->Update(newLSA);
                        delete newLSA;

                        FloodLSA(lsa);
                    } else {
                        summaryLSAsByID.erase(lsaKey);
                        delete lsa;
                        summaryLSAs[i] = NULL;
                        rebuildRoutingTable = true;
                    }
                }
            }
        }
    }

    std::vector<SummaryLSA*>::iterator summaryIt = summaryLSAs.begin();
    while (summaryIt != summaryLSAs.end()) {
        if ((*summaryIt) == NULL) {
            summaryIt = summaryLSAs.erase(summaryIt);
        } else {
            summaryIt++;
        }
    }

    long interfaceCount = associatedInterfaces.size();
    for (long m = 0; m < interfaceCount; m++) {
        associatedInterfaces[m]->AgeTransmittedLSALists();
    }

    if (rebuildRoutingTable) {
        parentRouter->RebuildRoutingTable();
    }
}

void OSPF::Area::CalculateInterAreaRoutes ( std::vector< RoutingTableEntry * > &  newRoutingTable  ) 
std::vector< OSPF::NextHop > * OSPF::Area::CalculateNextHops ( OSPFLSA *  destination,
OSPFLSA *  parent 
) const [private]

Definition at line 1811 of file OSPFArea.cc.

{
    std::vector<OSPF::NextHop>* hops = new std::vector<OSPF::NextHop>;
    unsigned long               i, j;

    OSPF::RouterLSA* routerLSA = dynamic_cast<OSPF::RouterLSA*> (parent);
    if (routerLSA != NULL) {
        if (routerLSA != spfTreeRoot) {
            unsigned int nextHopCount = routerLSA->GetNextHopCount();
            for (i = 0; i < nextHopCount; i++) {
                hops->push_back(routerLSA->GetNextHop(i));
            }
            return hops;
        } else {
            OSPF::RouterLSA* destinationRouterLSA = dynamic_cast<OSPF::RouterLSA*> (destination);
            if (destinationRouterLSA != NULL) {
                unsigned long interfaceNum   = associatedInterfaces.size();
                for (i = 0; i < interfaceNum; i++) {
                    OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType();
                    if ((intfType == OSPF::Interface::PointToPoint) ||
                        ((intfType == OSPF::Interface::Virtual) &&
                         (associatedInterfaces[i]->GetState() > OSPF::Interface::LoopbackState)))
                    {
                        OSPF::Neighbor* ptpNeighbor = associatedInterfaces[i]->GetNeighborCount() > 0 ? associatedInterfaces[i]->GetNeighbor(0) : NULL;
                        if (ptpNeighbor != NULL) {
                            if (ptpNeighbor->GetNeighborID() == destinationRouterLSA->getHeader().getLinkStateID()) {
                                NextHop nextHop;
                                nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex();
                                nextHop.hopAddress        = ptpNeighbor->GetAddress();
                                nextHop.advertisingRouter = destinationRouterLSA->getHeader().getAdvertisingRouter().getInt();
                                hops->push_back(nextHop);
                                break;
                            }
                        }
                    }
                    if (intfType == OSPF::Interface::PointToMultiPoint) {
                        OSPF::Neighbor* ptmpNeighbor = associatedInterfaces[i]->GetNeighborByID(destinationRouterLSA->getHeader().getLinkStateID());
                        if (ptmpNeighbor != NULL) {
                            unsigned int   linkCount = destinationRouterLSA->getLinksArraySize();
                            OSPF::RouterID rootID    = parentRouter->GetRouterID();
                            for (j = 0; j < linkCount; j++) {
                                Link& link = destinationRouterLSA->getLinks(j);
                                if (link.getLinkID() == rootID) {
                                    NextHop nextHop;
                                    nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex();
                                    nextHop.hopAddress        = IPv4AddressFromULong(link.getLinkData());
                                    nextHop.advertisingRouter = destinationRouterLSA->getHeader().getAdvertisingRouter().getInt();
                                    hops->push_back(nextHop);
                                }
                            }
                            break;
                        }
                    }
                }
            } else {
                OSPF::NetworkLSA* destinationNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (destination);
                if (destinationNetworkLSA != NULL) {
                    OSPF::IPv4Address networkDesignatedRouter = IPv4AddressFromULong(destinationNetworkLSA->getHeader().getLinkStateID());
                    unsigned long     interfaceNum            = associatedInterfaces.size();
                    for (i = 0; i < interfaceNum; i++) {
                        OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType();
                        if (((intfType == OSPF::Interface::Broadcast) ||
                             (intfType == OSPF::Interface::NBMA)) &&
                            (associatedInterfaces[i]->GetDesignatedRouter().ipInterfaceAddress == networkDesignatedRouter))
                        {
                            OSPF::IPv4AddressRange range = associatedInterfaces[i]->GetAddressRange();
                            NextHop                nextHop;

                            nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex();
                            nextHop.hopAddress        = (range.address & range.mask);
                            nextHop.advertisingRouter = destinationNetworkLSA->getHeader().getAdvertisingRouter().getInt();
                            hops->push_back(nextHop);
                        }
                    }
                }
            }
        }
    } else {
        OSPF::NetworkLSA* networkLSA = dynamic_cast<OSPF::NetworkLSA*> (parent);
        if (networkLSA != NULL) {
            if (networkLSA->GetParent() != spfTreeRoot) {
                unsigned int nextHopCount = networkLSA->GetNextHopCount();
                for (i = 0; i < nextHopCount; i++) {
                    hops->push_back(networkLSA->GetNextHop(i));
                }
                return hops;
            } else {
                unsigned long parentLinkStateID = parent->getHeader().getLinkStateID();

                OSPF::RouterLSA* destinationRouterLSA = dynamic_cast<OSPF::RouterLSA*> (destination);
                if (destinationRouterLSA != NULL) {
                    OSPF::RouterID destinationRouterID = destinationRouterLSA->getHeader().getLinkStateID();
                    unsigned int   linkCount           = destinationRouterLSA->getLinksArraySize();
                    for (i = 0; i < linkCount; i++) {
                        Link&   link = destinationRouterLSA->getLinks(i);
                        NextHop nextHop;

                        if (((link.getType() == TransitLink) &&
                             (link.getLinkID().getInt() == parentLinkStateID)) ||
                            ((link.getType() == StubLink) &&
                             ((link.getLinkID().getInt() & link.getLinkData()) == (parentLinkStateID & networkLSA->getNetworkMask().getInt()))))
                        {
                            unsigned long interfaceNum   = associatedInterfaces.size();
                            for (j = 0; j < interfaceNum; j++) {
                                OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[j]->GetType();
                                if (((intfType == OSPF::Interface::Broadcast) ||
                                     (intfType == OSPF::Interface::NBMA)) &&
                                    (associatedInterfaces[j]->GetDesignatedRouter().ipInterfaceAddress == IPv4AddressFromULong(parentLinkStateID)))
                                {
                                    OSPF::Neighbor* nextHopNeighbor = associatedInterfaces[j]->GetNeighborByID(destinationRouterID);
                                    if (nextHopNeighbor != NULL) {
                                        nextHop.ifIndex           = associatedInterfaces[j]->GetIfIndex();
                                        nextHop.hopAddress        = nextHopNeighbor->GetAddress();
                                        nextHop.advertisingRouter = destinationRouterLSA->getHeader().getAdvertisingRouter().getInt();
                                        hops->push_back(nextHop);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return hops;
}

std::vector< OSPF::NextHop > * OSPF::Area::CalculateNextHops ( Link &  destination,
OSPFLSA *  parent 
) const [private]

Definition at line 1939 of file OSPFArea.cc.

{
    std::vector<OSPF::NextHop>* hops = new std::vector<OSPF::NextHop>;
    unsigned long                i;

    OSPF::RouterLSA* routerLSA = check_and_cast<OSPF::RouterLSA*> (parent);
    if (routerLSA != spfTreeRoot) {
        unsigned int nextHopCount = routerLSA->GetNextHopCount();
        for (i = 0; i < nextHopCount; i++) {
            hops->push_back(routerLSA->GetNextHop(i));
        }
        return hops;
    } else {
        unsigned long interfaceNum = associatedInterfaces.size();
        for (i = 0; i < interfaceNum; i++) {
            OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType();

            if ((intfType == OSPF::Interface::PointToPoint) ||
                ((intfType == OSPF::Interface::Virtual) &&
                 (associatedInterfaces[i]->GetState() > OSPF::Interface::LoopbackState)))
            {
                OSPF::Neighbor* neighbor = (associatedInterfaces[i]->GetNeighborCount() > 0) ? associatedInterfaces[i]->GetNeighbor(0) : NULL;
                if (neighbor != NULL) {
                    OSPF::IPv4Address neighborAddress = neighbor->GetAddress();
                    if (((neighborAddress != OSPF::NullIPv4Address) &&
                         (ULongFromIPv4Address(neighborAddress) == destination.getLinkID().getInt())) ||
                        ((neighborAddress == OSPF::NullIPv4Address) &&
                         (ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().address) == destination.getLinkID().getInt()) &&
                         (ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().mask) == destination.getLinkData())))
                    {
                        NextHop nextHop;
                        nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex();
                        nextHop.hopAddress        = neighborAddress;
                        nextHop.advertisingRouter = parentRouter->GetRouterID();
                        hops->push_back(nextHop);
                        break;
                    }
                }
            }
            if ((intfType == OSPF::Interface::Broadcast) ||
                (intfType == OSPF::Interface::NBMA))
            {
                if ((destination.getLinkID().getInt() == ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().address & associatedInterfaces[i]->GetAddressRange().mask)) &&
                    (destination.getLinkData() == ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().mask)))
                {
                    NextHop nextHop;
                    nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex();
                    nextHop.hopAddress        = IPv4AddressFromULong(destination.getLinkID().getInt());
                    nextHop.advertisingRouter = parentRouter->GetRouterID();
                    hops->push_back(nextHop);
                    break;
                }
            }
            if (intfType == OSPF::Interface::PointToMultiPoint) {
                if (destination.getType() == StubLink) {
                    if (destination.getLinkID().getInt() == ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().address)) {
                        // The link contains the router's own interface address and a full mask,
                        // so we insert a next hop pointing to the interface itself. Kind of pointless, but
                        // not much else we could do...
                        // TODO: check what other OSPF implementations do in this situation
                        NextHop nextHop;
                        nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex();
                        nextHop.hopAddress        = associatedInterfaces[i]->GetAddressRange().address;
                        nextHop.advertisingRouter = parentRouter->GetRouterID();
                        hops->push_back(nextHop);
                        break;
                    }
                }
                if (destination.getType() == PointToPointLink) {
                    OSPF::Neighbor* neighbor = associatedInterfaces[i]->GetNeighborByID(destination.getLinkID().getInt());
                    if (neighbor != NULL) {
                        NextHop nextHop;
                        nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex();
                        nextHop.hopAddress        = neighbor->GetAddress();
                        nextHop.advertisingRouter = parentRouter->GetRouterID();
                        hops->push_back(nextHop);
                        break;
                    }
                }
            }
            // next hops for virtual links are generated later, after examining transit areas' SummaryLSAs
        }

        if (hops->size() == 0) {
            unsigned long hostRouteCount = hostRoutes.size();
            for (i = 0; i < hostRouteCount; i++) {
                if ((destination.getLinkID().getInt() == ULongFromIPv4Address(hostRoutes[i].address)) &&
                    (destination.getLinkData() == 0xFFFFFFFF))
                {
                    NextHop nextHop;
                    nextHop.ifIndex           = hostRoutes[i].ifIndex;
                    nextHop.hopAddress        = hostRoutes[i].address;
                    nextHop.advertisingRouter = parentRouter->GetRouterID();
                    hops->push_back(nextHop);
                    break;
                }
            }
        }
    }

    return hops;
}

void OSPF::Area::CalculateShortestPathTree ( std::vector< RoutingTableEntry * > &  newRoutingTable  ) 
bool OSPF::Area::ContainsAddress ( OSPF::IPv4Address  address  )  const

Definition at line 114 of file OSPFArea.cc.

{
    int addressRangeNum = areaAddressRanges.size();
    for (int i = 0; i < addressRangeNum; i++) {
        if ((areaAddressRanges[i].address & areaAddressRanges[i].mask) == (address & areaAddressRanges[i].mask)) {
            return true;
        }
    }
    return false;
}

OSPF::RoutingTableEntry * OSPF::Area::CreateRoutingTableEntryFromSummaryLSA ( const OSPF::SummaryLSA summaryLSA,
unsigned short  entryCost,
const OSPF::RoutingTableEntry borderRouterEntry 
) const [private]

Returns a new RoutingTableEntry based on the input SummaryLSA, with the input cost and the borderRouterEntry's next hops.

Definition at line 2167 of file OSPFArea.cc.

{
    OSPF::IPv4AddressRange destination;

    destination.address = IPv4AddressFromULong(summaryLSA.getHeader().getLinkStateID());
    destination.mask    = IPv4AddressFromULong(summaryLSA.getNetworkMask().getInt());

    OSPF::RoutingTableEntry* newEntry = new OSPF::RoutingTableEntry;

    if (summaryLSA.getHeader().getLsType() == SummaryLSA_NetworksType) {
        newEntry->SetDestinationID(ULongFromIPv4Address(destination.address & destination.mask));
        newEntry->SetAddressMask(ULongFromIPv4Address(destination.mask));
        newEntry->SetDestinationType(OSPF::RoutingTableEntry::NetworkDestination);
    } else {
        newEntry->SetDestinationID(ULongFromIPv4Address(destination.address));
        newEntry->SetAddressMask(0xFFFFFFFF);
        newEntry->SetDestinationType(OSPF::RoutingTableEntry::ASBoundaryRouterDestination);
    }
    newEntry->SetArea(areaID);
    newEntry->SetPathType(OSPF::RoutingTableEntry::InterArea);
    newEntry->SetCost(entryCost);
    newEntry->SetOptionalCapabilities(summaryLSA.getHeader().getLsOptions());
    newEntry->SetLinkStateOrigin(&summaryLSA);

    unsigned int nextHopCount = borderRouterEntry.GetNextHopCount();
    for (unsigned int j = 0; j < nextHopCount; j++) {
        newEntry->AddNextHop(borderRouterEntry.GetNextHop(j));
    }

    return newEntry;
}

std::string OSPF::Area::detailedInfo ( void   )  const

Definition at line 69 of file OSPFArea.cc.

Referenced by operator<<().

{
    std::stringstream out;
    char addressString[16];
    int i;
    out << "\n    areaID: " << AddressStringFromULong(addressString, 16, areaID) << ", ";
    out << "transitCapability: " << (transitCapability ? "true" : "false") << ", ";
    out << "externalRoutingCapability: " << (externalRoutingCapability ? "true" : "false") << ", ";
    out << "stubDefaultCost: " << stubDefaultCost << "\n";
    int addressRangeNum = areaAddressRanges.size();
    for (i = 0; i < addressRangeNum; i++) {
        out << "    addressRanges[" << i << "]: ";
        out << AddressStringFromIPv4Address(addressString, 16, areaAddressRanges[i].address);
        out << "/" << AddressStringFromIPv4Address(addressString, 16, areaAddressRanges[i].mask) << "\n";
    }
    int interfaceNum = associatedInterfaces.size();
    for (i = 0; i < interfaceNum; i++) {
        out << "    interface[" << i << "]: addressRange: ";
        out << AddressStringFromIPv4Address(addressString, 16, associatedInterfaces[i]->GetAddressRange().address);
        out << "/" << AddressStringFromIPv4Address(addressString, 16, associatedInterfaces[i]->GetAddressRange().mask) << "\n";
    }

    out << "\n";
    out << "    Database:\n";
    out << "      RouterLSAs:\n";
    long lsaCount = routerLSAs.size();
    for (i = 0; i < lsaCount; i++) {
        out << "        " << *routerLSAs[i] << "\n";
    }
    out << "      NetworkLSAs:\n";
    lsaCount = networkLSAs.size();
    for (i = 0; i < lsaCount; i++) {
        out << "        " << *networkLSAs[i] << "\n";
    }
    out << "      SummaryLSAs:\n";
    lsaCount = summaryLSAs.size();
    for (i = 0; i < lsaCount; i++) {
        out << "        " << *summaryLSAs[i] << "\n";
    }

    out << "--------------------------------------------------------------------------------";

    return out.str();
}

OSPF::NetworkLSA * OSPF::Area::FindNetworkLSA ( OSPF::LinkStateID  linkStateID  ) 

Definition at line 301 of file OSPFArea.cc.

Referenced by OSPF::NeighborState::ChangeState(), and OSPF::InterfaceState::ChangeState().

{
    std::map<OSPF::LinkStateID, OSPF::NetworkLSA*>::iterator lsaIt = networkLSAsByID.find(linkStateID);
    if (lsaIt != networkLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

const OSPF::NetworkLSA * OSPF::Area::FindNetworkLSA ( OSPF::LinkStateID  linkStateID  )  const

Definition at line 311 of file OSPFArea.cc.

{
    std::map<OSPF::LinkStateID, OSPF::NetworkLSA*>::const_iterator lsaIt = networkLSAsByID.find(linkStateID);
    if (lsaIt != networkLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

OSPF::RouterLSA * OSPF::Area::FindRouterLSA ( OSPF::LinkStateID  linkStateID  ) 

Definition at line 281 of file OSPFArea.cc.

Referenced by OSPF::NeighborState::ChangeState(), OSPF::InterfaceState::ChangeState(), and OSPF::HelloHandler::ProcessPacket().

{
    std::map<OSPF::LinkStateID, OSPF::RouterLSA*>::iterator lsaIt = routerLSAsByID.find(linkStateID);
    if (lsaIt != routerLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

const OSPF::RouterLSA * OSPF::Area::FindRouterLSA ( OSPF::LinkStateID  linkStateID  )  const

Definition at line 291 of file OSPFArea.cc.

{
    std::map<OSPF::LinkStateID, OSPF::RouterLSA*>::const_iterator lsaIt = routerLSAsByID.find(linkStateID);
    if (lsaIt != routerLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

bool OSPF::Area::FindSameOrWorseCostRoute ( const std::vector< OSPF::RoutingTableEntry * > &  newRoutingTable,
const OSPF::SummaryLSA summaryLSA,
unsigned short  currentCost,
bool &  destinationInRoutingTable,
std::list< OSPF::RoutingTableEntry * > &  sameOrWorseCost 
) const [private]

Browse through the newRoutingTable looking for entries describing the same destination as the currentLSA. If a cheaper route is found then skip this LSA(return true), else note those which are of equal or worse cost than the currentCost.

Definition at line 2104 of file OSPFArea.cc.

{
    destinationInRoutingTable = false;
    sameOrWorseCost.clear();

    long                   routeCount = newRoutingTable.size();
    OSPF::IPv4AddressRange destination;

    destination.address = IPv4AddressFromULong(summaryLSA.getHeader().getLinkStateID());
    destination.mask    = IPv4AddressFromULong(summaryLSA.getNetworkMask().getInt());

    for (long j = 0; j < routeCount; j++) {
        OSPF::RoutingTableEntry* routingEntry  = newRoutingTable[j];
        bool                     foundMatching = false;

        if (summaryLSA.getHeader().getLsType() == SummaryLSA_NetworksType) {
            if ((routingEntry->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) &&
                (ULongFromIPv4Address(destination.address & destination.mask) == routingEntry->GetDestinationID().getInt()))
            {
                foundMatching = true;
            }
        } else {
            if ((((routingEntry->GetDestinationType() & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
                 ((routingEntry->GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
                (ULongFromIPv4Address(destination.address) == routingEntry->GetDestinationID().getInt()))
            {
                foundMatching = true;
            }
        }

        if (foundMatching) {
            destinationInRoutingTable = true;

            /* If the matching entry is an IntraArea getRoute(intra-area paths are
                * always preferred to other paths of any cost), or it's a cheaper InterArea
                * route, then skip this LSA.
                */
            if ((routingEntry->GetPathType() == OSPF::RoutingTableEntry::IntraArea) ||
                ((routingEntry->GetPathType() == OSPF::RoutingTableEntry::InterArea) &&
                 (routingEntry->GetCost() < currentCost)))
            {
                return true;
            } else {
                // if it's an other InterArea path
                if ((routingEntry->GetPathType() == OSPF::RoutingTableEntry::InterArea) &&
                    (routingEntry->GetCost() >= currentCost))
                {
                    sameOrWorseCost.push_back(routingEntry);
                }   // else it's external -> same as if not in the table
            }
        }
    }
    return false;
}

OSPF::SummaryLSA * OSPF::Area::FindSummaryLSA ( OSPF::LSAKeyType  lsaKey  ) 

Definition at line 321 of file OSPFArea.cc.

Referenced by GetUniqueLinkStateID().

{
    std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find(lsaKey);
    if (lsaIt != summaryLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

const OSPF::SummaryLSA * OSPF::Area::FindSummaryLSA ( OSPF::LSAKeyType  lsaKey  )  const

Definition at line 331 of file OSPFArea.cc.

{
    std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::const_iterator lsaIt = summaryLSAsByID.find(lsaKey);
    if (lsaIt != summaryLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

OSPF::Interface * OSPF::Area::FindVirtualLink ( OSPF::RouterID  routerID  ) 

Definition at line 204 of file OSPFArea.cc.

Referenced by OSPF::MessageHandler::ProcessPacket().

{
    int interfaceNum = associatedInterfaces.size();
    for (int i = 0; i < interfaceNum; i++) {
        if ((associatedInterfaces[i]->GetType() == OSPF::Interface::Virtual) &&
            (associatedInterfaces[i]->GetNeighborByID(routerID) != NULL))
        {
            return associatedInterfaces[i];
        }
    }
    return NULL;
}

bool OSPF::Area::FloodLSA ( OSPFLSA *  lsa,
OSPF::Interface intf = NULL,
OSPF::Neighbor neighbor = NULL 
)

Definition at line 663 of file OSPFArea.cc.

Referenced by AgeDatabase(), OSPF::NeighborState::ChangeState(), OSPF::InterfaceState::ChangeState(), and OSPF::HelloHandler::ProcessPacket().

{
    bool floodedBackOut  = false;
    long interfaceCount = associatedInterfaces.size();

    for (long i = 0; i < interfaceCount; i++) {
        if (associatedInterfaces[i]->FloodLSA(lsa, intf, neighbor)) {
            floodedBackOut = true;
        }
    }

    return floodedBackOut;
}

IPv4AddressRange OSPF::Area::GetAddressRange ( unsigned int  index  )  const [inline]

Definition at line 59 of file OSPFArea.h.

Referenced by CalculateNextHops(), detailedInfo(), GetInterface(), and IsLocalAddress().

{ return areaAddressRanges[index]; }

unsigned int OSPF::Area::GetAddressRangeCount ( void   )  const [inline]

Definition at line 58 of file OSPFArea.h.

{ return areaAddressRanges.size(); }

AreaID OSPF::Area::GetAreaID ( void   )  const [inline]
OSPF::IPv4AddressRange OSPF::Area::GetContainingAddressRange ( OSPF::IPv4AddressRange  addressRange,
bool *  advertise = NULL 
) const

Definition at line 138 of file OSPFArea.cc.

{
    int addressRangeNum = areaAddressRanges.size();
    for (int i = 0; i < addressRangeNum; i++) {
        if ((areaAddressRanges[i].address & areaAddressRanges[i].mask) == (addressRange.address & areaAddressRanges[i].mask)) {
            if (advertise != NULL) {
                std::map<OSPF::IPv4AddressRange, bool, OSPF::IPv4AddressRange_Less>::const_iterator rangeIt = advertiseAddressRanges.find(areaAddressRanges[i]);
                if (rangeIt != advertiseAddressRanges.end()) {
                    *advertise = rangeIt->second;
                } else {
                    *advertise = true;
                }
            }
            return areaAddressRanges[i];
        }
    }
    if (advertise != NULL) {
        *advertise =  false;
    }
    return NullIPv4AddressRange;
}

bool OSPF::Area::GetExternalRoutingCapability ( void   )  const [inline]
OSPF::Interface * OSPF::Area::GetInterface ( unsigned char  ifIndex  ) 

Definition at line 160 of file OSPFArea.cc.

Referenced by AgeDatabase(), and OSPF::MessageHandler::ProcessPacket().

{
    int interfaceNum = associatedInterfaces.size();
    for (int i = 0; i < interfaceNum; i++) {
        if ((associatedInterfaces[i]->GetType() != OSPF::Interface::Virtual) &&
            (associatedInterfaces[i]->GetIfIndex() == ifIndex))
        {
            return associatedInterfaces[i];
        }
    }
    return NULL;
}

OSPF::Interface * OSPF::Area::GetInterface ( OSPF::IPv4Address  address  ) 

Definition at line 173 of file OSPFArea.cc.

{
    int interfaceNum = associatedInterfaces.size();
    for (int i = 0; i < interfaceNum; i++) {
        if ((associatedInterfaces[i]->GetType() != OSPF::Interface::Virtual) &&
            (associatedInterfaces[i]->GetAddressRange().address == address))
        {
            return associatedInterfaces[i];
        }
    }
    return NULL;
}

NetworkLSA* OSPF::Area::GetNetworkLSA ( unsigned long  i  )  [inline]

Definition at line 79 of file OSPFArea.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return networkLSAs[i]; }

const NetworkLSA* OSPF::Area::GetNetworkLSA ( unsigned long  i  )  const [inline]

Definition at line 80 of file OSPFArea.h.

{ return networkLSAs[i]; }

unsigned long OSPF::Area::GetNetworkLSACount ( void   )  const [inline]

Definition at line 78 of file OSPFArea.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return networkLSAs.size(); }

const Router* OSPF::Area::GetRouter ( void   )  const [inline]

Definition at line 73 of file OSPFArea.h.

{ return parentRouter; }

Router* OSPF::Area::GetRouter ( void   )  [inline]

Definition at line 72 of file OSPFArea.h.

Referenced by OSPF::InterfaceState::CalculateDesignatedRouter(), OSPF::NeighborState::ChangeState(), OSPF::InterfaceState::ChangeState(), OSPF::Neighbor::ClearRequestRetransmissionTimer(), OSPF::Neighbor::ClearUpdateRetransmissionTimer(), OSPF::Neighbor::CreateDatabaseSummary(), OSPF::Interface::CreateUpdatePacket(), OSPF::Interface::FloodLSA(), OSPF::Neighbor::NeedAdjacency(), OSPF::NeighborStateTwoWay::ProcessEvent(), OSPF::NeighborStateLoading::ProcessEvent(), OSPF::NeighborStateInit::ProcessEvent(), OSPF::NeighborStateFull::ProcessEvent(), OSPF::NeighborStateExchangeStart::ProcessEvent(), OSPF::NeighborStateExchange::ProcessEvent(), OSPF::NeighborStateDown::ProcessEvent(), OSPF::NeighborStateAttempt::ProcessEvent(), OSPF::InterfaceStateWaiting::ProcessEvent(), OSPF::InterfaceStatePointToPoint::ProcessEvent(), OSPF::InterfaceStateNotDesignatedRouter::ProcessEvent(), OSPF::InterfaceStateDown::ProcessEvent(), OSPF::InterfaceStateDesignatedRouter::ProcessEvent(), OSPF::InterfaceStateBackup::ProcessEvent(), OSPF::Neighbor::Reset(), OSPF::Interface::Reset(), OSPF::Neighbor::RetransmitDatabaseDescriptionPacket(), OSPF::Neighbor::RetransmitUpdatePacket(), OSPF::Neighbor::SendDatabaseDescriptionPacket(), OSPF::Interface::SendDelayedAcknowledgements(), OSPF::Interface::SendHelloPacket(), OSPF::Neighbor::SendLinkStateRequestPacket(), OSPF::Interface::SendLSAcknowledgement(), OSPF::Neighbor::StartRequestRetransmissionTimer(), OSPF::Neighbor::StartUpdateRetransmissionTimer(), OSPF::Interface::~Interface(), and OSPF::Neighbor::~Neighbor().

{ return parentRouter; }

RouterLSA* OSPF::Area::GetRouterLSA ( unsigned long  i  )  [inline]

Definition at line 76 of file OSPFArea.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return routerLSAs[i]; }

const RouterLSA* OSPF::Area::GetRouterLSA ( unsigned long  i  )  const [inline]

Definition at line 77 of file OSPFArea.h.

{ return routerLSAs[i]; }

unsigned long OSPF::Area::GetRouterLSACount ( void   )  const [inline]

Definition at line 75 of file OSPFArea.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return routerLSAs.size(); }

RouterLSA* OSPF::Area::GetSPFTreeRoot ( void   )  [inline]

Definition at line 68 of file OSPFArea.h.

{ return spfTreeRoot; }

const RouterLSA* OSPF::Area::GetSPFTreeRoot ( void   )  const [inline]

Definition at line 69 of file OSPFArea.h.

{ return spfTreeRoot; }

Metric OSPF::Area::GetStubDefaultCost ( void   )  const [inline]

Definition at line 66 of file OSPFArea.h.

{ return stubDefaultCost; }

const SummaryLSA* OSPF::Area::GetSummaryLSA ( unsigned long  i  )  const [inline]

Definition at line 83 of file OSPFArea.h.

{ return summaryLSAs[i]; }

SummaryLSA* OSPF::Area::GetSummaryLSA ( unsigned long  i  )  [inline]

Definition at line 82 of file OSPFArea.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return summaryLSAs[i]; }

unsigned long OSPF::Area::GetSummaryLSACount ( void   )  const [inline]

Definition at line 81 of file OSPFArea.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return summaryLSAs.size(); }

bool OSPF::Area::GetTransitCapability ( void   )  const [inline]

Definition at line 62 of file OSPFArea.h.

{ return transitCapability; }

OSPF::LinkStateID OSPF::Area::GetUniqueLinkStateID ( OSPF::IPv4AddressRange  destination,
OSPF::Metric  destinationCost,
OSPF::SummaryLSA *&  lsaToReoriginate 
) const [private]

Returns a link state ID for the input destination. If this router hasn't originated a Summary LSA for the input destination then the function returs the destination address as link state ID. If it has originated a Summary LSA for the input destination then the function checks which LSA would contain the longer netmask. If the two masks are equal then this means thet we're updating an LSA already in the database, so the function returns the destination address as link state ID. If the input destination netmask is longer then the one already in the database, then the returned link state ID is the input destination address ORed together with the inverse of the input destination mask. If the input destination netmask is shorter, then the Summary LSA already in the database has to be replaced by the current destination. In this case the lsaToReoriginate parameter is filled with a copy of the Summary LSA in the database with it's mask replaced by the destination mask and the cost replaced by the input destination cost; the returned link state ID is the input destination address ORed together with the inverse of the mask stored in the Summary LSA in the database. This means that if the lsaToReoriginate parameter is not NULL on return then another lookup in the database is needed with the same LSAKey as used here(input destination address and the router's own routerID) and the resulting Summary LSA's link state ID should be changed to the one returned by this function.

Definition at line 989 of file OSPFArea.cc.

{
    if (lsaToReoriginate != NULL) {
        delete lsaToReoriginate;
        lsaToReoriginate = NULL;
    }

    OSPF::LSAKeyType lsaKey;

    lsaKey.linkStateID = ULongFromIPv4Address(destination.address);
    lsaKey.advertisingRouter = parentRouter->GetRouterID();

    const OSPF::SummaryLSA* foundLSA = FindSummaryLSA(lsaKey);

    if (foundLSA == NULL) {
        return lsaKey.linkStateID;
    } else {
        OSPF::IPv4Address existingMask = IPv4AddressFromULong(foundLSA->getNetworkMask().getInt());

        if (destination.mask == existingMask) {
            return lsaKey.linkStateID;
        } else {
            if (destination.mask >= existingMask) {
                return (lsaKey.linkStateID | (~(ULongFromIPv4Address(destination.mask))));
            } else {
                OSPF::SummaryLSA* summaryLSA = new OSPF::SummaryLSA(*foundLSA);

                long sequenceNumber = summaryLSA->getHeader().getLsSequenceNumber();

                summaryLSA->getHeader().setLsAge(0);
                summaryLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
                summaryLSA->setNetworkMask(ULongFromIPv4Address(destination.mask));
                summaryLSA->setRouteCost(destinationCost);
                summaryLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum

                lsaToReoriginate = summaryLSA;

                return (lsaKey.linkStateID | (~(ULongFromIPv4Address(existingMask))));
            }
        }
    }
}

bool OSPF::Area::HasAddressRange ( OSPF::IPv4AddressRange  addressRange  )  const

Definition at line 125 of file OSPFArea.cc.

{
    int addressRangeNum = areaAddressRanges.size();
    for (int i = 0; i < addressRangeNum; i++) {
        if ((areaAddressRanges[i].address == addressRange.address) &&
            (areaAddressRanges[i].mask == addressRange.mask))
        {
            return true;
        }
    }
    return false;
}

bool OSPF::Area::HasAnyNeighborInStates ( int  states  )  const

Definition at line 633 of file OSPFArea.cc.

Referenced by AgeDatabase().

{
    long interfaceCount = associatedInterfaces.size();
    for (long i = 0; i < interfaceCount; i++) {
        if (associatedInterfaces[i]->HasAnyNeighborInStates(states)) {
            return true;
        }
    }
    return false;
}

bool OSPF::Area::HasLink ( OSPFLSA *  fromLSA,
OSPFLSA *  toLSA 
) const [private]

Definition at line 2042 of file OSPFArea.cc.

{
    unsigned int i;

    OSPF::RouterLSA* fromRouterLSA = dynamic_cast<OSPF::RouterLSA*> (fromLSA);
    if (fromRouterLSA != NULL) {
        unsigned int     linkCount   = fromRouterLSA->getLinksArraySize();
        OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (toLSA);
        if (toRouterLSA != NULL) {
            for (i = 0; i < linkCount; i++) {
                Link&    link     = fromRouterLSA->getLinks(i);
                LinkType linkType = static_cast<LinkType> (link.getType());

                if (((linkType == PointToPointLink) ||
                     (linkType == VirtualLink)) &&
                    (link.getLinkID().getInt() == toRouterLSA->getHeader().getLinkStateID()))
                {
                    return true;
                }
            }
        } else {
            OSPF::NetworkLSA* toNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (toLSA);
            if (toNetworkLSA != NULL) {
                for (i = 0; i < linkCount; i++) {
                    Link&    link     = fromRouterLSA->getLinks(i);

                    if ((link.getType() == TransitLink) &&
                        (link.getLinkID().getInt() == toNetworkLSA->getHeader().getLinkStateID()))
                    {
                        return true;
                    }
                    if ((link.getType() == StubLink) &&
                        ((link.getLinkID().getInt() & link.getLinkData()) == (toNetworkLSA->getHeader().getLinkStateID() & toNetworkLSA->getNetworkMask().getInt())))
                    {
                        return true;
                    }
                }
            }
        }
    } else {
        OSPF::NetworkLSA* fromNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (fromLSA);
        if (fromNetworkLSA != NULL) {
            unsigned int     routerCount   = fromNetworkLSA->getAttachedRoutersArraySize();
            OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (toLSA);
            if (toRouterLSA != NULL) {
                for (i = 0; i < routerCount; i++) {
                    if (fromNetworkLSA->getAttachedRouters(i).getInt() == toRouterLSA->getHeader().getLinkStateID()) {
                        return true;
                    }
                }
            }
        }
    }

    return false;
}

bool OSPF::Area::HasVirtualLink ( OSPF::AreaID  withTransitArea  )  const

Definition at line 186 of file OSPFArea.cc.

Referenced by OriginateRouterLSA().

{
    if ((areaID != OSPF::BackboneAreaID) || (withTransitArea == OSPF::BackboneAreaID)) {
        return false;
    }

    int interfaceNum = associatedInterfaces.size();
    for (int i = 0; i < interfaceNum; i++) {
        if ((associatedInterfaces[i]->GetType() == OSPF::Interface::Virtual) &&
            (associatedInterfaces[i]->GetTransitAreaID() == withTransitArea))
        {
            return true;
        }
    }
    return false;
}

void OSPF::Area::info ( char *  buffer  ) 

Definition at line 61 of file OSPFArea.cc.

{
    std::stringstream out;
    char areaString[16];
    out << "areaID: " << AddressStringFromULong(areaString, 16, areaID);
    strcpy(buffer, out.str().c_str());
}

bool OSPF::Area::InstallNetworkLSA ( OSPFNetworkLSA *  lsa  ) 

Definition at line 237 of file OSPFArea.cc.

Referenced by OSPF::InterfaceState::ChangeState().

{
    OSPF::LinkStateID linkStateID = lsa->getHeader().getLinkStateID();
    std::map<OSPF::LinkStateID, OSPF::NetworkLSA*>::iterator lsaIt = networkLSAsByID.find(linkStateID);
    if (lsaIt != networkLSAsByID.end()) {
        OSPF::LSAKeyType lsaKey;

        lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
        lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

        RemoveFromAllRetransmissionLists(lsaKey);
        return lsaIt->second->Update(lsa);
    } else {
        OSPF::NetworkLSA* lsaCopy = new OSPF::NetworkLSA(*lsa);
        networkLSAsByID[linkStateID] = lsaCopy;
        networkLSAs.push_back(lsaCopy);
        return true;
    }
}

bool OSPF::Area::InstallRouterLSA ( OSPFRouterLSA *  lsa  ) 

Definition at line 217 of file OSPFArea.cc.

Referenced by OSPF::InterfaceState::ChangeState().

{
    OSPF::LinkStateID linkStateID = lsa->getHeader().getLinkStateID();
    std::map<OSPF::LinkStateID, OSPF::RouterLSA*>::iterator lsaIt = routerLSAsByID.find(linkStateID);
    if (lsaIt != routerLSAsByID.end()) {
        OSPF::LSAKeyType lsaKey;

        lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
        lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

        RemoveFromAllRetransmissionLists(lsaKey);
        return lsaIt->second->Update(lsa);
    } else {
        OSPF::RouterLSA* lsaCopy = new OSPF::RouterLSA(*lsa);
        routerLSAsByID[linkStateID] = lsaCopy;
        routerLSAs.push_back(lsaCopy);
        return true;
    }
}

bool OSPF::Area::InstallSummaryLSA ( OSPFSummaryLSA *  lsa  ) 

Definition at line 257 of file OSPFArea.cc.

{
    OSPF::LSAKeyType lsaKey;

    lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
    lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

    std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find(lsaKey);
    if (lsaIt != summaryLSAsByID.end()) {
        OSPF::LSAKeyType lsaKey;

        lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
        lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

        RemoveFromAllRetransmissionLists(lsaKey);
        return lsaIt->second->Update(lsa);
    } else {
        OSPF::SummaryLSA* lsaCopy = new OSPF::SummaryLSA(*lsa);
        summaryLSAsByID[lsaKey] = lsaCopy;
        summaryLSAs.push_back(lsaCopy);
        return true;
    }
}

bool OSPF::Area::IsLocalAddress ( OSPF::IPv4Address  address  )  const

Definition at line 677 of file OSPFArea.cc.

{
    long interfaceCount = associatedInterfaces.size();
    for (long i = 0; i < interfaceCount; i++) {
        if (associatedInterfaces[i]->GetAddressRange().address == address) {
            return true;
        }
    }
    return false;
}

bool OSPF::Area::IsOnAnyRetransmissionList ( OSPF::LSAKeyType  lsaKey  )  const

Definition at line 652 of file OSPFArea.cc.

Referenced by AgeDatabase().

{
    long interfaceCount = associatedInterfaces.size();
    for (long i = 0; i < interfaceCount; i++) {
        if (associatedInterfaces[i]->IsOnAnyRetransmissionList(lsaKey)) {
            return true;
        }
    }
    return false;
}

OSPF::NetworkLSA * OSPF::Area::OriginateNetworkLSA ( const Interface intf  ) 

Definition at line 929 of file OSPFArea.cc.

Referenced by AgeDatabase(), OSPF::NeighborState::ChangeState(), and OSPF::InterfaceState::ChangeState().

{
    if (intf->HasAnyNeighborInStates(OSPF::Neighbor::FullState)) {
        OSPF::NetworkLSA* networkLSA      = new OSPF::NetworkLSA;
        OSPFLSAHeader&   lsaHeader        = networkLSA->getHeader();
        long             neighborCount    = intf->GetNeighborCount();
        OSPFOptions      lsOptions;

        lsaHeader.setLsAge(0);
        memset(&lsOptions, 0, sizeof(OSPFOptions));
        lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
        lsaHeader.setLsOptions(lsOptions);
        lsaHeader.setLsType(NetworkLSAType);
        lsaHeader.setLinkStateID(ULongFromIPv4Address(intf->GetAddressRange().address));
        lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID());
        lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);

        networkLSA->setNetworkMask(ULongFromIPv4Address(intf->GetAddressRange().mask));

        for (long j = 0; j < neighborCount; j++) {
            const OSPF::Neighbor* neighbor = intf->GetNeighbor(j);
            if (neighbor->GetState() == OSPF::Neighbor::FullState) {
                unsigned short netIndex = networkLSA->getAttachedRoutersArraySize();
                networkLSA->setAttachedRoutersArraySize(netIndex + 1);
                networkLSA->setAttachedRouters(netIndex, neighbor->GetNeighborID());
            }
        }
        unsigned short netIndex = networkLSA->getAttachedRoutersArraySize();
        networkLSA->setAttachedRoutersArraySize(netIndex + 1);
        networkLSA->setAttachedRouters(netIndex, parentRouter->GetRouterID());

        lsaHeader.setLsChecksum(0);    // TODO: calculate correct LS checksum

        return networkLSA;
    } else {
        return NULL;
    }
}

OSPF::RouterLSA * OSPF::Area::OriginateRouterLSA ( void   ) 

Definition at line 688 of file OSPFArea.cc.

Referenced by AgeDatabase(), OSPF::NeighborState::ChangeState(), OSPF::InterfaceState::ChangeState(), and OSPF::HelloHandler::ProcessPacket().

{
    OSPF::RouterLSA* routerLSA      = new OSPF::RouterLSA;
    OSPFLSAHeader&   lsaHeader      = routerLSA->getHeader();
    long             interfaceCount = associatedInterfaces.size();
    OSPFOptions      lsOptions;
    long             i;

    lsaHeader.setLsAge(0);
    memset(&lsOptions, 0, sizeof(OSPFOptions));
    lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
    lsaHeader.setLsOptions(lsOptions);
    lsaHeader.setLsType(RouterLSAType);
    lsaHeader.setLinkStateID(parentRouter->GetRouterID());
    lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID());
    lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);

    routerLSA->setB_AreaBorderRouter(parentRouter->GetAreaCount() > 1);
    routerLSA->setE_ASBoundaryRouter((externalRoutingCapability && parentRouter->GetASBoundaryRouter()) ? true : false);
    OSPF::Area* backbone = parentRouter->GetArea(OSPF::BackboneAreaID);
    routerLSA->setV_VirtualLinkEndpoint((backbone == NULL) ? false : backbone->HasVirtualLink(areaID));

    routerLSA->setNumberOfLinks(0);
    routerLSA->setLinksArraySize(0);
    for (i = 0; i < interfaceCount; i++) {
        OSPF::Interface* intf = associatedInterfaces[i];

        if (intf->GetState() == OSPF::Interface::DownState) {
            continue;
        }
        if ((intf->GetState() == OSPF::Interface::LoopbackState) &&
            ((intf->GetType() != OSPF::Interface::PointToPoint) ||
             (intf->GetAddressRange().address != OSPF::NullIPv4Address)))
        {
            Link stubLink;
            stubLink.setType(StubLink);
            stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address));
            stubLink.setLinkData(0xFFFFFFFF);
            stubLink.setLinkCost(0);
            stubLink.setNumberOfTOS(0);
            stubLink.setTosDataArraySize(0);

            unsigned short linkIndex = routerLSA->getLinksArraySize();
            routerLSA->setLinksArraySize(linkIndex + 1);
            routerLSA->setNumberOfLinks(linkIndex + 1);
            routerLSA->setLinks(linkIndex, stubLink);
        }
        if (intf->GetState() > OSPF::Interface::LoopbackState) {
            switch (intf->GetType()) {
                case OSPF::Interface::PointToPoint:
                    {
                        OSPF::Neighbor* neighbor = (intf->GetNeighborCount() > 0) ? intf->GetNeighbor(0) : NULL;
                        if (neighbor != NULL) {
                            if (neighbor->GetState() == OSPF::Neighbor::FullState) {
                                Link link;
                                link.setType(PointToPointLink);
                                link.setLinkID(neighbor->GetNeighborID());
                                if (intf->GetAddressRange().address != OSPF::NullIPv4Address) {
                                    link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address));
                                } else {
                                    link.setLinkData(intf->GetIfIndex());
                                }
                                link.setLinkCost(intf->GetOutputCost());
                                link.setNumberOfTOS(0);
                                link.setTosDataArraySize(0);

                                unsigned short linkIndex = routerLSA->getLinksArraySize();
                                routerLSA->setLinksArraySize(linkIndex + 1);
                                routerLSA->setNumberOfLinks(linkIndex + 1);
                                routerLSA->setLinks(linkIndex, link);
                            }
                            if (intf->GetState() == OSPF::Interface::PointToPointState) {
                                if (neighbor->GetAddress() != OSPF::NullIPv4Address) {
                                    Link stubLink;
                                    stubLink.setType(StubLink);
                                    stubLink.setLinkID(ULongFromIPv4Address(neighbor->GetAddress()));
                                    stubLink.setLinkData(0xFFFFFFFF);
                                    stubLink.setLinkCost(intf->GetOutputCost());
                                    stubLink.setNumberOfTOS(0);
                                    stubLink.setTosDataArraySize(0);

                                    unsigned short linkIndex = routerLSA->getLinksArraySize();
                                    routerLSA->setLinksArraySize(linkIndex + 1);
                                    routerLSA->setNumberOfLinks(linkIndex + 1);
                                    routerLSA->setLinks(linkIndex, stubLink);
                                } else {
                                    if (ULongFromIPv4Address(intf->GetAddressRange().mask) != 0xFFFFFFFF) {
                                        Link stubLink;
                                        stubLink.setType(StubLink);
                                        stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address &
                                                                                  intf->GetAddressRange().mask));
                                        stubLink.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().mask));
                                        stubLink.setLinkCost(intf->GetOutputCost());
                                        stubLink.setNumberOfTOS(0);
                                        stubLink.setTosDataArraySize(0);

                                        unsigned short linkIndex = routerLSA->getLinksArraySize();
                                        routerLSA->setLinksArraySize(linkIndex + 1);
                                        routerLSA->setNumberOfLinks(linkIndex + 1);
                                        routerLSA->setLinks(linkIndex, stubLink);
                                    }
                                }
                            }
                        }
                    }
                    break;
                case OSPF::Interface::Broadcast:
                case OSPF::Interface::NBMA:
                    {
                        if (intf->GetState() == OSPF::Interface::WaitingState) {
                            Link stubLink;
                            stubLink.setType(StubLink);
                            stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address &
                                                                      intf->GetAddressRange().mask));
                            stubLink.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().mask));
                            stubLink.setLinkCost(intf->GetOutputCost());
                            stubLink.setNumberOfTOS(0);
                            stubLink.setTosDataArraySize(0);

                            unsigned short linkIndex = routerLSA->getLinksArraySize();
                            routerLSA->setLinksArraySize(linkIndex + 1);
                            routerLSA->setNumberOfLinks(linkIndex + 1);
                            routerLSA->setLinks(linkIndex, stubLink);
                        } else {
                            OSPF::Neighbor* dRouter = intf->GetNeighborByAddress(intf->GetDesignatedRouter().ipInterfaceAddress);
                            if (((dRouter != NULL) && (dRouter->GetState() == OSPF::Neighbor::FullState)) ||
                                ((intf->GetDesignatedRouter().routerID == parentRouter->GetRouterID()) &&
                                 (intf->HasAnyNeighborInStates(OSPF::Neighbor::FullState))))
                            {
                                Link link;
                                link.setType(TransitLink);
                                link.setLinkID(ULongFromIPv4Address(intf->GetDesignatedRouter().ipInterfaceAddress));
                                link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address));
                                link.setLinkCost(intf->GetOutputCost());
                                link.setNumberOfTOS(0);
                                link.setTosDataArraySize(0);

                                unsigned short linkIndex = routerLSA->getLinksArraySize();
                                routerLSA->setLinksArraySize(linkIndex + 1);
                                routerLSA->setNumberOfLinks(linkIndex + 1);
                                routerLSA->setLinks(linkIndex, link);
                            } else {
                                Link stubLink;
                                stubLink.setType(StubLink);
                                stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address &
                                                                          intf->GetAddressRange().mask));
                                stubLink.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().mask));
                                stubLink.setLinkCost(intf->GetOutputCost());
                                stubLink.setNumberOfTOS(0);
                                stubLink.setTosDataArraySize(0);

                                unsigned short linkIndex = routerLSA->getLinksArraySize();
                                routerLSA->setLinksArraySize(linkIndex + 1);
                                routerLSA->setNumberOfLinks(linkIndex + 1);
                                routerLSA->setLinks(linkIndex, stubLink);
                            }
                        }
                    }
                    break;
                case OSPF::Interface::Virtual:
                    {
                        OSPF::Neighbor* neighbor = (intf->GetNeighborCount() > 0) ? intf->GetNeighbor(0) : NULL;
                        if ((neighbor != NULL) && (neighbor->GetState() == OSPF::Neighbor::FullState)) {
                            Link link;
                            link.setType(VirtualLink);
                            link.setLinkID(neighbor->GetNeighborID());
                            link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address));
                            link.setLinkCost(intf->GetOutputCost());
                            link.setNumberOfTOS(0);
                            link.setTosDataArraySize(0);

                            unsigned short linkIndex = routerLSA->getLinksArraySize();
                            routerLSA->setLinksArraySize(linkIndex + 1);
                            routerLSA->setNumberOfLinks(linkIndex + 1);
                            routerLSA->setLinks(linkIndex, link);
                        }
                    }
                    break;
                case OSPF::Interface::PointToMultiPoint:
                    {
                        Link stubLink;
                        stubLink.setType(StubLink);
                        stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address));
                        stubLink.setLinkData(0xFFFFFFFF);
                        stubLink.setLinkCost(0);
                        stubLink.setNumberOfTOS(0);
                        stubLink.setTosDataArraySize(0);

                        unsigned short linkIndex = routerLSA->getLinksArraySize();
                        routerLSA->setLinksArraySize(linkIndex + 1);
                        routerLSA->setNumberOfLinks(linkIndex + 1);
                        routerLSA->setLinks(linkIndex, stubLink);

                        long neighborCount = intf->GetNeighborCount();
                        for (long i = 0; i < neighborCount; i++) {
                            OSPF::Neighbor* neighbor = intf->GetNeighbor(i);
                            if (neighbor->GetState() == OSPF::Neighbor::FullState) {
                                Link link;
                                link.setType(PointToPointLink);
                                link.setLinkID(neighbor->GetNeighborID());
                                link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address));
                                link.setLinkCost(intf->GetOutputCost());
                                link.setNumberOfTOS(0);
                                link.setTosDataArraySize(0);

                                unsigned short linkIndex = routerLSA->getLinksArraySize();
                                routerLSA->setLinksArraySize(linkIndex + 1);
                                routerLSA->setNumberOfLinks(linkIndex + 1);
                                routerLSA->setLinks(linkIndex, stubLink);
                            }
                        }
                    }
                    break;
                default: break;
            }
        }
    }

    long hostRouteCount = hostRoutes.size();
    for (i = 0; i < hostRouteCount; i++) {
        Link stubLink;
        stubLink.setType(StubLink);
        stubLink.setLinkID(ULongFromIPv4Address(hostRoutes[i].address));
        stubLink.setLinkData(0xFFFFFFFF);
        stubLink.setLinkCost(hostRoutes[i].linkCost);
        stubLink.setNumberOfTOS(0);
        stubLink.setTosDataArraySize(0);

        unsigned short linkIndex = routerLSA->getLinksArraySize();
        routerLSA->setLinksArraySize(linkIndex + 1);
        routerLSA->setNumberOfLinks(linkIndex + 1);
        routerLSA->setLinks(linkIndex, stubLink);
    }

    lsaHeader.setLsChecksum(0);    // TODO: calculate correct LS checksum

    routerLSA->SetSource(OSPF::LSATrackingInfo::Originated);

    return routerLSA;
}

OSPF::SummaryLSA * OSPF::Area::OriginateSummaryLSA ( const OSPF::SummaryLSA summaryLSA  )  [private]

Definition at line 1292 of file OSPFArea.cc.

{
    const std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less> emptyMap;
    OSPF::SummaryLSA*                                             dontReoriginate = NULL;

    const OSPFLSAHeader& lsaHeader   = summaryLSA->getHeader();
    unsigned long   entryCount = parentRouter->GetRoutingTableEntryCount();

    for (unsigned long i = 0; i < entryCount; i++) {
        const OSPF::RoutingTableEntry* entry = parentRouter->GetRoutingTableEntry(i);

        if ((lsaHeader.getLsType() == SummaryLSA_ASBoundaryRoutersType) &&
            ((((entry->GetDestinationType() & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
              ((entry->GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
             ((entry->GetDestinationID().getInt() == lsaHeader.getLinkStateID()) &&
              (entry->GetAddressMask() == summaryLSA->getNetworkMask()))))
        {
            OSPF::SummaryLSA* returnLSA = OriginateSummaryLSA(entry, emptyMap, dontReoriginate);
            if (dontReoriginate != NULL) {
                delete dontReoriginate;
            }
            return returnLSA;
        }

        unsigned long lsaMask = summaryLSA->getNetworkMask().getInt();

        if ((lsaHeader.getLsType() == SummaryLSA_NetworksType) &&
            (entry->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) &&
            (entry->GetAddressMask().getInt() == lsaMask) &&
            ((entry->GetDestinationID().getInt() & lsaMask) == (lsaHeader.getLinkStateID() & lsaMask)))
        {
            OSPF::SummaryLSA* returnLSA = OriginateSummaryLSA(entry, emptyMap, dontReoriginate);
            if (dontReoriginate != NULL) {
                delete dontReoriginate;
            }
            return returnLSA;
        }
    }

    return NULL;
}

SummaryLSA* OSPF::Area::OriginateSummaryLSA ( const RoutingTableEntry entry,
const std::map< LSAKeyType, bool, LSAKeyType_Less > &  originatedLSAs,
SummaryLSA *&  lsaToReoriginate 
)

Referenced by AgeDatabase(), and OriginateSummaryLSA().

void OSPF::Area::ReCheckSummaryLSAs ( std::vector< RoutingTableEntry * > &  newRoutingTable  ) 
void OSPF::Area::RemoveFromAllRetransmissionLists ( OSPF::LSAKeyType  lsaKey  ) 

Definition at line 644 of file OSPFArea.cc.

Referenced by InstallNetworkLSA(), InstallRouterLSA(), and InstallSummaryLSA().

{
    long interfaceCount = associatedInterfaces.size();
    for (long i = 0; i < interfaceCount; i++) {
        associatedInterfaces[i]->RemoveFromAllRetransmissionLists(lsaKey);
    }
}

void OSPF::Area::SetAreaID ( AreaID  areaId  )  [inline]

Definition at line 55 of file OSPFArea.h.

{ areaID = areaId; }

void OSPF::Area::SetExternalRoutingCapability ( bool  flooded  )  [inline]

Definition at line 63 of file OSPFArea.h.

Referenced by OSPFRouting::LoadAreaFromXML().

void OSPF::Area::SetRouter ( Router router  )  [inline]

Definition at line 71 of file OSPFArea.h.

Referenced by OSPF::Router::AddArea().

{ parentRouter = router; }

void OSPF::Area::SetSPFTreeRoot ( RouterLSA root  )  [inline]

Definition at line 67 of file OSPFArea.h.

Referenced by OSPF::InterfaceState::ChangeState().

{ spfTreeRoot = root; }

void OSPF::Area::SetStubDefaultCost ( Metric  cost  )  [inline]

Definition at line 65 of file OSPFArea.h.

Referenced by OSPFRouting::LoadAreaFromXML().

{ stubDefaultCost = cost; }

void OSPF::Area::SetTransitCapability ( bool  transit  )  [inline]

Definition at line 61 of file OSPFArea.h.

{ transitCapability = transit; }


Member Data Documentation

Definition at line 35 of file OSPFArea.h.

Referenced by AddAddressRange(), and GetContainingAddressRange().

Definition at line 38 of file OSPFArea.h.

Referenced by AddHostRoute(), CalculateNextHops(), and OriginateRouterLSA().

std::vector<NetworkLSA*> OSPF::Area::networkLSAs [private]

Definition at line 41 of file OSPFArea.h.

Referenced by AgeDatabase(), FindNetworkLSA(), and InstallNetworkLSA().

std::vector<RouterLSA*> OSPF::Area::routerLSAs [private]

Definition at line 39 of file OSPFArea.h.

Referenced by AgeDatabase(), FindRouterLSA(), and InstallRouterLSA().

Definition at line 48 of file OSPFArea.h.

Referenced by CalculateNextHops(), GetSPFTreeRoot(), and SetSPFTreeRoot().

Definition at line 47 of file OSPFArea.h.

Referenced by detailedInfo(), GetStubDefaultCost(), and SetStubDefaultCost().

std::vector<SummaryLSA*> OSPF::Area::summaryLSAs [private]

Definition at line 43 of file OSPFArea.h.

Referenced by AgeDatabase(), FindSummaryLSA(), and InstallSummaryLSA().

Definition at line 45 of file OSPFArea.h.

Referenced by detailedInfo(), GetTransitCapability(), and SetTransitCapability().


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