Human readable format for http headers with tcpdump
Solution 1:
Here's a one-liner I came up with for displaying request and response HTTP headers using tcpdump
(which should work for your case too):
sudo tcpdump -A -s 10240 'tcp port 4080 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | egrep --line-buffered "^........(GET |HTTP\/|POST |HEAD )|^[A-Za-z0-9-]+: " | sed -r 's/^........(GET |HTTP\/|POST |HEAD )/\n\1/g'
It limits cuts the packet off at 10Kb and only knows GET, POST and HEAD commands, but that should be enough in the majority of cases.
EDIT: modified it to get rid of the buffers at every step to make it more responsive. Needs Perl and stdbuf now though, so use the original version if you don't have those: EDIT: Changed script port targets from 80 to 4080, to actually listen for traffic that went through apache already, instead of direct outside traffic arriving to port 80:
sudo stdbuf -oL -eL /usr/sbin/tcpdump -A -s 10240 "tcp port 4080 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)" | egrep -a --line-buffered ".+(GET |HTTP\/|POST )|^[A-Za-z0-9-]+: " | perl -nle 'BEGIN{$|=1} { s/.*?(GET |HTTP\/[0-9.]* |POST )/\n$1/g; print }'
Some explanations:
- sudo stdbuf -oL -eL makes tcpdump run line-buffered
- the tcpdump magic filter is explained in detail here: https://stackoverflow.com/questions/11757477/understanding-tcpdump-filter-bit-masking
- grep is looking for any lines with GET, HTTP/ or POST; or any lines that look like a header (letters and numbers followed by colon)
- BEGIN{$|=1} causes perl to run line-buffered
- s/.*?(GET |HTTP/[0-9.]* |POST )/\n$1/g adds a newline before the beginning of every new request or response
Solution 2:
You can get something close to what you want by using -A
, e.g.
E....c@.@...
.....Ng.d.P..Ch.).....s.......
.A...u.BHEAD / HTTP/1.1
User-Agent: curl/7.29.0
Host: www.google.com
Accept: */*
Remember to use -s 0
to make sure you get the whole packet.
Alternatively you could use wireshark
to view the headers interactively.