1 #ifndef _PROTO_ROUTE_TABLE 2 #define _PROTO_ROUTE_TABLE 3 4 #include "protoAddress.h" 5 #include "protoTree.h" 6 7 /** 8 * @class ProtoRouteTable 9 * 10 * @brief Class based on the ProtoTree Patricia tree to 11 * store routing table information. Uses the 12 * ProtoAddress class to store network routing 13 * addresses. 14 * 15 * It's a pretty dumbed-down routing 16 * table at the moment, but may be enhanced in 17 * the future. Example use of the ProtoTree. 18 * 19 * Notes: 20 * 21 * 1) Only one entry per destination/prefixLen is currently allowed. 22 * (Only one route per unique destination is maintained) 23 * (We may support multiple routes per dest in the future) 24 * 25 * 2) (ifIndex == 0) and (metric < 0) are "wildcards" 26 */ 27 class ProtoRouteTable 28 { 29 public: 30 ProtoRouteTable(); 31 ~ProtoRouteTable(); 32 Init()33 void Init() {Destroy();} 34 void Destroy(); 35 IsEmpty()36 bool IsEmpty() {return (tree.IsEmpty() && !default_entry.IsValid());} 37 38 // For "GetRoute()" to work there _must_ be 39 // an exact match (dst and prefixLen) route entry in the table. 40 bool GetRoute(const ProtoAddress& dst, // input 41 unsigned int prefixLen, // input 42 ProtoAddress& gw, // output 43 unsigned int& ifIndex, // output 44 int& metric); // output 45 46 bool SetRoute(const ProtoAddress& dst, 47 unsigned int maskLen, 48 const ProtoAddress& gw, 49 unsigned int ifIndex = 0, 50 int metric = -1); 51 52 // Note gateway is optional here 53 bool DeleteRoute(const ProtoAddress& dst, 54 unsigned int maskLen, 55 const ProtoAddress* gw = NULL, 56 unsigned int ifIndex = 0); 57 58 // Find the "best" route to the given destination 59 // (Finds route entry with longest matching prefix (or default)) 60 bool FindRoute(const ProtoAddress& dstAddr, 61 unsigned int prefixLen, 62 ProtoAddress& gwAddr, 63 unsigned int& ifIndex, 64 int& metric); 65 66 class Entry : public ProtoTree::Item 67 { 68 friend class ProtoRouteTable; 69 70 public: IsValid()71 bool IsValid() const 72 {return destination.IsValid();} IsGatewayRoute()73 bool IsGatewayRoute() const 74 {return gateway.IsValid();} IsDirectRoute()75 bool IsDirectRoute() const 76 {return (!gateway.IsValid() && iface_index > 0);} SetGateway(const ProtoAddress & gwAddr)77 void SetGateway(const ProtoAddress& gwAddr) 78 {gateway = gwAddr;} ClearGateway()79 void ClearGateway() 80 {gateway.Invalidate();} SetInterface(unsigned int ifaceIndex)81 void SetInterface(unsigned int ifaceIndex) 82 {iface_index = ifaceIndex;} ClearInterface()83 void ClearInterface() 84 {iface_index = 0;} SetMetric(int value)85 void SetMetric(int value) 86 {metric = value;} 87 GetDestination()88 const ProtoAddress& GetDestination() const {return destination;} GetPrefixSize()89 unsigned int GetPrefixSize() const {return prefix_size;} // in bits GetGateway()90 const ProtoAddress& GetGateway() const {return gateway;} GetInterfaceIndex()91 unsigned int GetInterfaceIndex() const {return iface_index;} GetMetric()92 int GetMetric() const {return metric;} 93 Clear()94 void Clear() 95 { 96 destination.Invalidate(); 97 prefix_size = 0; 98 gateway.Invalidate(); 99 iface_index = 0; 100 metric = -1; 101 } 102 103 // Required ProtoTree::Item overrides GetKey()104 const char* GetKey() const {return destination.GetRawHostAddress();} GetKeysize()105 unsigned int GetKeysize() const {return prefix_size;} 106 107 private: 108 Entry(); 109 Entry(const ProtoAddress& dstAddr, unsigned int prefixSize); 110 ~Entry(); 111 112 void Init(const ProtoAddress& dstAddr, unsigned int prefixSize); 113 114 ProtoAddress destination; 115 unsigned int prefix_size; // in bits 116 ProtoAddress gateway; 117 unsigned int iface_index; 118 int metric; 119 }; // end class ProtoRouteTable::Entry 120 121 class Iterator 122 { 123 public: 124 Iterator(ProtoRouteTable& table); Reset()125 void Reset() 126 { 127 iterator.Reset(); 128 default_pending = true; 129 } 130 Entry* GetNextEntry(); 131 132 private: 133 const ProtoRouteTable& table; 134 ProtoTree::Iterator iterator; 135 bool default_pending; 136 }; // end class ProtoRouteTable::Iterator 137 friend class ProtoRouteTable::Iterator; 138 139 ProtoRouteTable::Entry* CreateEntry(const ProtoAddress& dstAddr, 140 unsigned int prefixLen); 141 142 // Get entry exactly matching dstAddr/prefixLen 143 ProtoRouteTable::Entry* GetEntry(const ProtoAddress& dstAddr, 144 unsigned int prefixLen) const; 145 146 // Find best matching route entry 147 ProtoRouteTable::Entry* FindRouteEntry(const ProtoAddress& dstAddr, 148 unsigned int prefixLen) const; 149 GetDefaultEntry()150 ProtoRouteTable::Entry* GetDefaultEntry() const 151 {return (default_entry.IsValid() ? (Entry*)&default_entry : NULL);} 152 153 void DeleteEntry(ProtoRouteTable::Entry* entry); 154 155 private: 156 ProtoTree tree; 157 Entry default_entry; 158 }; // end class ProtoRouteTable 159 160 #endif // _PROTO_ROUTE_TABLE 161