use strict; use warnings; use IO::Select; my $an; my $timeout = 20; my $read_set = new IO::Select(); eval { local $SIG{ALRM} = sub { die "Timeout\n"; }; alarm $timeout; open my $fh, "tcpdump -nn -l -e dst 224.111.111.112 and not igmp 2>/dev/null |"; $read_set->add($fh); while (1) { my ($rh_set) = IO::Select->select($read_set, undef, undef, 1); if (defined $rh_set) { if ($_ = <$fh>) {; if (s/^\S* \S* M \S* \S* 0800 \S*: (\S*\.\S*\.\S*\.\S*)\.\S* > \S*\.\S*:.*$/$1/s) { $an = $1; alarm 0; last; } } else { logwarn "EOF while reading from tcpdump. sleeping 2 seconds and restarting tcpdump"; $read_set->remove($fh); close $fh; sleep 2; open $fh, "tcpdump -nn -l -e dst 224.111.111.112 and not igmp 2>/dev/null |"; $read_set->add($fh); } } } close $fh; }; if ($@ && ($@ ne "Timeout\n")) { die $@; } if (defined $an) { print "$an\n"; exit 0; } else { print "NONE\n"; exit 1; }