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