From 70ab20c96d504e7d2eed283467ac6356122d357c Mon Sep 17 00:00:00 2001 From: Giovanni Grieco Date: Tue, 23 Apr 2024 09:24:20 +0200 Subject: [PATCH] analysis: port pcap-get_pdr Jupyter notebook to interactive plaintext file --- analysis/pcap-get_pdr.ipynb | 1879 ----------------------------------- analysis/pcap-get_pdr.py | 149 +++ 2 files changed, 149 insertions(+), 1879 deletions(-) delete mode 100644 analysis/pcap-get_pdr.ipynb create mode 100644 analysis/pcap-get_pdr.py diff --git a/analysis/pcap-get_pdr.ipynb b/analysis/pcap-get_pdr.ipynb deleted file mode 100644 index b5a40fbb..00000000 --- a/analysis/pcap-get_pdr.ipynb +++ /dev/null @@ -1,1879 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Retrieve PDR/PLR data by analyzing a PCAP file in IoD Sim" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import os\n", - "import re\n", - "import subprocess\n", - "from collections import Counter\n", - "from multiprocessing import Pool\n", - "\n", - "import pandas as pd\n", - "import plotly.express as px" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "results_basepath = '../results'\n", - "# results_dir = 'paper_3-wifi-staticGU-UDP-2022-02-19.17-31-49'\n", - "# scenario_name = 'paper_3-wifi-staticGU-UDP'\n", - "results_dir = 'paper_3-wifi-2022-03-03.18-53-11'\n", - "scenario_name = 'paper_3-wifi'\n", - "\n", - "net_prefixes = ['7.0.0']\n", - "n_drones = [6, 9, 9, 8]\n", - "\n", - "#assert(len(net_prefixes) == len(n_drones))\n", - "n_stacks = len(n_drones)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'10.1.0.10': 3990, '10.1.0.11': 3990, '10.1.0.2': 4000, '10.1.0.3': 3995, '10.1.0.4': 3990, '10.1.0.5': 3990, '10.1.0.6': 3982, '10.1.0.8': 3990, '10.1.0.9': 3990, '10.2.0.10': 3999, '10.2.0.11': 4019, '10.2.0.12': 3864, '10.2.0.13': 4021, '10.2.0.14': 3675, '10.2.0.15': 2591, '10.2.0.16': 3331, '10.2.0.17': 3529, '10.2.0.18': 2869, '10.2.0.19': 2635, '10.2.0.2': 2822, '10.2.0.20': 4033, '10.2.0.21': 2987, '10.2.0.22': 3999, '10.2.0.23': 3933, '10.2.0.24': 3996, '10.2.0.25': 3896, '10.2.0.26': 3993, '10.2.0.27': 3101, '10.2.0.28': 4022, '10.2.0.29': 2895, '10.2.0.3': 2641, '10.2.0.30': 4007, '10.2.0.4': 4112, '10.2.0.6': 3665, '10.2.0.7': 4070, '10.2.0.8': 4019, '10.2.0.9': 4070, '10.3.0.10': 4001, '10.3.0.11': 4042, '10.3.0.12': 4107, '10.3.0.13': 4002, '10.3.0.14': 4056, '10.3.0.15': 4015, '10.3.0.16': 4017, '10.3.0.17': 4015, '10.3.0.18': 3933, '10.3.0.19': 3066, '10.3.0.2': 4035, '10.3.0.3': 4027, '10.3.0.4': 3990, '10.3.0.5': 4004, '10.3.0.6': 2800, '10.3.0.7': 3411, '10.3.0.8': 4034, '10.3.0.9': 3370}\n" - ] - } - ], - "source": [ - "def pkt_per_drone_in_stack(args):\n", - " base_path, n_drones, net_prefix, stack_id, key_field, pkt_type = args\n", - " flt_str = ' or '.join([f'ip.src == {net_prefix}.{i}' for i in range(2, n_drones + 1)])\n", - "\n", - " args = [\n", - " 'tshark', \n", - " '-r', f'{base_path}/wifi-phy-{stack_id}-drones-host-{stack_id}-2.pcap', \n", - " '-T', 'fields',\n", - " '-e', key_field,\n", - " f'{pkt_type} and {flt_str}'\n", - " ]\n", - " ret = subprocess.run(args, capture_output=True)\n", - "\n", - " if ret.returncode != 0:\n", - " print(ret)\n", - " exit(1)\n", - " \n", - " out = ret.stdout.decode('UTF-8').strip().split(os.linesep)\n", - " out.sort()\n", - " cnt = Counter(out)\n", - " \n", - " return dict(cnt)\n", - "\n", - "\n", - "r = None\n", - "with Pool(n_stacks) as p:\n", - " r = p.map(pkt_per_drone_in_stack, [(f'{results_basepath}/{results_dir}', n_drones[i], net_prefixes[i], i, 'ip.src', 'udp and not icmp') for i in range(n_stacks)])\n", - "\n", - "assert(r is not None)\n", - "udp_cnt = {k: v for d in r for k, v in d.items()}\n", - "print(udp_cnt)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Retrieve IP-Port mapping to learn the PNAT table used in the scenario" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"7.0.0.2:1\": \"10.1.0.7\",\n", - " \"7.0.0.2:2\": \"10.1.0.8\",\n", - " \"7.0.0.2:3\": \"10.1.0.4\",\n", - " \"7.0.0.2:4\": \"10.1.0.2\",\n", - " \"7.0.0.2:5\": \"10.1.0.5\",\n", - " \"7.0.0.2:6\": \"10.1.0.3\",\n", - " \"7.0.0.2:7\": \"10.1.0.6\",\n", - " \"7.0.0.3:1\": \"10.2.0.9\",\n", - " \"7.0.0.3:10\": \"10.2.0.7\",\n", - " \"7.0.0.3:2\": \"10.2.0.8\",\n", - " \"7.0.0.3:3\": \"10.2.0.3\",\n", - " \"7.0.0.3:4\": \"10.2.0.4\",\n", - " \"7.0.0.3:5\": \"10.2.0.11\",\n", - " \"7.0.0.3:6\": \"10.2.0.10\",\n", - " \"7.0.0.3:7\": \"10.2.0.2\",\n", - " \"7.0.0.3:8\": \"10.2.0.5\",\n", - " \"7.0.0.3:9\": \"10.2.0.6\",\n", - " \"7.0.0.4:1\": \"10.3.0.10\",\n", - " \"7.0.0.4:10\": \"10.3.0.5\",\n", - " \"7.0.0.4:2\": \"10.3.0.8\",\n", - " \"7.0.0.4:3\": \"10.3.0.3\",\n", - " \"7.0.0.4:4\": \"10.3.0.6\",\n", - " \"7.0.0.4:5\": \"10.3.0.9\",\n", - " \"7.0.0.4:6\": \"10.3.0.2\",\n", - " \"7.0.0.4:7\": \"10.3.0.7\",\n", - " \"7.0.0.4:8\": \"10.3.0.4\",\n", - " \"7.0.0.4:9\": \"10.3.0.11\",\n", - " \"7.0.0.5:1\": \"10.4.0.9\",\n", - " \"7.0.0.5:2\": \"10.4.0.8\",\n", - " \"7.0.0.5:3\": \"10.4.0.2\",\n", - " \"7.0.0.5:4\": \"10.4.0.6\",\n", - " \"7.0.0.5:5\": \"10.4.0.4\",\n", - " \"7.0.0.5:6\": \"10.4.0.3\",\n", - " \"7.0.0.5:7\": \"10.4.0.7\",\n", - " \"7.0.0.5:8\": \"10.4.0.10\",\n", - " \"7.0.0.5:9\": \"10.4.0.5\"\n", - "}\n" - ] - } - ], - "source": [ - "n_ue = len(n_drones) # UE drones control GU wifi networks\n", - "pnat = {} # empty PNAT lookup table\n", - "\n", - "rex = re.compile(r'([0-9\\.]+):([0-9]+) -> ([0-9\\.]+):([0-9]+)')\n", - "\n", - "with open(f'{results_basepath}/{results_dir}/paper_3-wifi.log', 'r') as f:\n", - " for l in f:\n", - " r = rex.search(l)\n", - " if r is None or r.lastindex != 4:\n", - " continue\n", - "\n", - " int_ipaddr, int_port, ext_ipaddr, ext_port = r.groups()\n", - " pnat[f'{ext_ipaddr}:{ext_port}'] = f'{int_ipaddr}'\n", - "\n", - " print(json.dumps(pnat, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"7.0.0.2:1\": 3670,\n", - " \"7.0.0.2:10\": 3573,\n", - " \"7.0.0.2:2\": 3618,\n", - " \"7.0.0.2:3\": 3583,\n", - " \"7.0.0.2:4\": 3583,\n", - " \"7.0.0.2:5\": 3531,\n", - " \"7.0.0.2:6\": 3542,\n", - " \"7.0.0.2:7\": 3619,\n", - " \"7.0.0.2:8\": 3585,\n", - " \"7.0.0.2:9\": 3644,\n", - " \"7.0.0.3:1\": 2667,\n", - " \"7.0.0.3:10\": 2447,\n", - " \"7.0.0.3:11\": 2624,\n", - " \"7.0.0.3:12\": 1842,\n", - " \"7.0.0.3:13\": 2348,\n", - " \"7.0.0.3:14\": 2810,\n", - " \"7.0.0.3:15\": 2207,\n", - " \"7.0.0.3:16\": 1821,\n", - " \"7.0.0.3:17\": 2375,\n", - " \"7.0.0.3:18\": 2537,\n", - " \"7.0.0.3:19\": 3490,\n", - " \"7.0.0.3:2\": 2522,\n", - " \"7.0.0.3:20\": 1933,\n", - " \"7.0.0.3:21\": 2766,\n", - " \"7.0.0.3:22\": 2356,\n", - " \"7.0.0.3:23\": 2559,\n", - " \"7.0.0.3:24\": 2409,\n", - " \"7.0.0.3:25\": 1767,\n", - " \"7.0.0.3:26\": 2271,\n", - " \"7.0.0.3:27\": 2176,\n", - " \"7.0.0.3:28\": 2219,\n", - " \"7.0.0.3:29\": 2600,\n", - " \"7.0.0.3:3\": 2117,\n", - " \"7.0.0.3:4\": 2801,\n", - " \"7.0.0.3:5\": 2432,\n", - " \"7.0.0.3:6\": 2378,\n", - " \"7.0.0.3:7\": 2044,\n", - " \"7.0.0.3:8\": 2290,\n", - " \"7.0.0.3:9\": 2526,\n", - " \"7.0.0.4:1\": 2808,\n", - " \"7.0.0.4:10\": 2535,\n", - " \"7.0.0.4:11\": 2695,\n", - " \"7.0.0.4:12\": 3052,\n", - " \"7.0.0.4:13\": 2698,\n", - " \"7.0.0.4:14\": 2588,\n", - " \"7.0.0.4:15\": 2740,\n", - " \"7.0.0.4:16\": 2714,\n", - " \"7.0.0.4:17\": 3118,\n", - " \"7.0.0.4:18\": 2218,\n", - " \"7.0.0.4:19\": 1971,\n", - " \"7.0.0.4:2\": 2873,\n", - " \"7.0.0.4:3\": 2785,\n", - " \"7.0.0.4:4\": 2892,\n", - " \"7.0.0.4:5\": 2823,\n", - " \"7.0.0.4:6\": 2716,\n", - " \"7.0.0.4:7\": 2762,\n", - " \"7.0.0.4:8\": 2932,\n", - " \"7.0.0.4:9\": 2905\n", - "}\n" - ] - } - ], - "source": [ - "# Now we should filter and get packets from internet. Retrieve IP-Port from NATApplication logs, then get udp packets \n", - "# from pcap and then evaluate PDR/PLR\n", - "def pkt_per_drone_internet(pcap_filename):\n", - " args = [\n", - " 'tshark', \n", - " '-r', pcap_filename, \n", - " '-T', 'fields',\n", - " '-e', 'ip.src',\n", - " '-e', 'udp.srcport',\n", - " 'udp'\n", - " ]\n", - " ret = subprocess.run(args, capture_output=True)\n", - "\n", - " if ret.returncode != 0:\n", - " print(ret)\n", - " exit(1)\n", - " \n", - " out = ret.stdout.decode('UTF-8').strip().replace('\\t', ':').split(os.linesep)\n", - " out.sort()\n", - " cnt = Counter(out)\n", - " \n", - " return dict(cnt)\n", - "\n", - "\n", - "internet_stack_id = sum(n_drones) + len(n_drones) + 1\n", - "inet_cnt = pkt_per_drone_internet(f'{results_basepath}/{results_dir}/internet-{internet_stack_id}-1.pcap')\n", - "\n", - "print(json.dumps(inet_cnt, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"10.1.0.10\": 3583,\n", - " \"10.1.0.11\": 3619,\n", - " \"10.1.0.12\": 3670,\n", - " \"10.1.0.2\": 3583,\n", - " \"10.1.0.3\": 3644,\n", - " \"10.1.0.4\": 3531,\n", - " \"10.1.0.5\": 3585,\n", - " \"10.1.0.6\": 3573,\n", - " \"10.1.0.8\": 3542,\n", - " \"10.1.0.9\": 3618,\n", - " \"10.2.0.10\": 2348,\n", - " \"10.2.0.11\": 3490,\n", - " \"10.2.0.12\": 2271,\n", - " \"10.2.0.13\": 2522,\n", - " \"10.2.0.14\": 2801,\n", - " \"10.2.0.15\": 1821,\n", - " \"10.2.0.16\": 2526,\n", - " \"10.2.0.17\": 2207,\n", - " \"10.2.0.18\": 2219,\n", - " \"10.2.0.19\": 1767,\n", - " \"10.2.0.2\": 2117,\n", - " \"10.2.0.20\": 2810,\n", - " \"10.2.0.21\": 2600,\n", - " \"10.2.0.22\": 2624,\n", - " \"10.2.0.23\": 2356,\n", - " \"10.2.0.24\": 2432,\n", - " \"10.2.0.25\": 2409,\n", - " \"10.2.0.26\": 2290,\n", - " \"10.2.0.27\": 2044,\n", - " \"10.2.0.28\": 2378,\n", - " \"10.2.0.29\": 1842,\n", - " \"10.2.0.3\": 1933,\n", - " \"10.2.0.30\": 2559,\n", - " \"10.2.0.31\": 2176,\n", - " \"10.2.0.4\": 2667,\n", - " \"10.2.0.6\": 2766,\n", - " \"10.2.0.7\": 2375,\n", - " \"10.2.0.8\": 2447,\n", - " \"10.2.0.9\": 2537,\n", - " \"10.3.0.10\": 2740,\n", - " \"10.3.0.11\": 2823,\n", - " \"10.3.0.12\": 2932,\n", - " \"10.3.0.13\": 2892,\n", - " \"10.3.0.14\": 2873,\n", - " \"10.3.0.15\": 2808,\n", - " \"10.3.0.16\": 3118,\n", - " \"10.3.0.17\": 2905,\n", - " \"10.3.0.18\": 3052,\n", - " \"10.3.0.19\": 1971,\n", - " \"10.3.0.2\": 2762,\n", - " \"10.3.0.20\": 2714,\n", - " \"10.3.0.3\": 2716,\n", - " \"10.3.0.4\": 2698,\n", - " \"10.3.0.5\": 2588,\n", - " \"10.3.0.6\": 2218,\n", - " \"10.3.0.7\": 2695,\n", - " \"10.3.0.8\": 2785,\n", - " \"10.3.0.9\": 2535\n", - "}\n" - ] - } - ], - "source": [ - "inet_cnt = {pnat[k]: v for k, v in inet_cnt.items()}\n", - "\n", - "print(json.dumps(inet_cnt, indent=4, sort_keys=True))" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
GU IP AddrPDR [%]
010.1.0.1089.799499
110.1.0.1190.701754
210.1.0.289.575000
310.1.0.391.214018
410.1.0.488.496241
510.1.0.589.849624
610.1.0.689.728780
710.1.0.888.771930
810.1.0.990.676692
910.2.0.1058.714679
1010.2.0.1186.837522
1110.2.0.1258.773292
1210.2.0.1362.720716
1310.2.0.1476.217687
1410.2.0.1570.281745
1510.2.0.1675.833083
1610.2.0.1762.538963
1710.2.0.1877.344022
1810.2.0.1967.058824
1910.2.0.275.017718
2010.2.0.2069.675180
2110.2.0.2187.043857
2210.2.0.2265.616404
2310.2.0.2359.903382
2410.2.0.2460.860861
2510.2.0.2561.832649
2610.2.0.2657.350363
2710.2.0.2765.914221
2810.2.0.2859.124814
2910.2.0.2963.626943
3010.2.0.373.191973
3110.2.0.3063.863239
3210.2.0.464.858949
3310.2.0.675.470668
3410.2.0.758.353808
3510.2.0.860.885792
3610.2.0.962.334152
3710.3.0.1068.482879
3810.3.0.1169.841663
3910.3.0.1271.390309
4010.3.0.1372.263868
4110.3.0.1470.833333
4210.3.0.1569.937733
4310.3.0.1677.620115
4410.3.0.1772.353674
4510.3.0.1877.599797
4610.3.0.1964.285714
4710.3.0.268.451053
4810.3.0.367.444748
4910.3.0.467.619048
5010.3.0.564.635365
5110.3.0.679.214286
5210.3.0.779.009088
5310.3.0.869.038176
5410.3.0.975.222552
\n", - "
" - ], - "text/plain": [ - " GU IP Addr PDR [%]\n", - "0 10.1.0.10 89.799499\n", - "1 10.1.0.11 90.701754\n", - "2 10.1.0.2 89.575000\n", - "3 10.1.0.3 91.214018\n", - "4 10.1.0.4 88.496241\n", - "5 10.1.0.5 89.849624\n", - "6 10.1.0.6 89.728780\n", - "7 10.1.0.8 88.771930\n", - "8 10.1.0.9 90.676692\n", - "9 10.2.0.10 58.714679\n", - "10 10.2.0.11 86.837522\n", - "11 10.2.0.12 58.773292\n", - "12 10.2.0.13 62.720716\n", - "13 10.2.0.14 76.217687\n", - "14 10.2.0.15 70.281745\n", - "15 10.2.0.16 75.833083\n", - "16 10.2.0.17 62.538963\n", - "17 10.2.0.18 77.344022\n", - "18 10.2.0.19 67.058824\n", - "19 10.2.0.2 75.017718\n", - "20 10.2.0.20 69.675180\n", - "21 10.2.0.21 87.043857\n", - "22 10.2.0.22 65.616404\n", - "23 10.2.0.23 59.903382\n", - "24 10.2.0.24 60.860861\n", - "25 10.2.0.25 61.832649\n", - "26 10.2.0.26 57.350363\n", - "27 10.2.0.27 65.914221\n", - "28 10.2.0.28 59.124814\n", - "29 10.2.0.29 63.626943\n", - "30 10.2.0.3 73.191973\n", - "31 10.2.0.30 63.863239\n", - "32 10.2.0.4 64.858949\n", - "33 10.2.0.6 75.470668\n", - "34 10.2.0.7 58.353808\n", - "35 10.2.0.8 60.885792\n", - "36 10.2.0.9 62.334152\n", - "37 10.3.0.10 68.482879\n", - "38 10.3.0.11 69.841663\n", - "39 10.3.0.12 71.390309\n", - "40 10.3.0.13 72.263868\n", - "41 10.3.0.14 70.833333\n", - "42 10.3.0.15 69.937733\n", - "43 10.3.0.16 77.620115\n", - "44 10.3.0.17 72.353674\n", - "45 10.3.0.18 77.599797\n", - "46 10.3.0.19 64.285714\n", - "47 10.3.0.2 68.451053\n", - "48 10.3.0.3 67.444748\n", - "49 10.3.0.4 67.619048\n", - "50 10.3.0.5 64.635365\n", - "51 10.3.0.6 79.214286\n", - "52 10.3.0.7 79.009088\n", - "53 10.3.0.8 69.038176\n", - "54 10.3.0.9 75.222552" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "pdr = {}\n", - "\n", - "for k, v in udp_cnt.items():\n", - " if k == '': continue\n", - " \n", - " v1 = inet_cnt[k]\n", - " pdr[k] = v1 * 100 / v\n", - "\n", - "pdr = pd.DataFrame(pdr.items(), columns=['GU IP Addr', 'PDR [%]'])\n", - "pdr" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "alignmentgroup": "True", - "bingroup": "x", - "histfunc": "sum", - "hovertemplate": "GU IP Addr=%{x}
sum of PDR [%]=%{y}", - "legendgroup": "", - "marker": { - "color": "#636efa", - "pattern": { - "shape": "" - } - }, - "name": "", - "offsetgroup": "", - "orientation": "v", - "showlegend": false, - "type": "histogram", - "x": [ - "10.1.0.10", - "10.1.0.11", - "10.1.0.2", - "10.1.0.3", - "10.1.0.4", - "10.1.0.5", - "10.1.0.6", - "10.1.0.8", - "10.1.0.9", - "10.2.0.10", - "10.2.0.11", - "10.2.0.12", - "10.2.0.13", - "10.2.0.14", - "10.2.0.15", - "10.2.0.16", - "10.2.0.17", - "10.2.0.18", - "10.2.0.19", - "10.2.0.2", - "10.2.0.20", - "10.2.0.21", - "10.2.0.22", - "10.2.0.23", - "10.2.0.24", - "10.2.0.25", - "10.2.0.26", - "10.2.0.27", - "10.2.0.28", - "10.2.0.29", - "10.2.0.3", - "10.2.0.30", - "10.2.0.4", - "10.2.0.6", - "10.2.0.7", - "10.2.0.8", - "10.2.0.9", - "10.3.0.10", - "10.3.0.11", - "10.3.0.12", - "10.3.0.13", - "10.3.0.14", - "10.3.0.15", - "10.3.0.16", - "10.3.0.17", - "10.3.0.18", - "10.3.0.19", - "10.3.0.2", - "10.3.0.3", - "10.3.0.4", - "10.3.0.5", - "10.3.0.6", - "10.3.0.7", - "10.3.0.8", - "10.3.0.9" - ], - "xaxis": "x", - "y": [ - 89.79949874686717, - 90.70175438596492, - 89.575, - 91.21401752190238, - 88.49624060150376, - 89.84962406015038, - 89.72877950778503, - 88.7719298245614, - 90.67669172932331, - 58.714678669667414, - 86.83752177158497, - 58.77329192546584, - 62.72071623974136, - 76.21768707482993, - 70.28174450019297, - 75.83308315821074, - 62.53896287900255, - 77.34402230742418, - 67.05882352941177, - 75.01771793054571, - 69.67517976692288, - 87.04385671242049, - 65.61640410102525, - 59.90338164251208, - 60.86086086086086, - 61.832648870636554, - 57.3503631354871, - 65.91422121896163, - 59.12481352560915, - 63.626943005181346, - 73.1919727375994, - 63.863239331170455, - 64.85894941634241, - 75.4706684856753, - 58.353808353808354, - 60.88579248569296, - 62.334152334152336, - 68.48287928017996, - 69.8416625432954, - 71.39030922814706, - 72.26386806596702, - 70.83333333333333, - 69.93773349937733, - 77.6201145133184, - 72.35367372353674, - 77.59979659293161, - 64.28571428571429, - 68.45105328376704, - 67.44474795132854, - 67.61904761904762, - 64.63536463536464, - 79.21428571428571, - 79.00908824391674, - 69.03817550818047, - 75.22255192878339 - ], - "yaxis": "y" - } - ], - "layout": { - "barmode": "relative", - "legend": { - "tracegroupgap": 0 - }, - "margin": { - "t": 60 - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "xaxis": { - "anchor": "y", - "domain": [ - 0, - 1 - ], - "title": { - "text": "GU IP Addr" - } - }, - "yaxis": { - "anchor": "x", - "domain": [ - 0, - 1 - ], - "title": { - "text": "sum of PDR [%]" - } - } - } - }, - "text/html": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig = px.histogram(pdr, x='GU IP Addr', y='PDR [%]')\n", - "fig.show()" - ] - } - ], - "metadata": { - "interpreter": { - "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" - }, - "kernelspec": { - "display_name": "Bash", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.2" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/analysis/pcap-get_pdr.py b/analysis/pcap-get_pdr.py new file mode 100644 index 00000000..024e17c0 --- /dev/null +++ b/analysis/pcap-get_pdr.py @@ -0,0 +1,149 @@ +# Retrieve PDR/PLR data by analyzing a PCAP file in IoD Sim + +#%% +import json +import os +import re +import subprocess +from collections import Counter +from multiprocessing import Pool + +import pandas as pd +import plotly.express as px + +#%% +results_basepath = "../results" +# results_dir = 'paper_3-wifi-staticGU-UDP-2022-02-19.17-31-49' +# scenario_name = 'paper_3-wifi-staticGU-UDP' +results_dir = "paper_3-wifi-2022-03-03.18-53-11" +scenario_name = "paper_3-wifi" + +net_prefixes = ["7.0.0"] +n_drones = [6, 9, 9, 8] + +# assert(len(net_prefixes) == len(n_drones)) +n_stacks = len(n_drones) + +#%% +def pkt_per_drone_in_stack(args): + base_path, n_drones, net_prefix, stack_id, key_field, pkt_type = args + flt_str = " or ".join( + [f"ip.src == {net_prefix}.{i}" for i in range(2, n_drones + 1)] + ) + + args = [ + "tshark", + "-r", + f"{base_path}/wifi-phy-{stack_id}-drones-host-{stack_id}-2.pcap", + "-T", + "fields", + "-e", + key_field, + f"{pkt_type} and {flt_str}", + ] + ret = subprocess.run(args, capture_output=True) + + if ret.returncode != 0: + print(ret) + exit(1) + + out = ret.stdout.decode("UTF-8").strip().split(os.linesep) + out.sort() + cnt = Counter(out) + + return dict(cnt) + + +r = None +with Pool(n_stacks) as p: + r = p.map( + pkt_per_drone_in_stack, + [ + ( + f"{results_basepath}/{results_dir}", + n_drones[i], + net_prefixes[i], + i, + "ip.src", + "udp and not icmp", + ) + for i in range(n_stacks) + ], + ) + +assert r is not None +udp_cnt = {k: v for d in r for k, v in d.items()} +print(udp_cnt) + +#%% Retrieve IP-Port mapping to learn the PNAT table used in the scenario +n_ue = len(n_drones) # UE drones control GU wifi networks +pnat = {} # empty PNAT lookup table + +rex = re.compile(r"([0-9\.]+):([0-9]+) -> ([0-9\.]+):([0-9]+)") + +with open(f"{results_basepath}/{results_dir}/paper_3-wifi.log", "r") as f: + for l in f: + r = rex.search(l) + if r is None or r.lastindex != 4: + continue + + int_ipaddr, int_port, ext_ipaddr, ext_port = r.groups() + pnat[f"{ext_ipaddr}:{ext_port}"] = f"{int_ipaddr}" + + print(json.dumps(pnat, indent=4, sort_keys=True)) + +#%% Now we should filter and get packets from internet. Retrieve IP-Port from NATApplication logs, then get udp packets from pcap and then evaluate PDR/PLR +def pkt_per_drone_internet(pcap_filename): + args = [ + "tshark", + "-r", + pcap_filename, + "-T", + "fields", + "-e", + "ip.src", + "-e", + "udp.srcport", + "udp", + ] + ret = subprocess.run(args, capture_output=True) + + if ret.returncode != 0: + print(ret) + exit(1) + + out = ret.stdout.decode("UTF-8").strip().replace("\t", ":").split(os.linesep) + out.sort() + cnt = Counter(out) + + return dict(cnt) + + +internet_stack_id = sum(n_drones) + len(n_drones) + 1 +inet_cnt = pkt_per_drone_internet( + f"{results_basepath}/{results_dir}/internet-{internet_stack_id}-1.pcap" +) + +print(json.dumps(inet_cnt, indent=4, sort_keys=True)) + +#%% +inet_cnt = {pnat[k]: v for k, v in inet_cnt.items()} + +print(json.dumps(inet_cnt, indent=4, sort_keys=True)) + +#%% +pdr = {} + +for k, v in udp_cnt.items(): + if k == "": + continue + + v1 = inet_cnt[k] + pdr[k] = v1 * 100 / v + +pdr = pd.DataFrame(pdr.items(), columns=["GU IP Addr", "PDR [%]"]) +pdr + +#%% +fig = px.histogram(pdr, x="GU IP Addr", y="PDR [%]") +fig.show()