Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm tasked with monitoring and debugging a SOAP web service, on network level. I can use tcpdump to capture the whole traffic coming from customers on port 80, but I can't limit the capture for every request to just the first received application-layer packet (the most significant packet in this case, which carries the HTTP request header and beginning of SOAP XML document). I want to know which tcpdump switch (or combination of other linux commands) to use to get this first packet for each TCP connection, and drop the rest of packets received for the same connection.

If possible, having the first response packet (and probably the only, because in this application, response XML documents are small) sent from server to customer, would be nice too.

Currently I run tcpdump -i any -A 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' example from tcpdump man page, so I don't get the TCP handshake packets.

And the problem with -c switch is tcpdump exits after capturing the packet, while I need it to stay running and continue showing the same information for new connections. Ideally I need something similar to tailing apache access log files, along with first meaningful chunks of request and response.

share|improve this question

3 Answers 3

up vote 3 down vote accepted

So your request is actually narrower than the title suggests - you're specifically looking for HTTP requests.

I use ngrep for this, which combines tcpdump and grep type functionality. eg:

sudo ngrep -d eth0 '^(GET|POST) ' port 80

That will give you text output. If you want, you can use the -w option to write the matched packets to a file in tcpdump format.

Use -d as above to specify the interface, since -i is used as in grep for case insensitivity.

The above will also include outgoing requests and so forth that you might not want. append tcpdump type options as required.

If you're debugging requests to a particular URL, you might want to use that to make the regular expression more specific. eg

sudo ngrep '^(GET|POST) /my/soap/interface .*Host: myhost.example.com' 'dst port 80 and dst host myhost.example.com'

In the unusual case that the request is split over multiple packets with the Host header in the second packet, the above may fail to catch some requests. Mostly that doesn't matter, but you could always capture more than you need with tcpdump, break it into files with chaosreader, and then start grepping the files.

share|improve this answer
    
thanks. ngrep did the job for me using it's grep filter, not pcap filter. I'm not a libpcap expert but I still wonder if it has a filter which allows this sort of thing by something like putting arithmetic conditions on TCP sequence numbers. I will accept this answer in few days, if no one suggests a solution using a pcap filter instead of grep. –  aalizadeh Apr 16 at 7:16
    
Looking at man pcap-filter I don't see anything for discriminating on sequence numbers. Wireshark has a more extensive (but harder to remember) filter language, and I know I've seen a command line variant on that. Somehow, there's a way. Is it really worth your while though? Are you really processing enough traffic for this bit of efficiency to be worth your while to chase after, even supposing you did know where to look? –  mc0e Apr 20 at 13:37

You probably don't just want the first packet - the first packets of a TCP session are the 3 way handshake which sets the session up in the first place. However, tcpdump does have the -c flag, which allows you to capture a defined number of packets.

share|improve this answer
    
I see you've updated your question. Ok. You're trying to do something quite complicated then, and I think it's beyond the scope of what tcpdump can accomplish - it's a filter based packet capture, with rule applied per packet. You're looking for a way to conditionally capture, based on preceding packets, which is considerably more difficult. Capture the whole lot and process is probably the next best option - wireshark is pretty good for general use, but you can probably write a custom parser in perl or a similar scripting language. –  Sobrique Apr 15 at 10:32

Dump the capture to a file (-w option).

You can analize it with wireshark afterwards, which has a powerful filtering engine. You'll have access to all the information you need: headers, SOAP payload, etc...

share|improve this answer
    
So, there's no way to have it live on a server with no X? –  aalizadeh Apr 15 at 10:04
    
wireshark as a companion program, tshark, for CLI users. As CLI addict as I am, this is usually a task I'd rather do in an X environment. –  dawud Apr 15 at 10:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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