aboutsummaryrefslogtreecommitdiff
path: root/sem5/net/mm3/pingplot.py
blob: 8811d2ebe7f1ac873b585f797fb1c410b56b9c50 (plain)
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()