Public Member Functions | Protected Member Functions | Protected Attributes

AccessNet Class Reference

Configuration module for access networks. More...

#include <AccessNet.h>

List of all members.

Public Member Functions

virtual int size ()
 Returns number of nodes at this access router.
virtual cModule * getAccessNode ()
 Getter for router module.
virtual IPvXAddress addOverlayNode (cModule *overlayNode, bool migrate=false)
 Gathers some information about the terminal and appends it to the overlay terminal vector.
int getRandomNodeId ()
 returns a random ID
virtual cModule * removeOverlayNode (int ID)
 Removes a node from the access net.
virtual cModule * getOverlayNode (int ID)
 searches overlayTerminal[] for a given node
void selectChannel (const std::string &typeRx, const std::string &typeTx)
 set access types

Protected Member Functions

IPvXAddress getAssignedPrefix (IInterfaceTable *ift)
virtual int numInitStages () const
 OMNeT number of init stages.
virtual void initialize (int stage)
 Gather some information about the router node.
virtual void handleMessage (cMessage *msg)
 OMNeT handleMessage method.
virtual void updateDisplayString ()
 Displays the current number of terminals connected to this access net.

Protected Attributes

NodeInfo router
 this access router
std::vector< TerminalInfooverlayTerminal
 the terminals at this access router
std::vector< IPvXAddress > returnedIPs
 list of IP addresses wich are no longer in use
uint32_t lastIP
 last assigned IP address
bool useIPv6
 IPv6 address usage.
std::vector< std::string > channelTypesRx
 vector of possible access channels (rx)
std::string channelTypeRxStr
 the current active channel type (rx)
std::vector< std::string > channelTypesTx
 vector of possible access channels (tx)
std::string channelTypeTxStr
 the current active channel type (tx)
cOutVector lifetimeVector
 vector of node lifetimes

Detailed Description

Configuration module for access networks.

Definition at line 106 of file AccessNet.h.


Member Function Documentation

IPvXAddress AccessNet::addOverlayNode ( cModule *  overlayNode,
bool  migrate = false 
) [virtual]

Gathers some information about the terminal and appends it to the overlay terminal vector.

Gathers some information about the terminal and appends it to the overlay terminal vector. (called by InetUnderlayConfigurator in stage MAX_STAGE_UNDERLAY)

Definition at line 88 of file AccessNet.cc.

Referenced by InetUnderlayConfigurator::migrateNode().

{
    Enter_Method("addOverlayNode()");

    TerminalInfo terminal;
    terminal.module = node;
    terminal.interfaceTable = IPAddressResolver().interfaceTableOf(node);
    terminal.remoteInterfaceTable = router.interfaceTable;
    if (useIPv6) {
        terminal.routingTable6 = IPAddressResolver().routingTable6Of(node);
    }
    else {
        terminal.routingTable = IPAddressResolver().routingTableOf(node);
    }
    terminal.PPPInterface = node->getSubmodule("ppp", 0);
    terminal.createdAt = simTime();

    // find unassigned ip address:
    // check list of returned IPs
    // TODO: check overlays for side effects of reused IP addresses
//    if (returnedIPs.size() != 0) {
//      terminal.IPAddress = returnedIPs.back();
//      returnedIPs.pop_back();
//    }
//    else {
    if (useIPv6) {
        IPv6Words candidate(router.IPAddress);
        // we dont need to check for duplicates because of the giant address space and reuse of old IPs
        candidate.d1 += ++lastIP;
        terminal.IPAddress = IPvXAddress(IPv6Address(candidate.d0, candidate.d1, candidate.d2, candidate.d3));
    } else {
        uint32_t routerAddr = router.IPAddress.get4().getInt();

        // Start at last given address, check if next address is valid and free.
        bool ip_test = false;
        for (uint32 ipOffset = lastIP + 1; ipOffset != lastIP; ipOffset++) {
            if ( ipOffset == 0x10000) {
                // Netmask = 255.255.0.0, so roll over if offset = 2**16
                ipOffset = 0;
                continue;
            }

            uint32_t ip = routerAddr + ipOffset;

            // Check if IP is valid:
            //   Reject x.y.z.0 or x.y.z.255 or x.y.255.z
            if ( ((ip & 0xff) == 0) || ((ip & 0xff) == 0xff)
                    || ((ip & 0xff00) == 0xff00) ) {
                continue;
            }

            // Check if IP is free
            ip_test = true;
            for (uint32_t i = 0; i < overlayTerminal.size(); i++) {
                if (overlayTerminal[i].IPAddress == ip) {
                    ip_test = false;
                    break;
                }
            }

            // found valid IP
            if (ip_test) {
                terminal.IPAddress = IPvXAddress(ip);
                lastIP = ipOffset;
                break;
            }
        }
        if (!ip_test)
            opp_error ("Error creating node: No available IP in access net!");
    }
//    }

    // update ip display string
    if (ev.isGUI()) {
        const char* ip_disp = const_cast<char*>
        (terminal.IPAddress.str().c_str());
        terminal.module->getDisplayString().insertTag("t", 0);
        terminal.module->getDisplayString().setTagArg("t", 0, ip_disp);
        terminal.module->getDisplayString().setTagArg("t", 1, "l");
    }


    //
    // Create new remote ppp interface module for this terminal
    //

    // create ppp interface module

    int k = 1;
    while ( router.module->findSubmodule("ppp", k) != -1 )
        k++;

    cModuleType* pppInterfaceModuleType = cModuleType::get("inet.linklayer.ppp.PPPInterface");
    terminal.remotePPPInterface = pppInterfaceModuleType->
    create("ppp", router.module, 0, k);


    //
    // Connect all gates
    //

    // connect terminal to access router and vice versa
    cGate* routerInGate = firstUnusedGate(router.module, "pppg", cGate::INPUT);
    cGate* routerOutGate = firstUnusedGate(router.module, "pppg", cGate::OUTPUT);

    cChannelType* channelTypeRx = cChannelType::find( channelTypeRxStr.c_str() );
    cChannelType* channelTypeTx = cChannelType::find( channelTypeTxStr.c_str() );
    if (!channelTypeRx || !channelTypeTx) 
        opp_error("Could not find Channel or ChannelRx Type. Most likely "
            "parameter channelTypes does not match the channels defined "
            "in channels.ned");

    terminal.module->gate("pppg$o", 0)->connectTo(routerInGate,
                channelTypeRx->create(channelTypeRxStr.c_str()));
    routerOutGate->connectTo(terminal.module->gate("pppg$i", 0),
                 channelTypeTx->create(channelTypeTxStr.c_str()));

    // connect ppp interface module to router module and vice versa
    routerInGate->connectTo(terminal.remotePPPInterface->gate("phys$i"));
    terminal.remotePPPInterface->gate("phys$o")->connectTo(routerOutGate);

    // connect ppp interface module to network layer module and vice versa
    cModule* netwModule = router.module->getSubmodule("networkLayer");

    cGate* netwInGate = firstUnusedGate(netwModule, "ifIn");
    cGate* netwOutGate = firstUnusedGate(netwModule, "ifOut");

    netwOutGate->connectTo(terminal.remotePPPInterface->gate("netwIn"));
    terminal.remotePPPInterface->gate("netwOut")->connectTo(netwInGate);

    // connect network layer module to ip and arp modules
    cModule* ipModule;
    if (useIPv6) {
        ipModule = router.module->getSubmodule("networkLayer")->getSubmodule("ipv6");
    }
    else {
        ipModule = router.module->getSubmodule("networkLayer")->getSubmodule("ip");
    }

    cGate* ipIn = firstUnusedGate(ipModule, "queueIn");
    netwInGate->connectTo(ipIn);

    if(useIPv6) {
        cGate* ipOut = firstUnusedGate(ipModule, "queueOut");
        ipOut->connectTo(netwOutGate);
    }

#ifdef _ORIG_INET
    cModule* arpModule = router.module->getSubmodule("networkLayer")->getSubmodule("arp"); //comment out for speed-hack

    cGate* arpOut = firstUnusedGate(arpModule, "nicOut"); //comment out for speed-hack

    //cGate* ipOut = firstUnusedGate(ipModule, "queueOut"); //comment out for speed-hack
    cGate* ipOut = ipModule->gate("queueOut");

    arpOut->connectTo(netwOutGate);    //comment out for speed-hack
#endif

    //
    // Start ppp interface modules
    //
    terminal.remotePPPInterface->finalizeParameters();
    terminal.remotePPPInterface->setDisplayString("i=block/ifcard");
    terminal.remotePPPInterface->buildInside();
    terminal.remotePPPInterface->scheduleStart(simTime());
    terminal.remotePPPInterface->callInitialize();

    if ( !migrate) {
        // we are already in stage 4 and need to call initialize
    // for all previous stages manually
        for (int i=0; i < MAX_STAGE_UNDERLAY + 1; i++) {
            terminal.module->callInitialize(i);
        }
    }

    terminal.remoteInterfaceEntry = router.interfaceTable->getInterface(
            router.interfaceTable->getNumInterfaces() - 1);
    terminal.interfaceEntry = terminal.interfaceTable->getInterfaceByName("ppp0");


    //
    // Fill in interface table and routing table.
    //

    if (useIPv6) {
        //
        // Fill in interface table.

        // router
        IPv6InterfaceData* interfaceData = new IPv6InterfaceData;
        interfaceData->setAdvSendAdvertisements(true); // router
        interfaceData->assignAddress(IPv6Address::formLinkLocalAddress(terminal.remoteInterfaceEntry->getInterfaceToken()), false, 0, 0);
        terminal.remoteInterfaceEntry->setIPv6Data(interfaceData);
        terminal.remoteInterfaceEntry->setMACAddress(MACAddress::generateAutoAddress());

        // terminal
        terminal.interfaceEntry->ipv6Data()->setAdvSendAdvertisements(false); // host
        terminal.interfaceEntry->ipv6Data()->assignAddress(terminal.IPAddress.get6(), false, 0, 0);
        terminal.interfaceEntry->ipv6Data()->assignAddress(IPv6Address::formLinkLocalAddress(terminal.interfaceEntry->getInterfaceToken()), false, 0, 0);
        terminal.interfaceEntry->setMACAddress(MACAddress::generateAutoAddress());

        //
        // Fill in routing table.
        //

        // router
        router.routingTable6->addStaticRoute(terminal.IPAddress.get6(),64, terminal.remoteInterfaceEntry->getInterfaceId(), terminal.interfaceEntry->ipv6Data()->getLinkLocalAddress());

        // terminal
        terminal.routingTable6->addDefaultRoute(terminal.remoteInterfaceEntry->ipv6Data()->getLinkLocalAddress(), terminal.interfaceEntry->getInterfaceId(), 0);

    } else {

        //
        // Fill in interface table.
        //

        // router
        IPv4InterfaceData* interfaceData = new IPv4InterfaceData;
        interfaceData->setIPAddress(router.IPAddress.get4());
        interfaceData->setNetmask(IPAddress::ALLONES_ADDRESS);
        terminal.remoteInterfaceEntry->setIPv4Data(interfaceData);

        // terminal
        terminal.interfaceEntry->ipv4Data()->setIPAddress(terminal.IPAddress.get4());
        terminal.interfaceEntry->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);

        //
        // Fill in routing table.
        //

        // router
        IPRoute* re = new IPRoute();
        re->setHost(terminal.IPAddress.get4());
        re->setNetmask(IPAddress(IPAddress::ALLONES_ADDRESS));
        re->setInterface(terminal.remoteInterfaceEntry);
        re->setType(IPRoute::DIRECT);
        re->setSource(IPRoute::MANUAL);
        router.routingTable->addRoute(re);
        terminal.remoteRoutingEntry = re;

        // terminal
        IPRoute* te = new IPRoute();
        te->setHost(IPAddress::UNSPECIFIED_ADDRESS);
        te->setNetmask(IPAddress::UNSPECIFIED_ADDRESS);
        te->setGateway(router.IPAddress.get4());
        te->setInterface(terminal.interfaceEntry);
        te->setType(IPRoute::REMOTE);
        te->setSource(IPRoute::MANUAL);
        terminal.routingTable->addRoute(te);
        terminal.routingEntry = te;

    }


    // append module to overlay terminal vector
    overlayTerminal.push_back(terminal);
    //int ID = terminal.module->getId();

    updateDisplayString();

    return terminal.IPAddress;
}

virtual cModule* AccessNet::getAccessNode (  )  [inline, virtual]

Getter for router module.

Returns:
pointer to router module

Definition at line 125 of file AccessNet.h.

    {
        return router.module;
    }

IPvXAddress AccessNet::getAssignedPrefix ( IInterfaceTable *  ift  )  [protected]

Definition at line 472 of file AccessNet.cc.

Referenced by initialize().

{
    //FIXME: support multiple prefixes
    for (int i = 0; i< ift->getNumInterfaces(); i++) {
        if (!ift->getInterface(i)->isLoopback()) {
            if (ift->getInterface(i)->ipv6Data()->getNumAdvPrefixes() == 1)
                return ift->getInterface(i)->ipv6Data()->getAdvPrefix(0).prefix;
            else
                opp_error("Prefix is not unique.");
        }
    }
    return IPvXAddress();
}

cModule * AccessNet::getOverlayNode ( int  ID  )  [virtual]

searches overlayTerminal[] for a given node

Parameters:
ID position of the node in overlayTerminal
Returns:
the nodeId if found, -1 else

Definition at line 431 of file AccessNet.cc.

Referenced by InetUnderlayConfigurator::preKillNode().

{
    Enter_Method("getOverlayNode()");

    cModule* node = NULL;

    for(unsigned int i=0; i<overlayTerminal.size(); i++) {
        if(overlayTerminal[i].module->getId() == ID)
            node = overlayTerminal[i].module;
    }
    return node;
}

int AccessNet::getRandomNodeId (  ) 

returns a random ID

Definition at line 352 of file AccessNet.cc.

{
    Enter_Method("getRandomNodeId()");

    return overlayTerminal[intuniform(0, overlayTerminal.size() - 1)].module->getId();
}

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

OMNeT handleMessage method.

Parameters:
msg the message to handle

Definition at line 83 of file AccessNet.cc.

{
    error("this module doesn't handle messages, it runs only in initialize()");
}

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

Gather some information about the router node.

Definition at line 46 of file AccessNet.cc.

{
    if(stage != MIN_STAGE_UNDERLAY + 1)
        return;

    router.module = getParentModule();
    router.interfaceTable = IPAddressResolver().interfaceTableOf(getParentModule());
    useIPv6 = par("useIPv6Addresses").boolValue();
    if (useIPv6){
        router.routingTable6 = IPAddressResolver().routingTable6Of(getParentModule());
        router.IPAddress = getAssignedPrefix(router.interfaceTable);
    } else {
        router.routingTable = IPAddressResolver().routingTableOf(getParentModule());
        router.IPAddress = IPAddressResolver().addressOf(getParentModule());
    }

    channelTypesTx = cStringTokenizer(par("channelTypes"), " ").asVector();
    channelTypesRx = cStringTokenizer(par("channelTypesRx"), " ").asVector();
    
    if (channelTypesRx.size() != channelTypesTx.size()) {
        channelTypesRx = channelTypesTx;
    }
    
    int chanIndex = intuniform(0, channelTypesTx.size()-1);

    selectChannel(channelTypesRx[chanIndex], channelTypesTx[chanIndex]);

    // statistics
    lifetimeVector.setName("Terminal Lifetime");

    WATCH_VECTOR(overlayTerminal);

    lastIP = 0;

    updateDisplayString();
}

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

OMNeT number of init stages.

Returns:
neede number of init stages

Definition at line 182 of file AccessNet.h.

    {
        return MAX_STAGE_UNDERLAY + 1;
    }

cModule * AccessNet::removeOverlayNode ( int  ID  )  [virtual]

Removes a node from the access net.

Definition at line 359 of file AccessNet.cc.

Referenced by InetUnderlayConfigurator::handleTimerEvent(), and InetUnderlayConfigurator::migrateNode().

{
    Enter_Method("removeOverlayNode()");

    cModule* node = NULL;
    TerminalInfo terminal;
    int index;

    for(unsigned int i=0; i<overlayTerminal.size(); i++) {
        if(overlayTerminal[i].module->getId() == ID) {
            terminal = overlayTerminal[i];
            node = terminal.module;
            index = i;
        }
    }

    if(node == NULL) return NULL;

    cModule* ppp = terminal.remotePPPInterface;

    // disconnect terminal
    node->gate("pppg$o", 0)->disconnect();
    node->gate("pppg$i", 0)->getPreviousGate()->disconnect();

    // disconnect ip and arp modules
    ppp->gate("netwIn")->getPathStartGate()->disconnect();
    ppp->gate("netwOut")->getNextGate()->disconnect();

    // remove associated ppp interface module
    ppp->callFinish();
    ppp->deleteModule();

    // remove associated interface table entry
    router.interfaceTable->deleteInterface(terminal.remoteInterfaceEntry);

    // remove routing entries //TODO: IPv6
    if (!useIPv6) {
        terminal.routingTable->deleteRoute(terminal.routingEntry);
        router.routingTable->deleteRoute(terminal.remoteRoutingEntry);
    } else {
#if 0
        for (int i = 0; i < terminal.routingTable6->getNumRoutes(); i++) {
            IPv6Route* route = terminal.routingTable6->getRoute(i);
            if (route->getDestPrefix() == terminal.remoteInterfaceEntry->
                    ipv6Data()->getLinkLocalAddress()) {
                terminal.routingTable6->purgeDestCacheEntriesToNeighbour(terminal.remoteInterfaceEntry->ipv6Data()->getLinkLocalAddress(), route->getInterfaceId());
                terminal.routingTable6->removeRoute(route);
            }
        }
#endif

        for (int i = 0; i < router.routingTable6->getNumRoutes(); i++) {
            IPv6Route* route = router.routingTable6->getRoute(i);
            if (route->getDestPrefix() == terminal.IPAddress.get6()) {
                router.routingTable6->purgeDestCacheEntriesToNeighbour(terminal.interfaceEntry->ipv6Data()->getLinkLocalAddress(), route->getInterfaceId());
                router.routingTable6->removeRoute(route);
                break;
            }
        }
    }

    // statistics
    lifetimeVector.record(simTime() - overlayTerminal[index].createdAt);

    // remove terminal from overlay terminal vector
    overlayTerminal.erase(overlayTerminal.begin() + index);

    updateDisplayString();

    return node;
}

void AccessNet::selectChannel ( const std::string &  typeRx,
const std::string &  typeTx 
) [inline]

set access types

Parameters:
typeRx access receive type
typeTx access transmit type

Definition at line 164 of file AccessNet.h.

Referenced by initialize().

    {
        channelTypeRxStr = typeRx;
        channelTypeTxStr = typeTx;
    }

virtual int AccessNet::size (  )  [inline, virtual]

Returns number of nodes at this access router.

Returns:
number of nodes

Definition at line 115 of file AccessNet.h.

    {
        return overlayTerminal.size();
    }

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

Displays the current number of terminals connected to this access net.

Definition at line 444 of file AccessNet.cc.

Referenced by addOverlayNode(), initialize(), and removeOverlayNode().

{
    if (ev.isGUI()) {
        char buf[80];
        if ( overlayTerminal.size() == 1 ) {
            sprintf(buf, "1 terminal connected");
        } else {
            sprintf(buf, "%zi terminals connected", overlayTerminal.size());
        }
        getDisplayString().setTagArg("t", 0, buf);
        getDisplayString().setTagArg("t", 2, "blue");
    }
}


Member Data Documentation

std::string AccessNet::channelTypeRxStr [protected]

the current active channel type (rx)

Definition at line 208 of file AccessNet.h.

Referenced by addOverlayNode(), and selectChannel().

std::vector<std::string> AccessNet::channelTypesRx [protected]

vector of possible access channels (rx)

Definition at line 207 of file AccessNet.h.

Referenced by initialize().

std::vector<std::string> AccessNet::channelTypesTx [protected]

vector of possible access channels (tx)

Definition at line 209 of file AccessNet.h.

Referenced by initialize().

std::string AccessNet::channelTypeTxStr [protected]

the current active channel type (tx)

Definition at line 210 of file AccessNet.h.

Referenced by addOverlayNode(), and selectChannel().

uint32_t AccessNet::lastIP [protected]

last assigned IP address

Definition at line 204 of file AccessNet.h.

Referenced by addOverlayNode(), and initialize().

cOutVector AccessNet::lifetimeVector [protected]

vector of node lifetimes

Definition at line 213 of file AccessNet.h.

Referenced by initialize(), and removeOverlayNode().

std::vector<TerminalInfo> AccessNet::overlayTerminal [protected]

the terminals at this access router

Definition at line 173 of file AccessNet.h.

Referenced by addOverlayNode(), getOverlayNode(), getRandomNodeId(), initialize(), removeOverlayNode(), size(), and updateDisplayString().

std::vector<IPvXAddress> AccessNet::returnedIPs [protected]

list of IP addresses wich are no longer in use

Definition at line 174 of file AccessNet.h.

this access router

Definition at line 172 of file AccessNet.h.

Referenced by addOverlayNode(), getAccessNode(), initialize(), and removeOverlayNode().

bool AccessNet::useIPv6 [protected]

IPv6 address usage.

Definition at line 205 of file AccessNet.h.

Referenced by addOverlayNode(), initialize(), and removeOverlayNode().


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