tcpdump icon indicating copy to clipboard operation
tcpdump copied to clipboard

Reading from stdin while dumping to file causes crash

Open guyharris opened this issue 11 years ago • 10 comments

Converted from SourceForge issue 3602279, submitted by toreanderson

When attempting to reading from stdin and dumping the result to a capture file, the process crashes almost instantly. An easy way to reproduce this, is:

computer$ nc -l 12345 | tcpdump -r- -v -wfoo.pcap reading from file -, link-type EN10MB (Ethernet) tcpdump: pcap_loop: error reading dump file: Interrupted system call write: Broken pipe

If I omit the "-wroo.pcap" option, it works just fine, decoded traffic is printed to stdout just as expected and no crashes are experienced.

The version used is the one included in Fedora 18: tcpdump-4.3.0-2.fc18.x86_64.

The PCAP stream coming in on 12345/tcp to the nc process is a tcpdump running on another machine like so: "tcpdump -i eth1.3900 -s0 -w- -U ip6 | nc computer 12345".

guyharris avatar Apr 16 '13 00:04 guyharris

This reproduces on the current master branch on a Linux host.

infrastation avatar Jul 25 '13 12:07 infrastation

To quote a comment in tcpdump.c:

            /*
             * When capturing to a file, "-v" means tcpdump should,
             * every 10 secodns, "v"erbosely report the number of
             * packets captured.
             */

In most cases, -v isn't useful when reading from a file and writing to a file, rather than when capturing from a device and writing to a file; however, there's probably no harm in supporting it - if you don't want that output, don't specify -v.

In this case, it might be more useful, as you are, in effect, capturing from the other machine.

Therefore, we need to do something with EINTR when reading packets. Obviously, if it was interrupted by SIGINT (^C), we should quit, but if it was interrupted by SIGALRM (the timer for -v when writing to a file), we should just keep reading.

guyharris avatar Feb 01 '14 23:02 guyharris

This will require libpcap changes - merely setting the SA_RESTART flag for SIGALRM means that, instead of getting "Interrupted system call", we get "truncated dump file; tried to read 300 captured bytes, only got 170". At least when reading from a pipe, we need to keep reading bytes until we get an EOF.

guyharris avatar Feb 02 '14 00:02 guyharris

See also the-tcpdump-group/libpcap#1258.

guyharris avatar May 03 '14 21:05 guyharris

Naively, since we're only setting the callback when using -w, can't this be implemented in dump_packet() instead? If enough time has passed, then call print_packets_captured(), and don't set the itimer at all?

fenner avatar Aug 24 '20 17:08 fenner

If there is a difficult to fix reason for once per second counter update not to work when reading from a file, let's enable the counter for live captures only and document the behaviour. This would resolve the corner case crash; if anybody wants to make it perfect later, they can propose a patch.

infrastation avatar Aug 24 '20 18:08 infrastation

I naively suggested:

Naively, ... can't this be implemented in dump_packet() instead?

Obviously there's a significant difference in that, if you get 1000 packets in the first 0.9 seconds, and then no more, the counter will never update. (The use case that I'm interested in is sflowtool, which converts sflow-format captured packets to pcap, so libpcap will block regularly.)

infrastation said:

let's enable the counter for live captures only and document the behaviour

This is obviously the best short-term approach.

fenner avatar Aug 24 '20 19:08 fenner

Do you think a separate thread around print_packets_captured() would be easier to implement? Would it still be portable enough?

infrastation avatar Aug 24 '20 19:08 infrastation

Do you think a separate thread around print_packets_captured() would be easier to implement? Would it still be portable enough?

I've always tried to avoid threads in portable code, but I don't have an educated opinion here, more just a mystical one :-)

fenner avatar Aug 25 '20 14:08 fenner

The master branch of tcpdump now has a documented safeguard with comments as discussed above. @guyharris, is signal handling in libpcap you described earlier still an important enough problem to state/document it elsewhere and maybe to work on a solution?

infrastation avatar Aug 29 '20 02:08 infrastation