#include <InterfaceTable.h>
Inheritance diagram for InterfaceTable:

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 RoutingTable 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.
Public Member Functions | |
| InterfaceTable () | |
| virtual | ~InterfaceTable () |
| virtual void | receiveChangeNotification (int category, cPolymorphic *details) |
| void | addInterface (InterfaceEntry *entry, cModule *ifmod) |
| int | numInterfaces () |
| InterfaceEntry * | interfaceAt (int pos) |
| InterfaceEntry * | interfaceByNodeOutputGateId (int id) |
| InterfaceEntry * | interfaceByNodeInputGateId (int id) |
| InterfaceEntry * | interfaceByNetworkLayerGateIndex (int index) |
| InterfaceEntry * | interfaceByName (const char *name) |
| InterfaceEntry * | firstLoopbackInterface () |
Protected Member Functions | |
| void | updateDisplayString () |
| void | discoverConnectingGates (InterfaceEntry *entry, cModule *ifmod) |
| int | numInitStages () const |
| void | initialize (int stage) |
| void | handleMessage (cMessage *) |
Private Types | |
| typedef std::vector< InterfaceEntry * > | InterfaceVector |
Private Attributes | |
| NotificationBoard * | nb |
| InterfaceVector | interfaces |
|
|
|
|
|
00041 {
00042 }
|
|
|
00045 {
00046 for (unsigned int i=0; i<interfaces.size(); i++)
00047 delete interfaces[i];
00048 }
|
|
||||||||||||
|
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 networkLayerGateIndex(), nodeOutputGateId(), and nodeInputGateId() in InterfaceEntry. It should be NULL if this is a virtual interface (e.g. loopback). Note: Interface deletion is not supported, but one can mark one as "down". 00103 {
00104 // check name is unique
00105 if (interfaceByName(entry->name())!=NULL)
00106 opp_error("addInterface(): interface '%s' already registered", entry->name());
00107
00108 // insert
00109 entry->_interfaceId = interfaces.size();
00110 interfaces.push_back(entry);
00111
00112 // fill in networkLayerGateIndex, nodeOutputGateId, nodeInputGateId
00113 if (ifmod)
00114 discoverConnectingGates(entry, ifmod);
00115 }
|
|
||||||||||||
|
00118 {
00119 // ifmod is something like "host.eth[1].mac"; climb up to find "host.eth[1]" from it
00120 cModule *host = parentModule();
00121 while (ifmod && ifmod->parentModule()!=host)
00122 ifmod = ifmod->parentModule();
00123 if (!ifmod)
00124 opp_error("addInterface(): specified module is not in this host/router");
00125
00126 // find gates connected to host / network layer
00127 cGate *nwlayerInGate=NULL, *nwlayerOutGate=NULL;
00128 for (int i=0; i<ifmod->gates(); i++)
00129 {
00130 cGate *g = ifmod->gate(i);
00131 if (!g) continue;
00132
00133 // find the host/router's gates that internally connect to this interface
00134 if (g->type()=='O' && g->toGate() && g->toGate()->ownerModule()==host)
00135 entry->setNodeOutputGateId(g->toGate()->id());
00136 if (g->type()=='I' && g->fromGate() && g->fromGate()->ownerModule()==host)
00137 entry->setNodeInputGateId(g->fromGate()->id());
00138
00139 // find the gate index of networkLayer/networkLayer6/mpls that connects to this interface
00140 if (g->type()=='O' && g->toGate() && g->toGate()->isName("ifIn"))
00141 nwlayerInGate = g->toGate();
00142 if (g->type()=='I' && g->fromGate() && g->fromGate()->isName("ifOut"))
00143 nwlayerOutGate = g->fromGate();
00144 }
00145
00146 // consistency checks
00147 // note: we don't check nodeOutputGateId/nodeInputGateId, because wireless interfaces
00148 // are not connected to the host
00149 if (!nwlayerInGate || !nwlayerOutGate || nwlayerInGate->index()!=nwlayerOutGate->index())
00150 opp_error("addInterface(): interface must be connected to network layer's ifIn[]/ifOut[] gates of the same index");
00151 entry->setNetworkLayerGateIndex(nwlayerInGate->index());
00152 }
|
|
|
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.) 00211 {
00212 Enter_Method_Silent();
00213
00214 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i)
00215 if ((*i)->isLoopback())
00216 return *i;
00217 return NULL;
00218 }
|
|
|
Raises an error. 00082 {
00083 opp_error("This module doesn't process messages");
00084 }
|
|
|
00051 {
00052 if (stage==0)
00053 {
00054 // get a pointer to the NotificationBoard module
00055 nb = NotificationBoardAccess().get();
00056
00057 // register a loopback interface
00058 InterfaceEntry *ie = new InterfaceEntry();
00059 ie->setName("lo0");
00060 ie->setMtu(3924);
00061 ie->setLoopback(true);
00062 addInterface(ie, NULL);
00063 }
00064 else if (stage==1)
00065 {
00066 WATCH_PTRVECTOR(interfaces);
00067 updateDisplayString();
00068 }
00069 }
|
|
|
Returns the InterfaceEntry specified by an index 0..numInterfaces-1. 00094 {
00095 if (pos==-1) // -1 is commonly used as "none"
00096 return NULL;
00097 if (pos<0 || pos>=(int)interfaces.size())
00098 opp_error("interfaceAt(): nonexistent interface %d", pos);
00099 return interfaces[pos];
00100 }
|
|
|
Returns an interface given by its name. Returns NULL if not found. 00199 {
00200 Enter_Method_Silent();
00201
00202 if (!name)
00203 return NULL;
00204 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i)
00205 if (!strcmp(name, (*i)->name()))
00206 return *i;
00207 return NULL;
00208 }
|
|
|
Returns an interface given by its networkLayerGateIndex(). Returns NULL if not found. 00189 {
00190 // linear search is OK because normally we have don't have many interfaces and this func is rarely called
00191 Enter_Method_Silent();
00192 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i)
00193 if ((*i)->networkLayerGateIndex()==index)
00194 return *i;
00195 return NULL;
00196 }
|
|
|
Returns an interface given by its nodeInputGateId(). Returns NULL if not found. 00179 {
00180 // linear search is OK because normally we have don't have many interfaces and this func is rarely called
00181 Enter_Method_Silent();
00182 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i)
00183 if ((*i)->nodeInputGateId()==id)
00184 return *i;
00185 return NULL;
00186 }
|
|
|
Returns an interface given by its nodeOutputGateId(). Returns NULL if not found. 00169 {
00170 // linear search is OK because normally we have don't have many interfaces and this func is rarely called
00171 Enter_Method_Silent();
00172 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i)
00173 if ((*i)->nodeOutputGateId()==id)
00174 return *i;
00175 return NULL;
00176 }
|
|
|
00071 {return 2;}
|
|
|
Returns the number of interfaces. 00101 {return interfaces.size();}
|
|
||||||||||||
|
Called by the NotificationBoard whenever a change of a category occurs to which this client has subscribed. Implements INotifiable. 00087 {
00088 // nothing needed here at the moment
00089 }
|
|
|
00072 {
00073 if (!ev.isGUI())
00074 return;
00075
00076 char buf[80];
00077 sprintf(buf, "%d interfaces", interfaces.size());
00078 displayString().setTagArg("t",0,buf);
00079 }
|
|
|
|
|
|
|
1.4.1