diff --git a/utils/packet_input.py b/utils/packet_input.py index ea45d23..1d6ca08 100755 --- a/utils/packet_input.py +++ b/utils/packet_input.py @@ -31,6 +31,7 @@ def copy_input_packets(os_name: str, trace_retransmission: bool): " ********************************************************************** ") print( " paste here the first packet hex dump start with the IP layer and then enter :") + print(" . . . - . . . . - . . . . - . . . . - . ") copy_packet_1 = IP(import_hexcap()) print(" . . . - . . . . - . . . . - . . . . - . ") print(" . . . - . developed view of this packet:") @@ -38,25 +39,28 @@ def copy_input_packets(os_name: str, trace_retransmission: bool): print(" . . . - . . . . - . . . . - . . . . - . ") if not trace_retransmission: if copy_packet_1.haslayer(TCP): - if os_name == "Linux": - do_tcph1 = yesno_second_packet( - "Would you like to do a TCP Handshake before sending this packet?" - + firewall_commands_help) - else: - do_tcph1 = yesno_second_packet( - "Would you like to do a TCP Handshake before sending this packet?") - print(" · - · - · · - · - · · - · - · · - · - · ") + if copy_packet_1[TCP].flags == "PA": + if os_name == "Linux": + do_tcph1 = yesno_second_packet( + "Would you like to do a TCP Handshake before sending this packet?" + + firewall_commands_help) + else: + do_tcph1 = yesno_second_packet( + "Would you like to do a TCP Handshake before sending this packet?") + print(" · - · - · · - · - · · - · - · · - · - · ") if yesno_second_packet("Would you like to add a second packet"): print( " paste here the second packet hex dump start with the IP layer and then enter (optional) :") + print(" . . . - . . . . - . . . . - . . . . - . ") copy_packet_2 = IP(import_hexcap()) print(" . . . - . . . . - . . . . - . . . . - . ") print(" . . . - . developed view of this packet:") copy_packet_2.show() print(" . . . - . . . . - . . . . - . . . . - . ") - if copy_packet_1.haslayer(TCP): - do_tcph2 = yesno_second_packet( - "Would you like to do a TCP Handshake before sending this packet?") + if copy_packet_2.haslayer(TCP): + if copy_packet_2[TCP].flags == "PA": + do_tcph2 = yesno_second_packet( + "Would you like to do a TCP Handshake before sending this packet?") print( " ********************************************************************** ") return copy_packet_1, copy_packet_2, do_tcph1, do_tcph2 diff --git a/utils/trace.py b/utils/trace.py index d3e1475..d6bf2cb 100755 --- a/utils/trace.py +++ b/utils/trace.py @@ -3,6 +3,7 @@ import contextlib import json +import platform import socket import sys import time @@ -22,6 +23,7 @@ SLEEP_TIME = 1 have_2_packet = False measurement_data = [[], []] +OS_NAME = platform.system() def parse_packet(request_and_answer, current_ttl, elapsed_ms): @@ -83,9 +85,61 @@ def ephemeral_port_reserve(proto: str = "tcp"): return sockname[1] +def tcp_options_correction(tcp_options, new_timestamp, syn_ack_timestamp): + new_options = [] + default_timestamp = ('Timestamp', (new_timestamp, syn_ack_timestamp)) + for attr in tcp_options: + if 'Timestamp' == str(attr[0]): + new_options.append(default_timestamp) + else: + new_options.append(attr) + return new_options + + +def generate_syn_tcp_options(new_timestamp): + if OS_NAME == "Linux": + tcp_options = [('MSS', 1460), ('SAckOK', b''), + ('Timestamp', (new_timestamp, 0)), ('NOP', None), ('WScale', 7)] + return tcp_options + elif OS_NAME == "Windows": + tcp_options = [('MSS', 1460), ('NOP', None), + ('NOP', None), ('SAckOK', b'')] + return tcp_options + elif OS_NAME == "Darwin": + tcp_options = [('MSS', 1460), ('NOP', None), ('WScale', 6), ('NOP', None), + ('NOP', None), ('Timestamp', (new_timestamp, 0)), ('SAckOK', b''), ('EOL', None)] + return tcp_options + else: + return [] + + +def generate_ack_tcp_options(new_timestamp, syn_ack_timestamp): + if OS_NAME == "Linux" or OS_NAME == "Darwin": + tcp_options = [('NOP', None), ('NOP', None), + ('Timestamp', (new_timestamp, syn_ack_timestamp))] + return tcp_options + else: + return [] + + +def get_timestamp(tcp_options): + default_timestamp = 0 + for attr in tcp_options: + if 'Timestamp' == str(attr[0]): + default_timestamp = attr[1][0] + return default_timestamp + + +def get_new_timestamp(): + timestamp_now = time.time() + return timestamp_now, (int(timestamp_now) ^ int(RandInt())) + + def send_packet_with_tcphandshake(this_request, timeout): + timestamp_start, new_timestamp = get_new_timestamp() ip_address = this_request[IP].dst destination_port = this_request[TCP].dport + syn_tcp_options = generate_syn_tcp_options(new_timestamp) ans = [] max_repeat = 0 # here we are trying to do a new TCP handshake every time because @@ -95,7 +149,7 @@ def send_packet_with_tcphandshake(this_request, timeout): source_port = ephemeral_port_reserve("tcp") send_syn = IP( dst=ip_address, id=RandShort())/TCP( - sport=source_port, dport=destination_port, seq=RandInt(), flags="S") + sport=source_port, dport=destination_port, seq=RandInt(), flags="S", options=syn_tcp_options) tcp_handshake_timeout = timeout + max_repeat ans, unans = sr(send_syn, verbose=0, timeout=tcp_handshake_timeout) if len(ans) == 0: @@ -109,10 +163,15 @@ def send_packet_with_tcphandshake(this_request, timeout): return ans, unans else: timeout += 2 # we should wait more for data packets. + syn_ack_timestamp = get_timestamp(ans[0][1][TCP].options) + new_timestamp = new_timestamp + \ + int((time.time() - timestamp_start) * 1000) + ack_tcp_options = generate_ack_tcp_options( + new_timestamp, syn_ack_timestamp) send_ack = IP( dst=ip_address, id=(ans[0][0][IP].id + 1))/TCP( sport=source_port, dport=destination_port, seq=ans[0][1][TCP].ack, - ack=ans[0][1][TCP].seq + 1, flags="A") + ack=ans[0][1][TCP].seq + 1, flags="A", options=ack_tcp_options) send(send_ack, verbose=0) send_data = this_request del(send_data[IP].src) @@ -120,6 +179,8 @@ def send_packet_with_tcphandshake(this_request, timeout): send_data[TCP].sport = source_port send_data[TCP].seq = ans[0][1][TCP].ack send_data[TCP].ack = ans[0][1][TCP].seq + 1 + send_data[TCP].options = tcp_options_correction( + send_data[TCP].options, new_timestamp, syn_ack_timestamp) del(send_data[TCP].chksum) del(send_data[IP].len) del(send_data[IP].chksum) @@ -142,6 +203,9 @@ def send_single_packet(this_request, timeout): this_request[TCP].sport = ephemeral_port_reserve("tcp") if this_request[TCP].flags == "S": this_request[TCP].seq = RandInt() + timestamp_start, new_timestamp = get_new_timestamp() + this_request[TCP].options = tcp_options_correction( + this_request[TCP].options, new_timestamp, int(timestamp_start)) del(this_request[TCP].chksum) elif this_request.haslayer(UDP): this_request[UDP].sport = ephemeral_port_reserve("udp")