--- /dev/null
+#!/usr/bin/env python\r
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2013 INRIA\r
+#\r
+# This program is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License version 2 as\r
+# published by the Free Software Foundation;\r
+#\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License\r
+# along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+# Alina Quereilhac <alina.quereilhac@inria.fr>\r
+\r
+import os\r
+from experiment imptort Experiment\r
+from nepi.execution.ec import ExperimentController\r
+from nepi.execution.resource import ResourceState, ResourceManager\r
+\r
+# Experiment parameters\r
+experiment_id = "case_a"\r
+agent = "10.0.1.1"\r
+netblock = "10.0.1.0"\r
+prefix = "24"\r
+# number of nodes to test\r
+parameters = [3]\r
+\r
+# list of hosts for running the experiment on \r
+node_info = [\r
+ {"hostname":"onelab4.warsaw.rd.tp.pl", \r
+ "username":"inria_nepi", \r
+ "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])}]\r
+\r
+# tunning\r
+os.environ["NEPI_NTHREADS"] = "1"\r
+ResourceManager._reschedule_delay = "0s"\r
+\r
+# == Experimentation setup ====================================================\r
+def main():\r
+ # Prepare the ExperimentController\r
+ ec = ExperimentController(exp_id = experiment_id)\r
+\r
+ # run experimentation as long as there is something to do\r
+ while len(parameters) > 0:\r
+ # Collection of application being processed\r
+ jobs = list()\r
+\r
+ # Collection of experiments launched\r
+ xps = list()\r
+\r
+ # Push a job on each node in the cluster\r
+ for node in node_info:\r
+ # Stop if nothing else to do\r
+ if len(parameters) == 0:\r
+ break\r
+\r
+ # Determine what network size to test\r
+ nb_nodes = parameters.pop(0)\r
+\r
+ # Create the simulated network\r
+ xp = Experiment(ec, node, nb_nodes, False)\r
+ xp.build_topology(netblock, prefix, agent)\r
+\r
+ # Remember the experiments just created\r
+ xps.append(xp)\r
+\r
+ # Remember the applications to be executed\r
+ jobs += xp.apps\r
+ \r
+ # Let's run the experiment\r
+ ec.deploy()\r
+ ec.wait_finished(jobs)\r
+\r
+ # Check if everything went well for each experiment\r
+ for xp in xps:\r
+ # and see the output\r
+ stdout = ec.trace(xp.apps[0], "stdout")\r
+ print "[", stdout, "]"\r
+ # check if one transmitter failed (if everything goes well, all trasmitters\r
+ # must have stopped properly) (ignore the agent)\r
+ for app in xp.apps[1:len(xp.apps)]:\r
+ if ec.state(app, hr=False) != ResourceState.STOPPED:\r
+ raise Exception("Crashed at size %d" % xp.nb_nodes)\r
+ # et voila \r
+ ec.shutdown()\r
+\r
+main()\r
--- /dev/null
+#!/usr/bin/env python\r
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2013 INRIA\r
+#\r
+# This program is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License version 2 as\r
+# published by the Free Software Foundation;\r
+#\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License\r
+# along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+# Alina Quereilhac <alina.quereilhac@inria.fr>\r
+\r
+import os\r
+from experiment_interconnected_ns3_ns3 import ExperimentInterconnectedNs3Ns3\r
+from nepi.execution.ec import ExperimentController \r
+from nepi.execution.resource import ResourceManager\r
+\r
+# Experiment parameters\r
+experiment_id = "case_b"\r
+agent = ["10.0.2.1", "10.0.1.1"]\r
+netblock = ["10.0.1.0", "10.0.2.0"]\r
+prefix = ["24", "24"]\r
+nb_nodes = [1, 1]\r
+# list of hosts for running the experiment on\r
+node_info = [\r
+ {"hostname":"onelab4.warsaw.rd.tp.pl", \r
+ "username":"inria_nepi", \r
+ "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])}, \r
+ {"hostname":"planet2.servers.ua.pt", \r
+ "username":"inria_nepi", \r
+ "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])}\r
+ ]\r
+\r
+# tunning\r
+os.environ["NEPI_NTHREADS"] = "1"\r
+ResourceManager._reschedule_delay = "0s"\r
+\r
+# == Experimentation setup ====================================================\r
+def main():\r
+ # Prepare the ExperimentController\r
+ ec = ExperimentController(exp_id = experiment_id)\r
+\r
+ # Create the simulated network\r
+ #\r
+ # On the first machine\r
+ xp1 = ExperimentInterconnectedNs3Ns3(ec, node_info[0], nb_nodes[0])\r
+ xp1.build_topology(netblock = netblock[0], prefix = prefix[0], target = agent[0])\r
+ #\r
+ # On the second machine\r
+ xp2 = ExperimentInterconnectedNs3Ns3(ec, node_info[1], nb_nodes[1])\r
+ xp2.build_topology(netblock = netblock[1], prefix = prefix[1], target = agent[1])\r
+\r
+ # interconnect the two experiments\r
+ xp1.interconnect(xp2)\r
+\r
+ # Let's run the experiment\r
+ ec.deploy()\r
+ ec.wait_finished( xp1.apps[1:len(xp1.apps)] + xp2.apps[1:len(xp2.apps)] )\r
+\r
+\r
+ # and see the output\r
+ stdout = ec.trace(xp1.apps[0], "stdout")\r
+ print "1[", stdout, "]"\r
+\r
+ stdout = ec.trace(xp2.apps[0], "stdout")\r
+ print "2[", stdout, "]"\r
+\r
+ # et voila\r
+ ec.shutdown()\r
+\r
+main()\r
--- /dev/null
+#!/usr/bin/env python\r
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2013 INRIA\r
+#\r
+# This program is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License version 2 as\r
+# published by the Free Software Foundation;\r
+#\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License\r
+# along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+# Alina Quereilhac <alina.quereilhac@inria.fr>\r
+\r
+import os\r
+from experiment_interconnected_ns3_planetlab import ExperimentInterconnectedNs3Planetlab\r
+from nepi.execution.ec import ExperimentController \r
+from nepi.execution.resource import ResourceManager\r
+\r
+# Experiment parameters\r
+experiment_id = "case_c"\r
+agent = None\r
+netblock = "192.168.3.0"\r
+prefix = "25"\r
+nb_nodes = 1\r
+\r
+node_info = {\r
+ "hostname":"onelab4.warsaw.rd.tp.pl", \r
+ "username":"inria_nepi", \r
+ "identity": "%s/.ssh/id_rsa_planetlab" % (os.environ['HOME'])\r
+ }\r
+\r
+\r
+# tunning\r
+os.environ["NEPI_NTHREADS"] = "1"\r
+ResourceManager._reschedule_delay = "0s"\r
+\r
+# == Experimentation setup ====================================================\r
+def main():\r
+ # Prepare the ExperimentController\r
+ ec = ExperimentController(exp_id = experiment_id)\r
+\r
+ # Create the simulated network\r
+ xp = ExperimentInterconnectedNs3Planetlab(ec, node_info, nb_nodes)\r
+ xp.build_topology(netblock = netblock, prefix = prefix, target = agent)\r
+\r
+ # Create Planetlab application\r
+ app = xp.add_planetlab_client(xp.ip_ap)\r
+\r
+ # Interconnect Planetlab and ns3\r
+ xp.interconnect("192.168.3.128", "25")\r
+\r
+ # Let's run the experiment\r
+ ec.deploy()\r
+ ec.wait_finished([app])\r
+\r
+ # and see the output\r
+ stdout = ec.trace(xp.apps[0], "stdout")\r
+ print "[", stdout, "]"\r
+\r
+ # et voila\r
+ ec.shutdown()\r
+\r
+main()\r
--- /dev/null
+/* Sample UDP server */\r
+\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <strings.h>\r
+\r
+int main(int argc, char**argv)\r
+{\r
+ int sockfd,n;\r
+ struct sockaddr_in servaddr,cliaddr;\r
+ socklen_t len;\r
+ char mesg[1000];\r
+\r
+ printf("DEBUT\n");\r
+ if (argc != 2)\r
+ {\r
+ fprintf(stderr, "usage: %s <port>\n", argv[0]);\r
+ exit(1);\r
+ }\r
+\r
+ sockfd = socket(AF_INET,SOCK_DGRAM,0);\r
+ if(sockfd < 0){\r
+ perror("socket");\r
+ exit(1);\r
+ }\r
+\r
+ bzero(&servaddr,sizeof(servaddr));\r
+ servaddr.sin_family = AF_INET;\r
+ servaddr.sin_addr.s_addr=htonl(INADDR_ANY);\r
+ servaddr.sin_port = htons(atoi(argv[1]));\r
+ if(bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0){\r
+ perror("bind");\r
+ exit(2);\r
+ }\r
+\r
+ for (;;)\r
+ {\r
+ len = sizeof(cliaddr);\r
+ n = recvfrom(sockfd,mesg,1000,0,(struct sockaddr *)&cliaddr,&len);\r
+ if(n < 0){\r
+ perror("recvfrom");\r
+ continue;\r
+ }\r
+ if(n==1){\r
+ exit(0);\r
+ }\r
+ mesg[n] = 0;\r
+ printf("[%s]\n",mesg);\r
+ }\r
+ printf("FIN\n");\r
+}\r
--- /dev/null
+\r
+/* Sample UDP client */\r
+\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <stdio.h>\r
+#include <strings.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+\r
+int main(int argc, char**argv)\r
+{\r
+ int sockfd,n;\r
+ struct sockaddr_in servaddr,cliaddr;\r
+ char * sendline = "coucou";\r
+\r
+ if (argc != 3)\r
+ {\r
+ fprintf(stderr, "usage: %s <IP address> <port>\n", argv[0]);\r
+ exit(1);\r
+ }\r
+\r
+ sockfd = socket(AF_INET,SOCK_DGRAM,0);\r
+ if(sockfd < 0){\r
+ perror("socket");\r
+ exit(1);\r
+ }\r
+\r
+ bzero(&servaddr,sizeof(servaddr));\r
+ servaddr.sin_family = AF_INET;\r
+ servaddr.sin_addr.s_addr=inet_addr(argv[1]);\r
+ servaddr.sin_port=htons(atoi(argv[2]));\r
+\r
+ int i;\r
+ for(i = 0; i < 10; i++){\r
+ if(sendto(sockfd,sendline,strlen(sendline),0, (struct sockaddr *)&servaddr,sizeof(servaddr)) < 0){\r
+ perror("sendto");\r
+ }\r
+ printf("%d\n", i);\r
+ sleep(1);\r
+ }\r
+ sendto(sockfd,sendline,1,0, (struct sockaddr *)&servaddr,sizeof(servaddr));\r
+ exit(0);\r
+}\r
--- /dev/null
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2013 INRIA\r
+#\r
+# This program is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License version 2 as\r
+# published by the Free Software Foundation;\r
+#\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License\r
+# along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+# Alina Quereilhac <alina.quereilhac@inria.fr>\r
+\r
+import ipaddr\r
+from random import randint\r
+from nepi.execution.ec import ExperimentController \r
+from nepi.execution.resource import ResourceState, ResourceAction\r
+\r
+# ########################################################\r
+class Experiment(object):\r
+ # ec : ExperimentController\r
+ # node: planetlab::Node\r
+ def __init__(self, ec, node_info, nb_nodes, real_time = True):\r
+ print "Experiement %s %s" % (node_info, nb_nodes)\r
+\r
+ # remember the ExperimentController the experiment is associated to\r
+ self.ec = ec\r
+\r
+ # define the physical machine to run the experiment on\r
+ self.add_node(node_info)\r
+\r
+ # number of simulated nodes moving in the \r
+ self.nb_nodes = nb_nodes\r
+ \r
+ # fix the geographical boundaries of the network\r
+ self.bounds_width = self.bounds_height = 100\r
+ \r
+ # fix the speed at which mobile nodes can move\r
+ self.speed = 1\r
+\r
+ # collection of simulated node (their GID) in the simulator\r
+ # nsnodes[0] is always the GID of the simulated node containing the\r
+ # access point\r
+ self.nsnodes = list()\r
+ \r
+ # collection of application (their GID) running in the simulator\r
+ # apps[0] is always the GID of the agent application running on the\r
+ # access point\r
+ self.apps = list()\r
+\r
+ # prepare the ns-3 simulator to use for the experiment\r
+ self.add_simulator(real_time)\r
+\r
+ # for sanity check\r
+ self.topology_built = False\r
+\r
+ def add_node(self, node_info):\r
+ """\r
+ Define the physical machine on which run the experiment\r
+ """\r
+ if node_info["hostname"] == "localhost":\r
+ self.node = self.ec.register_resource("linux::Node")\r
+ self.ec.set(self.node, "hostname", "localhost")\r
+ else:\r
+ self.node = self.ec.register_resource("planetlab::Node")\r
+ self.ec.set(self.node, "hostname", node_info["hostname"])\r
+ self.ec.set(self.node, "username", node_info["username"])\r
+ self.ec.set(self.node, "identity", node_info["identity"])\r
+ self.ec.set(self.node, "cleanProcesses", True)\r
+ self.ec.set(self.node, "cleanExperiment", True)\r
+\r
+ return self.node\r
+\r
+ def add_simulator(self, real_time):\r
+ """\r
+ Add a ns-3 simulator on the node used for the experiment\r
+ """\r
+ # creat the ns-3 simulator instance\r
+ self.simu = self.ec.register_resource("linux::ns3::Simulation")\r
+ self.ec.set (self.simu, "StopTime", "200s")\r
+ #\r
+ # run it in realtime mode if asked\r
+ if real_time:\r
+ self.ec.set(self.simu, "simulatorImplementationType", "ns3::RealtimeSimulatorImpl")\r
+ # \r
+ # log additional information\r
+ self.ec.set(self.simu, "checksumEnabled", True)\r
+ self.ec.set(self.simu, "verbose", True)\r
+ self.ec.set(self.simu, "enableDump", True)\r
+ self.ec.register_connection(self.simu, self.node)\r
+\r
+ return self.simu\r
+\r
+ # == ns-3 simulation helper functions =====================================\r
+ def add_nsnode(self):\r
+ """\r
+ Create a ns-3 node and add it to the simulator\r
+ """\r
+ # create a ns-3 node\r
+ nsnode = self.ec.register_resource("ns3::Node")\r
+ # enable its network stack\r
+ self.ec.set(nsnode, "enableStack", True)\r
+ self.ec.register_connection(nsnode, self.simu)\r
+\r
+ return nsnode\r
+\r
+ def add_wifi_channel(self):\r
+ """\r
+ Create the WiFi channel on which all nodes will be connected\r
+ """\r
+ # create a channel\r
+ channel = self.ec.register_resource("ns3::YansWifiChannel")\r
+ \r
+ # specify the delay model\r
+ delay = self.ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")\r
+ self.ec.register_connection(channel, delay)\r
+\r
+ # specify a loss model\r
+ loss = self.ec.register_resource("ns3::LogDistancePropagationLossModel")\r
+ self.ec.register_connection(channel, loss)\r
+\r
+ return channel\r
+\r
+ def add_wifi_device(self, node, ip, prefix, access_point = False):\r
+ """\r
+ Add and configure the WiFi interface on a simulated node\r
+ """\r
+ \r
+ # create the WiFi network interface\r
+ dev = self.ec.register_resource("ns3::WifiNetDevice")\r
+ \r
+ # specify the network layer parameters\r
+ self.ec.set(dev, "ip", ip)\r
+ self.ec.set(dev, "prefix", prefix)\r
+ self.ec.register_connection(node, dev)\r
+ \r
+ # specify the MAC layer parameters\r
+ #\r
+ # can be in access point mode or not\r
+ if access_point:\r
+ mac = self.ec.register_resource("ns3::ApWifiMac")\r
+ else:\r
+ mac = self.ec.register_resource("ns3::StaWifiMac")\r
+ # the MAC is IEEE 802.11a\r
+ self.ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")\r
+ self.ec.register_connection(dev, mac)\r
+\r
+ # specify the physical layer parameters\r
+ phy = self.ec.register_resource("ns3::YansWifiPhy")\r
+ #\r
+ # it physical layer is IEEE802.11a\r
+ self.ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")\r
+ self.ec.register_connection(dev, phy)\r
+ #\r
+ # specify an error model for transmissions\r
+ error = self.ec.register_resource("ns3::NistErrorRateModel")\r
+ self.ec.register_connection(phy, error)\r
+ \r
+ # specify the Wifi manager to be assocated with the interface\r
+ manager = self.ec.register_resource("ns3::ArfWifiManager")\r
+ self.ec.register_connection(dev, manager)\r
+\r
+ return dev, phy\r
+\r
+ def add_random_mobility(self, node, x, y, z, speed, bounds_width, bounds_height):\r
+ """\r
+ Create a mobility model for node with random movements\r
+ """\r
+ position = "%d:%d:%d" % (x, y, z)\r
+ bounds = "0|%d|0|%d" % (bounds_width, bounds_height) \r
+ speed = "ns3::UniformRandomVariable[Min=%d|Max=%s]" % (speed, speed)\r
+ pause = "ns3::ConstantRandomVariable[Constant=1.0]"\r
+\r
+ mobility = self.ec.register_resource("ns3::RandomDirection2dMobilityModel")\r
+ self.ec.set(mobility, "Position", position)\r
+ self.ec.set(mobility, "Bounds", bounds)\r
+ self.ec.set(mobility, "Speed", speed)\r
+ self.ec.set(mobility, "Pause", pause)\r
+ self.ec.register_connection(node, mobility)\r
+\r
+ return mobility\r
+\r
+ def add_constant_mobility(self, node, x, y, z):\r
+ """\r
+ Create a mobility model for node with a constant position\r
+ """\r
+ mobility = self.ec.register_resource("ns3::ConstantPositionMobilityModel") \r
+ position = "%d:%d:%d" % (x, y, z)\r
+ self.ec.set(mobility, "Position", position)\r
+ self.ec.register_connection(node, mobility)\r
+\r
+ return mobility\r
+\r
+ def create_simulated_node(self, ip, prefix, channel, access_point, x, y):\r
+ """\r
+ Create a simulated node connected on a WiFi channel\r
+ """\r
+ # Create the ns node that will run the application\r
+ nsnode = self.add_nsnode()\r
+\r
+ # Add a WiFi interface to the node\r
+ dev, phy = self.add_wifi_device(nsnode, ip, prefix, access_point)\r
+ #\r
+ # Connect the access point to the WiFi network\r
+ self.ec.register_connection(channel, phy)\r
+\r
+ # Specify that the node mobility \r
+ #\r
+ # access point is not mobile\r
+ if access_point:\r
+ mobility = self.add_constant_mobility(nsnode, x, y, 0)\r
+ # other nodes have random mobility pattern\r
+ else:\r
+ mobility = self.add_random_mobility(nsnode, x, y, 0, self.speed, self.bounds_width, self.bounds_height)\r
+\r
+ return nsnode\r
+\r
+ def add_route(self, nsnode, netblock, prefix, nexthop):\r
+ """\r
+ add a route on ns-3 node nsnode for netblock/prefix via nexthop\r
+ """\r
+ route = self.ec.register_resource("ns3::Route")\r
+ self.ec.set(route, "network", netblock)\r
+ self.ec.set(route, "prefix", prefix)\r
+ self.ec.set(route, "nexthop", nexthop)\r
+ self.ec.register_connection(route, nsnode)\r
+ print "route %s/%s via %s added on nsnode %s (%s)" % (netblock, prefix, nexthop, nsnode, self)\r
+\r
+ return route\r
+\r
+ def add_vroute(self, dev, netblock, prefix, nexthop):\r
+ """\r
+ Add a route on Planetlab node for netblock/prefix via nexthop\r
+ """\r
+ route = self.ec.register_resource("planetlab::Vroute")\r
+ self.ec.set(route, "network", netblock)\r
+ self.ec.set(route, "prefix", prefix)\r
+ self.ec.set(route, "nexthop", nexthop)\r
+ self.ec.register_connection(route, dev)\r
+ print "Vroute %s/%s via %s added on nsnode %s (%s)" % (netblock, prefix, nexthop, dev, self)\r
+\r
+ return route\r
+\r
+ def add_agent(self, nsnode):\r
+ """\r
+ Add a agent application\r
+ """\r
+ # Create a DCE application running the agent code\r
+ app = self.ec.register_resource("linux::ns3::dce::Application")\r
+ self.ec.set(app, "sources", "code/agent.c")\r
+ self.ec.set(app "build", "gcc -fPIC -pie -rdynamic ${SRC}/agent.c -o ${BIN_DCE}/agent")\r
+ self.ec.set(app, "binary", "agent")\r
+ self.ec.set(app, "arguments", "45005")\r
+ self.ec.set(app, "stackSize", 1<<20)\r
+ self.ec.set(app, "StartTime", "10s")\r
+ self.ec.set(app, "StopTime", "200s")\r
+\r
+ # Associate the application with the simulated node\r
+ self.ec.register_connection(app, nsnode)\r
+ \r
+ # Make the application start only once the simulated node is started\r
+ self.ec.register_condition(app, ResourceAction.START, \r
+ nsnode, ResourceState.STARTED, time="5s")\r
+\r
+ return app\r
+\r
+ def add_transmitter(self, nsnode):\r
+ """\r
+ Add a transmitter application\r
+ """\r
+ # Create a DCE application running the transmitter code\r
+ app = self.ec.register_resource("linux::ns3::dce::Application")\r
+ self.ec.set(app, "sources", "code/transmitter.c")\r
+ self.ec.set(app, "build", "gcc -fPIC -pie -rdynamic ${SRC}/transmitter.c -o ${BIN_DCE}/transmitter")\r
+ self.ec.set(app, "binary", "transmitter")\r
+ self.ec.set(app, "arguments", "%s;45005" % target)\r
+ self.ec.set(app, "stackSize", 1<<20)\r
+ self.ec.set(app, "StartTime", "10s")\r
+ self.ec.set(app, "StopTime", "200s")\r
+\r
+ # Associate the application with the simulated node\r
+ self.ec.register_connection(app, nsnode)\r
+ #\r
+ # Make the application start only once the simulated node and the serer are started\r
+ self.ec.register_condition(app, ResourceAction.START, \r
+ [nsnode, self.apps[0]], ResourceState.STARTED, time="10s")\r
+\r
+ return app\r
+\r
+ def add_planetlab_transmitter(self, target):\r
+ """\r
+ Add a planetlab transmitter application\r
+ """\r
+\r
+ # Create an application running the transmitter code\r
+ app = self.ec.register_resource("linux::Application")\r
+ self.ec.set(app, "sources", "code/transmitter.c")\r
+ self.ec.set(app, "build", "make ${SRC}/transmitter")\r
+ self.ec.set(app, "command", "${SRC}/transmitter %s 45005" % target)\r
+\r
+ # Associate the application with the Planetlab node\r
+ self.ec.register_connection(app, self.node)\r
+ \r
+ # Make the application start only once the simulated agent and the node are started\r
+ self.ec.register_condition(app, ResourceAction.START, \r
+ [self.apps[0], self.node], ResourceState.STARTED, time="10s")\r
+\r
+ return app\r
+\r
+ # == Topology construction ================================================\r
+ def build_topology(self, netblock, prefix, target):\r
+ """\r
+ Builds a topology composed of one fixed access point and nb_nodes\r
+ mobile nodes\r
+ """\r
+\r
+ # Rember network parameters\r
+ self.netblock = netblock\r
+ self.prefix = prefix\r
+\r
+ # Create the WiFi network via which nodes are connected\r
+ chan = self.add_wifi_channel()\r
+\r
+ # == Access point\r
+ # Geographical position of the access point\r
+ x=50\r
+ y=0\r
+\r
+ # the IP address of the access point is the first in the prefix\r
+ self.ip_ap = str(ipaddr.IPv4Address(self.netblock) + 1)\r
+ print "IP AP: %s " % (self.ip_ap)\r
+\r
+ # Create the ns node that will run the access point\r
+ nsnode = self.create_simulated_node(self.ip_ap, self.prefix, chan, True, x, y)\r
+ \r
+ # add the node in the collection of simulated nodes\r
+ self.nsnodes.append(nsnode)\r
+\r
+ # Run a agent application on the access point\r
+ agent = self.add_agent(nsnode)\r
+ \r
+ # add the agent application in the collection of applications\r
+ self.apps.append(agent)\r
+ \r
+ # Add nb_nodes mobile nodes in the WiFi network\r
+ for i in range(1, self.nb_nodes + 1):\r
+ # pic a random initial location\r
+ x = randint(0, self.bounds_width)\r
+ y = randint(0, self.bounds_height)\r
+\r
+ # define the appropriate IP address of the node (sequential IP in what remains after the access point IP)\r
+ ip = str(ipaddr.IPv4Address(self.ip_ap) + i)\r
+\r
+ print "IP mobile: " , ip\r
+\r
+ # Create the ns node that will run the mobile node\r
+ nsnode = self.create_simulated_node(ip, self.prefix, chan, False, x, y)\r
+ # \r
+ # add the node in the collection of simulated nodes\r
+ self.nsnodes.append(nsnode)\r
+\r
+ if target:\r
+ # Run a transmitter application on the mobile node\r
+ transmitter = self.add_transmitter(nsnode)\r
+ \r
+ # add the trasmitter application in the collection of applications\r
+ self.apps.append(transmitter)\r
+\r
+ # Add a default route via the access point\r
+ self.add_route(nsnode, "0.0.0.0", "0", self.ip_ap)\r
+\r
+ # for sanity check\r
+ self.topology_built = True\r
--- /dev/null
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2013 INRIA\r
+#\r
+# This program is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License version 2 as\r
+# published by the Free Software Foundation;\r
+#\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License\r
+# along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+# Alina Quereilhac <alina.quereilhac@inria.fr>\r
+\r
+from experiment import Experiment\r
+\r
+class ExperimentInterconnected(Experiment):\r
+ def __init__(self, ec, node, nb_nodes, real_time = True): \r
+ super(ExperimentInterconnected, self).__init__(ec, node, nb_nodes, real_time)\r
+ self.interconnected = False\r
+ self.fddev = None\r
+\r
+ def add_fdnetdevice(self, ip, prefix, nsnode = None):\r
+ # Sanity check\r
+ #\r
+ # only one FD device allowed\r
+ if self.fddev:\r
+ raise Exception("A FD device is already setup")\r
+\r
+ # Attach the FD device to the access point by default\r
+ if not nsnode:\r
+ nsnode = self.nsnodes[0]\r
+\r
+ # Create the FD device\r
+ self.fddev = self.ec.register_resource("ns3::FdNetDevice")\r
+ self.ec.set(self.fddev, "ip", ip)\r
+ self.ec.set(self.fddev, "prefix", prefix)\r
+\r
+ # attach it to the simulated node\r
+ self.ec.register_connection(nsnode, self.fddev)\r
+\r
+ return self.fddev\r
--- /dev/null
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2013 INRIA\r
+#\r
+# This program is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License version 2 as\r
+# published by the Free Software Foundation;\r
+#\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License\r
+# along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+# Alina Quereilhac <alina.quereilhac@inria.fr>\r
+\r
+import ipaddr\r
+from experiment_interconnected import ExperimentInterconnected\r
+\r
+class ExperimentInterconnectedNs3Planetlab(ExperimentInterconnected):\r
+ def add_tap_device(self, node, ip, prefix, pointopoint):\r
+ """\r
+ Add a point-to-point tap device on the planetlab node. This tap device\r
+ is used to exchange traffic with the simulated network\r
+ """\r
+ # Create the tap device\r
+ dev = self.ec.register_resource("planetlab::Tap")\r
+\r
+ # Define the local network associated with the TAP device\r
+ self.ec.set(dev, "ip", ip)\r
+ self.ec.set(dev, "prefix", prefix)\r
+\r
+ # Define the other side of the tap (the simulated network device)\r
+ self.ec.set(dev, "pointopoint", pointopoint)\r
+\r
+ # Associate the TAP device with the Planetlab node\r
+ self.ec.register_connection(node, dev)\r
+\r
+ return dev\r
+\r
+ def connect_with_tuntap(self, tap):\r
+ """\r
+ Connect the simulated network with the Planetlab node via the TAP of\r
+ the Planetlab node and the FD device of the simulated network\r
+ """\r
+ # Create the link\r
+ crosslink = self.ec.register_resource("planetlab::ns3::TunTapFdLink") \r
+\r
+ # Associate it with the Planetlab tap device on one side\r
+ self.ec.register_connection(crosslink, tap)\r
+ # \r
+ # Associate it with the simulated network FD device on the other side\r
+ self.ec.register_connection(crosslink, self.fddev)\r
+\r
+ return crosslink\r
+\r
+ def interconnect(self, netblock_pl, prefix_pl):\r
+ """\r
+ Interconnect a simulated network with a Planetlab network via a tap device\r
+ """\r
+ # sanity checks\r
+ #\r
+ # topology must be setup\r
+ if not self.topology_built:\r
+ raise Exception("Topology not setup on ", self)\r
+ #\r
+ # experiment cannot be interconnected to another experiment\r
+ if self.interconnected:\r
+ raise Exception("Experiment already interconnected on ", self)\r
+ \r
+\r
+ ip_simulated = str(ipaddr.IPv4Address(netblock_pl) + 1)\r
+ ip_pl = str(ipaddr.IPv4Address(ip_simulated) + 1)\r
+\r
+ # Add a TAP interface on the Planetlab machine to connect the real\r
+ # application with the simulated network\r
+ tap = self.add_tap_device(self.node, ip_pl, prefix_pl, ip_simulated)\r
+ \r
+ # Add an FD device on the simulator to connect to the real\r
+ self.add_fdnetdevice(ip_simulated, prefix_pl)\r
+\r
+ # Connect both Planetlab and simulated network via the tap device\r
+ self.connect_with_tuntap(tap)\r
+\r
+ # Route traffic for the Planetlab node to the Planetlab machine\r
+ self.add_route(self.nsnodes[0], netblock_pl, prefix_pl, self.ip_ap)\r
+\r
+ # Route traffic for the simulated node to the simulator\r
+ self.add_vroute(tap, self.netblock, self.prefix, ip_simulated)\r
+\r
+ # Sanity check\r
+ self.interconnected = True\r
+\r
--- /dev/null
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2013 INRIA\r
+#\r
+# This program is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License version 2 as\r
+# published by the Free Software Foundation;\r
+#\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+# GNU General Public License for more details.\r
+#\r
+# You should have received a copy of the GNU General Public License\r
+# along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+# Author: Damien Saucez <damien.saucez@inria.fr>\r
+# Alina Quereilhac <alina.quereilhac@inria.fr>\r
+\r
+from experiment_interconnected import ExperimentInterconnected\r
+\r
+class ExperimentInterconnectedNs3Ns3(ExperimentInterconnected):\r
+ def connect_with_udp_tunnel(self, xp_remote):\r
+ # Connect the two experiments via a UDP tunnel direcly on the FD devices\r
+ tunnel = self.ec.register_resource("planetlab::ns3::FdUdpTunnel")\r
+ self.ec.register_connection(tunnel, self.fddev)\r
+ self.ec.register_connection(tunnel, xp_remote.fddev)\r
+\r
+ return tunnel\r
+\r
+ def interconnect(self, xp_remote):\r
+ """\r
+ Interconnect two ns3 simulations via a UDP tunnel\r
+ """\r
+ # sanity checks\r
+ #\r
+ # topology must be setup\r
+ if not self.topology_built:\r
+ raise Exception("Topology not setup on ", self)\r
+ if not xp_remote.topology_built:\r
+ raise Exception("Topology not setup on ", xp_remote )\r
+ #\r
+ # experiment cannot be interconnected to another experiment\r
+ if self.interconnected:\r
+ raise Exception("Experiment already interconnected on ", self)\r
+ if xp_remote.interconnected:\r
+ raise Exception("Experiment already interconnected on ", xp_remote)\r
+\r
+ # IP for the AP of the two experiments\r
+ # XXX DSA: ugly\r
+ ip = ["10.0.0.1", "10.0.0.2"]\r
+\r
+ # add an FD device on both local and remote experiments\r
+ self.add_fdnetdevice(ip[0], "30")\r
+ xp_remote.add_fdnetdevice(ip[1], "30")\r
+\r
+ # Connect the two experiments via a UDP tunnel direcly on the FD devices\r
+ self.connect_with_udp_tunnel(xp_remote)\r
+\r
+ # Add a route to the remote network on each experiment, via the FD device\r
+ self.add_route(self.nsnodes[0], xp_remote.netblock, xp_remote.prefix, ip[1])\r
+ xp_remote.add_route(xp_remote.nsnodes[0], self.netblock, self.prefix, ip[0])\r
+\r
+ # Sanity check\r
+ self.interconnected = True\r