Search code examples
pythonhttptcpscapy

How to get the length of http response python scapy


So I am writing a python scapy script that will first just complete a 3 way handshake, send an http get, and then close the connection.

This is the code so far:

!/usr/bin/env python

from scapy.all import *

getStr = 'GET / HTTP/1.0\r\nHost: www.google.com\r\n\r\n'

#Send SYN
syn = IP(src="31.31.31.10",dst='31.31.31.17') /         TCP(dport=80,sport=RandShort(),flags='S')
syn_ack = sr1(syn)`

#Send GET w/ ACK of server's SA
get1 = (IP(src="31.31.31.10",dst="31.31.31.17")/TCP(dport=80, sport=syn_ack[TCP].dport,seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='PA')/getStr)
send (get1)

pkts = sniff(count=1,filter="host 31.31.31.17 and port 80",prn=lambda x:x.summary())
print pkts.sprintf("%TCP.len%") #Will this work? I am getting an issue here

AttributeError: 'list' object has no attribute 'sprintf'

Basically I just want to extract the len of data from the PA, which is the http response, so I can correctly generate the following sequence number to ACK the http response.

I have also tried: ans,uns=sr(get1) But I could not find a good way to get the length from this either.

I have also tried: print len(pkts.getlayer(TCP)) AttributeError: 'list' object has no attribute 'getlayer'

Any help would be appreciated


Solution

  • As you suspected since you have used a plural, pkts is a PacketList and not a Packet.

    You can use:

    for p in pkts:
        if TCP in p:
            print len(p[TCP].payload)
    

    You can add and not isinstance(p[TCP].payload, NoPayload) if you want to skip packets with no data.

    You can also modify the BPF filter so that it reads: "host 31.31.31.17 and tcp port 80" (add tcp).