00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <vector>
00025 #include <iostream>
00026
00027 #include <omnetpp.h>
00028
00029 #include <IRoutingTable.h>
00030 #include <IInterfaceTable.h>
00031 #include <RoutingTable6.h>
00032 #include <IPAddressResolver.h>
00033 #include <IPv4InterfaceData.h>
00034 #include <IPv6InterfaceData.h>
00035
00036 #include "AccessNet.h"
00037
00038 Define_Module(AccessNet);
00039
00040 std::ostream& operator<<(std::ostream& os, NodeInfo& n)
00041 {
00042 os << n.IPAddress;
00043 return os;
00044 }
00045
00046 void AccessNet::initialize(int stage)
00047 {
00048 if(stage != MIN_STAGE_UNDERLAY + 1)
00049 return;
00050
00051 router.module = getParentModule();
00052 router.interfaceTable = IPAddressResolver().interfaceTableOf(getParentModule());
00053 useIPv6 = par("useIPv6Addresses").boolValue();
00054 if (useIPv6){
00055 router.routingTable6 = IPAddressResolver().routingTable6Of(getParentModule());
00056 router.IPAddress = getAssignedPrefix(router.interfaceTable);
00057 } else {
00058 router.routingTable = IPAddressResolver().routingTableOf(getParentModule());
00059 router.IPAddress = IPAddressResolver().addressOf(getParentModule());
00060 }
00061
00062 channelTypesTx = cStringTokenizer(par("channelTypes"), " ").asVector();
00063 channelTypesRx = cStringTokenizer(par("channelTypesRx"), " ").asVector();
00064
00065 if (channelTypesRx.size() != channelTypesTx.size()) {
00066 channelTypesRx = channelTypesTx;
00067 }
00068
00069 int chanIndex = intuniform(0, channelTypesTx.size()-1);
00070
00071 selectChannel(channelTypesRx[chanIndex], channelTypesTx[chanIndex]);
00072
00073
00074 lifetimeVector.setName("Terminal Lifetime");
00075
00076 WATCH_VECTOR(overlayTerminal);
00077
00078 lastIP = 0;
00079
00080 updateDisplayString();
00081 }
00082
00083 void AccessNet::handleMessage(cMessage* msg)
00084 {
00085 error("this module doesn't handle messages, it runs only in initialize()");
00086 }
00087
00088 IPvXAddress AccessNet::addOverlayNode(cModule* node, bool migrate)
00089 {
00090 Enter_Method("addOverlayNode()");
00091
00092 TerminalInfo terminal;
00093 terminal.module = node;
00094 terminal.interfaceTable = IPAddressResolver().interfaceTableOf(node);
00095 terminal.remoteInterfaceTable = router.interfaceTable;
00096 if (useIPv6) {
00097 terminal.routingTable6 = IPAddressResolver().routingTable6Of(node);
00098 }
00099 else {
00100 terminal.routingTable = IPAddressResolver().routingTableOf(node);
00101 }
00102 terminal.PPPInterface = node->getSubmodule("ppp", 0);
00103 terminal.createdAt = simTime();
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 if (useIPv6) {
00114 IPv6Words candidate(router.IPAddress);
00115
00116 candidate.d1 += ++lastIP;
00117 terminal.IPAddress = IPvXAddress(IPv6Address(candidate.d0, candidate.d1, candidate.d2, candidate.d3));
00118 } else {
00119 uint32_t routerAddr = router.IPAddress.get4().getInt();
00120
00121
00122 bool ip_test = false;
00123 for (uint32 ipOffset = lastIP + 1; ipOffset != lastIP; ipOffset++) {
00124 if ( ipOffset == 0x10000) {
00125
00126 ipOffset = 0;
00127 continue;
00128 }
00129
00130 uint32_t ip = routerAddr + ipOffset;
00131
00132
00133
00134 if ( ((ip & 0xff) == 0) || ((ip & 0xff) == 0xff)
00135 || ((ip & 0xff00) == 0xff00) ) {
00136 continue;
00137 }
00138
00139
00140 ip_test = true;
00141 for (uint32_t i = 0; i < overlayTerminal.size(); i++) {
00142 if (overlayTerminal[i].IPAddress == ip) {
00143 ip_test = false;
00144 break;
00145 }
00146 }
00147
00148
00149 if (ip_test) {
00150 terminal.IPAddress = IPvXAddress(ip);
00151 lastIP = ipOffset;
00152 break;
00153 }
00154 }
00155 if (!ip_test)
00156 opp_error ("Error creating node: No available IP in access net!");
00157 }
00158
00159
00160
00161 if (ev.isGUI()) {
00162 const char* ip_disp = const_cast<char*>
00163 (terminal.IPAddress.str().c_str());
00164 terminal.module->getDisplayString().insertTag("t", 0);
00165 terminal.module->getDisplayString().setTagArg("t", 0, ip_disp);
00166 terminal.module->getDisplayString().setTagArg("t", 1, "l");
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176 int k = 1;
00177 while ( router.module->findSubmodule("ppp", k) != -1 )
00178 k++;
00179
00180 cModuleType* pppInterfaceModuleType = cModuleType::get("inet.linklayer.ppp.PPPInterface");
00181 terminal.remotePPPInterface = pppInterfaceModuleType->
00182 create("ppp", router.module, 0, k);
00183
00184
00185
00186
00187
00188
00189
00190 cGate* routerInGate = firstUnusedGate(router.module, "pppg", cGate::INPUT);
00191 cGate* routerOutGate = firstUnusedGate(router.module, "pppg", cGate::OUTPUT);
00192
00193 cChannelType* channelTypeRx = cChannelType::find( channelTypeRxStr.c_str() );
00194 cChannelType* channelTypeTx = cChannelType::find( channelTypeTxStr.c_str() );
00195 if (!channelTypeRx || !channelTypeTx)
00196 opp_error("Could not find Channel or ChannelRx Type. Most likely "
00197 "parameter channelTypes does not match the channels defined "
00198 "in channels.ned");
00199
00200 terminal.module->gate("pppg$o", 0)->connectTo(routerInGate,
00201 channelTypeRx->create(channelTypeRxStr.c_str()));
00202 routerOutGate->connectTo(terminal.module->gate("pppg$i", 0),
00203 channelTypeTx->create(channelTypeTxStr.c_str()));
00204
00205
00206 routerInGate->connectTo(terminal.remotePPPInterface->gate("phys$i"));
00207 terminal.remotePPPInterface->gate("phys$o")->connectTo(routerOutGate);
00208
00209
00210 cModule* netwModule = router.module->getSubmodule("networkLayer");
00211
00212 cGate* netwInGate = firstUnusedGate(netwModule, "ifIn");
00213 cGate* netwOutGate = firstUnusedGate(netwModule, "ifOut");
00214
00215 netwOutGate->connectTo(terminal.remotePPPInterface->gate("netwIn"));
00216 terminal.remotePPPInterface->gate("netwOut")->connectTo(netwInGate);
00217
00218
00219 cModule* ipModule;
00220 if (useIPv6) {
00221 ipModule = router.module->getSubmodule("networkLayer")->getSubmodule("ipv6");
00222 }
00223 else {
00224 ipModule = router.module->getSubmodule("networkLayer")->getSubmodule("ip");
00225 }
00226
00227 cGate* ipIn = firstUnusedGate(ipModule, "queueIn");
00228 netwInGate->connectTo(ipIn);
00229
00230 if(useIPv6) {
00231 cGate* ipOut = firstUnusedGate(ipModule, "queueOut");
00232 ipOut->connectTo(netwOutGate);
00233 }
00234
00235 #ifdef _ORIG_INET
00236 cModule* arpModule = router.module->getSubmodule("networkLayer")->getSubmodule("arp");
00237
00238 cGate* arpOut = firstUnusedGate(arpModule, "nicOut");
00239
00240
00241 cGate* ipOut = ipModule->gate("queueOut");
00242
00243 arpOut->connectTo(netwOutGate);
00244 #endif
00245
00246
00247
00248
00249 terminal.remotePPPInterface->finalizeParameters();
00250 terminal.remotePPPInterface->setDisplayString("i=block/ifcard");
00251 terminal.remotePPPInterface->buildInside();
00252 terminal.remotePPPInterface->scheduleStart(simTime());
00253 terminal.remotePPPInterface->callInitialize();
00254
00255 if ( !migrate) {
00256
00257
00258 for (int i=0; i < MAX_STAGE_UNDERLAY + 1; i++) {
00259 terminal.module->callInitialize(i);
00260 }
00261 }
00262
00263 terminal.remoteInterfaceEntry = router.interfaceTable->getInterface(
00264 router.interfaceTable->getNumInterfaces() - 1);
00265 terminal.interfaceEntry = terminal.interfaceTable->getInterfaceByName("ppp0");
00266
00267
00268
00269
00270
00271
00272 if (useIPv6) {
00273
00274
00275
00276
00277 IPv6InterfaceData* interfaceData = new IPv6InterfaceData;
00278 interfaceData->setAdvSendAdvertisements(true);
00279 interfaceData->assignAddress(IPv6Address::formLinkLocalAddress(terminal.remoteInterfaceEntry->getInterfaceToken()), false, 0, 0);
00280 terminal.remoteInterfaceEntry->setIPv6Data(interfaceData);
00281 terminal.remoteInterfaceEntry->setMACAddress(MACAddress::generateAutoAddress());
00282
00283
00284 terminal.interfaceEntry->ipv6Data()->setAdvSendAdvertisements(false);
00285 terminal.interfaceEntry->ipv6Data()->assignAddress(terminal.IPAddress.get6(), false, 0, 0);
00286 terminal.interfaceEntry->ipv6Data()->assignAddress(IPv6Address::formLinkLocalAddress(terminal.interfaceEntry->getInterfaceToken()), false, 0, 0);
00287 terminal.interfaceEntry->setMACAddress(MACAddress::generateAutoAddress());
00288
00289
00290
00291
00292
00293
00294 router.routingTable6->addStaticRoute(terminal.IPAddress.get6(),64, terminal.remoteInterfaceEntry->getInterfaceId(), terminal.interfaceEntry->ipv6Data()->getLinkLocalAddress());
00295
00296
00297 terminal.routingTable6->addDefaultRoute(terminal.remoteInterfaceEntry->ipv6Data()->getLinkLocalAddress(), terminal.interfaceEntry->getInterfaceId(), 0);
00298
00299 } else {
00300
00301
00302
00303
00304
00305
00306 IPv4InterfaceData* interfaceData = new IPv4InterfaceData;
00307 interfaceData->setIPAddress(router.IPAddress.get4());
00308 interfaceData->setNetmask(IPAddress::ALLONES_ADDRESS);
00309 terminal.remoteInterfaceEntry->setIPv4Data(interfaceData);
00310
00311
00312 terminal.interfaceEntry->ipv4Data()->setIPAddress(terminal.IPAddress.get4());
00313 terminal.interfaceEntry->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);
00314
00315
00316
00317
00318
00319
00320 IPRoute* re = new IPRoute();
00321 re->setHost(terminal.IPAddress.get4());
00322 re->setNetmask(IPAddress(IPAddress::ALLONES_ADDRESS));
00323 re->setInterface(terminal.remoteInterfaceEntry);
00324 re->setType(IPRoute::DIRECT);
00325 re->setSource(IPRoute::MANUAL);
00326 router.routingTable->addRoute(re);
00327 terminal.remoteRoutingEntry = re;
00328
00329
00330 IPRoute* te = new IPRoute();
00331 te->setHost(IPAddress::UNSPECIFIED_ADDRESS);
00332 te->setNetmask(IPAddress::UNSPECIFIED_ADDRESS);
00333 te->setGateway(router.IPAddress.get4());
00334 te->setInterface(terminal.interfaceEntry);
00335 te->setType(IPRoute::REMOTE);
00336 te->setSource(IPRoute::MANUAL);
00337 terminal.routingTable->addRoute(te);
00338 terminal.routingEntry = te;
00339
00340 }
00341
00342
00343
00344 overlayTerminal.push_back(terminal);
00345
00346
00347 updateDisplayString();
00348
00349 return terminal.IPAddress;
00350 }
00351
00352 int AccessNet::getRandomNodeId()
00353 {
00354 Enter_Method("getRandomNodeId()");
00355
00356 return overlayTerminal[intuniform(0, overlayTerminal.size() - 1)].module->getId();
00357 }
00358
00359 cModule* AccessNet::removeOverlayNode(int ID)
00360 {
00361 Enter_Method("removeOverlayNode()");
00362
00363 cModule* node = NULL;
00364 TerminalInfo terminal;
00365 int index;
00366
00367 for(unsigned int i=0; i<overlayTerminal.size(); i++) {
00368 if(overlayTerminal[i].module->getId() == ID) {
00369 terminal = overlayTerminal[i];
00370 node = terminal.module;
00371 index = i;
00372 }
00373 }
00374
00375 if(node == NULL) return NULL;
00376
00377 cModule* ppp = terminal.remotePPPInterface;
00378
00379
00380 node->gate("pppg$o", 0)->disconnect();
00381 node->gate("pppg$i", 0)->getPreviousGate()->disconnect();
00382
00383
00384 ppp->gate("netwIn")->getPathStartGate()->disconnect();
00385 ppp->gate("netwOut")->getNextGate()->disconnect();
00386
00387
00388 ppp->callFinish();
00389 ppp->deleteModule();
00390
00391
00392 router.interfaceTable->deleteInterface(terminal.remoteInterfaceEntry);
00393
00394
00395 if (!useIPv6) {
00396 terminal.routingTable->deleteRoute(terminal.routingEntry);
00397 router.routingTable->deleteRoute(terminal.remoteRoutingEntry);
00398 } else {
00399 #if 0
00400 for (int i = 0; i < terminal.routingTable6->getNumRoutes(); i++) {
00401 IPv6Route* route = terminal.routingTable6->getRoute(i);
00402 if (route->getDestPrefix() == terminal.remoteInterfaceEntry->
00403 ipv6Data()->getLinkLocalAddress()) {
00404 terminal.routingTable6->purgeDestCacheEntriesToNeighbour(terminal.remoteInterfaceEntry->ipv6Data()->getLinkLocalAddress(), route->getInterfaceId());
00405 terminal.routingTable6->removeRoute(route);
00406 }
00407 }
00408 #endif
00409
00410 for (int i = 0; i < router.routingTable6->getNumRoutes(); i++) {
00411 IPv6Route* route = router.routingTable6->getRoute(i);
00412 if (route->getDestPrefix() == terminal.IPAddress.get6()) {
00413 router.routingTable6->purgeDestCacheEntriesToNeighbour(terminal.interfaceEntry->ipv6Data()->getLinkLocalAddress(), route->getInterfaceId());
00414 router.routingTable6->removeRoute(route);
00415 break;
00416 }
00417 }
00418 }
00419
00420
00421 lifetimeVector.record(simTime() - overlayTerminal[index].createdAt);
00422
00423
00424 overlayTerminal.erase(overlayTerminal.begin() + index);
00425
00426 updateDisplayString();
00427
00428 return node;
00429 }
00430
00431 cModule* AccessNet::getOverlayNode(int ID)
00432 {
00433 Enter_Method("getOverlayNode()");
00434
00435 cModule* node = NULL;
00436
00437 for(unsigned int i=0; i<overlayTerminal.size(); i++) {
00438 if(overlayTerminal[i].module->getId() == ID)
00439 node = overlayTerminal[i].module;
00440 }
00441 return node;
00442 }
00443
00444 void AccessNet::updateDisplayString()
00445 {
00446 if (ev.isGUI()) {
00447 char buf[80];
00448 if ( overlayTerminal.size() == 1 ) {
00449 sprintf(buf, "1 terminal connected");
00450 } else {
00451 sprintf(buf, "%zi terminals connected", overlayTerminal.size());
00452 }
00453 getDisplayString().setTagArg("t", 0, buf);
00454 getDisplayString().setTagArg("t", 2, "blue");
00455 }
00456 }
00457
00458 cGate* firstUnusedGate(cModule* owner, const char* name, cGate::Type type)
00459 {
00460 int index;
00461 for (index = 0; index < owner->gateSize(name); index++) {
00462 cGate *gate = type == cGate::NONE ? owner->gate(name, index) : owner->gateHalf(name, type, index);
00463 if (!gate->isConnectedOutside()) {
00464 return gate;
00465 }
00466 }
00467
00468 owner->setGateSize(name, index + 2);
00469 return type == cGate::NONE ? owner->gate(name, index + 1) : owner->gateHalf(name, type, index + 1);
00470 }
00471
00472 IPvXAddress AccessNet::getAssignedPrefix(IInterfaceTable* ift)
00473 {
00474
00475 for (int i = 0; i< ift->getNumInterfaces(); i++) {
00476 if (!ift->getInterface(i)->isLoopback()) {
00477 if (ift->getInterface(i)->ipv6Data()->getNumAdvPrefixes() == 1)
00478 return ift->getInterface(i)->ipv6Data()->getAdvPrefix(0).prefix;
00479 else
00480 opp_error("Prefix is not unique.");
00481 }
00482 }
00483 return IPvXAddress();
00484 }