Commit 113feb5a by Kévin Vermeulen

Initial commit

parents
# TestParisTraceroute
This tool has been developped in order to statistically test the MultiPathsDetection algorithm implemented in [Paris Traceroute](https://).
## Getting Started
First you need to create your topology:
At the moment, a topology is just a file describing nodes and edges.
An example is given below :
```
127.0.0.1 10.0.0.1
10.0.0.1 10.1.2.3
10.0.0.1 2.3.3.3
10.1.2.3 127.1.1.6
2.3.3.3 127.1.1.6
```
The file is composed of lines that are composed of pairs of addresses.
Note that the localhost address (127.0.0.1) is mandatory at first line.
It saves this topology so it can be tested that this expected topology is the one you have or have not discovered via Paris Traceroute.
Then it launches a certain number of samples of Paris Traceroute that you specify.
It then gives you the measured failure rate and the confidence interval at a certain value that you can specify.
### Prerequisites
You will need the following libraries of python:
```
dpkt
scipy
numpy
shlex
```
You also need paris-traceroute to be installed.
### Installing
You don't need any tools to install TestParisTraceroute
###Usage
In folder where paris-traceroute executable is:
```
python /path/to/TestParisTraceroute/main.py -t <topology_file> -p <paris-traceroute_command>
```
### Break down into end to end tests
You can test this tool in combination with [fakerouteC++](https://)
In a terminal, tap:
```
./fakerouteC__ resources/2-pathsLoadBalancer 127.1.1.6
```
In another terminal in paris-traceroute folder:
```
python /path/to/TestParisTraceroute/main.py -t resources/2-pathsLoadBalancer -p "paris-traceroute -amda -B95,1,128 127.1.1.6"
```
See paris-traceroute for options meanings.
You should see on standard output:
```
Topology file is " resources/2-pathsLoadBalancer
Will execute this paris-traceroute command: paris-traceroute -amda -B95,1,128 127.1.1.6
Output file is "
Iteration number : 0
Iteration number : 10
Iteration number : 20
Iteration number : 30
Iteration number : 40
sample number: 50
run number by sample : 1000
mean estimated: 0.03206
interval : 0.00156437713451
interval of confidence with 0.95: [0.0304956228655, 0.0336243771345]
```
The iteration number tells you the state of your experiment.
By default, it writes the results in the topologyFile_output in the working directory.
\ No newline at end of file
import sys, getopt
from subprocess import Popen, PIPE
import shlex
from dpkt.ip import IP
import dpkt, socket
from statistics import mean_confidence_interval
TARGET_IPV4 = ("127.1.1.1", 0)
# To send signal of resetting flows
sock4 = socket.socket(socket.AF_INET, socket.SOCK_RAW, dpkt.ip.IP_PROTO_ICMP)
class Route:
def __init__(self, source, destination):
self.source = source
self.destination = destination
def __eq__(self, other):
return self.source == other.source and self.destination == other.destination
def parseRoutes(topologyFile):
routes = []
with open(topologyFile) as topology:
for route in topology:
addresses = route.split(" ")
if len(addresses) == 2:
# Remove the backslash n from the destination
addresses[1] = addresses[1].replace("\n", "")
routes.append(Route(addresses[0], addresses[1]))
return routes
def compareRoutes(parsedRoutes, foundRoutes):
for route in parsedRoutes:
if route not in foundRoutes:
return False
if len(parsedRoutes) != len(foundRoutes):
return False
return True
def startParisTraceroute(parisTracerouteCmd):
args = shlex.split(parisTracerouteCmd)
p = Popen(args, stdout=PIPE, bufsize=1)
startedLattice = False
foundRoutes = []
with p.stdout:
for line in iter(p.stdout.readline, b''):
if startedLattice:
tokens = line.split("-> [")
# If there is only one token, means that we have reached our destination
if len(tokens) == 1:
continue
# If it is None, deduce it as source localhost
if tokens[0] == "None ":
tokens[0] = "127.0.0.1"
# Remove space from source too
source = tokens[0].replace(" ", "")
# Check if there are more than 1 destination
destinations = tokens[1].split(", ")
# Remove the ] from the last destination address
destinations[len(destinations) - 1] = destinations[len(destinations) - 1].replace("]", "")
for destination in destinations:
destination = destination.replace(" ", "")
destination = destination.replace("\n", "")
foundRoutes.append(Route(source, destination))
if line.startswith("Lattice:"):
startedLattice = True
return foundRoutes
p.wait()
def main(argv):
topologyFile = ''
outputfile = ''
parisTracerouteCmd = ""
confidenceIntervalPercent = 0.95
runNumber = 1000
try:
opts, args = getopt.getopt(argv, "ht:p:o:n:c:", ["topology=", "ofile=", "paris-traceroute="])
except getopt.GetoptError:
print 'main.py -i <inputfile> -o <outputfile>'
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print 'main.py -i <inputfile> -o <outputfile>'
sys.exit()
elif opt in ("-t", "--topology"):
topologyFile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg
elif opt in ("-p", "--paris-traceroute"):
parisTracerouteCmd = arg
elif opt in ("-n", "--run-number"):
runNumber = int(arg)
elif opt in ("-c", "--confidence-interval"):
confidenceIntervalPercent = float(arg)
print 'Topology file is "', topologyFile
print "Will execute this paris-traceroute command: ", parisTracerouteCmd
print 'Output file is "', outputfile
parsedRoutes = parseRoutes(topologyFile)
ipPacket = IP(
src="127.0.0.1",
dst="127.1.1.1",
p=dpkt.ip.IP_PROTO_UDP,
ttl=128
)
sampleNumber = 50
samples = []
for k in range(0, sampleNumber):
failure = 0
success = 0
if k % 10 == 0:
print "Iteration number : ", k
for x in range(0, runNumber):
foundRoutes = startParisTraceroute(parisTracerouteCmd)
sock4.sendto(str(ipPacket), TARGET_IPV4)
if compareRoutes(parsedRoutes, foundRoutes):
success += 1
else:
failure += 1
samples.append(failure / float((failure + success)))
print "sample number: ", sampleNumber
print "run number by sample : ", runNumber
m, interval = mean_confidence_interval(samples,confidenceIntervalPercent)
print "mean estimated: ", m
print "interval :", interval
confidenceInterval = "interval of confidence with "+str(confidenceIntervalPercent)+": " + "[" + str(m - interval) + ", " + str(m + interval) + "]"
print confidenceInterval
if outputfile == "":
outputfile = topologyFile + "_output"
with open(outputfile, "w") as output:
output.write("sample number: " + str(sampleNumber) + "\n")
output.write("run number by sample: " + str(runNumber) + "\n")
output.write("mean estimated of failure: " + str(m) + "\n")
output.write("interval :" + str(interval) + "\n")
output.write("confidenceInterval: " + confidenceInterval + "\n")
if __name__ == "__main__":
main(sys.argv[1:])
import numpy as np
import scipy as sp
import scipy.stats
def mean_confidence_interval(data, confidence=0.95):
a = 1.0*np.array(data)
n = len(a)
m, se = np.mean(a), scipy.stats.sem(a)
percentile = sp.stats.norm.ppf((1+confidence)/2.)
h = se * percentile
return m, h
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment