1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
# We are not allowed to send ICMP packets without root
# and will therefore just parse the output from standard ping.
# This requires the ping command to keep going forever
import subprocess
import sys
import numpy as np
import json
import argparse
import re
import matplotlib.pyplot as plt
# group 1: number of bytes
# group 2: destination
# group 3: icmp_seq
# group 4: ttl
# group 5: round time (This we want to plot)
pingre = re.compile("(\d*) bytes from (.*): icmp_seq=(\d*) ttl=(\d*) time=(.*)")
# Lets hope we only get milliseconds
timere = re.compile("([\d\.]*) ms")
parser = argparse.ArgumentParser()
parser.add_argument("--config", "-c", default="hosts.json")
parser.add_argument("--samples", "-s", default=10, type=int)
parser.add_argument("--out", "-o", default=None)
args = parser.parse_args()
hosts = {}
with open(args.config, "r") as f:
hosts = json.load(f)
# Pings the specified host, samples number of times and returns the result
# as a numpy array.
# Runs the hook function on every response with arguments: destination, index, ttl, latency
def pinghost(host, samples, hook=None):
# Well there goes cross platform
cmd = subprocess.Popen(f"ping -c {samples} {host}", shell=True, stdout=subprocess.PIPE)
res = np.empty(samples)
index = 0
for line in cmd.stdout:
line = line.decode("utf-8")
m = pingre.match(str(line))
if m is None:
continue
ms = m[5]
tm = timere.match(ms)
if tm is None:
print(f"Could not parse time {ms}, is this the correct version of ping?", file=sys.stderr)
sys.exit(1)
res[index] = float(tm[1])
index += 1
if hook:
hook(m[2], index, m[4], m[5])
if index != samples:
print(f"Got {index} samples which is not the {samples} we asked for, is this the correct version of ping?", file=sys.stderr)
sys.exit(1)
return res
def statprint(dest, index, ttl, latency):
print(f"ping {index} for {dest} with latency: {latency}")
x = np.empty(len(hosts))
y = np.empty(len(hosts))
for i, host in enumerate(hosts):
print(host)
res = pinghost(host["host"], args.samples, statprint)
y[i] = np.average(res)
print(f"Average: {y[i]}")
x[i] = host["dist"]
sort = x.argsort()
x = x[sort]
y = y[sort]
plt.xlabel("distance [km]")
plt.ylabel(f"gennemsnitlig pingtid over {args.samples} målinger [ms]")
plt.plot(x, y)
if args.out:
plt.savefig(args.out, dpi=300)
else:
plt.show()
|