--- /dev/null
+#!/usr/bin/env python\r
+#\r
+# NEPI, a framework to manage network experiments\r
+# Copyright (C) 2015 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
+\r
+import ipaddr\r
+from optparse import OptionParser\r
+import os\r
+from random import randint\r
+\r
+# list of hosts for running the experiment on\r
+hostname1 = "onelab4.warsaw.rd.tp.pl"\r
+hostname2 = "planet2.servers.ua.pt"\r
+\r
+def get_options():\r
+ # PlanetLab credentials\r
+ pl_slice = os.environ.get("PL_SLICE")\r
+ pl_user = os.environ.get("PL_USER")\r
+ pl_password = os.environ.get("PL_PASS")\r
+ pl_ssh_key = os.environ.get("PL_SSHKEY")\r
+\r
+ usage = ("usage: %prog -s <pl-slice> -u <pl-user> -p <pl-password> "\r
+ "-k <pl-ssh-key> -n <node-count> ")\r
+\r
+ parser = OptionParser(usage = usage)\r
+ parser.add_option("-s", "--pl-slice", dest="pl_slice",\r
+ help="PlanetLab slicename", default=pl_slice, type="str")\r
+ parser.add_option("-u", "--pl-user", dest="pl_user",\r
+ help="PlanetLab web username", default=pl_user, type="str")\r
+ parser.add_option("-p", "--pl-password", dest="pl_password",\r
+ help="PlanetLab web password", default=pl_password, type="str")\r
+ parser.add_option("-k", "--pl-ssh-key", dest="pl_ssh_key",\r
+ help="Path to private SSH key associated with the PL account",\r
+ default=pl_ssh_key, type="str")\r
+ parser.add_option("-n", "--node-count", dest="node_count",\r
+ help="Number of nodes in the wireless network",\r
+ default = 4, type="int")\r
+\r
+ (options, args) = parser.parse_args()\r
+\r
+ return (options.pl_slice, options.pl_user, options.pl_password, \r
+ options.pl_ssh_key, options.node_count)\r
+\r
+# == add host and simu =======================================================\r
+def add_host_simu(ec, hostname, username, pl_user, pl_password, ssh_key):\r
+ host = ec.register_resource("planetlab::Node")\r
+ ec.set(host, "hostname", hostname)\r
+\r
+ if username:\r
+ ec.set(host, "username", username)\r
+\r
+ if pl_user:\r
+ ec.set(host, "pluser", pl_user)\r
+\r
+ if pl_password:\r
+ ec.set(host, "plpassword", pl_password)\r
+\r
+ if ssh_key:\r
+ ec.set(host, "identity", ssh_key)\r
+\r
+ ec.set(host, "cleanProcesses", True)\r
+ ec.set(host, "cleanExperiment", True)\r
+\r
+ simu = ec.register_resource("linux::ns3::Simulation")\r
+ ec.set(simu, "simulatorImplementationType", "ns3::RealtimeSimulatorImpl")\r
+ ec.set(simu, "checksumEnabled", True)\r
+ ec.set(simu, "verbose", True)\r
+ ec.set(simu, "enableDump", True)\r
+ ec.set (simu, "StopTime", "200s")\r
+ ec.register_connection(simu, host)\r
+\r
+ return host, simu\r
+\r
+# == build topology =========================================================\r
+\r
+def add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode):\r
+ # create the WiFi network interface\r
+ dev = ec.register_resource("ns3::WifiNetDevice")\r
+\r
+ # specify the network layer parameters\r
+ ec.set(dev, "ip", ip)\r
+ ec.set(dev, "prefix", prefixlen)\r
+ ec.register_connection(ns3_node, dev)\r
+\r
+ # specify the MAC layer parameters\r
+ #\r
+ # can be in access point mode or not\r
+ if ap_mode:\r
+ mac = ec.register_resource("ns3::ApWifiMac")\r
+ else:\r
+ mac = ec.register_resource("ns3::StaWifiMac")\r
+\r
+ # the MAC is IEEE 802.11a\r
+ ec.set(mac, "Standard", "WIFI_PHY_STANDARD_80211a")\r
+ ec.register_connection(dev, mac)\r
+\r
+ # specify the physical layer parameters\r
+ phy = ec.register_resource("ns3::YansWifiPhy")\r
+ #\r
+ # it physical layer is IEEE802.11a\r
+ ec.set(phy, "Standard", "WIFI_PHY_STANDARD_80211a")\r
+ ec.register_connection(dev, phy)\r
+ #\r
+ # specify an error model for transmissions\r
+ error = ec.register_resource("ns3::NistErrorRateModel")\r
+ ec.register_connection(phy, error)\r
+\r
+ # specify the Wifi manager to be assocated with the interface\r
+ manager = ec.register_resource("ns3::ArfWifiManager")\r
+ ec.register_connection(dev, manager)\r
+\r
+ return dev, phy\r
+\r
+def add_ns3_wifi_channel(ec):\r
+ channel = ec.register_resource("ns3::YansWifiChannel")\r
+\r
+ delay = ec.register_resource("ns3::ConstantSpeedPropagationDelayModel")\r
+ ec.register_connection(channel, delay)\r
+\r
+ loss = ec.register_resource("ns3::LogDistancePropagationLossModel")\r
+ ec.register_connection(channel, loss)\r
+\r
+ return channel\r
+\r
+# == Add random mobility\r
+def add_ns3_random_mobility(ec, ns3_node):\r
+ speed = 1\r
+ bounds_width = 100\r
+ bounds_height = 100\r
+ x = randint(0, bounds_width)\r
+ y = randint(0, bounds_height)\r
+ z = 0\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 = ec.register_resource("ns3::RandomDirection2dMobilityModel")\r
+ ec.set(mobility, "Position", position)\r
+ ec.set(mobility, "Bounds", bounds)\r
+ ec.set(mobility, "Speed", speed)\r
+ ec.set(mobility, "Pause", pause)\r
+ ec.register_connection(ns3_node, mobility)\r
+\r
+ return mobility\r
+\r
+# == Add constant mobility\r
+def add_ns3_constant_mobility(ec, ns3_node):\r
+ mobility = ec.register_resource("ns3::ConstantPositionMobilityModel")\r
+ position = "%d:%d:%d" % (0, 50, 0)\r
+ ec.set(mobility, "Position", position)\r
+ ec.register_connection(ns3_node, mobility)\r
+\r
+ return mobility\r
+\r
+# == add ns-3 node\r
+def add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False):\r
+ ns3_node = ec.register_resource("ns3::Node")\r
+ ec.set(ns3_node, "enableStack", True)\r
+ ec.register_connection(ns3_node, simu)\r
+\r
+ dev, phy = add_ns3_wifi_device(ec, ns3_node, ip, prefixlen, ap_mode)\r
+ ec.register_connection(channel, phy)\r
+\r
+ if not ap_mode:\r
+ add_ns3_random_mobility(ec, ns3_node)\r
+ else:\r
+ add_ns3_constant_mobility(ec, ns3_node)\r
+\r
+ return ns3_node\r
+\r
+# == add DCE agent\r
+def add_dce_agent(ec, ns3_node):\r
+ agent = ec.register_resource("linux::ns3::dce::Application")\r
+ ec.set(agent, "sources", "code/agent.c")\r
+ ec.set(agent, "build", "gcc -fPIC -pie -rdynamic ${SRC}/agent.c -o ${BIN_DCE}/agent")\r
+ ec.set(agent, "binary", "agent")\r
+ ec.set(agent, "stackSize", 1<<20)\r
+ ec.set(agent, "StartTime", "10s")\r
+ ec.set(agent, "StopTime", "200s")\r
+\r
+ ec.register_connection(agent, ns3_node)\r
+\r
+ return agent\r
+\r
+# == add DCE transmitter\r
+def add_dce_transmitter(ec, ns3_node, target):\r
+ transmitter = ec.register_resource("linux::ns3::dce::Application")\r
+ ec.set(transmitter, "sources", "code/transmitter.c")\r
+ ec.set(transmitter, "build", "gcc -fPIC -pie -rdynamic ${SRC}/transmitter.c -o ${BIN_DCE}/transmitter")\r
+ ec.set(transmitter, "binary", "transmitter")\r
+ ec.set(transmitter, "arguments", target)\r
+ ec.set(transmitter, "stackSize", 1<<20)\r
+ ec.set(transmitter, "StartTime", "10s")\r
+ ec.set(transmitter, "StopTime", "200s")\r
+ \r
+ ec.register_connection(transmitter, ns3_node)\r
+\r
+ return transmitter\r
+\r
+# == Add ns-3 route\r
+def add_ns3_route(ec, ns3_node, network, prefixlen, nexthop):\r
+ route = ec.register_resource("ns3::Route")\r
+ ec.set(route, "network", network)\r
+ ec.set(route, "prefix", prefixlen)\r
+ ec.set(route, "nexthop", nexthop)\r
+ ec.register_connection(route, ns3_node)\r
+\r
+ return route\r
+\r
+# = build ns3 topology =======================================================\r
+def build_ns3_topology(ec, simu, node_count, network, prefixlen, agent_ip):\r
+ channel = add_ns3_wifi_channel(ec)\r
+\r
+ net = ipaddr.IPv4Network("%s/%s" % (network, prefixlen)) \r
+ itr = net.iterhosts()\r
+\r
+ ap_ip = itr.next().exploded\r
+ ap = add_ns3_node(ec, simu, ap_ip, prefixlen, channel, ap_mode=True)\r
+\r
+ agent = None\r
+ if ap_ip == agent_ip:\r
+ agent = add_dce_agent(ec, ap)\r
+\r
+ for i in range(0, node_count):\r
+ ip = itr.next().exploded\r
+ sensor = add_ns3_node(ec, simu, ip, prefixlen, channel, ap_mode=False)\r
+ transmitter = add_dce_transmitter(ec, sensor, ap_ip)\r
+ add_ns3_route(ec, sensor, network="0.0.0.0", prefixlen="0", nexthop=ap_ip)\r
+\r
+ return ap, agent\r
+\r
+\r
+# == add FdNetDevice =========================================================\r
+def add_fdnet_device(ec, ap, ip, prefixlen):\r
+ fddev = ec.register_resource("ns3::FdNetDevice")\r
+ ec.set(fddev, "ip", ip)\r
+ ec.set(fddev, "prefix", prefixlen)\r
+ ec.register_connection(ap, fddev)\r
+\r
+ return fddev\r
+\r
+# == connect with UDP tunnel =================================================\r
+def connect_with_udp_tunnel(ec, fddev1, fddev2): \r
+ tunnel = ec.register_resource("planetlab::ns3::FdUdpTunnel")\r
+ ec.register_connection(tunnel, fddev1)\r
+ ec.register_connection(tunnel, fddev2)\r
+\r
+ return tunnel\r
+\r
+# == connect with virtual link ===============================================\r
+def connect_with_virtual_link(ec, tap, fddev): \r
+ link = ec.register_resource("planetlab::ns3::TunTapFdLink") \r
+ ec.register_connection(link, tap)\r
+ ec.register_connection(link, fddev)\r
+\r
+ return link\r
+\r
+# == Add planet lab route ====================================================\r
+\r
+def add_planetlab_route(ec, dev, network, prefixlen, nexthop):\r
+ route = ec.register_resource("planetlab::Vroute")\r
+ ec.set(route, "network", network)\r
+ ec.set(route, "prefix", prefixlen)\r
+ ec.set(route, "nexthop", nexthop)\r
+ ec.register_connection(route, dev)\r
+\r
+ return route\r
+\r