00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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; }
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; }
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; }
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; }
00150
00151 bool Update (const OSPFASExternalLSA* lsa);
00152 bool DiffersFrom(const OSPFASExternalLSA* asExternalLSA) const;
00153 };
00154
00155 }
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