aboutsummaryrefslogtreecommitdiff
path: root/sem5/net/mm3/pingplot.py
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2020-09-15 18:51:46 +0200
committerJulian T <julian@jtle.dk>2020-09-15 18:51:46 +0200
commitd285183c42f5d377b197bd0efab3bb20b240ef34 (patch)
tree7c0754c4b36e6cc18a3ee9353ab605511ce53446 /sem5/net/mm3/pingplot.py
parent4bfbc29c7ea0b711f96346deb25dde0b2298ecde (diff)
Added assignments for net
Diffstat (limited to 'sem5/net/mm3/pingplot.py')
-rw-r--r--sem5/net/mm3/pingplot.py90
1 files changed, 90 insertions, 0 deletions
diff --git a/sem5/net/mm3/pingplot.py b/sem5/net/mm3/pingplot.py
new file mode 100644
index 0000000..8811d2e
--- /dev/null
+++ b/sem5/net/mm3/pingplot.py
@@ -0,0 +1,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()