OSPFRoutingTableEntry.h

Go to the documentation of this file.
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