I'm trying to save only POST packets using tcpdump filter expressions. I started with 'tcp port 80' and I found on the web a specific expression to achieve that.

tcpdump -i wlan0 -s 0 -A -vv 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'

Where 0x504f5354 means POST.

That works, but when only saving packets instead of printing them on the standard output and opening it on Wireshark I get just a few random packets. Here's my command,

tcpdump -i wlan0 -s 0 -A -w test.pcap 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354'

1 Answer 1


I have not clear what you mean by, "when only saving packets instead of printing them on the standard output and opening it on Wireshark".

I believe, however, that you're trying to save "POST data" (which lives at the HTTP level) while your expression specifies only the first POST packet (living at the TCP level).

If you're intercepting, say, a 5Kb POST packet, chances are that it has been fragmented into three or more shorter packets (with say 1476, 1476, 1476 and 692 bytes payload - numbers almost at random, I haven't checked, but you see my meaning). Of these, only the first does actually contain the HTTP POST command, so that it is actually intercepted.

And there's more. The HTTP1.1 protocol allows for keeping the connection alive and "pipelining" commands in a single TCP connection so as to save the handshake and socket maintenance hassle. So you can have three POST commands in a single conversation: POST data1... POST data2... POST data3...

and of course the chances of any but the very first POST to come exactly at the beginning of a packet and be snatched by Wireshark are very small.

In order to properly capture POST data you need a HTTP proxy with conversation capture facility (or Firefox's Firebug, which is better for some applications), and have the whole HTTP stream parsed and the POST requests captured. Otherwise you would need a PCAP regexp complex enough to understand HTTP, which, even if feasible (which I'm not too sure), would be exceedingly impractical.

  • Oh, thanks for your detailed answer. I also understand the fact that the POST packet might be fragmented in almost all cases, so using that filter expression I pasted above I would only intercept the first one containing the POST command. Although, not saving it, and using -vv for verbose I can see the complete packet in terminal. I finally should be using 'tcp port 80' and then filter the resulting capture. I was trying to avoid that way in order to save hard disk space.
    – autorun
    Aug 13, 2014 at 19:39
  • Are you sure you see the whole packet? The display code is the same for captured and intercepted packets. If you see the whole packet one way, you should see it the other way. Unless you're doing something else differently in the two cases?
    – LSerni
    Aug 14, 2014 at 14:35
  • It's strange, but running the first command above I actually see the POST packet with its clear data, and running the second one (saving the capture and opening it on Wireshark) I can only see some kind of incomplete packet.
    – autorun
    Aug 15, 2014 at 5:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .