Skip to content

Commit

Permalink
fix tcp options for trace data packet (#35)
Browse files Browse the repository at this point in the history
* fix tcp options for trace data packet

* only ask for tcp handshake if flag is psh,ack

* fix tcp options for trace single packet

* timestamp correction: convert to milliseconds

* fix packet trace mistake
  • Loading branch information
xhdix authored Feb 18, 2022
1 parent 9a2a5d1 commit 11545c0
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 13 deletions.
26 changes: 15 additions & 11 deletions utils/packet_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,36 @@ 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:")
copy_packet_1.show()
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
68 changes: 66 additions & 2 deletions utils/trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import contextlib
import json
import platform
import socket
import sys
import time
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -109,17 +163,24 @@ 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)
send_data[IP].id = ans[0][0][IP].id + 2
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)
Expand All @@ -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")
Expand Down

0 comments on commit 11545c0

Please sign in to comment.