summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code/perflow/get_tcp_states.py196
-rw-r--r--code/perflow/parser_mod1.py56
-rw-r--r--data/perflow/get_tcp_states_res.txt8
3 files changed, 260 insertions, 0 deletions
diff --git a/code/perflow/get_tcp_states.py b/code/perflow/get_tcp_states.py
new file mode 100644
index 0000000..fb3f6fd
--- /dev/null
+++ b/code/perflow/get_tcp_states.py
@@ -0,0 +1,196 @@
+import pickle
+import datetime
+import sys
+import dpkt
+
+tcp_dump_filename = 'tcpout.pickle'
+pkts_dump_filename = 'pkts2.pickle'
+pkts = []
+flowsTCP = []
+
+def create_pcap_to_pickle_dump():
+ global pkts
+ print("Reading pccp file ...")
+ f = open("univ1_pt13", 'rb')
+ pcap = dpkt.pcap.Reader(f)
+ for ts, buf in pcap:
+ eth = dpkt.ethernet.Ethernet(buf)
+ # we will store the frame, along with timestamp
+ # as a tuple
+ pkts.append((ts, eth))
+
+ print("number of frames", len(pkts))
+ print("Writing to pcap to pickle ...")
+ with open('pkts2.pickle', 'wb') as fp3:
+ pickle.dump(pkts, fp3)
+ f.close()
+ fp3.close()
+
+def read_dump(filename):
+ print("Reading pickle file " + filename + " ...")
+ with open(filename, 'rb') as fp:
+ py_arr = pickle.load(fp)
+ fp.close()
+ return py_arr
+
+# will get a list of the starting frame for each flow
+def get_flow_start_frame_nums():
+ start_frame_nums = []
+ for flow in flowsTCP:
+ start_frame = flow[5][0]
+ start_frame_nums.append(int(start_frame))
+ return start_frame_nums
+
+# will get a list of the ending frame for each flow
+def get_flow_end_frame_nums():
+ end_frame_nums = []
+ for flow in flowsTCP:
+ num_packs_in_flow = len(flow[5])
+ end_frame = flow[5][num_packs_in_flow-1]
+ end_frame_nums.append(int(end_frame))
+ return end_frame_nums
+
+# only used for detecting FINS
+def get_last_two_end_frames():
+ end_frame_nums = []
+ for flow in flowsTCP:
+ num_packs_in_flow = len(flow[5])
+ if num_packs_in_flow > 1:
+ end_frame = flow[5][num_packs_in_flow-1]
+ sec_last_end_fram = flow[5][num_packs_in_flow-2]
+ end_frame_nums.append((int(sec_last_end_fram), int(end_frame)))
+ return end_frame_nums
+
+# returns a count for 1 packet flows that end with syn only
+def count_syns_only():
+ count = 0
+ for start_frame, end_frame in zip(start_frame_nums,end_frame_nums):
+ if start_frame == end_frame:
+ # only 1 packet in this flow, get the packet
+ ts, eth_frame = pkts[end_frame]
+ if hasattr(eth_frame, 'data'):
+ ip = eth_frame.data
+ if hasattr(ip, 'data'):
+ tcp = ip.data
+ if hasattr(tcp, 'flags'):
+ # check syn and ack for this packet
+ syn_flag = ( tcp.flags & dpkt.tcp.TH_SYN ) != 0
+ ack_flag = ( tcp.flags & dpkt.tcp.TH_ACK ) != 0
+ if syn_flag == 1 and ack_flag == 0:
+ count += 1
+ return count
+
+# returns a count of flows that ended with reset
+def count_resets():
+ count = 0
+ for end_frame in end_frame_nums:
+ ts, eth_frame = pkts[end_frame]
+ if hasattr(eth_frame, 'data'):
+ ip = eth_frame.data
+ if hasattr(ip, 'data'):
+ tcp = ip.data
+ if hasattr(tcp, 'flags'):
+ # check reset flag for this packet
+ rst_flag = ( tcp.flags & dpkt.tcp.TH_RST ) != 0
+ if rst_flag == 1:
+ count += 1
+ return count
+
+# returns a count of flows that ended with Fin properly
+def count_fins():
+ count = 0
+ for sec_last_frame, last_frame in two_end_frame_nums:
+ ts_sl, eth_frame_sl = pkts[sec_last_frame]
+ ts_ll, eth_frame_ll = pkts[last_frame]
+ if hasattr(eth_frame_sl, 'data') and hasattr(eth_frame_ll, 'data'):
+ ip_sl = eth_frame_sl.data
+ ip_ll = eth_frame_ll.data
+ if hasattr(ip_sl, 'data') and hasattr(ip_ll, 'data'):
+ tcp_sl = ip_sl.data
+ tcp_ll = ip_ll.data
+ if hasattr(tcp_sl, 'flags') and hasattr(tcp_ll, 'flags'):
+ # check if fin and ack were sent by second last
+ # check if last acked it
+ fin_flag = ( tcp_sl.flags & dpkt.tcp.TH_FIN ) != 0
+ ack_flag = ( tcp_sl.flags & dpkt.tcp.TH_ACK ) != 0
+ ack_flag_ll = ( tcp_ll.flags & dpkt.tcp.TH_ACK ) != 0
+ if fin_flag == 1 and ack_flag == 1 and ack_flag_ll == 1:
+ count += 1
+ return count
+
+# returns a count of flows that have last packet within 5 mins of pcap start
+def count_ongoing():
+ count = 0
+ first_frame_time = get_frame_timestamp(0)
+ for end_frame in end_frame_nums:
+ end_frame_time = get_frame_timestamp(end_frame)
+ delta_s = (end_frame_time - first_frame_time).total_seconds()
+ # check if within 5 mins
+ if delta_s <= (5 * 60): count += 1
+ return count
+
+# returns a count of flows that have last packet before 5 mins of pcap start
+# and some more checks for failure
+def count_failed():
+ count = 0
+ first_frame_time = get_frame_timestamp(0)
+ for end_frame in end_frame_nums:
+ end_frame_time = get_frame_timestamp(end_frame)
+ delta_s = (end_frame_time - first_frame_time).total_seconds()
+ # check if beyond 5 mins
+ if delta_s > (5 * 60):
+ # check for some flags
+ ts, eth_frame = pkts[end_frame]
+ if hasattr(eth_frame, 'data'):
+ ip = eth_frame.data
+ if hasattr(ip, 'data'):
+ tcp = ip.data
+ if hasattr(tcp, 'flags'):
+ # check reset, and fin flag for this packet
+ rst_flag = ( tcp.flags & dpkt.tcp.TH_RST ) != 0
+ fin_flag = ( tcp.flags & dpkt.tcp.TH_FIN ) != 0
+ if rst_flag == 0 or fin_flag == 0:
+ count += 1
+
+ return count
+
+# returns a python datetime obj for a frame's timestamp
+def get_frame_timestamp(frame_number):
+ ts, eth = pkts[frame_number]
+ time = datetime.datetime.utcfromtimestamp(ts)
+ return time
+
+# From dpkt docs...
+# Source: http://www.commercialventvac.com/dpkt.html
+# Author: Jeff Silverman, jeffsilverm at gmail dot com
+# This function is not used anywhere, but some of the
+# lines are.
+def decode_tcp_flags(tcp):
+ fin_flag = ( tcp.flags & dpkt.tcp.TH_FIN ) != 0
+ syn_flag = ( tcp.flags & dpkt.tcp.TH_SYN ) != 0
+ rst_flag = ( tcp.flags & dpkt.tcp.TH_RST ) != 0
+ psh_flag = ( tcp.flags & dpkt.tcp.TH_PUSH) != 0
+ ack_flag = ( tcp.flags & dpkt.tcp.TH_ACK ) != 0
+ urg_flag = ( tcp.flags & dpkt.tcp.TH_URG ) != 0
+ ece_flag = ( tcp.flags & dpkt.tcp.TH_ECE ) != 0
+ cwr_flag = ( tcp.flags & dpkt.tcp.TH_CWR ) != 0
+ pass
+
+
+# If first time running then run next line
+# otherwise leave commented out:
+# create_pcap_to_pickle_dump()
+
+flowsTCP = read_dump(tcp_dump_filename);
+pkts = read_dump(pkts_dump_filename);
+
+start_frame_nums = get_flow_start_frame_nums()
+end_frame_nums = get_flow_end_frame_nums()
+two_end_frame_nums = get_last_two_end_frames()
+
+print("SYN count", count_syns_only())
+print("RESET count", count_resets())
+print("FIN count", count_fins())
+print("ONGOING count", count_ongoing())
+print("FAILED count", count_failed())
+print("done")
diff --git a/code/perflow/parser_mod1.py b/code/perflow/parser_mod1.py
new file mode 100644
index 0000000..80b9381
--- /dev/null
+++ b/code/perflow/parser_mod1.py
@@ -0,0 +1,56 @@
+# NOTES:
+# This file is exactly the same as original with 2 modifications as follows:
+
+# 1. every time we know a packet belongs to a flow (new or old),
+# add it's FRAME NUMBER (given by Wireshark csv export) to the END [5]
+# of the arrays containing flow info - flowTCP, flowUDP
+# This way, we can know which packets (by id) belong to a flow
+# 2. Once the arrays are built, we dump the binary as a pickle for
+# future use as these are constant.
+
+# This file excludes any modification for numpy etc that were made later on.
+# because it was not needed for our purposes for this file.
+
+import pickle
+import csv
+
+with open('packetdata.csv', mode='r') as csv_file:
+ csv_reader = csv.DictReader(csv_file)
+ line_count = 0
+ flowsTCP = []
+ flowsUDP = []
+ for row in csv_reader:
+ if row["Protocol"] == 'TCP':
+ flowExists = False
+ src = row["Source"]
+ dest = row["Destination"]
+ srcPort = row["Info"].split(' > ')[0].split(' ')[0]
+ destPort = row["Info"].split(' > ')[1].split(' ')[1]
+ startTime = float(row["Time"])
+ for flow in flowsTCP:
+ if src in flow and dest in flow and srcPort in flow and destPort in flow:
+ flowExists = True
+ flow[5].append(row["No."])
+ break
+ if not flowExists:
+ flowsTCP.append([src, dest, srcPort, destPort, startTime, [row["No."]] ])
+ if row["Protocol"] == 'UDP':
+ flowExists = False
+ src = row["Source"]
+ dest = row["Destination"]
+ srcPort = row["Info"].split(' > ')[0].split(' ')[0]
+ destPort = row["Info"].split(' > ')[1].split(' ')[1]
+ for flow in flowsUDP:
+ if src in flow and dest in flow and srcPort in flow and destPort in flow:
+ flowExists = True
+ break
+ if not flowExists:
+ flowsUDP.append([src, dest, srcPort, destPort, [row["No."]] ])
+ print('TCP Length ' + str(len(flowsTCP)))
+ print('UDP Length ' + str(len(flowsUDP)))
+
+ with open('tcpout.pickle', 'wb') as fp1:
+ pickle.dump(flowsTCP, fp1)
+
+ with open('udpout.pickle', 'wb') as fp2:
+ pickle.dump(flowsUDP, fp2)
diff --git a/data/perflow/get_tcp_states_res.txt b/data/perflow/get_tcp_states_res.txt
new file mode 100644
index 0000000..b1013a7
--- /dev/null
+++ b/data/perflow/get_tcp_states_res.txt
@@ -0,0 +1,8 @@
+Reading pickle file tcpout.pickle ...
+Reading pickle file pkts2.pickle ...
+SYN count 17
+RESET count 167
+FIN count 427
+ONGOING count 10526
+FAILED count 0
+done