Skip to content

Commit 2e48ac8

Browse files
authored
Adding Analysis Code
1 parent 1a32530 commit 2e48ac8

File tree

2 files changed

+238
-0
lines changed

2 files changed

+238
-0
lines changed

analyze.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import argparse
2+
from wsgiref.simple_server import WSGIRequestHandler
3+
from calc_funcs import *
4+
5+
args_parser = argparse.ArgumentParser()
6+
args_parser.add_argument('--sender_pcap', '-sp', type=str, required=True, help='Pcap from the node sending traffic.')
7+
args_parser.add_argument('--receiver_pcap', '-rp', type=str, required=True, help='Pcap from the node receiving traffic.')
8+
args_parser.add_argument('--sender_ip', '-sip', type=str, required=True, help='IP address of the sender node.')
9+
args_parser.add_argument('--receiver_ip', '-rip', required=True, help='IP address of the receiver node.')
10+
args_parser.add_argument('--dest_port', '-dp', type=int, required=False, default=5201, help='Listening server port, in case of iperf3 5201.')
11+
args_parser.add_argument('--name', '-n', type=str, required=False, default='noname', help='Name of the experiment to generate graphs with that name for distiction.')
12+
args_parser.add_argument('--hist_filename', '-hf', type=str, required=False, help='File name to save histogram of packet delays. E.g., hist.jpg')
13+
args_parser.add_argument('--pdf_filename', '-pf', type=str, required=False, help='File name to save pdf graph. E.g., pdf.jpg')
14+
args_parser.add_argument('--cdf_filename', '-cf', type=str, required=False, help='File name to save cdf graph. E.g., cdf.jpg')
15+
args_parser.add_argument('--pdf_cdf_filename', '-pcf', type=str, required=False, help='File name to save pdf-cdf graph. E.g., pdf-cdf.jpg')
16+
args_parser.add_argument('--bins', '-bn', default='auto', required=False, help='Number of bins for drawing histogram/pdf/cdf.')
17+
args_parser.add_argument('--hist_yscale', '-hy', default='linear', required=False, type=str, choices=['linear', 'log', 'symlog', 'logit'], help='Histogram Y-Scale, ')
18+
args_parser.add_argument('--pcaps_dir', '-pd', default='pcaps', required=False, type=str, help='Directory name containing pcaps.')
19+
args_parser.add_argument('--graphs_dir', '-gd', default='graphs', required=False, type=str, help='Directory name to save graph plots output.')
20+
21+
args = args_parser.parse_args()
22+
23+
if __name__ == '__main__':
24+
if args.hist_filename:
25+
hist_filename = os.path.join(args.graphs_dir, args.hist_filename)
26+
else:
27+
hist_filename = os.path.join(args.graphs_dir, args.name, args.name + '_histogram.jpg')
28+
29+
if args.pdf_filename:
30+
pdf_filename = os.path.join(args.graphs_dir, args.pdf_filename)
31+
else:
32+
pdf_filename = os.path.join(args.graphs_dir, args.name, args.name + '_pdf.jpg')
33+
34+
if args.cdf_filename:
35+
cdf_filename = os.path.join(args.graphs_dir, args.cdf_filename)
36+
else:
37+
cdf_filename = os.path.join(args.graphs_dir, args.name, args.name + '_cdf.jpg')
38+
39+
if args.pdf_cdf_filename:
40+
pdf_cdf_filename = os.path.join(args.graphs_dir, args.pdf_cdf_filename)
41+
else:
42+
pdf_cdf_filename = os.path.join(args.graphs_dir, args.name, args.name + '_pdf_cdf.jpg')
43+
44+
create_if_not_present_dir(args.graphs_dir)
45+
graphs_save_dir = os.path.join(args.graphs_dir, args.name)
46+
create_if_not_present_dir(graphs_save_dir)
47+
48+
sender_pcap_filename = os.path.join(args.pcaps_dir, args.sender_pcap)
49+
receiver_pcap_filename = os.path.join(args.pcaps_dir, args.receiver_pcap)
50+
51+
sender_scapy_cap = read_pcap(sender_pcap_filename)
52+
receiver_scapy_cap = read_pcap(receiver_pcap_filename)
53+
54+
ip_filtered_sender_scapy_cap = filter_pcap(scapy_cap=sender_scapy_cap, src_ip=args.sender_ip, dest_ip=args.receiver_ip)
55+
ip_filtered_receiver_scapy_cap = filter_pcap(scapy_cap=receiver_scapy_cap, src_ip=args.sender_ip, dest_ip=args.receiver_ip)
56+
57+
src_port = get_src_port(ip_filtered_sender_scapy_cap)
58+
59+
sender_filtered_scapy_cap = filter_pcap(scapy_cap=ip_filtered_sender_scapy_cap, src_port=src_port, dest_port=args.dest_port)
60+
receiver_filtered_scapy_cap = filter_pcap(scapy_cap=ip_filtered_receiver_scapy_cap, src_port=src_port, dest_port=args.dest_port)
61+
62+
sender_seq_time_list = get_pkt_seq_n_time(sender_filtered_scapy_cap)
63+
receiver_seq_time_list = get_pkt_seq_n_time(receiver_filtered_scapy_cap)
64+
65+
sender_df = pd.DataFrame(sender_seq_time_list, columns =['Sequence', 'Time_Transmit'])
66+
receiver_df = pd.DataFrame(receiver_seq_time_list, columns =['Sequence', 'Time_Receive'])
67+
68+
sender_df.drop_duplicates(subset ="Sequence", keep = 'last', inplace = True)
69+
receiver_df.drop_duplicates(subset ="Sequence", keep = 'last', inplace = True)
70+
71+
final_df = pd.merge(sender_df, receiver_df, on='Sequence', how='outer')
72+
final_df = remove_NaN(final_df)
73+
74+
final_df['Delay'] = (final_df['Time_Receive'] - final_df['Time_Transmit']) * 1000
75+
data_arr = final_df['Delay'].to_numpy()
76+
77+
78+
draw_hist(data_arr, bins=args.bins, yscale=args.hist_yscale, hist_filename=hist_filename)
79+
draw_pdf(data_arr, bins=args.bins, pdf_filename=pdf_filename)
80+
draw_cdf(data_arr, bins=args.bins, cdf_filename=cdf_filename)
81+
draw_pdf_cdf(data_arr, bins=args.bins, pdf_cdf_filename=pdf_cdf_filename)

calc_funcs.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
from scapy.all import *
2+
import os
3+
import numpy as np
4+
import pandas as pd
5+
import matplotlib.pyplot as plt
6+
7+
def read_pcap(pcap_name):
8+
scapy_cap = rdpcap(pcap_name)
9+
print('Read ', pcap_name, '. Total Packets: ', len(scapy_cap))
10+
return scapy_cap
11+
12+
def create_if_not_present_dir(path):
13+
if not os.path.exists(path):
14+
os.makedirs(path)
15+
16+
def filter_pcap(scapy_cap=None, src_ip=None, src_port=None, dest_ip=None, dest_port=None):
17+
filtered = []
18+
if scapy_cap:
19+
for pkt in scapy_cap:
20+
if IP in pkt and TCP in pkt:
21+
if pkt.len > 1400:
22+
if src_ip:
23+
if pkt[IP].src != src_ip:
24+
continue
25+
if src_port:
26+
if pkt[TCP].sport != src_port:
27+
continue
28+
if dest_ip:
29+
if pkt[IP].dst != dest_ip:
30+
continue
31+
if dest_port:
32+
if pkt[TCP].dport != dest_port:
33+
continue
34+
filtered.append(pkt)
35+
print('After Filtering No. of Packets: ', len(filtered))
36+
return filtered
37+
38+
def get_pkt_seq_n_time(scapy_cap):
39+
seq_time_list = []
40+
for pkt in scapy_cap:
41+
seq_time_list.append((pkt[TCP].seq, float(pkt.time)))
42+
print('Fetched sequence number and timestamp')
43+
return seq_time_list
44+
45+
def save_pcap(pkt_list, name):
46+
print('Saved as pcap: ', name)
47+
wrpcap(name, pkt_list)
48+
49+
def most_common(lst):
50+
return max(set(lst), key=lst.count)
51+
52+
def remove_NaN(pandas_df):
53+
for column in pandas_df.columns:
54+
pandas_df = pandas_df[pandas_df[column].notna()]
55+
print('Removed NaN from columns.')
56+
return pandas_df
57+
58+
def get_src_port(scapy_cap):
59+
src_port_list = []
60+
for pkt in scapy_cap:
61+
if TCP in pkt:
62+
src_port_list.append(pkt[TCP].sport)
63+
src_port = most_common(src_port_list)
64+
print('Source Port is: ', src_port)
65+
return src_port
66+
67+
def draw_hist(data_arr, bins='auto', yscale='log', hist_filename='histogram.jpg'):
68+
plt_hist = plt
69+
plt_hist.yscale(yscale)
70+
plt_hist.xlabel('Delay(ms) (min: ' + str(round(data_arr.min(), 3)) + 'ms max: ' + str(round(data_arr.max(), 3)) + 'ms)')
71+
plt_hist.ylabel('Frequency')
72+
plt_hist.hist(data_arr, bins=bins)
73+
plt_hist.savefig(hist_filename)
74+
plt_hist.close()
75+
if data_arr.max() > 20:
76+
plt_hist = plt
77+
plt_hist.yscale(yscale)
78+
plt_hist.xlabel('Delay(ms)')
79+
plt_hist.ylabel('Frequency')
80+
plt_hist.xlim([data_arr.min(), data_arr.min() + 10])
81+
plt_hist.hist(data_arr, bins=bins)
82+
plt_hist.savefig(hist_filename.split('.')[0] + '_zoomed.' + hist_filename.split('.')[1])
83+
plt_hist.close()
84+
85+
def draw_pdf(data_arr, color='red', label='PDF', bins='auto', pdf_filename='pdf.jpg'):
86+
count, bins_count = np.histogram(data_arr, bins=bins)
87+
pdf = count / sum(count)
88+
plt_pdf = plt
89+
plt_pdf.xlabel('Delay(ms)')
90+
plt_pdf.ylabel('PDF')
91+
plt_pdf.axhline(y = 0.0, color = 'r', linestyle = '-')
92+
plt_pdf.plot(bins_count[1:], pdf, color=color, label='PDF')
93+
plt_pdf.savefig(pdf_filename)
94+
plt_pdf.close()
95+
if data_arr.max() > 20:
96+
plt_pdf = plt
97+
plt_pdf.xlabel('Delay(ms)')
98+
plt_pdf.ylabel('PDF')
99+
plt_pdf.xlim([data_arr.min(), data_arr.min() + 10])
100+
plt_pdf.axhline(y = 0.0, color = 'r', linestyle = '-')
101+
plt_pdf.plot(bins_count[1:], pdf, color=color, label='PDF')
102+
plt_pdf.savefig(pdf_filename.split('.')[0] + '_zoomed.' + pdf_filename.split('.')[1])
103+
plt_pdf.close()
104+
105+
def draw_cdf(data_arr, color='blue', label='CDF', bins='auto', cdf_filename='cdf.jpg'):
106+
count, bins_count = np.histogram(data_arr, bins=bins)
107+
pdf = count / sum(count)
108+
cdf = np.cumsum(pdf)
109+
plt_cdf = plt
110+
plt_cdf.xlabel('Delay(ms)')
111+
plt_cdf.ylabel('CDF')
112+
plt_cdf.axhline(y = 1.0, color = 'r', linestyle = '-')
113+
plt_cdf.plot(bins_count[1:], cdf, color=color, label="CDF")
114+
plt_cdf.savefig(cdf_filename)
115+
plt_cdf.close()
116+
if data_arr.max() > 20:
117+
plt_cdf = plt
118+
plt_cdf.xlabel('Delay(ms)')
119+
plt_cdf.ylabel('CDF')
120+
plt_cdf.xlim([data_arr.min(), data_arr.min() + 10])
121+
plt_cdf.axhline(y = 1.0, color = 'r', linestyle = '-')
122+
plt_cdf.plot(bins_count[1:], cdf, color=color, label="CDF")
123+
plt_cdf.savefig(cdf_filename.split('.')[0] + '_zoomed.' + cdf_filename.split('.')[1])
124+
plt_cdf.close()
125+
126+
def draw_pdf_cdf(data_arr, pdf_color='red', cdf_color='blue', bins='auto', pdf_cdf_filename='pdf_cdf.jpg'):
127+
count, bins_count = np.histogram(data_arr, bins=bins)
128+
pdf = count / sum(count)
129+
cdf = np.cumsum(pdf)
130+
fig, ax1 = plt.subplots()
131+
color = 'tab:red'
132+
ax1.set_xlabel('Delay(ms)')
133+
ax1.set_ylabel('PDF')
134+
ax1.plot(bins_count[1:], pdf, color=pdf_color, label='PDF')
135+
ax1.tick_params(axis='y', labelcolor=color)
136+
ax2 = ax1.twinx()
137+
color = 'tab:blue'
138+
ax2.set_ylabel('CDF')
139+
ax2.plot(bins_count[1:], cdf, color=cdf_color, label='CDF')
140+
ax2.tick_params(axis='y', labelcolor=color)
141+
plt.savefig(pdf_cdf_filename)
142+
plt.close()
143+
if data_arr.max() > 20:
144+
fig, ax1 = plt.subplots()
145+
color = 'tab:red'
146+
plt.xlim([data_arr.min(), data_arr.min() + 10])
147+
ax1.set_xlabel('Delay(ms)')
148+
ax1.set_ylabel('PDF')
149+
ax1.plot(bins_count[1:], pdf, color=pdf_color, label='PDF')
150+
ax1.tick_params(axis='y', labelcolor=color)
151+
ax2 = ax1.twinx()
152+
color = 'tab:blue'
153+
ax2.set_ylabel('CDF')
154+
ax2.plot(bins_count[1:], cdf, color=cdf_color, label='CDF')
155+
ax2.tick_params(axis='y', labelcolor=color)
156+
plt.savefig(pdf_cdf_filename.split('.')[0] + '_zoomed.' + pdf_cdf_filename.split('.')[1])
157+
plt.close()

0 commit comments

Comments
 (0)