cmv has asked for the wisdom of the Perl Monks concerning the following question:
My goal is to fork a child process running tshark, and feed it messages (in pcap format) for it to decode, then grab the decoded output to do stuff with.
The attached example script works on unix (you need to have wireshark installed). I setup NBread() to handle the edge cases when the input message is bad, and I get stuck in the do-until loop, looking for a blank like that isn't coming. NOTE: The assumption that tshark always prints out a blank line after each decode seems reliable, except on these edge cases.
On unix, I'll get stuck for up to 2 seconds, then pop out and continue on.
On windows, I get stuck forever.
What are good options to make this work on both unix and windows? Should the solution be a non-blocking read for windows, or should I re-design in some other (better) way for both platforms?
Thanks
-Craig
Update: Also, when you hit ctrl-c in windows to get out, the tshark process ends up hanging around forever (yuk)!
use strict; use English; use IPC::Open2; use Data::Dumper; $|++; my $TSHARKOPTS = "-l -V -i -"; my $TSHARK = $ENV{TSHARK} || '/opt/exp/sbin/tshark' || 'tshark'; # Need to use elsif's here, since perl (-e) uses unix-type path names # and TSHARK needs dos-type path names... if($OSNAME eq 'MSWin32'){ if(-e $ENV{TSHARK}) { $TSHARK = $ENV{TSHARK}; }elsif(-e 'c:/Program Files/wireshark/tshark.exe' ) { $TSHARK = "c:\\\"Program Files\"\\wireshark\\tshark.exe"; }else{ die "Cannot find TSHARK"; } } # Startup child... my $CHILD = open2(\*READ, \*WRITE, "$TSHARK $TSHARKOPTS") || die "Can't open2 child process: $!"; print STDERR "tshark started CHILD=$CHILD...\n"; my @header = ( 0xa1b2, 0xc3d4, 0x0002, 0x0004, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0001); my @msg1 = ( 0x4c, 0x52, 0x56, 0x67, 0x00, 0x0c, 0xc5, 0x88, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x56, 0x00, 0x21, 0x05, 0x6e, 0x7d, 0xcb, 0x00, 0x16, 0x4d, 0xc4, 0xdf, 0x64, 0x08, 0x00, 0x45, 0x02, 0x00, 0x48, 0x00, 0x00, 0x40, 0x00, 0x3f, 0x84, 0x1f, 0xdb, 0x0a, 0x98, 0x02, 0x21, 0x0a, 0x98, 0x04, 0x05, 0x0b, 0xb9, 0x04, 0x00, 0x78, 0xa1, 0x28, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x26, 0x4d, 0x2b, 0x6d, 0xf8, 0x00, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x12, 0x00, 0x17, 0x00, 0x12, 0x00, 0x00, 0x02, 0x00, 0x63, 0x00, 0x05, 0x04, 0x46, 0xb3, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x02, 0x80, 0x00, 0x00, ); my $bhead = pack('n*', @header); my $bmsg1 = pack('c*', @msg1); # Output PCAP file header to tshark... print WRITE $bhead; # Count as we go through the message loop... my $c=0; while (1) { if(! $CHILD) { last }; $c++; # Force a blocking read after 2 rounds... if($c<3) { print WRITE $bmsg1; } my $got = NBread(\*READ); print STDERR "$c: ", scalar(split(/^/, $got)), " lines\n"; sleep 1; } sub NBread { my $fd = shift || die "Missing read file descriptor"; # Read from decoder... my $line; my $otext; eval { local $SIG{ALRM} = sub { die 'TIMEOUT' }; do { alarm 2; if( ! ($line = <$fd>) ) { # Child died for some reason... alarm 0; warn "Decoder pid=$CHILD, not available!\n"; undef($CHILD); last; } $otext .= $line; alarm 0; } until ($line =~ /^\s*$/); }; if ($@) { print STDERR "$@" }; return($otext); }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: TSHARK Child: Windows open2 non-blocking read, or redesign?
by Corion (Patriarch) on Oct 12, 2010 at 07:28 UTC | |
by afoken (Chancellor) on Oct 12, 2010 at 09:36 UTC | |
by Corion (Patriarch) on Oct 12, 2010 at 17:06 UTC | |
by afoken (Chancellor) on Oct 13, 2010 at 08:59 UTC | |
by Corion (Patriarch) on Oct 13, 2010 at 09:03 UTC | |
|
Re: TSHARK Child: Windows open2 non-blocking read, or redesign?
by BrowserUk (Patriarch) on Oct 12, 2010 at 10:49 UTC |