#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 | deleteInterface (InterfaceEntry *entry) |
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 |
typedef std::vector<InterfaceEntry *> InterfaceTable::InterfaceVector [private] |
InterfaceTable::~InterfaceTable | ( | ) | [virtual] |
void InterfaceTable::addInterface | ( | InterfaceEntry * | entry, | |
cModule * | ifmod | |||
) |
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".
00105 { 00106 // check name is unique 00107 if (interfaceByName(entry->name())!=NULL) 00108 opp_error("addInterface(): interface '%s' already registered", entry->name()); 00109 00110 // insert 00111 entry->_interfaceId = interfaces.size(); 00112 interfaces.push_back(entry); 00113 00114 // fill in networkLayerGateIndex, nodeOutputGateId, nodeInputGateId 00115 if (ifmod) 00116 discoverConnectingGates(entry, ifmod); 00117 }
void InterfaceTable::deleteInterface | ( | InterfaceEntry * | entry | ) |
00171 { 00172 InterfaceVector::iterator i = 00173 std::find(interfaces.begin(), interfaces.end(), entry); 00174 00175 interfaces.erase(i); 00176 delete entry; 00177 }
void InterfaceTable::discoverConnectingGates | ( | InterfaceEntry * | entry, | |
cModule * | ifmod | |||
) | [protected] |
00120 { 00121 // ifmod is something like "host.eth[1].mac"; climb up to find "host.eth[1]" from it 00122 cModule *host = parentModule(); 00123 while (ifmod && ifmod->parentModule()!=host) 00124 ifmod = ifmod->parentModule(); 00125 if (!ifmod) 00126 opp_error("addInterface(): specified module is not in this host/router"); 00127 00128 // find gates connected to host / network layer 00129 cGate *nwlayerInGate=NULL, *nwlayerOutGate=NULL; 00130 for (int i=0; i<ifmod->gates(); i++) 00131 { 00132 cGate *g = ifmod->gate(i); 00133 if (!g) continue; 00134 00135 // find the host/router's gates that internally connect to this interface 00136 if (g->type()=='O' && g->toGate() && g->toGate()->ownerModule()==host) 00137 entry->setNodeOutputGateId(g->toGate()->id()); 00138 if (g->type()=='I' && g->fromGate() && g->fromGate()->ownerModule()==host) 00139 entry->setNodeInputGateId(g->fromGate()->id()); 00140 00141 // find the gate index of networkLayer/networkLayer6/mpls that connects to this interface 00142 if (g->type()=='O' && g->toGate() && g->toGate()->isName("ifIn")) 00143 nwlayerInGate = g->toGate(); 00144 if (g->type()=='I' && g->fromGate() && g->fromGate()->isName("ifOut")) 00145 nwlayerOutGate = g->fromGate(); 00146 } 00147 00148 // consistency checks 00149 // note: we don't check nodeOutputGateId/nodeInputGateId, because wireless interfaces 00150 // are not connected to the host 00151 if (!nwlayerInGate || !nwlayerOutGate || nwlayerInGate->index()!=nwlayerOutGate->index()) 00152 opp_error("addInterface(): interface must be connected to network layer's ifIn[]/ifOut[] gates of the same index"); 00153 entry->setNetworkLayerGateIndex(nwlayerInGate->index()); 00154 }
InterfaceEntry * InterfaceTable::firstLoopbackInterface | ( | ) |
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.)
00222 { 00223 Enter_Method_Silent(); 00224 00225 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i) 00226 if ((*i)->isLoopback()) 00227 return *i; 00228 return NULL; 00229 }
void InterfaceTable::handleMessage | ( | cMessage * | ) | [protected] |
void InterfaceTable::initialize | ( | int | stage | ) | [protected] |
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 }
InterfaceEntry * InterfaceTable::interfaceAt | ( | int | pos | ) |
Returns the InterfaceEntry specified by an index 0..numInterfaces-1.
00096 { 00097 if (pos==-1) // -1 is commonly used as "none" 00098 return NULL; 00099 if (pos<0 || pos>=(int)interfaces.size()) 00100 opp_error("interfaceAt(): nonexistent interface %d", pos); 00101 return interfaces[pos]; 00102 }
InterfaceEntry * InterfaceTable::interfaceByName | ( | const char * | name | ) |
Returns an interface given by its name. Returns NULL if not found.
00210 { 00211 Enter_Method_Silent(); 00212 00213 if (!name) 00214 return NULL; 00215 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i) 00216 if (!strcmp(name, (*i)->name())) 00217 return *i; 00218 return NULL; 00219 }
InterfaceEntry * InterfaceTable::interfaceByNetworkLayerGateIndex | ( | int | index | ) |
Returns an interface given by its networkLayerGateIndex(). Returns NULL if not found.
00200 { 00201 // linear search is OK because normally we have don't have many interfaces and this func is rarely called 00202 Enter_Method_Silent(); 00203 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i) 00204 if ((*i)->networkLayerGateIndex()==index) 00205 return *i; 00206 return NULL; 00207 }
InterfaceEntry * InterfaceTable::interfaceByNodeInputGateId | ( | int | id | ) |
Returns an interface given by its nodeInputGateId(). Returns NULL if not found.
00190 { 00191 // linear search is OK because normally we have don't have many interfaces and this func is rarely called 00192 Enter_Method_Silent(); 00193 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i) 00194 if ((*i)->nodeInputGateId()==id) 00195 return *i; 00196 return NULL; 00197 }
InterfaceEntry * InterfaceTable::interfaceByNodeOutputGateId | ( | int | id | ) |
Returns an interface given by its nodeOutputGateId(). Returns NULL if not found.
00180 { 00181 // linear search is OK because normally we have don't have many interfaces and this func is rarely called 00182 Enter_Method_Silent(); 00183 for (InterfaceVector::iterator i=interfaces.begin(); i!=interfaces.end(); ++i) 00184 if ((*i)->nodeOutputGateId()==id) 00185 return *i; 00186 return NULL; 00187 }
int InterfaceTable::numInterfaces | ( | ) | [inline] |
void InterfaceTable::receiveChangeNotification | ( | int | category, | |
cPolymorphic * | details | |||
) | [virtual] |
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 Enter_Method_Silent(); 00090 printNotificationBanner(category, details); 00091 }
void InterfaceTable::updateDisplayString | ( | ) | [protected] |
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 }
InterfaceVector InterfaceTable::interfaces [private] |
NotificationBoard* InterfaceTable::nb [private] |