Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
Greetings all;

I have a need to scratch and haven't been able to work out a good way of doing it all together in an elegant, let alone functional, way.
I need to capture and count packets coming from multiple sources, using multiple filters, in real time. Right now I just have three separate perl scripts doing the task, but I'd like to fold it into a single tool. I currently use an open() on the tcpdump tool (under Linux).

Simple psuedo-code to give you an idea what I'm up to:

$SIG{ALRM} = \&every_sec(); alarm(1); open(PROCESS, "tcpdump -ln 'filter'"|); while(<PROCESS>) { next if (!&ParseIPandCheckSomething($_)); $Counter++; } sub every_sec { print "This past second: $Counter\n"; $Counter = 0; alarm(1); }
Here are the approaches I've looked at:
Incorporating Net::Pcap and doing it the "proper" way without reading the external 'tcpdump' output... except Net::Pcap can't handle multiple instances (the filters and like are stored in a single shared variable, according to its documentation). I also require the use of a SIGALRM to keep track of per-second counts, and Net::Pcap::loop must disable this, because the alarm callback certainly isn't being called each second like it's supposed to.

Opening several 'tcpdump' filehandles and looping over reading each one. When I do this the 'real time' aspect of it goes to heck. I was trying to do a bunch of non-blocking read()s and pull in a block of bytes, jump to the next file handle, and so on, and then process completed inputted packets... but it obviously isn't either fast enough, or designed properly, because "real time" it is not.

foreach $filter (qw(filter1 filter2 filter3)) { my $fh = FileHandle->new(); $fh->open("tcpdump -ln $filter|"); $fh->autoflush(1); push(@FHStack, $fh); } while(1) { # Read anything (up to 4096 bytes) from tcpdump foreach my $fh (@FHStack) { my $bytes = read($FH, my $buffer, 4096); $PackStack{$FH} .= $buffer; } # Process what we've gotten, looking for a complete packet foreach my $fh (@FHStack) { if ($PackStack{$FH} =~ /\n/) { # LF means completed packet received from tcpdump $PackStack{$FH} = &ProcessPacketAndRemove($PackStack{$FH +}); } } }
Boy, folks, I know there's a better way to do this, I'd sure love to hear your input.


-- Alexander Widdlemouse undid his bellybutton and his bum dropped off --

In reply to Real time reading of multiple pcap 'instances' at once by JPaul

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2023-09-24 02:49 GMT
Find Nodes?
    Voting Booth?

    No recent polls found