Search code examples
pythonnetwork-programmingscapy

Http request with scapy


I need to implement http request with scapy for a school assignment. Everything works until I need to acknowledge the http segments and close the connection. It is mandatory to use scapy and manually open and close the tcp connection. In wireshark I can see that the 2 errors are TCP retransmission and TCP out-of-order segment. Anyone who can solve this? Thanks in advance!

from scapy.all import *

sport = random.randint(1024,65535)
dest = "128.119.245.12" 
getStr = 'GET / HTTP/1.1\r\nHost:' + dest + '\r\nAccept-Encoding: gzip, deflate\r\n\r\n'


#SYN
ip=IP(src='192.168.1.6',dst='128.119.245.12')
SYN=TCP(sport=sport, dport=80, flags='S', seq=0)
SYNACK=sr1(ip/SYN)
print(SYNACK.summary())


# SYN-ACK
ACK=TCP(sport=sport, dport=80, flags='A', seq=1, ack=SYNACK.seq + 1)
send(ip/ACK)

response = sr1(IP(dst=dest) / TCP(dport=80, sport=sport, seq=1, ack=SYNACK.seq + 1, flags='P''A') / getStr, timeout = 5)
print(response.dataofs)

ACK=TCP(sport=sport, dport=80, flags='A', seq=response.seq, ack=response.seq + 1)
send(ip/ACK)

FIN=ip/TCP(sport=sport, dport=80, flags="FA", seq=SYNACK.ack, ack=SYNACK.seq + 1)
FINACK=sr1(FIN)
LASTACK=ip/TCP(sport=sport, dport=80, flags="A", seq=FINACK.ack, ack=FINACK.seq + 1)
send(LASTACK)

Wireshark


Solution

  • I see that the ack number you send from the clinet with packet 25 is wrong. You are simply incrementing the first ack number, when in reality you should send TCP_len + 1. To acknowledge the receipt of TCP_len bytes.

    ACK=TCP(sport=sport, dport=80, flags='A', seq=response.seq, ack=response.seq + 1)
    

    If you modify this line it should be fine. The other 2 "errors" that you talk about are expected TCP behaviour. Since you only acknowledged the receipt of 1 byte with the ACK packet, the server would attempt to re-transmit the rest of the payload. Then you will get failed retransmission attempts because the client already closed the connection by setting the FIN ACK. And the out of order warning also comes from sending the wrong ACK number.