LSA.h

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Andras Babos and Andras Varga
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #ifndef __LSA_HPP__
00019 #define __LSA_HPP__
00020 
00021 #include "OSPFPacket_m.h"
00022 #include "OSPFcommon.h"
00023 #include <vector>
00024 #include <math.h>
00025 
00026 namespace OSPF {
00027 
00028 struct NextHop {
00029     unsigned char ifIndex;
00030     IPv4Address   hopAddress;
00031     RouterID      advertisingRouter;
00032 };
00033 
00034 class RoutingInfo
00035 {
00036 private:
00037     std::vector<NextHop>  nextHops;
00038     unsigned long         distance;
00039     OSPFLSA*              parent;
00040 
00041 public:
00042             RoutingInfo  (void) : distance(0), parent(NULL) {}
00043 
00044             RoutingInfo  (const RoutingInfo& routingInfo) : nextHops(routingInfo.nextHops), distance(routingInfo.distance), parent(routingInfo.parent) {}
00045 
00046     virtual ~RoutingInfo(void) {}
00047 
00048     void            AddNextHop          (NextHop nextHop)           { nextHops.push_back(nextHop); }
00049     void            ClearNextHops       (void)                      { nextHops.clear(); }
00050     unsigned int    GetNextHopCount     (void) const                { return nextHops.size(); }
00051     NextHop         GetNextHop          (unsigned int index) const  { return nextHops[index]; }
00052     void            SetDistance         (unsigned long d)           { distance = d; }
00053     unsigned long   GetDistance         (void) const                { return distance; }
00054     void            SetParent           (OSPFLSA* p)                { parent = p; }
00055     OSPFLSA*        GetParent           (void) const                { return parent; }
00056 };
00057 
00058 class LSATrackingInfo
00059 {
00060 public:
00061     enum InstallSource {
00062         Originated = 0,
00063         Flooded = 1
00064     };
00065 
00066 private:
00067     InstallSource   source;
00068     unsigned long   installTime;
00069 
00070 public:
00071         LSATrackingInfo(void) : source(Flooded), installTime(0) {}
00072         LSATrackingInfo(const LSATrackingInfo& info) : source(info.source), installTime(info.installTime) {}
00073 
00074     void            SetSource               (InstallSource installSource)   { source = installSource; }
00075     InstallSource   GetSource               (void) const                    { return source; }
00076     void            IncrementInstallTime    (void)                          { installTime++; }
00077     void            ResetInstallTime        (void)                          { installTime = 0; }
00078     unsigned long   GetInstallTime          (void) const                    { return installTime; }
00079 };
00080 
00081 class RouterLSA : public OSPFRouterLSA,
00082                   public RoutingInfo,
00083                   public LSATrackingInfo
00084 {
00085 public:
00086             RouterLSA  (void) : OSPFRouterLSA(), RoutingInfo(), LSATrackingInfo() {}
00087             RouterLSA  (const OSPFRouterLSA& lsa) : OSPFRouterLSA(lsa), RoutingInfo(), LSATrackingInfo() {}
00088             RouterLSA  (const RouterLSA& lsa) : OSPFRouterLSA(lsa), RoutingInfo(lsa), LSATrackingInfo(lsa) {}
00089     virtual ~RouterLSA(void) {}
00090 
00091     bool    ValidateLSChecksum() const   { return true; } // not implemented
00092 
00093     bool    Update      (const OSPFRouterLSA* lsa);
00094     bool    DiffersFrom(const OSPFRouterLSA* routerLSA) const;
00095 };
00096 
00097 class NetworkLSA : public OSPFNetworkLSA,
00098                    public RoutingInfo,
00099                    public LSATrackingInfo
00100 {
00101 public:
00102             NetworkLSA  (void) : OSPFNetworkLSA(), RoutingInfo(), LSATrackingInfo() {}
00103             NetworkLSA  (const OSPFNetworkLSA& lsa) : OSPFNetworkLSA(lsa), RoutingInfo(), LSATrackingInfo() {}
00104             NetworkLSA  (const NetworkLSA& lsa) : OSPFNetworkLSA(lsa), RoutingInfo(lsa), LSATrackingInfo(lsa) {}
00105     virtual ~NetworkLSA(void) {}
00106 
00107     bool    ValidateLSChecksum() const   { return true; } // not implemented
00108 
00109     bool    Update      (const OSPFNetworkLSA* lsa);
00110     bool    DiffersFrom(const OSPFNetworkLSA* networkLSA) const;
00111 };
00112 
00113 class SummaryLSA : public OSPFSummaryLSA,
00114                    public RoutingInfo,
00115                    public LSATrackingInfo
00116 {
00117 protected:
00118     bool    purgeable;
00119 public:
00120             SummaryLSA  (void) : OSPFSummaryLSA(), RoutingInfo(), LSATrackingInfo(), purgeable(false) {}
00121             SummaryLSA  (const OSPFSummaryLSA& lsa) : OSPFSummaryLSA(lsa), RoutingInfo(), LSATrackingInfo(), purgeable(false) {}
00122             SummaryLSA  (const SummaryLSA& lsa) : OSPFSummaryLSA(lsa), RoutingInfo(lsa), LSATrackingInfo(lsa), purgeable(lsa.purgeable) {}
00123     virtual ~SummaryLSA(void) {}
00124 
00125     bool    GetPurgeable(void) const           { return purgeable; }
00126     void    SetPurgeable(bool purge = true)    { purgeable = purge; }
00127 
00128     bool    ValidateLSChecksum() const   { return true; } // not implemented
00129 
00130     bool    Update      (const OSPFSummaryLSA* lsa);
00131     bool    DiffersFrom(const OSPFSummaryLSA* summaryLSA) const;
00132 };
00133 
00134 class ASExternalLSA : public OSPFASExternalLSA,
00135                       public RoutingInfo,
00136                       public LSATrackingInfo
00137 {
00138 protected:
00139     bool    purgeable;
00140 public:
00141             ASExternalLSA  (void) : OSPFASExternalLSA(), RoutingInfo(), LSATrackingInfo(), purgeable(false) {}
00142             ASExternalLSA  (const OSPFASExternalLSA& lsa) : OSPFASExternalLSA(lsa), RoutingInfo(), LSATrackingInfo(), purgeable(false) {}
00143             ASExternalLSA  (const ASExternalLSA& lsa) : OSPFASExternalLSA(lsa), RoutingInfo(lsa), LSATrackingInfo(lsa), purgeable(lsa.purgeable) {}
00144     virtual ~ASExternalLSA(void) {}
00145 
00146     bool    GetPurgeable(void) const           { return purgeable; }
00147     void    SetPurgeable(bool purge = true)    { purgeable = purge; }
00148 
00149     bool    ValidateLSChecksum() const   { return true; } // not implemented
00150 
00151     bool    Update      (const OSPFASExternalLSA* lsa);
00152     bool    DiffersFrom(const OSPFASExternalLSA* asExternalLSA) const;
00153 };
00154 
00155 } // namespace OSPF
00156 
00160 inline bool operator< (const OSPFLSAHeader& leftLSA, const OSPFLSAHeader& rightLSA)
00161 {
00162     long leftSequenceNumber  = leftLSA.getLsSequenceNumber();
00163     long rightSequenceNumber = rightLSA.getLsSequenceNumber();
00164 
00165     if (leftSequenceNumber < rightSequenceNumber) {
00166         return true;
00167     }
00168     if (leftSequenceNumber == rightSequenceNumber) {
00169         unsigned short leftChecksum  = leftLSA.getLsChecksum();
00170         unsigned short rightChecksum = rightLSA.getLsChecksum();
00171 
00172         if (leftChecksum < rightChecksum) {
00173             return true;
00174         }
00175         if (leftChecksum == rightChecksum) {
00176             unsigned short leftAge  = leftLSA.getLsAge();
00177             unsigned short rightAge = rightLSA.getLsAge();
00178 
00179             if ((leftAge != MAX_AGE) && (rightAge == MAX_AGE)) {
00180                 return true;
00181             }
00182             if ((abs(leftAge - rightAge) > MAX_AGE_DIFF) && (leftAge > rightAge)) {
00183                 return true;
00184             }
00185         }
00186     }
00187     return false;
00188 }
00189 
00193 inline bool operator== (const OSPFLSAHeader& leftLSA, const OSPFLSAHeader& rightLSA)
00194 {
00195     long           leftSequenceNumber  = leftLSA.getLsSequenceNumber();
00196     long           rightSequenceNumber = rightLSA.getLsSequenceNumber();
00197     unsigned short leftChecksum        = leftLSA.getLsChecksum();
00198     unsigned short rightChecksum       = rightLSA.getLsChecksum();
00199     unsigned short leftAge             = leftLSA.getLsAge();
00200     unsigned short rightAge            = rightLSA.getLsAge();
00201 
00202     if ((leftSequenceNumber == rightSequenceNumber) &&
00203         (leftChecksum == rightChecksum) &&
00204         (((leftAge == MAX_AGE) && (rightAge == MAX_AGE)) ||
00205          (((leftAge != MAX_AGE) && (rightAge != MAX_AGE)) &&
00206           (abs(leftAge - rightAge) <= MAX_AGE_DIFF))))
00207     {
00208         return true;
00209     }
00210     else {
00211         return false;
00212     }
00213 }
00214 
00215 inline bool operator== (const OSPFOptions& leftOptions, const OSPFOptions& rightOptions)
00216 {
00217     return ((leftOptions.E_ExternalRoutingCapability == rightOptions.E_ExternalRoutingCapability) &&
00218             (leftOptions.MC_MulticastForwarding      == rightOptions.MC_MulticastForwarding) &&
00219             (leftOptions.NP_Type7LSA                 == rightOptions.NP_Type7LSA) &&
00220             (leftOptions.EA_ForwardExternalLSAs      == rightOptions.EA_ForwardExternalLSAs) &&
00221             (leftOptions.DC_DemandCircuits           == rightOptions.DC_DemandCircuits));
00222 }
00223 
00224 inline bool operator!= (const OSPFOptions& leftOptions, const OSPFOptions& rightOptions)
00225 {
00226     return (!(leftOptions == rightOptions));
00227 }
00228 
00229 inline bool operator== (const OSPF::NextHop& leftHop, const OSPF::NextHop& rightHop)
00230 {
00231     return ((leftHop.ifIndex           == rightHop.ifIndex) &&
00232             (leftHop.hopAddress        == rightHop.hopAddress) &&
00233             (leftHop.advertisingRouter == rightHop.advertisingRouter));
00234 }
00235 
00236 inline bool operator!= (const OSPF::NextHop& leftHop, const OSPF::NextHop& rightHop)
00237 {
00238     return (!(leftHop == rightHop));
00239 }
00240 
00241 inline unsigned int CalculateLSASize(const OSPFRouterLSA* routerLSA)
00242 {
00243     unsigned int   lsaLength = OSPF_LSA_HEADER_LENGTH + OSPF_ROUTERLSA_HEADER_LENGTH;
00244     unsigned short linkCount = routerLSA->getLinksArraySize();
00245 
00246     for (unsigned short i = 0; i < linkCount; i++) {
00247         const Link& link = routerLSA->getLinks(i);
00248         lsaLength += OSPF_LINK_HEADER_LENGTH + (link.getTosDataArraySize() * OSPF_TOS_LENGTH);
00249     }
00250 
00251     return lsaLength;
00252 }
00253 
00254 inline unsigned int CalculateLSASize(const OSPFNetworkLSA* networkLSA)
00255 {
00256     return (OSPF_LSA_HEADER_LENGTH + OSPF_NETWORKLSA_MASK_LENGTH +
00257             (networkLSA->getAttachedRoutersArraySize() * OSPF_NETWORKLSA_ADDRESS_LENGTH));
00258 }
00259 
00260 inline unsigned int CalculateLSASize(const OSPFSummaryLSA* summaryLSA)
00261 {
00262     return (OSPF_LSA_HEADER_LENGTH + OSPF_SUMMARYLSA_HEADER_LENGTH +
00263             (summaryLSA->getTosDataArraySize() * OSPF_TOS_LENGTH));
00264 }
00265 
00266 inline unsigned int CalculateLSASize(const OSPFASExternalLSA* asExternalLSA)
00267 {
00268     return (OSPF_LSA_HEADER_LENGTH + OSPF_ASEXTERNALLSA_HEADER_LENGTH +
00269             (asExternalLSA->getContents().getExternalTOSInfoArraySize() * OSPF_ASEXTERNALLSA_TOS_INFO_LENGTH));
00270 }
00271 
00272 inline void PrintLSAHeader(const OSPFLSAHeader& lsaHeader, std::ostream& output) {
00273     char addressString[16];
00274     output << "LSAHeader: age="
00275            << lsaHeader.getLsAge()
00276            << ", type=";
00277     switch (lsaHeader.getLsType()) {
00278         case RouterLSAType:                     output << "RouterLSA";                     break;
00279         case NetworkLSAType:                    output << "NetworkLSA";                    break;
00280         case SummaryLSA_NetworksType:           output << "SummaryLSA_Networks";           break;
00281         case SummaryLSA_ASBoundaryRoutersType:  output << "SummaryLSA_ASBoundaryRouters";  break;
00282         case ASExternalLSAType:                 output << "ASExternalLSA";                 break;
00283         default:                                output << "Unknown";                       break;
00284     }
00285     output << ", LSID="
00286            << AddressStringFromULong(addressString, sizeof(addressString), lsaHeader.getLinkStateID());
00287     output << ", advertisingRouter="
00288            << AddressStringFromULong(addressString, sizeof(addressString), lsaHeader.getAdvertisingRouter().getInt())
00289            << ", seqNumber="
00290            << lsaHeader.getLsSequenceNumber();
00291     output << endl;
00292 }
00293 
00294 inline std::ostream& operator<< (std::ostream& ostr, OSPFLSA& lsa)
00295 {
00296     PrintLSAHeader(lsa.getHeader(), ostr);
00297     return ostr;
00298 }
00299 
00300 #endif // __LSA_HPP__
00301