#include <InterfaceTable.h>
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.
Definition at line 66 of file InterfaceTable.h.
typedef std::vector<InterfaceEntry *> InterfaceTable::InterfaceVector [protected] |
Definition at line 73 of file InterfaceTable.h.
InterfaceTable::InterfaceTable | ( | ) |
Definition at line 41 of file InterfaceTable.cc.
{ tmpNumInterfaces = -1; tmpInterfaceList = NULL; }
InterfaceTable::~InterfaceTable | ( | ) | [virtual] |
Definition at line 47 of file InterfaceTable.cc.
{ for (int i=0; i < (int)idToInterface.size(); i++) delete idToInterface[i]; delete [] tmpInterfaceList; }
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).
Definition at line 141 of file InterfaceTable.cc.
Referenced by initialize().
{ // check name is unique if (getInterfaceByName(entry->getName())!=NULL) opp_error("addInterface(): interface '%s' already registered", entry->getName()); // insert entry->setInterfaceId(INTERFACEIDS_START + idToInterface.size()); entry->setInterfaceTable(this); idToInterface.push_back(entry); invalidateTmpInterfaceList(); // fill in networkLayerGateIndex, nodeOutputGateId, nodeInputGateId if (ifmod) discoverConnectingGates(entry, ifmod); nb->fireChangeNotification(NF_INTERFACE_CREATED, entry); }
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.
Definition at line 197 of file InterfaceTable.cc.
{ int id = entry->getInterfaceId(); if (entry != getInterfaceById(id)) opp_error("deleteInterface(): interface '%s' not found in interface table", entry->getName()); nb->fireChangeNotification(NF_INTERFACE_DELETED, entry); // actually, only going to be deleted idToInterface[id - INTERFACEIDS_START] = NULL; delete entry; invalidateTmpInterfaceList(); }
void InterfaceTable::discoverConnectingGates | ( | InterfaceEntry * | entry, | |
cModule * | ifmod | |||
) | [protected, virtual] |
Definition at line 160 of file InterfaceTable.cc.
Referenced by addInterface().
{ // ifmod is something like "host.eth[1].mac"; climb up to find "host.eth[1]" from it cModule *host = getParentModule(); while (ifmod && ifmod->getParentModule()!=host) ifmod = ifmod->getParentModule(); if (!ifmod) opp_error("addInterface(): specified module is not in this host/router"); // find gates connected to host / network layer cGate *nwlayerInGate=NULL, *nwlayerOutGate=NULL; for (GateIterator i(ifmod); !i.end(); i++) { cGate *g = i(); if (!g) continue; // find the host/router's gates that internally connect to this interface if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->getOwnerModule()==host) entry->setNodeOutputGateId(g->getNextGate()->getId()); if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->getOwnerModule()==host) entry->setNodeInputGateId(g->getPreviousGate()->getId()); // find the gate index of networkLayer/networkLayer6/mpls that connects to this interface if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->isName("ifIn")) nwlayerInGate = g->getNextGate(); if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->isName("ifOut")) nwlayerOutGate = g->getPreviousGate(); } // consistency checks // note: we don't check nodeOutputGateId/nodeInputGateId, because wireless interfaces // are not connected to the host if (!nwlayerInGate || !nwlayerOutGate || nwlayerInGate->getIndex()!=nwlayerOutGate->getIndex()) opp_error("addInterface(): interface must be connected to network layer's ifIn[]/ifOut[] gates of the same index"); entry->setNetworkLayerGateIndex(nwlayerInGate->getIndex()); }
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.)
Definition at line 267 of file InterfaceTable.cc.
{ Enter_Method_Silent(); int n = idToInterface.size(); for (int i=0; i<n; i++) if (idToInterface[i] && idToInterface[i]->isLoopback()) return idToInterface[i]; return NULL; }
virtual std::string InterfaceTable::getFullPath | ( | ) | const [inline, virtual] |
Definition at line 96 of file InterfaceTable.h.
{return cSimpleModule::getFullPath();}
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.
Definition at line 115 of file InterfaceTable.cc.
{ int n = getNumInterfaces(); // also fills tmpInterfaceList if (pos<0 || pos>=n) opp_error("getInterface(): interface index %d out of range 0..%d", pos, n-1); if (!tmpInterfaceList) { // collect non-NULL elements into tmpInterfaceList[] tmpInterfaceList = new InterfaceEntry *[n]; int k = 0; int maxId = idToInterface.size(); for (int i=0; i<maxId; i++) if (idToInterface[i]) tmpInterfaceList[k++] = idToInterface[i]; } return tmpInterfaceList[pos]; }
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.)
Definition at line 135 of file InterfaceTable.cc.
Referenced by deleteInterface().
{ id -= INTERFACEIDS_START; return (id<0 || id>=(int)idToInterface.size()) ? NULL : idToInterface[id]; }
InterfaceEntry * InterfaceTable::getInterfaceByName | ( | const char * | name | ) | [virtual] |
Returns an interface given by its name. Returns NULL if not found.
Definition at line 255 of file InterfaceTable.cc.
Referenced by addInterface().
{ Enter_Method_Silent(); if (!name) return NULL; int n = idToInterface.size(); for (int i=0; i<n; i++) if (idToInterface[i] && !strcmp(name, idToInterface[i]->getName())) return idToInterface[i]; return NULL; }
InterfaceEntry * InterfaceTable::getInterfaceByNetworkLayerGateIndex | ( | int | index | ) | [virtual] |
Returns an interface given by its getNetworkLayerGateIndex(). Returns NULL if not found.
Definition at line 244 of file InterfaceTable.cc.
{ // linear search is OK because normally we have don't have many interfaces and this func is rarely called Enter_Method_Silent(); int n = idToInterface.size(); for (int i=0; i<n; i++) if (idToInterface[i] && idToInterface[i]->getNetworkLayerGateIndex()==index) return idToInterface[i]; return NULL; }
InterfaceEntry * InterfaceTable::getInterfaceByNodeInputGateId | ( | int | id | ) | [virtual] |
Returns an interface given by its getNodeInputGateId(). Returns NULL if not found.
Definition at line 233 of file InterfaceTable.cc.
{ // linear search is OK because normally we have don't have many interfaces and this func is rarely called Enter_Method_Silent(); int n = idToInterface.size(); for (int i=0; i<n; i++) if (idToInterface[i] && idToInterface[i]->getNodeInputGateId()==id) return idToInterface[i]; return NULL; }
InterfaceEntry * InterfaceTable::getInterfaceByNodeOutputGateId | ( | int | id | ) | [virtual] |
Returns an interface given by its getNodeOutputGateId(). Returns NULL if not found.
Definition at line 222 of file InterfaceTable.cc.
{ // linear search is OK because normally we have don't have many interfaces and this func is rarely called Enter_Method_Silent(); int n = idToInterface.size(); for (int i=0; i<n; i++) if (idToInterface[i] && idToInterface[i]->getNodeOutputGateId()==id) return idToInterface[i]; return NULL; }
int InterfaceTable::getNumInterfaces | ( | ) | [virtual] |
Returns the number of interfaces.
Definition at line 99 of file InterfaceTable.cc.
Referenced by getInterface(), and updateDisplayString().
{ if (tmpNumInterfaces == -1) { // count non-NULL elements int n = 0; int maxId = idToInterface.size(); for (int i=0; i<maxId; i++) if (idToInterface[i]) n++; tmpNumInterfaces = n; } return tmpNumInterfaces; }
void InterfaceTable::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
Raises an error.
Definition at line 85 of file InterfaceTable.cc.
{
opp_error("This module doesn't process messages");
}
void InterfaceTable::initialize | ( | int | stage | ) | [protected, virtual] |
Definition at line 54 of file InterfaceTable.cc.
{ if (stage==0) { // get a pointer to the NotificationBoard module nb = NotificationBoardAccess().get(); // register a loopback interface InterfaceEntry *ie = new InterfaceEntry(); ie->setName("lo0"); ie->setMtu(3924); ie->setLoopback(true); addInterface(ie, NULL); } else if (stage==1) { WATCH_PTRVECTOR(idToInterface); updateDisplayString(); } }
void InterfaceTable::interfaceChanged | ( | InterfaceEntry * | entry, | |
int | category | |||
) | [protected, virtual] |
Definition at line 217 of file InterfaceTable.cc.
{ nb->fireChangeNotification(category, entry); }
void InterfaceTable::invalidateTmpInterfaceList | ( | ) | [protected, virtual] |
Definition at line 210 of file InterfaceTable.cc.
Referenced by addInterface(), and deleteInterface().
{ tmpNumInterfaces = -1; delete[] tmpInterfaceList; tmpInterfaceList = NULL; }
virtual int InterfaceTable::numInitStages | ( | ) | const [inline, protected, virtual] |
Definition at line 99 of file InterfaceTable.h.
{return 2;}
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.
Definition at line 90 of file InterfaceTable.cc.
{ // nothing needed here at the moment Enter_Method_Silent(); printNotificationBanner(category, details); }
void InterfaceTable::updateDisplayString | ( | ) | [protected, virtual] |
Definition at line 75 of file InterfaceTable.cc.
Referenced by initialize().
{ if (!ev.isGUI()) return; char buf[80]; sprintf(buf, "%d interfaces", getNumInterfaces()); getDisplayString().setTagArg("t",0,buf); }
InterfaceVector InterfaceTable::idToInterface [protected] |
Definition at line 74 of file InterfaceTable.h.
Referenced by addInterface(), deleteInterface(), getFirstLoopbackInterface(), getInterface(), getInterfaceById(), getInterfaceByName(), getInterfaceByNetworkLayerGateIndex(), getInterfaceByNodeInputGateId(), getInterfaceByNodeOutputGateId(), getNumInterfaces(), initialize(), and ~InterfaceTable().
NotificationBoard* InterfaceTable::nb [protected] |
Definition at line 69 of file InterfaceTable.h.
Referenced by addInterface(), deleteInterface(), initialize(), and interfaceChanged().
InterfaceEntry** InterfaceTable::tmpInterfaceList [protected] |
Definition at line 78 of file InterfaceTable.h.
Referenced by getInterface(), InterfaceTable(), invalidateTmpInterfaceList(), and ~InterfaceTable().
int InterfaceTable::tmpNumInterfaces [protected] |
Definition at line 77 of file InterfaceTable.h.
Referenced by getNumInterfaces(), InterfaceTable(), and invalidateTmpInterfaceList().