I am trying to understand how ECN flag affects TCP congestion window of sender (snd_cwnd parameter in linux).

To do so, I used scapy to generate the desired packet on HostA directed to HostB as sr(IP(src='a.a.a.a',dst='b.b.b.b')/TCP(flags=0x050)).

This did trigger hostA to send a tcp ecn enabled packet to hostB, but since scapy works in user space and not particularly with Linux Kernel TCP I could not extract the the congestion window parameters . I then used StraemSocket() module of scapy to tie scapy connection to linux TCP socket. Hosta = server(a.a.a.a), HostB =client(b.b.b.b)

code as below: server:

from scapy.all import *
import socket

serversocket = socket.socket()
sc,sockname = serversocket.accept()


from scpay.all import *
import socket
clientsocket = socket.socket()
clientstream = StreamSocket(clientsocket)

as can be seen from below snapshot, 3 way handshake with ecn and cwd flags is successful( I have enabled ecn on the hosts and all intermediate routers). but wireshark just doesn’t capture the ecn flagged packet sent by server.I am not sure if the server sent the packet at all and I am really at the end of my thoughts here.

missing ecn enabled tcp packet

  • Was there network congestion which the router detected and flagged in the packet header? Is that what you are looking for?
    – Ron Maupin
    Jan 28 '16 at 7:22
  • nope. I am trying to simulate the senders response by triggering a TCP with ecn flag enabled. Understandably , the intermediate routers mark the IP headers while transmitting the packets. But what I am trying to achieve is to observe how the sender reacts after receiving an congestion feedback. Thank You.
    – durga
    Jan 28 '16 at 7:23
  • Are you sending a TCP control packet marked with congestion?
    – Ron Maupin
    Jan 28 '16 at 7:51
  • Yes. I am doing that using scapy.
    – durga
    Jan 28 '16 at 8:13
  • Typically, a host doesn't respond to control packets marked with congestion, only to data packets marked with congestion. You want the two ECN bits set to ones to indicate that congestion was encountered on a data packet from the sender to the receiver.
    – Ron Maupin
    Jan 28 '16 at 8:16

When using a StreamSocket, the packets sent are sent over the TCP connection. In Scapy notation, when you type serverstream.sr(IP(src='a.a.a.a',dst='b.b.b.b')/TCP(flags=0x050)) (BTW, you can replace flags=0x050 by flags="AE"), it will result in sending a packet like:

IP(src="a.a.a.a", dst="b.b.b.b") / TCP(flags="PA") / \
    IP(src="a.a.a.a", dst="b.b.b.b")/TCP(flags="AE")

The first IP()/TCP() layers are not under Scapy's control, but under the server's network stack control (e.g., you cannot change the flags there with Scapy).

The second IP()/TCP() layers, converted as an str() object, are the packet crafted by Scapy (so you have a total control over it). On the network, and for Wireshark, the packet is only raw data transported over TCP. You can guess that the fourth and sixth packets shown on your screenshot are IP()/TCP()/IP()/TCP() thanks to the length of the data (40 bytes, len(IP()/TCP()) returns 40).

You can save your capture (as PCAP, not PCAPNG) from Wireshark, and then load it in Scapy to decode it:

>>> x = rdpcap('your_capture.cap')
>>> PacketList(IP(str(p[TCP].payload)) for p in x
...            if TCP in p and p[IP].len >= 80).show()

If you want to control the TCP options with Scapy, then you have to create the packets and send them with sr() (but then you will have to open the connection by yourself).

  • Linux TCP stack sees the TCP packet created by scapy as a rogue packet and sends a RST packet. I used Ip tables to drop RST packets, I know that socket.getsocketopt() to find the value of congestion window but I dont know how to get Scapy connection's information . Hence, I used StreamSocket(). So, does it mean that my 'AE' TCP packet is just data payload of under lying TCP ('PA')? is that the reason why wireshark shows PA packets and not see 'EA' packets ??? In that case, I think I will start building packets using raw_sockets. Thank You.
    – durga
    Jan 28 '16 at 11:02
  • Also, few other questions: what do you mean by 'open the connection by yourself?" . Do you mean I use scapy to do the TCP 3way handshake ? if yes- Is there a way in which I can get the socket parameters of this connection? Secondly, is the encapsulation of IP()/TCP()/IP()/TCP() limited to the usage of StreamSocket() ? I ask this because when I trigger a standalone IP()/TCP(flags='AE') packet from scapy, I see wireshark caputring the packet as it is. cntd...
    – durga
    Jan 29 '16 at 0:58
  • ...cntd Third: Incase the scapy packet is indeed encapsulated , even then wireshark should show the packets as encapsulated. Sorry about the barge of questions. I am trying to wrap my head around how Scapy's StreamSocket() actually works.
    – durga
    Jan 29 '16 at 0:58
  • As I mention, "On the network, and for Wireshark, the packet is only raw data transported over TCP". Wireshark has no way to guess that the payload of the first IP()/TCP() payload can be decoded as an IP packet. I'm updating the answer to add more about that.
    – Pierre
    Jan 29 '16 at 11:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.