Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes

InterfaceTable Class Reference

#include <InterfaceTable.h>

Inheritance diagram for InterfaceTable:
IInterfaceTable INotifiable

List of all members.

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

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

Definition at line 66 of file InterfaceTable.h.


Member Typedef Documentation

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

Definition at line 73 of file InterfaceTable.h.


Constructor & Destructor Documentation

InterfaceTable::InterfaceTable (  ) 

Definition at line 41 of file InterfaceTable.cc.

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;
}


Member Function Documentation

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.

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().

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);
}


Member Data Documentation


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