def extract_flow_data(out_file): """ Given an (open) file, return a dictionary of as many elements as there are mptcp flows """ # Return at the beginning of the file out_file.seek(0) data = out_file.readlines() connections = {} current_connection = False for line in data: # Case 1: line start with MPTCP connection if line.startswith("MPTCP connection"): # A typical line: MPTCP connection 0 with id 2 words = line.split() current_connection = int(words[-1]) connections[current_connection] = MPTCPConnection( current_connection) # Case 2: line for a subflow elif current_connection is not False and line.startswith("\tSubflow"): # A typical line: # Subflow 0 with wscale : 6 0 IPv4 sport 59570 dport 443 saddr # 37.185.171.74 daddr 194.78.99.114 words = line.split() sub_flow_id = int(words[1]) subflow = MPTCPSubFlow(sub_flow_id) index_wscale = words.index("wscale") subflow.attr[co.WSCALESRC] = words[index_wscale + 2] subflow.attr[co.WSCALEDST] = words[index_wscale + 3] subflow.attr[co.TYPE] = words[index_wscale + 4] index = words.index("sport") while index + 1 < len(words): attri = words[index] value = words[index + 1] # Cope with different format from tcptrace and mptcptrace if attri == co.SADDR or attri == co.DADDR: value = co.long_ipv6_address(value) subflow.attr[attri] = value index += 2 subflow.indicates_wifi_or_cell() connections[current_connection].flows[sub_flow_id] = subflow connections[current_connection].attr[co.C2S][co.BYTES] = {} connections[current_connection].attr[co.S2C][co.BYTES] = {} connections[current_connection].attr[co.C2S][co.RETRANS_DSS] = [] connections[current_connection].attr[co.S2C][co.RETRANS_DSS] = [] # Case 3: skip the line (no more current connection) else: current_connection = False return connections
def extract_flow_data(out_file): """ Given an (open) file, return a dictionary of as many elements as there are mptcp flows """ # Return at the beginning of the file out_file.seek(0) data = out_file.readlines() connections = {} current_connection = False for line in data: # Case 1: line start with MPTCP connection if line.startswith("MPTCP connection"): # A typical line: MPTCP connection 0 with id 2 words = line.split() current_connection = int(words[-1]) connections[current_connection] = MPTCPConnection(current_connection) # Case 2: line for a subflow elif current_connection is not False and line.startswith("\tSubflow"): # A typical line: # Subflow 0 with wscale : 6 0 IPv4 sport 59570 dport 443 saddr # 37.185.171.74 daddr 194.78.99.114 words = line.split() sub_flow_id = int(words[1]) subflow = MPTCPSubFlow(sub_flow_id) index_wscale = words.index("wscale") subflow.attr[co.WSCALESRC] = words[index_wscale + 2] subflow.attr[co.WSCALEDST] = words[index_wscale + 3] subflow.attr[co.TYPE] = words[index_wscale + 4] index = words.index("sport") while index + 1 < len(words): attri = words[index] value = words[index + 1] # Cope with different format from tcptrace and mptcptrace if attri == co.SADDR or attri == co.DADDR: value = co.long_ipv6_address(value) subflow.attr[attri] = value index += 2 subflow.indicates_wifi_or_cell() connections[current_connection].flows[sub_flow_id] = subflow connections[current_connection].attr[co.C2S][co.BYTES] = {} connections[current_connection].attr[co.S2C][co.BYTES] = {} connections[current_connection].attr[co.C2S][co.RETRANS_DSS] = [] connections[current_connection].attr[co.S2C][co.RETRANS_DSS] = [] # Case 3: skip the line (no more current connection) else: current_connection = False return connections
def extract_tstat_data_tcp_complete(filename, connections, conn_id): """ Subpart of extract_tstat_data dedicated to the processing of the log_tcp_complete file Returns the connections seen and the conn_id reached """ log_file = open(filename) data = log_file.readlines() for line in data: # Case 1: line start with #; skip it if not line.startswith("#"): # Case 2: extract info from the line info = line.split() conn_id += 1 connection = TCPConnection(conn_id) connection.flow.attr[co.SADDR] = co.long_ipv6_address(info[0]) connection.flow.attr[co.DADDR] = co.long_ipv6_address(info[14]) connection.flow.attr[co.SPORT] = info[1] connection.flow.attr[co.DPORT] = info[15] connection.flow.detect_ipv4() connection.flow.indicates_wifi_or_cell() # Except RTT, all time (in ms in tstat) shoud be converted into seconds connection.flow.attr[co.START] = float(info[28]) / 1000.0 connection.flow.attr[co.DURATION] = float(info[30]) / 1000.0 connection.flow.attr[co.C2S][co.PACKS] = int(info[2]) connection.flow.attr[co.S2C][co.PACKS] = int(info[16]) # Note that this count is about unique data bytes (sent in the payload) connection.flow.attr[co.C2S][co.BYTES] = int(info[6]) connection.flow.attr[co.S2C][co.BYTES] = int(info[20]) # This is about actual data bytes (sent in the payload, including retransmissions) connection.flow.attr[co.C2S][co.BYTES_DATA] = int(info[8]) connection.flow.attr[co.S2C][co.BYTES_DATA] = int(info[22]) connection.flow.attr[co.C2S][co.PACKS_RETRANS] = int(info[9]) connection.flow.attr[co.S2C][co.PACKS_RETRANS] = int(info[23]) connection.flow.attr[co.C2S][co.BYTES_RETRANS] = int(info[10]) connection.flow.attr[co.S2C][co.BYTES_RETRANS] = int(info[24]) connection.flow.attr[co.C2S][co.PACKS_OOO] = int(info[11]) connection.flow.attr[co.S2C][co.PACKS_OOO] = int(info[25]) connection.flow.attr[co.C2S][co.NB_SYN] = int(info[12]) connection.flow.attr[co.S2C][co.NB_SYN] = int(info[26]) connection.flow.attr[co.C2S][co.NB_FIN] = int(info[13]) connection.flow.attr[co.S2C][co.NB_FIN] = int(info[27]) connection.flow.attr[co.C2S][co.NB_RST] = int(info[3]) connection.flow.attr[co.S2C][co.NB_RST] = int(info[17]) connection.flow.attr[co.C2S][co.NB_ACK] = int(info[4]) connection.flow.attr[co.S2C][co.NB_ACK] = int(info[18]) # Except RTT, all time (in ms in tstat) shoud be converted into seconds connection.flow.attr[co.C2S][co.TIME_FIRST_PAYLD] = float( info[31]) / 1000.0 connection.flow.attr[co.S2C][co.TIME_FIRST_PAYLD] = float( info[32]) / 1000.0 connection.flow.attr[co.C2S][co.TIME_LAST_PAYLD] = float( info[33]) / 1000.0 connection.flow.attr[co.S2C][co.TIME_LAST_PAYLD] = float( info[34]) / 1000.0 connection.flow.attr[co.C2S][co.TIME_FIRST_ACK] = float( info[35]) / 1000.0 connection.flow.attr[co.S2C][co.TIME_FIRST_ACK] = float( info[36]) / 1000.0 connection.flow.attr[co.C2S][co.RTT_SAMPLES] = int(info[48]) connection.flow.attr[co.S2C][co.RTT_SAMPLES] = int(info[55]) connection.flow.attr[co.C2S][co.RTT_MIN] = float(info[45]) connection.flow.attr[co.S2C][co.RTT_MIN] = float(info[52]) connection.flow.attr[co.C2S][co.RTT_MAX] = float(info[46]) connection.flow.attr[co.S2C][co.RTT_MAX] = float(info[53]) connection.flow.attr[co.C2S][co.RTT_AVG] = float(info[44]) connection.flow.attr[co.S2C][co.RTT_AVG] = float(info[51]) connection.flow.attr[co.C2S][co.RTT_STDEV] = float(info[47]) connection.flow.attr[co.S2C][co.RTT_STDEV] = float(info[54]) connection.flow.attr[co.C2S][co.TTL_MIN] = float(info[49]) connection.flow.attr[co.S2C][co.TTL_MIN] = float(info[56]) connection.flow.attr[co.C2S][co.TTL_MAX] = float(info[50]) connection.flow.attr[co.S2C][co.TTL_MAX] = float(info[57]) connection.flow.attr[co.C2S][co.SS_MIN] = int(info[71]) connection.flow.attr[co.S2C][co.SS_MIN] = int(info[94]) connection.flow.attr[co.C2S][co.SS_MAX] = int(info[70]) connection.flow.attr[co.S2C][co.SS_MAX] = int(info[93]) connection.flow.attr[co.C2S][co.CWIN_MIN] = int(info[76]) connection.flow.attr[co.S2C][co.CWIN_MIN] = int(info[99]) connection.flow.attr[co.C2S][co.CWIN_MAX] = int(info[75]) connection.flow.attr[co.S2C][co.CWIN_MAX] = int(info[98]) connection.flow.attr[co.C2S][co.NB_RTX_RTO] = int(info[78]) connection.flow.attr[co.S2C][co.NB_RTX_RTO] = int(info[101]) connection.flow.attr[co.C2S][co.NB_RTX_FR] = int(info[79]) connection.flow.attr[co.S2C][co.NB_RTX_FR] = int(info[102]) connection.flow.attr[co.C2S][co.NB_REORDERING] = int(info[80]) connection.flow.attr[co.S2C][co.NB_REORDERING] = int(info[103]) connection.flow.attr[co.C2S][co.NB_NET_DUP] = int(info[81]) connection.flow.attr[co.S2C][co.NB_NET_DUP] = int(info[104]) connection.flow.attr[co.C2S][co.NB_UNKNOWN] = int(info[82]) connection.flow.attr[co.S2C][co.NB_UNKNOWN] = int(info[105]) connection.flow.attr[co.C2S][co.NB_FLOW_CONTROL] = int(info[83]) connection.flow.attr[co.S2C][co.NB_FLOW_CONTROL] = int(info[106]) connection.flow.attr[co.C2S][co.NB_UNNECE_RTX_RTO] = int(info[84]) connection.flow.attr[co.S2C][co.NB_UNNECE_RTX_RTO] = int(info[107]) connection.flow.attr[co.C2S][co.NB_UNNECE_RTX_FR] = int(info[85]) connection.flow.attr[co.S2C][co.NB_UNNECE_RTX_FR] = int(info[108]) connection.attr[co.C2S][co.BYTES] = {} connection.attr[co.S2C][co.BYTES] = {} connection.flow.attr[co.C2S][co.TIMESTAMP_RETRANS] = [] connection.flow.attr[co.S2C][co.TIMESTAMP_RETRANS] = [] connection.flow.attr[co.C2S][co.TIME_FIN_ACK_TCP] = 0.0 connection.flow.attr[co.S2C][co.TIME_FIN_ACK_TCP] = 0.0 connection.flow.attr[co.C2S][co.TIME_LAST_ACK_TCP] = 0.0 connection.flow.attr[co.S2C][co.TIME_LAST_ACK_TCP] = 0.0 connection.flow.attr[co.C2S][co.TIME_LAST_PAYLD_TCP] = 0.0 connection.flow.attr[co.S2C][co.TIME_LAST_PAYLD_TCP] = 0.0 connection.flow.attr[co.C2S][ co.TIME_LAST_PAYLD_WITH_RETRANS_TCP] = 0.0 connection.flow.attr[co.S2C][ co.TIME_LAST_PAYLD_WITH_RETRANS_TCP] = 0.0 connections[conn_id] = connection log_file.close() return connections, conn_id
def extract_tstat_data_tcp_nocomplete(filename, connections, conn_id): log_file = open(filename) data = log_file.readlines() for line in data: # Case 1: line start with #; skip it if not line.startswith("#"): # Case 2: extract info from the line info = line.split() conn_id += 1 connection = TCPConnection(conn_id) connection.flow.attr[co.SADDR] = co.long_ipv6_address(info[0]) connection.flow.attr[co.DADDR] = co.long_ipv6_address(info[14]) connection.flow.attr[co.SPORT] = info[1] connection.flow.attr[co.DPORT] = info[15] connection.flow.detect_ipv4() connection.flow.indicates_wifi_or_cell() # Except RTT, all time (in ms in tstat) shoud be converted into seconds connection.flow.attr[co.START] = float(info[28]) / 1000.0 connection.flow.attr[co.DURATION] = float(info[30]) / 1000.0 connection.flow.attr[co.C2S][co.PACKS] = int(info[2]) connection.flow.attr[co.S2C][co.PACKS] = int(info[16]) # Note that this count is about unique data bytes (sent in the payload) connection.flow.attr[co.C2S][co.BYTES] = int(info[6]) connection.flow.attr[co.S2C][co.BYTES] = int(info[20]) # This is about actual data bytes (sent in the payload, including retransmissions) connection.flow.attr[co.C2S][co.BYTES_DATA] = int(info[8]) connection.flow.attr[co.S2C][co.BYTES_DATA] = int(info[22]) connection.flow.attr[co.C2S][co.PACKS_RETRANS] = int(info[9]) connection.flow.attr[co.S2C][co.PACKS_RETRANS] = int(info[23]) connection.flow.attr[co.C2S][co.BYTES_RETRANS] = int(info[10]) connection.flow.attr[co.S2C][co.BYTES_RETRANS] = int(info[24]) connection.flow.attr[co.C2S][co.PACKS_OOO] = int(info[11]) connection.flow.attr[co.S2C][co.PACKS_OOO] = int(info[25]) connection.flow.attr[co.C2S][co.NB_SYN] = int(info[12]) connection.flow.attr[co.S2C][co.NB_SYN] = int(info[26]) connection.flow.attr[co.C2S][co.NB_FIN] = int(info[13]) connection.flow.attr[co.S2C][co.NB_FIN] = int(info[27]) connection.flow.attr[co.C2S][co.NB_RST] = int(info[3]) connection.flow.attr[co.S2C][co.NB_RST] = int(info[17]) connection.flow.attr[co.C2S][co.NB_ACK] = int(info[4]) connection.flow.attr[co.S2C][co.NB_ACK] = int(info[18]) # Except RTT, all time (in ms in tstat) shoud be converted into seconds connection.flow.attr[co.C2S][co.TIME_FIRST_PAYLD] = float( info[31]) / 1000.0 connection.flow.attr[co.S2C][co.TIME_FIRST_PAYLD] = float( info[32]) / 1000.0 connection.flow.attr[co.C2S][co.TIME_LAST_PAYLD] = float( info[33]) / 1000.0 connection.flow.attr[co.S2C][co.TIME_LAST_PAYLD] = float( info[34]) / 1000.0 connection.flow.attr[co.C2S][co.TIME_FIRST_ACK] = float( info[35]) / 1000.0 connection.flow.attr[co.S2C][co.TIME_FIRST_ACK] = float( info[36]) / 1000.0 connection.attr[co.C2S][co.BYTES] = {} connection.attr[co.S2C][co.BYTES] = {} connection.flow.attr[co.C2S][co.TIMESTAMP_RETRANS] = [] connection.flow.attr[co.S2C][co.TIMESTAMP_RETRANS] = [] connection.flow.attr[co.C2S][co.TIME_FIN_ACK_TCP] = 0.0 connection.flow.attr[co.S2C][co.TIME_FIN_ACK_TCP] = 0.0 connection.flow.attr[co.C2S][co.TIME_LAST_ACK_TCP] = 0.0 connection.flow.attr[co.S2C][co.TIME_LAST_ACK_TCP] = 0.0 connection.flow.attr[co.C2S][co.TIME_LAST_PAYLD_TCP] = 0.0 connection.flow.attr[co.S2C][co.TIME_LAST_PAYLD_TCP] = 0.0 connection.flow.attr[co.C2S][ co.TIME_LAST_PAYLD_WITH_RETRANS_TCP] = 0.0 connection.flow.attr[co.S2C][ co.TIME_LAST_PAYLD_WITH_RETRANS_TCP] = 0.0 connections[conn_id] = connection log_file.close() return connections, conn_id