diff options
Diffstat (limited to 'code')
| -rw-r--r-- | code/perflow/get_tcp_states.py | 196 | ||||
| -rw-r--r-- | code/perflow/parser_mod1.py | 56 |
2 files changed, 252 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) |
