intranetman has asked for the wisdom of the Perl Monks concerning the following question:

I want to capture packets using tcpdump over a certain period of time. However, if there are not packets captured in that time period I would like the program to exit. tcpdump does not allow you to specify a time period just packets based on time period. So if I receive 0 packets over a specific time period it should exit. The source code (a mod of an old sniffer program) is as follows:
open (fileOUT, ">> /results.out") or dienice ("Can't open file for wr +iting"); close(fileOUT); open (STDIN,"/usr/sbin/tcpdump -lnx -s 1024 dst port 80 |"); while (<>) { if (/^\S/) { last unless $LIMIT--; while ($packet=~/(GET|POST|WWW-Authenticate|Authorization).+/g) + { open (fileOUT, ">> /results.out") or dienice ("Can't open fi +le for writing"); flock(fileOUT, 2); seek(fileOUT, 0, 2); print fileOUT "$client -> $host\t$&\n"; close(fileOUT); } undef $client; undef $host; undef $packet; ($client,$host) = /(\d+\.\d+\.\d+\.\d+).+ > (\d+\.\d+\.\d+\.\d+) +/ if /P \d+:\d+\((\d+)\)/ && $1 > 0; } next unless $client && $host; s/\s+//; s/([0-9a-f]{2})\s?/chr(hex($1))/eg; tr/\x1F-\x7E\r\n//cd; $packet .= $_; }
I've tried using gmtime but it still continues reading even when it reaches a set time. Should I make the tcpdump a thread and then kill that thread after a specific time? Any comments/suggestions would be great. Thanks.

2004-11-22 Edited by Arunbear: Changed title from 'tcpdump', as per Monastery guidelines

Replies are listed 'Best First'.
•Re: tcpdump: setting a conditional timeout
by merlyn (Sage) on Nov 19, 2004 at 18:40 UTC

      Be forewarned that POCO::Pcap is going to give you back the raw unparsed contents of the captured packets, not neatly parsed data like tcpdump does. You'll need to pull captured traffic apart using NetPacket::TCP and friends.

Re: tcpdump: setting a conditional timeout
by kappa (Chaplain) on Nov 19, 2004 at 18:49 UTC

    Your task is perfect for IPC::Run, try it :)

    You can redirect output to a scalar, update (pump) it when you need and timeouts are supported automatically.

Re: tcpdump: setting a conditional timeout
by Anonymous Monk on Nov 20, 2004 at 06:30 UTC

    perldoc -f alarm

    #!/usr/bin/perl $lines=0; eval { local $SIG{ALRM} = sub { die "timeout\n" }; alarm( 5 ); while (<>) { $lines++; if ( $lines > 2 ) { alarm( 0 ); last; } } }; if ( $@ =~ /timeout/ ) { print "timed out with $lines lines\n"; } elsif ( $@ ) { print "died from some other random reason: $@"; } else { print "didn't timeout with $lines lines\n"; }
    $ ( sleep 10 ) | perl 409100.pl timed out with 0 lines $ ( echo one; sleep 10 ) | perl 409100.pl timed out with 1 lines $ ( echo one; echo two; sleep 10 ) | perl 409100.pl timed out with 2 lines $ ( echo one; echo two; echo three; sleep 10 ) | perl 409100.pl didn't timeout with 3 lines