OverSim
SingleHostUnderlayConfigurator.cc
Go to the documentation of this file.
1 //
2 // This program is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU General Public License
4 // as published by the Free Software Foundation; either version 2
5 // of the License, or (at your option) any later version.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License for more details.
11 //
12 // You should have received a copy of the GNU General Public License
13 // along with this program; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 //
16 
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <fcntl.h>
27 
28 #define WANT_WINSOCK2
29 #include <platdep/sockets.h>
30 
31 #ifndef _WIN32
32 #include <net/if.h>
33 #include <sys/ioctl.h>
34 #include <arpa/inet.h>
35 #include <netinet/in.h>
36 #endif
37 
38 #include <omnetpp.h>
39 
40 #include "IInterfaceTable.h"
41 #include "InterfaceEntry.h"
42 #include "IPv4InterfaceData.h"
43 #include "IPAddressResolver.h"
44 
45 #include <PeerInfo.h>
46 #include <IRoutingTable.h>
47 #include <NodeHandle.h>
48 #include <GlobalNodeListAccess.h>
49 
51 
53 
55 {
56  IPvXAddress addr;
57 
58  if(stage != MAX_STAGE_UNDERLAY)
59  return;
60 
62 
63  // Set IP, Routes, etc
64  cModule* node = getParentModule()->getSubmodule("overlayTerminal", 0);
65 
66  std::string nodeInterface = std::string(par("nodeInterface").stringValue());
67  std::string stunServer = std::string(par("stunServer").stringValue());
68  std::string nodeIP = std::string(par("nodeIP").stringValue());
69 
70  if (!nodeInterface.size() && !stunServer.size() && !nodeIP.size()) {
71  throw cRuntimeError("SingleHostConfigurator::initializeUnderlay(): "
72  "Please specify at least one of "
73  "**.nodeInterface, **.nodeIP, or **.stunServer");
74  }
75 
76  if (nodeInterface.size()) {
77 #ifndef _WIN32
78  SOCKET sock_fd;
79  struct ifreq req;
80  if ((sock_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) !=
81  INVALID_SOCKET) {
82 
83  snprintf(req.ifr_name, sizeof(req.ifr_name), "%s", nodeInterface.c_str());
84 
85  if (!ioctl(sock_fd, SIOCGIFADDR, &req)) {
86  addr = IPAddress(inet_ntoa(((struct sockaddr_in *)
87  (&req.ifr_addr))->sin_addr));
88  } else {
89  throw cRuntimeError("SingleHostConfigurator::"
90  "initializeUnderlay(): "
91  "Invalid interface!");
92  }
93  close(sock_fd);
94  }
95 #else
96  throw cRuntimeError("SingleHostConfigurator::"
97  "initializeUnderlay(): "
98  "**.nodeInterface parameter not supported on WIN32 yet!");
99 #endif
100  } else if (nodeIP.size()) {
101  addr = IPAddress(nodeIP.c_str());
102  }
103 
104  IPvXAddress gw = addr;
105  InterfaceEntry* ifEntry = IPAddressResolver().interfaceTableOf(node)->
106  getInterfaceByName("outDev");
107  IRoutingTable* rTable = check_and_cast<IRoutingTable*>(node->getSubmodule("routingTable", 0));
108 
109  ifEntry->ipv4Data()->setIPAddress(addr.get4());
110  ifEntry->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);
111 
112  IPRoute* te = new IPRoute();
113  te->setHost(IPAddress::UNSPECIFIED_ADDRESS);
114  te->setNetmask(IPAddress::UNSPECIFIED_ADDRESS);
115  te->setGateway(gw.get4());
116  te->setInterface(ifEntry);
117  te->setType(IPRoute::REMOTE);
118  te->setSource(IPRoute::MANUAL);
119  rTable->addRoute(te);
120 
121  //add node to bootstrap oracle
122  PeerInfo* info = new PeerInfo(0, node->getId(), NULL);
123  globalNodeList->addPeer(addr, info);
124 
125  if (strlen(par("bootstrapIP")) > 0) {
126  PeerInfo* bootstrapInfo = new PeerInfo(0, -1, NULL);
127  globalNodeList->addPeer(IPAddress(par("bootstrapIP").stringValue()),
128  bootstrapInfo);
129 
131  IPAddress(par("bootstrapIP").stringValue()), par("bootstrapPort")));
132  }
133 
134  // update display
136 
137  scheduleAt(simTime(), new cMessage("init phase finished"));
138 }
140 {
141  if (std::string(msg->getName()) != "init phase finished") {
142  throw cRuntimeError("unknown self-message received");
143  }
144  delete msg;
145 
146  initFinished();
147 }
148 
150 {
151  // updates the statistics display string
152  char buf[80];
153  sprintf(buf, "%i overlay terminals", overlayTerminalCount);
154  getDisplayString().setTagArg("t", 0, buf);
155 }
156 
158 {
159  if (!isInInitPhase()) {
160  struct timeval now, diff;
161  gettimeofday(&now, NULL);
162  timersub(&now, &initFinishedTime, &diff);
163  printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
164  }
165 }