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