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

Hi monks, I have a weird problem. I'm using Tcpdump to some analysis of my network (some kind of DHCP messages coming in) to change my network configuration.
Everything works ok on a first startup, but sometimes everything just freezes.
My code is:
print("****************"); open(FH_END1, "$TCPDUMP -v -lnnet -i eth1 -s 1000|") || die; print("****************"); my $select = IO::Select->new(); $select->add(*FH_END1); while(1){ print("1"); while (my @ready = $select->can_read(5)){ print("2"); foreach my $fh (@ready){ my $line =<FH_END1> ; #check if line is valid and take some actions #....
Now, once every 5 seconds I receive a message containing some relevant information whether or not to change my configuration.
When I receive new information to change the configuration my perl script just blocks. It still runs but it does nothing.

When I restart the script then, it prints the first ******* and opens tcpdump but then stops. Tcpdump runs perfectly because it captures the packets, but the perl script itself just frezes on that line (it still runs but it doesn't print the second *****).

Replies are listed 'Best First'.
Re: Script with tcpdump freezes
by sgifford (Prior) on Apr 05, 2006 at 15:01 UTC
    First, you can't mix select and buffered file I/O (like <FH_END1>). You'll have to use sysread to make this work reliably.

    Second, if you use tcpdump, use the -l flag, which will cause it to write its output as soon as it's available; otherwise it will wait until it has a full output buffer before writing anything.

    Finally, consider using Net::Pcap instead; it's a native Perl interface to packet sniffing, and you'll probably find it's easier and more efficient than having tcpdump do the sniffing and parsing its output.

Re: Script with tcpdump freezes
by ikegami (Patriarch) on Apr 05, 2006 at 15:05 UTC
    There's nothing there to flush your second print. I bet it reaches the second print, but you just don't see it. Change your prints to print("****************\n"); (note the newline) assuming you're not redirecting STDOUT, or add $| = 1; at the top. That will fix your problem of not seeing the stars, and others have suggested solutions to fix your real problem.
Re: Script with tcpdump freezes
by bowei_99 (Friar) on Apr 05, 2006 at 15:41 UTC
    I did a search on cpan for tcpdump, and found Net::Packet::Dump. Using that might save you the trouble of writing your own code.

    -- Burvil