|
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 __INET_OSPFROUTINGTABLEENTRY_H 00019 #define __INET_OSPFROUTINGTABLEENTRY_H 00020 00021 #include "IRoutingTable.h" 00022 #include "InterfaceTableAccess.h" 00023 #include "OSPFcommon.h" 00024 #include <memory.h> 00025 00026 namespace OSPF { 00027 00028 class RoutingTableEntry : public IPRoute 00029 { 00030 public: 00031 enum RoutingPathType { 00032 IntraArea = 0, 00033 InterArea = 1, 00034 Type1External = 2, 00035 Type2External = 3 00036 }; 00037 00038 typedef unsigned char RoutingDestinationType; 00039 00040 // destinationType bitfield values 00041 static const unsigned char NetworkDestination = 0; 00042 static const unsigned char AreaBorderRouterDestination = 1; 00043 static const unsigned char ASBoundaryRouterDestination = 2; 00044 00045 private: 00046 RoutingDestinationType destinationType; 00047 // destinationID is IPRoute::host 00048 // addressMask is IPRoute::netmask 00049 OSPFOptions optionalCapabilities; 00050 AreaID area; 00051 RoutingPathType pathType; 00052 Metric cost; 00053 Metric type2Cost; 00054 const OSPFLSA* linkStateOrigin; 00055 std::vector<NextHop> nextHops; 00056 // IPRoute::interfacePtr comes from nextHops[0].ifIndex 00057 // IPRoute::gateway is nextHops[0].hopAddress 00058 00059 public: 00060 RoutingTableEntry (void); 00061 RoutingTableEntry (const RoutingTableEntry& entry); 00062 virtual ~RoutingTableEntry(void) {} 00063 00064 bool operator== (const RoutingTableEntry& entry) const; 00065 bool operator!= (const RoutingTableEntry& entry) const { return (!((*this) == entry)); } 00066 00067 void SetDestinationType (RoutingDestinationType type) { destinationType = type; } 00068 RoutingDestinationType GetDestinationType (void) const { return destinationType; } 00069 void SetDestinationID (IPAddress destID) { host = destID; } 00070 IPAddress GetDestinationID (void) const { return host; } 00071 void SetAddressMask (IPAddress destMask) { netmask = destMask; } 00072 IPAddress GetAddressMask (void) const { return netmask; } 00073 void SetOptionalCapabilities(OSPFOptions options) { optionalCapabilities = options; } 00074 OSPFOptions GetOptionalCapabilities(void) const { return optionalCapabilities; } 00075 void SetArea (AreaID source) { area = source; } 00076 AreaID GetArea (void) const { return area; } 00077 void SetPathType (RoutingPathType type); 00078 RoutingPathType GetPathType (void) const { return pathType; } 00079 void SetCost (Metric pathCost); 00080 Metric GetCost (void) const { return cost; } 00081 void SetType2Cost (Metric pathCost); 00082 Metric GetType2Cost (void) const { return type2Cost; } 00083 void SetLinkStateOrigin (const OSPFLSA* lsa) { linkStateOrigin = lsa; } 00084 const OSPFLSA* GetLinkStateOrigin (void) const { return linkStateOrigin; } 00085 void AddNextHop (NextHop hop); 00086 void ClearNextHops (void) { nextHops.clear(); } 00087 unsigned int GetNextHopCount (void) const { return nextHops.size(); } 00088 NextHop GetNextHop (unsigned int index) const { return nextHops[index]; } 00089 }; 00090 00091 } // namespace OSPF 00092 00093 inline OSPF::RoutingTableEntry::RoutingTableEntry(void) : 00094 IPRoute(), 00095 destinationType(OSPF::RoutingTableEntry::NetworkDestination), 00096 area(OSPF::BackboneAreaID), 00097 pathType(OSPF::RoutingTableEntry::IntraArea), 00098 type2Cost(0), 00099 linkStateOrigin(NULL) 00100 { 00101 netmask = 0xFFFFFFFF; 00102 source = IPRoute::OSPF; 00103 memset(&optionalCapabilities, 0, sizeof(OSPFOptions)); 00104 } 00105 00106 inline OSPF::RoutingTableEntry::RoutingTableEntry(const RoutingTableEntry& entry) : 00107 destinationType(entry.destinationType), 00108 optionalCapabilities(entry.optionalCapabilities), 00109 area(entry.area), 00110 pathType(entry.pathType), 00111 cost(entry.cost), 00112 type2Cost(entry.type2Cost), 00113 linkStateOrigin(entry.linkStateOrigin), 00114 nextHops(entry.nextHops) 00115 { 00116 host = entry.host; 00117 netmask = entry.netmask; 00118 gateway = entry.gateway; 00119 interfacePtr = entry.interfacePtr; 00120 type = entry.type; 00121 source = entry.source; 00122 metric = entry.metric; 00123 } 00124 00125 inline void OSPF::RoutingTableEntry::SetPathType(RoutingPathType type) 00126 { 00127 pathType = type; 00128 // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF... 00129 if (pathType == OSPF::RoutingTableEntry::Type2External) { 00130 metric = cost + type2Cost * 1000; 00131 } else { 00132 metric = cost; 00133 } 00134 } 00135 00136 inline void OSPF::RoutingTableEntry::SetCost(Metric pathCost) 00137 { 00138 cost = pathCost; 00139 // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF... 00140 if (pathType == OSPF::RoutingTableEntry::Type2External) { 00141 metric = cost + type2Cost * 1000; 00142 } else { 00143 metric = cost; 00144 } 00145 } 00146 00147 inline void OSPF::RoutingTableEntry::SetType2Cost(Metric pathCost) 00148 { 00149 type2Cost = pathCost; 00150 // FIXME: this is a hack. But the correct way to do it is to implement a separate IRoutingTable module for OSPF... 00151 if (pathType == OSPF::RoutingTableEntry::Type2External) { 00152 metric = cost + type2Cost * 1000; 00153 } else { 00154 metric = cost; 00155 } 00156 } 00157 00158 inline void OSPF::RoutingTableEntry::AddNextHop(OSPF::NextHop hop) 00159 { 00160 if (nextHops.size() == 0) { 00161 InterfaceEntry* routingInterface = InterfaceTableAccess().get()->getInterfaceById(hop.ifIndex); 00162 00163 interfacePtr = routingInterface; 00164 //gateway = ULongFromIPv4Address(hop.hopAddress); // TODO: verify this isn't necessary 00165 } 00166 nextHops.push_back(hop); 00167 } 00168 00169 inline bool OSPF::RoutingTableEntry::operator== (const RoutingTableEntry& entry) const 00170 { 00171 unsigned int hopCount = nextHops.size(); 00172 unsigned int i = 0; 00173 00174 if (hopCount != entry.nextHops.size()) { 00175 return false; 00176 } 00177 for (i = 0; i < hopCount; i++) { 00178 if ((nextHops[i] != entry.nextHops[i])) 00179 { 00180 return false; 00181 } 00182 } 00183 00184 return ((destinationType == entry.destinationType) && 00185 (host == entry.host) && 00186 (netmask == entry.netmask) && 00187 (optionalCapabilities == entry.optionalCapabilities) && 00188 (area == entry.area) && 00189 (pathType == entry.pathType) && 00190 (cost == entry.cost) && 00191 (type2Cost == entry.type2Cost) && 00192 (linkStateOrigin == entry.linkStateOrigin)); 00193 } 00194 00195 inline std::ostream& operator<< (std::ostream& out, const OSPF::RoutingTableEntry& entry) 00196 { 00197 out << "Destination: " 00198 << entry.GetDestinationID().str() 00199 << "/" 00200 << entry.GetAddressMask().str() 00201 << " ("; 00202 if (entry.GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) { 00203 out << "Network"; 00204 } else { 00205 if ((entry.GetDestinationType() & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) { 00206 out << "AreaBorderRouter"; 00207 } 00208 if ((entry.GetDestinationType() & (OSPF::RoutingTableEntry::ASBoundaryRouterDestination | OSPF::RoutingTableEntry::AreaBorderRouterDestination)) != 0) { 00209 out << "+"; 00210 } 00211 if ((entry.GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) { 00212 out << "ASBoundaryRouter"; 00213 } 00214 } 00215 out << "), Area: " 00216 << entry.GetArea() 00217 << ", PathType: "; 00218 switch (entry.GetPathType()) { 00219 case OSPF::RoutingTableEntry::IntraArea: out << "IntraArea"; break; 00220 case OSPF::RoutingTableEntry::InterArea: out << "InterArea"; break; 00221 case OSPF::RoutingTableEntry::Type1External: out << "Type1External"; break; 00222 case OSPF::RoutingTableEntry::Type2External: out << "Type2External"; break; 00223 default: out << "Unknown"; break; 00224 } 00225 out << ", Cost: " 00226 << entry.GetCost() 00227 << ", Type2Cost: " 00228 << entry.GetType2Cost() 00229 << ", Origin: ["; 00230 PrintLSAHeader(entry.GetLinkStateOrigin()->getHeader(), out); 00231 out << "], NextHops: "; 00232 00233 unsigned int hopCount = entry.GetNextHopCount(); 00234 for (unsigned int i = 0; i < hopCount; i++) { 00235 char addressString[16]; 00236 out << AddressStringFromIPv4Address(addressString, sizeof(addressString), entry.GetNextHop(i).hopAddress) 00237 << " "; 00238 } 00239 00240 return out; 00241 } 00242 00243 #endif // __INET_OSPFROUTINGTABLEENTRY_H