InterfaceTable Class Reference

#include <InterfaceTable.h>

Inheritance diagram for InterfaceTable:

IInterfaceTable INotifiable

List of all members.


Detailed Description

Represents the interface table. This object has one instance per host or router. It has methods to manage the interface table, so one can access functionality similar to the "ifconfig" command.

See the NED documentation for general overview.

This is a simple module without gates, it requires function calls to it (message handling does nothing). Methods are provided for reading and updating the interface table.

Interfaces are dynamically registered: at the start of the simulation, every L2 module adds its own InterfaceEntry to the table; after that, IPv4's IRoutingTable and IPv6's RoutingTable6 (an possibly, further L3 protocols) add protocol-specific data on each InterfaceEntry (see IPv4InterfaceData, IPv6InterfaceData, and InterfaceEntry::setIPv4Data(), InterfaceEntry::setIPv6Data())

Interfaces are represented by InterfaceEntry objects.

When interfaces need to be reliably and efficiently identified from other modules, interfaceIds should be used. They are better suited than pointers because when an interface gets removed (see deleteInterface()), it is often impossible/impractical to invalidate all pointers to it, and also because pointers are not necessarily unique (a new InterfaceEntry may get allocated exactly at the address of a previously deleted one). Interface Ids are unique (Ids of removed interfaces are not issued again), stale Ids can be detected, and they are also invariant to insertion/deletion.

Clients can get notified about interface changes by subscribing to the following notifications in NotificationBoard: NF_INTERFACE_CREATED, NF_INTERFACE_DELETED, NF_INTERFACE_STATE_CHANGED, NF_INTERFACE_CONFIG_CHANGED. State change gets fired for up/down events; all other changes fire as config change.

See also:
InterfaceEntry

Public Member Functions

 InterfaceTable ()
virtual ~InterfaceTable ()
virtual std::string getFullPath () const
virtual void receiveChangeNotification (int category, const cPolymorphic *details)
virtual void addInterface (InterfaceEntry *entry, cModule *ifmod)
virtual void deleteInterface (InterfaceEntry *entry)
virtual int getNumInterfaces ()
virtual InterfaceEntrygetInterface (int pos)
virtual InterfaceEntrygetInterfaceById (int id)
virtual InterfaceEntrygetInterfaceByNodeOutputGateId (int id)
virtual InterfaceEntrygetInterfaceByNodeInputGateId (int id)
virtual InterfaceEntrygetInterfaceByNetworkLayerGateIndex (int index)
virtual InterfaceEntrygetInterfaceByName (const char *name)
virtual InterfaceEntrygetFirstLoopbackInterface ()

Protected Types

typedef std::vector
< InterfaceEntry * > 
InterfaceVector

Protected Member Functions

virtual void updateDisplayString ()
virtual void discoverConnectingGates (InterfaceEntry *entry, cModule *ifmod)
virtual void interfaceChanged (InterfaceEntry *entry, int category)
virtual void invalidateTmpInterfaceList ()
virtual int numInitStages () const
virtual void initialize (int stage)
virtual void handleMessage (cMessage *)

Protected Attributes

NotificationBoardnb
InterfaceVector idToInterface
int tmpNumInterfaces
InterfaceEntry ** tmpInterfaceList

Member Typedef Documentation

typedef std::vector<InterfaceEntry *> InterfaceTable::InterfaceVector [protected]


Constructor & Destructor Documentation

InterfaceTable::InterfaceTable (  ) 

00042 {
00043     tmpNumInterfaces = -1;
00044     tmpInterfaceList = NULL;
00045 }

InterfaceTable::~InterfaceTable (  )  [virtual]

00048 {
00049     for (int i=0; i < (int)idToInterface.size(); i++)
00050         delete idToInterface[i];
00051     delete [] tmpInterfaceList;
00052 }


Member Function Documentation

void InterfaceTable::updateDisplayString (  )  [protected, virtual]

Referenced by initialize().

00076 {
00077     if (!ev.isGUI())
00078         return;
00079 
00080     char buf[80];
00081     sprintf(buf, "%d interfaces", getNumInterfaces());
00082     getDisplayString().setTagArg("t",0,buf);
00083 }

void InterfaceTable::discoverConnectingGates ( InterfaceEntry entry,
cModule *  ifmod 
) [protected, virtual]

Referenced by addInterface().

00161 {
00162     // ifmod is something like "host.eth[1].mac"; climb up to find "host.eth[1]" from it
00163     cModule *host = getParentModule();
00164     while (ifmod && ifmod->getParentModule()!=host)
00165         ifmod = ifmod->getParentModule();
00166     if (!ifmod)
00167         opp_error("addInterface(): specified module is not in this host/router");
00168 
00169     // find gates connected to host / network layer
00170     cGate *nwlayerInGate=NULL, *nwlayerOutGate=NULL;
00171     for (GateIterator i(ifmod); !i.end(); i++)
00172     {
00173         cGate *g = i();
00174         if (!g) continue;
00175 
00176         // find the host/router's gates that internally connect to this interface
00177         if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->getOwnerModule()==host)
00178             entry->setNodeOutputGateId(g->getNextGate()->getId());
00179         if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->getOwnerModule()==host)
00180             entry->setNodeInputGateId(g->getPreviousGate()->getId());
00181 
00182         // find the gate index of networkLayer/networkLayer6/mpls that connects to this interface
00183         if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->isName("ifIn"))
00184             nwlayerInGate = g->getNextGate();
00185         if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->isName("ifOut"))
00186             nwlayerOutGate = g->getPreviousGate();
00187     }
00188 
00189     // consistency checks
00190     // note: we don't check nodeOutputGateId/nodeInputGateId, because wireless interfaces
00191     // are not connected to the host
00192     if (!nwlayerInGate || !nwlayerOutGate || nwlayerInGate->getIndex()!=nwlayerOutGate->getIndex())
00193         opp_error("addInterface(): interface must be connected to network layer's ifIn[]/ifOut[] gates of the same index");
00194     entry->setNetworkLayerGateIndex(nwlayerInGate->getIndex());
00195 }

void InterfaceTable::interfaceChanged ( InterfaceEntry entry,
int  category 
) [protected, virtual]

Implements IInterfaceTable.

00218 {
00219     nb->fireChangeNotification(category, entry);
00220 }

void InterfaceTable::invalidateTmpInterfaceList (  )  [protected, virtual]

Referenced by addInterface(), and deleteInterface().

00211 {
00212     tmpNumInterfaces = -1;
00213     delete[] tmpInterfaceList;
00214     tmpInterfaceList = NULL;
00215 }

virtual std::string InterfaceTable::getFullPath (  )  const [inline, virtual]

Module path name

Implements IInterfaceTable.

00096 {return cSimpleModule::getFullPath();}

virtual int InterfaceTable::numInitStages (  )  const [inline, protected, virtual]

00099 {return 2;}

void InterfaceTable::initialize ( int  stage  )  [protected, virtual]

00055 {
00056     if (stage==0)
00057     {
00058         // get a pointer to the NotificationBoard module
00059         nb = NotificationBoardAccess().get();
00060 
00061         // register a loopback interface
00062         InterfaceEntry *ie = new InterfaceEntry();
00063         ie->setName("lo0");
00064         ie->setMtu(3924);
00065         ie->setLoopback(true);
00066         addInterface(ie, NULL);
00067     }
00068     else if (stage==1)
00069     {
00070         WATCH_PTRVECTOR(idToInterface);
00071         updateDisplayString();
00072     }
00073 }

void InterfaceTable::handleMessage ( cMessage *  msg  )  [protected, virtual]

Raises an error.

00086 {
00087     opp_error("This module doesn't process messages");
00088 }

void InterfaceTable::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [virtual]

Called by the NotificationBoard whenever a change of a category occurs to which this client has subscribed.

Implements INotifiable.

00091 {
00092     // nothing needed here at the moment
00093     Enter_Method_Silent();
00094     printNotificationBanner(category, details);
00095 }

void InterfaceTable::addInterface ( InterfaceEntry entry,
cModule *  ifmod 
) [virtual]

Adds an interface. The second argument should be a module which belongs to the physical interface (e.g. PPP or EtherMac) -- it will be used to discover and fill in getNetworkLayerGateIndex(), getNodeOutputGateId(), and getNodeInputGateId() in InterfaceEntry. It should be NULL if this is a virtual interface (e.g. loopback).

Implements IInterfaceTable.

Referenced by initialize().

00142 {
00143     // check name is unique
00144     if (getInterfaceByName(entry->getName())!=NULL)
00145         opp_error("addInterface(): interface '%s' already registered", entry->getName());
00146 
00147     // insert
00148     entry->setInterfaceId(INTERFACEIDS_START + idToInterface.size());
00149     entry->setInterfaceTable(this);
00150     idToInterface.push_back(entry);
00151     invalidateTmpInterfaceList();
00152 
00153     // fill in networkLayerGateIndex, nodeOutputGateId, nodeInputGateId
00154     if (ifmod)
00155         discoverConnectingGates(entry, ifmod);
00156 
00157     nb->fireChangeNotification(NF_INTERFACE_CREATED, entry);
00158 }

void InterfaceTable::deleteInterface ( InterfaceEntry entry  )  [virtual]

Deletes the given interface from the table. Indices of existing interfaces (see getInterface(int)) may change. It is an error if the given interface is not in the table.

Implements IInterfaceTable.

00198 {
00199     int id = entry->getInterfaceId();
00200     if (entry != getInterfaceById(id))
00201         opp_error("deleteInterface(): interface '%s' not found in interface table", entry->getName());
00202 
00203     nb->fireChangeNotification(NF_INTERFACE_DELETED, entry);  // actually, only going to be deleted
00204 
00205     idToInterface[id - INTERFACEIDS_START] = NULL;
00206     delete entry;
00207     invalidateTmpInterfaceList();
00208 }

int InterfaceTable::getNumInterfaces (  )  [virtual]

Returns the number of interfaces.

Implements IInterfaceTable.

Referenced by getInterface(), and updateDisplayString().

00100 {
00101     if (tmpNumInterfaces == -1)
00102     {
00103         // count non-NULL elements
00104         int n = 0;
00105         int maxId = idToInterface.size();
00106         for (int i=0; i<maxId; i++)
00107             if (idToInterface[i])
00108                 n++;
00109         tmpNumInterfaces = n;
00110     }
00111 
00112     return tmpNumInterfaces;
00113 }

InterfaceEntry * InterfaceTable::getInterface ( int  pos  )  [virtual]

Returns the InterfaceEntry specified by an index 0..numInterfaces-1. Throws an error if index is out of range.

Note that this index is NOT the same as interfaceId! Indices are not guaranteed to stay the same after interface addition/deletion, so cannot be used to reliably identify the interface. Use interfaceId to refer to interfaces from other modules or from messages/packets.

Implements IInterfaceTable.

00116 {
00117     int n = getNumInterfaces(); // also fills tmpInterfaceList
00118     if (pos<0 || pos>=n)
00119         opp_error("getInterface(): interface index %d out of range 0..%d", pos, n-1);
00120 
00121     if (!tmpInterfaceList)
00122     {
00123         // collect non-NULL elements into tmpInterfaceList[]
00124         tmpInterfaceList = new InterfaceEntry *[n];
00125         int k = 0;
00126         int maxId = idToInterface.size();
00127         for (int i=0; i<maxId; i++)
00128             if (idToInterface[i])
00129                 tmpInterfaceList[k++] = idToInterface[i];
00130     }
00131 
00132     return tmpInterfaceList[pos];
00133 }

InterfaceEntry * InterfaceTable::getInterfaceById ( int  id  )  [virtual]

Returns an interface by its Id. Ids are guaranteed to be invariant to interface deletions/additions. Returns NULL if there is no such interface (This allows detecting stale IDs without raising an error.)

Implements IInterfaceTable.

Referenced by deleteInterface().

00136 {
00137     id -= INTERFACEIDS_START;
00138     return (id<0 || id>=(int)idToInterface.size()) ? NULL : idToInterface[id];
00139 }

InterfaceEntry * InterfaceTable::getInterfaceByNodeOutputGateId ( int  id  )  [virtual]

Returns an interface given by its getNodeOutputGateId(). Returns NULL if not found.

Implements IInterfaceTable.

00223 {
00224     // linear search is OK because normally we have don't have many interfaces and this func is rarely called
00225     Enter_Method_Silent();
00226     int n = idToInterface.size();
00227     for (int i=0; i<n; i++)
00228         if (idToInterface[i] && idToInterface[i]->getNodeOutputGateId()==id)
00229             return idToInterface[i];
00230     return NULL;
00231 }

InterfaceEntry * InterfaceTable::getInterfaceByNodeInputGateId ( int  id  )  [virtual]

Returns an interface given by its getNodeInputGateId(). Returns NULL if not found.

Implements IInterfaceTable.

00234 {
00235     // linear search is OK because normally we have don't have many interfaces and this func is rarely called
00236     Enter_Method_Silent();
00237     int n = idToInterface.size();
00238     for (int i=0; i<n; i++)
00239         if (idToInterface[i] && idToInterface[i]->getNodeInputGateId()==id)
00240             return idToInterface[i];
00241     return NULL;
00242 }

InterfaceEntry * InterfaceTable::getInterfaceByNetworkLayerGateIndex ( int  index  )  [virtual]

Returns an interface given by its getNetworkLayerGateIndex(). Returns NULL if not found.

Implements IInterfaceTable.

00245 {
00246     // linear search is OK because normally we have don't have many interfaces and this func is rarely called
00247     Enter_Method_Silent();
00248     int n = idToInterface.size();
00249     for (int i=0; i<n; i++)
00250         if (idToInterface[i] && idToInterface[i]->getNetworkLayerGateIndex()==index)
00251             return idToInterface[i];
00252     return NULL;
00253 }

InterfaceEntry * InterfaceTable::getInterfaceByName ( const char *  name  )  [virtual]

Returns an interface given by its name. Returns NULL if not found.

Implements IInterfaceTable.

Referenced by addInterface().

00256 {
00257     Enter_Method_Silent();
00258     if (!name)
00259         return NULL;
00260     int n = idToInterface.size();
00261     for (int i=0; i<n; i++)
00262         if (idToInterface[i] && !strcmp(name, idToInterface[i]->getName()))
00263             return idToInterface[i];
00264     return NULL;
00265 }

InterfaceEntry * InterfaceTable::getFirstLoopbackInterface (  )  [virtual]

Returns the first interface with the isLoopback flag set. (If there's no loopback, it returns NULL -- but this should never happen because InterfaceTable itself registers a loopback interface on startup.)

Implements IInterfaceTable.

00268 {
00269     Enter_Method_Silent();
00270     int n = idToInterface.size();
00271     for (int i=0; i<n; i++)
00272         if (idToInterface[i] && idToInterface[i]->isLoopback())
00273             return idToInterface[i];
00274     return NULL;
00275 }


Member Data Documentation


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:19 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5