|
INET Framework for OMNeT++/OMNEST
|
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