|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2004-2006 Andras Varga 00003 // Copyright (C) 2000 Institut fuer Telematik, Universitaet Karlsruhe 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 // 00019 00020 00021 // Cleanup and rewrite: Andras Varga, 2004 00022 00023 #include <stdio.h> 00024 #include <stdlib.h> 00025 #include <string.h> 00026 #include <ctype.h> 00027 #include <algorithm> 00028 #include <sstream> 00029 00030 #include "AnsaRoutingTable.h" 00031 #include "RoutingTableXmlParser.h" 00032 #include "IPRoute.h" 00033 #include "IPv4InterfaceData.h" 00034 #include "IInterfaceTable.h" 00035 #include "InterfaceTableAccess.h" 00036 #include "NotifierConsts.h" 00037 00038 00039 Define_Module(AnsaRoutingTable); 00040 00041 std::ostream& operator<<(std::ostream& os, const IPRoute& e); 00042 00043 AnsaRoutingTable::AnsaRoutingTable() 00044 { 00045 // DSDV 00046 timetolive_routing_entry = timetolive_routing_entry.getMaxTime(); 00047 initializeAD(); 00048 } 00049 00050 AnsaRoutingTable::~AnsaRoutingTable() 00051 { 00052 for (unsigned int i=0; i<routes.size(); i++) 00053 delete routes[i]; 00054 for (unsigned int i=0; i<multicastRoutes.size(); i++) 00055 delete multicastRoutes[i]; 00056 } 00057 00058 // 00059 00060 void AnsaRoutingTable::initializeAD() 00061 { 00062 ADmap[IPRoute::MANUAL]=1; 00063 ADmap[IPRoute::IFACENETMASK]=0; 00064 ADmap[IPRoute::RIP]=120; 00065 ADmap[IPRoute::OSPF]=110; 00066 ADmap[IPRoute::BGP]=20; 00067 } 00068 void AnsaRoutingTable::initialize(int stage) 00069 { 00070 if (stage==0) 00071 { 00072 // get a pointer to the NotificationBoard module and IInterfaceTable 00073 nb = NotificationBoardAccess().get(); 00074 ift = InterfaceTableAccess().get(); 00075 00076 IPForward = par("IPForward").boolValue(); 00077 00078 nb->subscribe(this, NF_INTERFACE_CREATED); 00079 nb->subscribe(this, NF_INTERFACE_DELETED); 00080 nb->subscribe(this, NF_INTERFACE_STATE_CHANGED); 00081 nb->subscribe(this, NF_INTERFACE_CONFIG_CHANGED); 00082 nb->subscribe(this, NF_INTERFACE_IPv4CONFIG_CHANGED); 00083 00084 WATCH_VECTOR(showIPRoute); // 00085 WATCH_PTRVECTOR(multicastRoutes); 00086 WATCH(IPForward); 00087 WATCH(routerId); 00088 } 00089 else if (stage==1) 00090 { 00091 // L2 modules register themselves in stage 0, so we can only configure 00092 // the interfaces in stage 1. 00093 const char *filename = par("configFile"); 00094 00095 // At this point, all L2 modules have registered themselves (added their 00096 // interface entries). Create the per-interface IPv4 data structures. 00097 IInterfaceTable *interfaceTable = InterfaceTableAccess().get(); 00098 for (int i=0; i<interfaceTable->getNumInterfaces(); ++i) 00099 configureInterfaceForIPv4(interfaceTable->getInterface(i)); 00100 00101 00102 const char *routerIdStr = par("routerId").stringValue(); 00103 00104 // read routing table file (and interface configuration) 00105 RoutingTableXmlParser parser(ift, this); 00106 if (*filename && !parser.readRoutingTableFromXml(filename, routerIdStr)) 00107 error("Error reading routing table file %s", filename); 00108 00109 // set routerId if param is not "" (==no routerId) or "auto" (in which case we'll 00110 // do it later in stage 3, after network configurators configured the interfaces) 00111 00112 if (strcmp(routerIdStr, "") && strcmp(routerIdStr, "auto")) 00113 routerId = IPAddress(routerIdStr); 00114 } 00115 else if (stage==3) 00116 { 00117 // routerID selection must be after stage==2 when network autoconfiguration 00118 // assigns interface addresses 00119 configureRouterId(); 00120 00121 // we don't use notifications during initialize(), so we do it manually. 00122 // Should be in stage=3 because autoconfigurator runs in stage=2. 00123 updateNetmaskRoutes(); 00124 00125 //printRoutingTable(); 00126 } 00127 } 00128 00129 void AnsaRoutingTable::configureRouterId() 00130 { 00131 if (routerId.isUnspecified()) // not yet configured 00132 { 00133 const char *routerIdStr = par("routerId").stringValue(); 00134 if (!strcmp(routerIdStr, "auto")) // non-"auto" cases already handled in stage 1 00135 { 00136 // choose highest interface address as routerId 00137 for (int i=0; i<ift->getNumInterfaces(); ++i) 00138 { 00139 InterfaceEntry *ie = ift->getInterface(i); 00140 if (!ie->isLoopback() && ie->ipv4Data()->getIPAddress().getInt() > routerId.getInt()) 00141 routerId = ie->ipv4Data()->getIPAddress(); 00142 } 00143 } 00144 } 00145 else // already configured 00146 { 00147 // if there is no interface with routerId yet, assign it to the loopback address; 00148 // TODO find out if this is a good practice, in which situations it is useful etc. 00149 if (getInterfaceByAddress(routerId)==NULL) 00150 { 00151 InterfaceEntry *lo0 = ift->getFirstLoopbackInterface(); 00152 lo0->ipv4Data()->setIPAddress(routerId); 00153 lo0->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS); 00154 } 00155 } 00156 } 00157 00158 void AnsaRoutingTable::updateDisplayString() 00159 { 00160 if (!ev.isGUI()) 00161 return; 00162 00163 char buf[80]; 00164 if (routerId.isUnspecified()) 00165 sprintf(buf, "%d+%d routes", routes.size(), multicastRoutes.size()); 00166 else 00167 sprintf(buf, "routerId: %s\n%d+%d routes", routerId.str().c_str(), routes.size(), multicastRoutes.size()); 00168 getDisplayString().setTagArg("t",0,buf); 00169 } 00170 00171 void AnsaRoutingTable::handleMessage(cMessage *msg) 00172 { 00173 opp_error("This module doesn't process messages"); 00174 } 00175 00176 void AnsaRoutingTable::receiveChangeNotification(int category, const cPolymorphic *details) 00177 { 00178 if (simulation.getContextType()==CTX_INITIALIZE) 00179 return; // ignore notifications during initialize 00180 00181 Enter_Method_Silent(); 00182 printNotificationBanner(category, details); 00183 00184 if (category==NF_INTERFACE_CREATED) 00185 { 00186 // add netmask route for the new interface 00187 updateNetmaskRoutes(); 00188 } 00189 else if (category==NF_INTERFACE_DELETED) 00190 { 00191 // remove all routes that point to that interface 00192 InterfaceEntry *entry = check_and_cast<InterfaceEntry*>(details); 00193 deleteInterfaceRoutes(entry); 00194 } 00195 else if (category==NF_INTERFACE_STATE_CHANGED) 00196 { 00197 updateNetmaskRoutes(); 00198 } 00199 else if (category==NF_INTERFACE_CONFIG_CHANGED) 00200 { 00201 invalidateCache(); 00202 } 00203 else if (category==NF_INTERFACE_IPv4CONFIG_CHANGED) 00204 { 00205 // if anything IPv4-related changes in the interfaces, interface netmask 00206 // based routes have to be re-built. 00207 updateNetmaskRoutes(); 00208 } 00209 } 00210 00211 void AnsaRoutingTable::deleteInterfaceRoutes(InterfaceEntry *entry) 00212 { 00213 RouteVector::iterator it = routes.begin(); 00214 while (it != routes.end()) 00215 { 00216 IPRoute *route = *it; 00217 if (route->getInterface() == entry) 00218 { 00219 deleteRoute(route); 00220 it = routes.begin(); // iterator became invalid -- start over 00221 } 00222 else 00223 { 00224 ++it; 00225 } 00226 } 00227 } 00228 00229 void AnsaRoutingTable::invalidateCache() 00230 { 00231 routingCache.clear(); 00232 localAddresses.clear(); 00233 } 00234 00235 void AnsaRoutingTable::printRoutingTable() const 00236 { 00237 EV << "-- Routing table --\n"; 00238 ev.printf("%-16s %-16s %-16s %-3s %s\n", 00239 "Destination", "Gateway", "Netmask", "Iface"); 00240 00241 for (int i=0; i<getNumRoutes(); i++) 00242 EV << getRoute(i)->detailedInfo() << "\n"; 00243 EV << "\n"; 00244 } 00245 00246 std::vector<IPAddress> AnsaRoutingTable::gatherAddresses() const 00247 { 00248 std::vector<IPAddress> addressvector; 00249 00250 for (int i=0; i<ift->getNumInterfaces(); ++i) 00251 addressvector.push_back(ift->getInterface(i)->ipv4Data()->getIPAddress()); 00252 return addressvector; 00253 } 00254 00255 //--- 00256 00257 void AnsaRoutingTable::configureInterfaceForIPv4(InterfaceEntry *ie) 00258 { 00259 IPv4InterfaceData *d = new IPv4InterfaceData(); 00260 ie->setIPv4Data(d); 00261 00262 // metric: some hints: OSPF cost (2e9/bps value), MS KB article Q299540, ... 00263 d->setMetric((int)ceil(2e9/ie->getDatarate())); // use OSPF cost as default 00264 } 00265 00266 InterfaceEntry *AnsaRoutingTable::getInterfaceByAddress(const IPAddress& addr) const 00267 { 00268 Enter_Method("getInterfaceByAddress(%x)", addr.getInt()); // note: str().c_str() too slow here 00269 00270 if (addr.isUnspecified()) 00271 return NULL; 00272 for (int i=0; i<ift->getNumInterfaces(); ++i) 00273 { 00274 InterfaceEntry *ie = ift->getInterface(i); 00275 if (ie->ipv4Data()->getIPAddress()==addr) 00276 return ie; 00277 } 00278 return NULL; 00279 } 00280 00281 00282 void AnsaRoutingTable::configureLoopbackForIPv4() 00283 { 00284 InterfaceEntry *ie = ift->getFirstLoopbackInterface(); 00285 00286 // add IPv4 info. Set 127.0.0.1/8 as address by default -- 00287 // we may reconfigure later it to be the routerId 00288 IPv4InterfaceData *d = new IPv4InterfaceData(); 00289 d->setIPAddress(IPAddress::LOOPBACK_ADDRESS); 00290 d->setNetmask(IPAddress::LOOPBACK_NETMASK); 00291 d->setMetric(1); 00292 ie->setIPv4Data(d); 00293 } 00294 00295 //--- 00296 00297 bool AnsaRoutingTable::isLocalAddress(const IPAddress& dest) const 00298 { 00299 Enter_Method("isLocalAddress(%x)", dest.getInt()); // note: str().c_str() too slow here 00300 00301 if (localAddresses.empty()) 00302 { 00303 // collect interface addresses if not yet done 00304 for (int i=0; i<ift->getNumInterfaces(); i++) 00305 { 00306 IPAddress interfaceAddr = ift->getInterface(i)->ipv4Data()->getIPAddress(); 00307 localAddresses.insert(interfaceAddr); 00308 } 00309 } 00310 00311 AddressSet::iterator it = localAddresses.find(dest); 00312 return it!=localAddresses.end(); 00313 } 00314 00315 bool AnsaRoutingTable::isLocalMulticastAddress(const IPAddress& dest) const 00316 { 00317 Enter_Method("isLocalMulticastAddress(%x)", dest.getInt()); // note: str().c_str() too slow here 00318 00319 for (int i=0; i<ift->getNumInterfaces(); i++) 00320 { 00321 InterfaceEntry *ie = ift->getInterface(i); 00322 for (unsigned int j=0; j < ie->ipv4Data()->getMulticastGroups().size(); j++) 00323 if (dest.equals(ie->ipv4Data()->getMulticastGroups()[j])) 00324 return true; 00325 } 00326 return false; 00327 } 00328 00329 void AnsaRoutingTable::dsdvTestAndDelete() 00330 { 00331 if (timetolive_routing_entry==timetolive_routing_entry.getMaxTime()) 00332 return; 00333 for (RouteVector::iterator i=routes.begin(); i!=routes.end(); ++i) 00334 { 00335 00336 IPRoute *e = *i; 00337 if (this->isLocalAddress(e->getHost())) 00338 continue; 00339 if (((e->getHost()).str() != "*") && ((e->getHost()).str() != "<unspec>") && ((e->getHost()).str() != "127.0.0.1") && (simTime()-(getInstallTime()))>timetolive_routing_entry){ 00340 //EV << "Routes ends at" << routes.end() <<"\n"; 00341 deleteRoute(e); 00342 //EV << "After deleting Routes ends at" << routes.end() <<"\n"; 00343 EV << "Deleting entry ip=" << e->getHost().str() <<"\n"; 00344 i--; 00345 } 00346 } 00347 00348 } 00349 00350 const bool AnsaRoutingTable::testValidity(const IPRoute *entry) const 00351 { 00352 if (timetolive_routing_entry==timetolive_routing_entry.getMaxTime()) 00353 return true; 00354 if (this->isLocalAddress(entry->getHost())) 00355 return true; 00356 if (((entry->getHost()).str() != "*") && ((entry->getHost()).str() != "<unspec>") && ((entry->getHost()).str() != "127.0.0.1") && (simTime()-(getInstallTime()))>timetolive_routing_entry){ 00357 return false; 00358 } 00359 return true; 00360 00361 } 00362 00363 const IPRoute *AnsaRoutingTable::findBestMatchingRoute(const IPAddress& dest) const 00364 { 00365 Enter_Method("findBestMatchingRoute(%x)", dest.getInt()); // note: str().c_str() too slow here 00366 RoutingCache::iterator it = routingCache.find(dest); 00367 00368 if (it != routingCache.end()) 00369 { 00370 if (it->second==NULL) 00371 { 00372 routingCache.clear(); 00373 localAddresses.clear(); 00374 } 00375 else if (testValidity(it->second)) 00376 { 00377 return it->second; 00378 } 00379 } 00380 00381 // find best match (one with longest prefix) 00382 // default route has zero prefix length, so (if exists) it'll be selected as last resort 00383 const IPRoute *bestRoute = NULL; 00384 uint32 longestNetmask = 0; 00385 for (RouteVector::const_iterator i=routes.begin(); i!=routes.end(); ++i) 00386 { 00387 IPRoute *e = *i; 00388 if (testValidity(e)) 00389 { 00390 if (IPAddress::maskedAddrAreEqual(dest, e->getHost(), e->getNetmask()) && // match 00391 (!bestRoute || e->getNetmask().getInt() > longestNetmask)) // longest so far 00392 { 00393 bestRoute = e; 00394 longestNetmask = e->getNetmask().getInt(); 00395 } 00396 } 00397 } 00398 00399 if (bestRoute && bestRoute->getHost()!=dest) 00400 { 00401 bestRoute=NULL; 00402 /* in this case we must find the mask must be 255.255.255.255 route */ 00403 for (RouteVector::const_iterator i=routes.begin(); i!=routes.end(); ++i) 00404 { 00405 IPRoute *e = *i; 00406 if (testValidity(e)) 00407 { 00408 if (IPAddress::maskedAddrAreEqual(dest, e->getHost(), IPAddress::ALLONES_ADDRESS) && // match 00409 (!bestRoute || e->getNetmask().getInt()>longestNetmask)) // longest so far 00410 { 00411 bestRoute = e; 00412 longestNetmask = e->getNetmask().getInt(); 00413 } 00414 } 00415 } 00416 } 00417 00418 routingCache[dest] = bestRoute; 00419 return bestRoute; 00420 } 00421 00422 InterfaceEntry *AnsaRoutingTable::getInterfaceForDestAddr(const IPAddress& dest) const 00423 { 00424 Enter_Method("getInterfaceForDestAddr(%x)", dest.getInt()); // note: str().c_str() too slow here 00425 00426 const IPRoute *e = findBestMatchingRoute(dest); 00427 return e ? e->getInterface() : NULL; 00428 } 00429 00430 IPAddress AnsaRoutingTable::getGatewayForDestAddr(const IPAddress& dest) const 00431 { 00432 Enter_Method("getGatewayForDestAddr(%x)", dest.getInt()); // note: str().c_str() too slow here 00433 00434 const IPRoute *e = findBestMatchingRoute(dest); 00435 return e ? e->getGateway() : IPAddress(); 00436 } 00437 00438 00439 MulticastRoutes AnsaRoutingTable::getMulticastRoutesFor(const IPAddress& dest) const 00440 { 00441 Enter_Method("getMulticastRoutesFor(%x)", dest.getInt()); // note: str().c_str() too slow here here 00442 00443 MulticastRoutes res; 00444 res.reserve(16); 00445 for (RouteVector::const_iterator i=multicastRoutes.begin(); i!=multicastRoutes.end(); ++i) 00446 { 00447 const IPRoute *e = *i; 00448 if (IPAddress::maskedAddrAreEqual(dest, e->getHost(), e->getNetmask())) 00449 { 00450 MulticastRoute r; 00451 r.interf = e->getInterface(); 00452 r.gateway = e->getGateway(); 00453 res.push_back(r); 00454 } 00455 } 00456 return res; 00457 } 00458 00459 00460 int AnsaRoutingTable::getNumRoutes() const 00461 { 00462 return routes.size()+multicastRoutes.size(); 00463 } 00464 00465 const IPRoute *AnsaRoutingTable::getRoute(int k) const 00466 { 00467 if (k < (int)routes.size()) 00468 return routes[k]; 00469 k -= routes.size(); 00470 if (k < (int)multicastRoutes.size()) 00471 return multicastRoutes[k]; 00472 return NULL; 00473 } 00474 00475 const IPRoute *AnsaRoutingTable::getDefaultRoute() const 00476 { 00477 int n = (int)routes.size(); 00478 for (int i=0; i<n; i++) 00479 if (routes[i]->getNetmask().isUnspecified()) 00480 return routes[i]; 00481 return NULL; 00482 } 00483 00484 const IPRoute *AnsaRoutingTable::findRoute(const IPAddress& target, const IPAddress& netmask, 00485 const IPAddress& gw, int metric, const char *dev) const 00486 { 00487 int n = getNumRoutes(); 00488 for (int i=0; i<n; i++) 00489 if (routeMatches(getRoute(i), target, netmask, gw, metric, dev)) 00490 return getRoute(i); 00491 return NULL; 00492 } 00493 00494 void AnsaRoutingTable::addRoute(const IPRoute *entry) 00495 { 00496 Enter_Method("addRoute(...)"); 00497 00498 // check for null address and default route 00499 if (entry->getHost().isUnspecified() != entry->getNetmask().isUnspecified()) 00500 error("addRoute(): to add a default route, set both host and netmask to zero"); 00501 00502 if (entry->getHost().doAnd(entry->getNetmask().isUnspecified()).getInt() != 0) 00503 error("addRoute(): suspicious route: host %s has 1-bits outside netmask %s", 00504 entry->getHost().str().c_str(), entry->getNetmask().str().c_str()); 00505 00506 // check that the interface exists 00507 00508 if (!entry->getInterface()) 00509 error("addRoute(): interface cannot be NULL"); 00510 if (checkRoute(entry)) 00511 { 00512 // if this is a default route, remove old default route (we're replacing it) 00513 if (entry->getNetmask().isUnspecified() && getDefaultRoute()!=NULL) 00514 deleteRoute(getDefaultRoute()); 00515 00516 // add to tables 00517 if (!entry->getHost().isMulticast()) 00518 routes.push_back(const_cast<IPRoute*>(entry)); 00519 else 00520 multicastRoutes.push_back(const_cast<IPRoute*>(entry)); 00521 00522 invalidateCache(); 00523 updateDisplayString(); 00524 00525 nb->fireChangeNotification(NF_IPv4_ROUTE_ADDED, entry); 00526 } 00527 generateShowIPRoute(); 00528 } 00529 00530 00531 bool AnsaRoutingTable::deleteRoute(const IPRoute *entry) 00532 { 00533 Enter_Method("deleteRoute(...)"); 00534 00535 RouteVector::iterator i = std::find(routes.begin(), routes.end(), entry); 00536 if (i!=routes.end()) 00537 { 00538 nb->fireChangeNotification(NF_IPv4_ROUTE_DELETED, entry); // rather: going to be deleted 00539 routes.erase(i); 00540 delete entry; 00541 invalidateCache(); 00542 updateDisplayString(); 00543 generateShowIPRoute(); 00544 return true; 00545 } 00546 i = std::find(multicastRoutes.begin(), multicastRoutes.end(), entry); 00547 if (i!=multicastRoutes.end()) 00548 { 00549 nb->fireChangeNotification(NF_IPv4_ROUTE_DELETED, entry); // rather: going to be deleted 00550 multicastRoutes.erase(i); 00551 delete entry; 00552 invalidateCache(); 00553 updateDisplayString(); 00554 generateShowIPRoute(); 00555 return true; 00556 } 00557 generateShowIPRoute(); 00558 return false; 00559 } 00560 00561 00562 bool AnsaRoutingTable::routeMatches(const IPRoute *entry, 00563 const IPAddress& target, const IPAddress& nmask, 00564 const IPAddress& gw, int metric, const char *dev) const 00565 { 00566 if (!target.isUnspecified() && !target.equals(entry->getHost())) 00567 return false; 00568 if (!nmask.isUnspecified() && !nmask.equals(entry->getNetmask())) 00569 return false; 00570 if (!gw.isUnspecified() && !gw.equals(entry->getGateway())) 00571 return false; 00572 if (metric && metric!=entry->getMetric()) 00573 return false; 00574 if (dev && strcmp(dev, entry->getInterfaceName())) 00575 return false; 00576 00577 return true; 00578 } 00579 00580 void AnsaRoutingTable::updateNetmaskRoutes() 00581 { 00582 // first, delete all routes with src=IFACENETMASK 00583 for (unsigned int k=0; k<routes.size(); k++) 00584 if (routes[k]->getSource()==IPRoute::IFACENETMASK) 00585 routes.erase(routes.begin()+(k--)); // '--' is necessary because indices shift down 00586 00587 // then re-add them, according to actual interface configuration 00588 for (int i=0; i<ift->getNumInterfaces(); i++) 00589 { 00590 InterfaceEntry *ie = ift->getInterface(i); 00591 if (!ie->isDown()) 00592 { 00593 if (ie->ipv4Data()->getNetmask()!=IPAddress::ALLONES_ADDRESS) 00594 { 00595 IPRoute *route = new IPRoute(); 00596 route->setType(IPRoute::DIRECT); 00597 route->setSource(IPRoute::IFACENETMASK); 00598 route->setHost((ie->ipv4Data()->getIPAddress()).doAnd(ie->ipv4Data()->getNetmask())); 00599 route->setNetmask(ie->ipv4Data()->getNetmask()); 00600 route->setGateway(IPAddress()); 00601 route->setMetric(ie->ipv4Data()->getMetric()); 00602 route->setInterface(ie); 00603 routes.push_back(route); 00604 } 00605 } 00606 } 00607 00608 invalidateCache(); 00609 updateDisplayString(); 00610 generateShowIPRoute(); 00611 } 00612 00613 bool AnsaRoutingTable::checkRoute(const IPRoute* entry) 00614 { 00615 int n = getNumRoutes(); 00616 const IPRoute* ipr = NULL; 00617 for (int i=0; i<n; i++) 00618 { 00619 if (matchHostMask(getRoute(i), entry->getHost(), entry->getNetmask())) 00620 ipr=getRoute(i); 00621 } 00622 if (ipr==NULL) 00623 return true; 00624 else 00625 { 00626 if(ADmap.find(entry->getSource())->second < ADmap.find(ipr->getSource())->second) 00627 return true; 00628 } 00629 return false; 00630 } 00631 00632 bool AnsaRoutingTable::matchHostMask(const IPRoute* entry, const IPAddress& target, const IPAddress& nmask) 00633 { 00634 if (!target.isUnspecified() && !target.equals(entry->getHost())) 00635 return false; 00636 if (!nmask.isUnspecified() && !nmask.equals(entry->getNetmask())) 00637 return false; 00638 return true; 00639 } 00640 00641 void AnsaRoutingTable::generateShowIPRoute() 00642 { 00643 showIPRoute.clear(); 00644 00645 int n = getNumRoutes(); 00646 const IPRoute* ipr; 00647 for (int i=0; i<n; i++) 00648 { 00649 ipr=getRoute(i); 00650 switch (ipr->getSource()) 00651 { 00652 case IPRoute::MANUAL: 00653 if ((ipr->getMetric())>0) 00654 showIPRoute.push_back(otherIPRouteFormat(ipr)); 00655 else 00656 showIPRoute.push_back(directIPRouteFormat(ipr)); 00657 break; 00658 00659 case IPRoute::IFACENETMASK: 00660 showIPRoute.push_back(directIPRouteFormat(ipr)); 00661 break; 00662 case IPRoute::RIP: 00663 00664 case IPRoute::OSPF: 00665 00666 case IPRoute::BGP: 00667 showIPRoute.push_back(otherIPRouteFormat(ipr)); 00668 break; 00669 default: break; 00670 } 00671 } 00672 } 00673 00674 std::string AnsaRoutingTable::directIPRouteFormat(const IPRoute* ipr) 00675 { 00676 std::stringstream str; 00677 if ((ipr->getSource())==IPRoute::IFACENETMASK) 00678 str << "C "; 00679 else 00680 str << "S "; 00681 00682 str << (ipr->getHost()).str(); 00683 str << "/"; 00684 str << (ipr->getNetmask()).getNetmaskLength(); 00685 str << " is directly connected, "; 00686 str << ipr->getInterfaceName(); 00687 00688 return str.str(); 00689 } 00690 00691 std::string AnsaRoutingTable::otherIPRouteFormat(const IPRoute* ipr) 00692 { 00693 std::stringstream str; 00694 switch (ipr->getSource()) 00695 { 00696 case IPRoute::RIP: 00697 str << "R "; 00698 break; 00699 case IPRoute::OSPF: 00700 str << "O "; 00701 break; 00702 case IPRoute::BGP: 00703 str << "B "; 00704 break; 00705 case IPRoute::MANUAL: 00706 str << "S "; 00707 break; 00708 default: 00709 break; 00710 } 00711 str << (ipr->getHost()).str(); 00712 str << "/"; 00713 str << (ipr->getNetmask()).getNetmaskLength(); 00714 str << " ["; 00715 str << ADmap.find(ipr->getSource())->second; 00716 str << "/"; 00717 str << ipr->getMetric(); 00718 str << "] via "; 00719 if ((ipr->getGateway()).isUnspecified()) 00720 str << "*"; 00721 else 00722 str << (ipr->getGateway()).str(); 00723 00724 return str.str(); 00725 }