Multicast Routing Modelling In OMNeT++
MulticastRoutingTable.cc
Go to the documentation of this file.
00001 
00008 #include "MulticastRoutingTable.h"
00009 
00010 Define_Module(MulticastRoutingTable);
00011 
00012 using namespace std;
00013 
00015 std::ostream& operator<<(std::ostream& os, const MulticastIPRoute& e)
00016 {
00017         return os;
00018 };
00019 
00025 MulticastRoutingTable::~MulticastRoutingTable()
00026 {
00027     for (unsigned int i=0; i<multicastRoutes.size(); i++)
00028         delete multicastRoutes[i];
00029 }
00030 
00038 void MulticastRoutingTable::initialize(int stage)
00039 {
00040     if (stage==0)
00041     {
00042         // get a pointer to IInterfaceTable
00043         ift = AnsaInterfaceTableAccess().get();
00044 
00045         // watch multicast table
00046         //WATCH_PTRVECTOR(multicastRoutes);
00047         WATCH_VECTOR(showMRoute);
00048     }
00049 }
00050 
00056 void MulticastRoutingTable::updateDisplayString()
00057 {
00058     if (!ev.isGUI())
00059         return;
00060 
00061     char buf[80];
00062     sprintf(buf, "%d routes", multicastRoutes.size());
00063     getDisplayString().setTagArg("t",0,buf);
00064 }
00065 
00071 void MulticastRoutingTable::printRoutingTable() const
00072 {
00073     EV << "-- Multicast routing table --\n";
00074     for (int i=0; i<getNumRoutes(); i++)
00075         EV << getRoute(i)->detailedInfo() << "\n";
00076     EV << "\n";
00077 }
00078 
00084 void MulticastRoutingTable::handleMessage(cMessage *msg)
00085 {
00086     opp_error("This module doesn't process messages");
00087 }
00088 
00104 const MulticastIPRoute *MulticastRoutingTable::findRoute(const IPAddress& source, const IPAddress& group,
00105     const IPAddress& RP, int intId, const IPAddress& nextHop) const
00106 {
00107     int n = getNumRoutes();
00108     for (int i=0; i<n; i++)
00109         if (routeMatches(getRoute(i), source, group, RP, intId, nextHop))
00110             return getRoute(i);
00111     return NULL;
00112 }
00113 
00119 int MulticastRoutingTable::getNumRoutes() const
00120 {
00121     return multicastRoutes.size();
00122 }
00123 
00131 MulticastIPRoute *MulticastRoutingTable::getRoute(int k) const
00132 {
00133     if (k < (int)multicastRoutes.size())
00134         return multicastRoutes[k];
00135 
00136     return NULL;
00137 }
00138 
00152 bool MulticastRoutingTable::routeMatches(const MulticastIPRoute *entry,
00153     const IPAddress& source, const IPAddress& group,
00154     const IPAddress& RP, int intId, const IPAddress& nextHop) const
00155 {
00156     if (!source.isUnspecified() && !source.equals(entry->getSource()))
00157         return false;
00158     if (!group.isUnspecified() && !group.equals(entry->getGroup()))
00159         return false;
00160     if (!RP.isUnspecified() && !RP.equals(entry->getRP()))
00161         return false;
00162     if (intId!=entry->getInIntId())
00163         return false;
00164     if (!nextHop.isUnspecified() && !nextHop.equals(entry->getInIntNextHop()))
00165         return false;
00166     return true;
00167 }
00168 
00178 vector<MulticastIPRoute*> MulticastRoutingTable::getRouteFor(IPAddress group)
00179 {
00180     Enter_Method("getMulticastRoutesFor(%x)", group.getInt()); // note: str().c_str() too slow here here
00181     EV << "MulticastRoutingTable::getRouteFor - address = " << group << endl;
00182     vector<MulticastIPRoute*> routes;
00183 
00184     // search in multicast table
00185     int n = multicastRoutes.size();
00186     for (int i = 0; i < n; i++)
00187     {
00188         MulticastIPRoute *route = getRoute(i);
00189         if (route->getGroup().getInt() == group.getInt())
00190                 routes.push_back(route);
00191     }
00192 
00193     return routes;
00194 }
00195 
00196 
00207 MulticastIPRoute *MulticastRoutingTable::getRouteFor(IPAddress group, IPAddress source)
00208 {
00209     Enter_Method("getMulticastRoutesFor(%x, %x)", group.getInt(), source.getInt()); // note: str().c_str() too slow here here
00210     EV << "MulticastRoutingTable::getRouteFor - group = " << group << ", source = " << source << endl;
00211 
00212     // search in multicast routing table
00213     MulticastIPRoute *route = NULL;
00214     int n = multicastRoutes.size();
00215     int i;
00216     // go through all multicast routes
00217     for (i = 0; i < n; i++)
00218     {
00219         route = getRoute(i);
00220         if (route->getGroup().getInt() == group.getInt() && route->getSource().getInt() == source.getInt())
00221                 break;
00222     }
00223 
00224     if (i == n)
00225         return NULL;
00226     return route;
00227 }
00228 
00238 std::vector<MulticastIPRoute*> MulticastRoutingTable::getRoutesForSource(IPAddress source)
00239 {
00240         Enter_Method("getRoutesForSource(%x)", source.getInt()); // note: str().c_str() too slow here here
00241         EV << "MulticastRoutingTable::getRoutesForSource - source = " << source << endl;
00242         vector<MulticastIPRoute*> routes;
00243 
00244         // search in multicast table
00245         int n = multicastRoutes.size();
00246         int i;
00247         for (i = 0; i < n; i++)
00248         {
00249                 //FIXME works only for classfull adresses (function getNetwork) !!!!
00250                 MulticastIPRoute *route = getRoute(i);
00251                 if (route->getSource().getNetwork().getInt() == source.getInt())
00252                         routes.push_back(route);
00253         }
00254         return routes;
00255 }
00256 
00267 void MulticastRoutingTable::addRoute(const MulticastIPRoute *entry)
00268 {
00269     Enter_Method("addMulticastRoute(...)");
00270 
00271     // check for null multicast group address
00272     if (entry->getGroup().isUnspecified())
00273         error("addMulticastRoute(): multicast group address cannot be NULL");
00274 
00275     // check that group address is multicast address
00276         if (!entry->getGroup().isMulticast())
00277                 error("addMulticastRoute(): group address is not multicast address");
00278 
00279     // check for source or RP address
00280     if (entry->getSource().isUnspecified() && entry->getRP().isUnspecified())
00281         error("addMulticastRoute(): source or RP address has to be specified");
00282 
00283     // check that the incoming interface exists
00284     if (!entry->getInIntPtr() || entry->getInIntNextHop().isUnspecified())
00285         error("addMulticastRoute(): incoming interface has to be specified");
00286 
00287     // add to tables
00288     multicastRoutes.push_back(const_cast<MulticastIPRoute*>(entry));
00289 
00290     updateDisplayString();
00291     generateShowIPMroute();
00292 }
00293 
00305 bool MulticastRoutingTable::deleteRoute(const MulticastIPRoute *entry)
00306 {
00307     Enter_Method("deleteMulticastRoute(...)");
00308 
00309     // find entry in routing table
00310     vector<MulticastIPRoute*>::iterator i;
00311     for (i=multicastRoutes.begin(); i!=multicastRoutes.end(); ++i)
00312         {
00313                 if ((*i) == entry)
00314                         break;
00315         }
00316 
00317     // if entry was found, it can be deleted
00318     if (i!=multicastRoutes.end())
00319         {
00320         // first delete all timers assigned to route
00321         if (entry->getSrt() != NULL)
00322                 {
00323                         cancelEvent(entry->getSrt());
00324                         delete entry->getSrt();
00325                 }
00326                 if (entry->getGrt() != NULL)
00327                 {
00328                         cancelEvent(entry->getGrt());
00329                         delete entry->getGrt();
00330                 }
00331                 if (entry->getSat())
00332                 {
00333                         cancelEvent(entry->getSat());
00334                         delete entry->getSat();
00335                 }
00336 
00337                 // delete timers from outgoing interfaces
00338                 InterfaceVector outInt = entry->getOutInt();
00339                 for (unsigned int j = 0;j < outInt.size(); j++)
00340                 {
00341                         if (outInt[j].pruneTimer != NULL)
00342                         {
00343                                 cancelEvent(outInt[j].pruneTimer);
00344                                 delete outInt[j].pruneTimer;
00345                         }
00346                 }
00347 
00348                 // delete route
00349                 multicastRoutes.erase(i);
00350                 delete entry;
00351                 updateDisplayString();
00352                 generateShowIPMroute();
00353                 return true;
00354         }
00355     return false;
00356 }
00357 
00364 void MulticastRoutingTable::generateShowIPMroute()
00365 {
00366         EV << "MulticastRoutingTable::generateShowIPRoute()" << endl;
00367         showMRoute.clear();
00368 
00369         int n = getNumRoutes();
00370         const MulticastIPRoute* ipr;
00371 
00372         for (int i=0; i<n; i++)
00373         {
00374                 ipr = getRoute(i);
00375                 stringstream os;
00376                 os << "(";
00377                 if (ipr->getSource().isUnspecified()) os << "*, "; else os << ipr->getSource() << ",  ";
00378                 os << ipr->getGroup() << "), ";
00379                 if (!ipr->getRP().isUnspecified()) os << "RP is " << ipr->getRP()<< ", ";
00380                 os << "flags: ";
00381                 vector<flag> flags = ipr->getFlags();
00382                 for (unsigned int j = 0; j < flags.size(); j++)
00383                 {
00384                         EV << "MulticastRoutingTable::generateShowIPRoute(): Flag = " << flags[j] << endl;
00385                         switch(flags[j])
00386                         {
00387                                 case D:
00388                                         os << "D";
00389                                         break;
00390                                 case S:
00391                                         os << "S";
00392                                         break;
00393                                 case C:
00394                                         os << "C";
00395                                         break;
00396                                 case P:
00397                                         os << "P";
00398                                         break;
00399                                 case A:
00400                                         os << "A";
00401                                         break;
00402                         }
00403                 }
00404                 os << endl;
00405 
00406                 os << "Incoming interface: ";
00407                 if (ipr->getInIntPtr()) os << ipr->getInIntPtr()->getName() << ", ";
00408                 os << "RPF neighbor " << ipr->getInIntNextHop() << endl;
00409                 os << "Outgoing interface list:" << endl;
00410 
00411                 InterfaceVector all = ipr->getOutInt();
00412                 if (all.size() == 0)
00413                         os << "Null" << endl;
00414                 else
00415                         for (unsigned int k = 0; k < all.size(); k++)
00416                         {
00417                                 os << all[k].intPtr->getName() << ", ";
00418                                 if (all[k].forwarding == Forward) os << "Forward/"; else os << "Pruned/";
00419                                 if (all[k].mode == Densemode) os << "Dense"; else os << "Sparse";
00420                                 os << endl;
00421                         }
00422                 showMRoute.push_back(os.str());
00423         }
00424         stringstream out;
00425 }