Re: Continuous packet capture

2009-03-27 Thread Jonathan S. Polacheck
Brad,

Great stuff.  Thanks.  I'm going on the assumption that $inst-[1] (line
94) is the raw packet, headers and all.  I plan to test by pointing pcap at
a capture file and comparing output to input.  My next plan is to add a sql
insert of $hexpacket at line 108.  My goal is to keep up with an incoming
data stream of 20-30 k-bytes a second.  After the hex data is safely stored
in the database I can go back and insert whatever fields (layer 3-4, packet
length, etc) I want.  Then do a gui to extract traces and do other analysis
from the stored data.   Here is my code;

  1  use strict;
  2  use warnings;
  3
  4  use Data::Dumper;
  5  use Carp;
  6
  7  #
  8  # POE Environment
  9  # use POE qw(
 10  #  Component::Pcap
 11  #  Component::Daemon
 12  # );
 13
 14  use POE qw(
 15   Component::Pcap
 16  );
 17
 18  #
 19  # PCAP Options
 20  my %pcap_opts = (
 21   dev = 'eth0',
 22   snaplen   = 1514,
 23   promisc   = 1,
 24   timeout   = 100,
 25  );
 26
 27  ##
 28  # POE Environment Setup
 29  ##
 30  #POE::Component::Daemon-spawn( detach = 1, babysit = 600, max_children 
= 5 );
 31
 32  POE::Session-create(
 33   inline_states = {
 34 _start  = \start_processor,
 35 _stop = \stop_processor,
 36 handle_packet   = \handle_packet,
 37   },
 38  );
 39
 40  $_[HEAP]-{i} = 0;
 41
 42  ##
 43  # Run the POE Sessions
 44  ##
 45  POE::Kernel-run;
 46
 47  ##
 48  exit 0;
 49  ##
 50
 51  ##
 52  # Start the Processor
 53  sub start_processor {
 54   my ($kernel, $heap) = @_[KERNEL, HEAP];
 55
 56   $kernel-alias_set('processor');
 57
 58   #
 59   # Start Packet Capturing
 60   POE::Component::Pcap-spawn(
 61 Alias   = 'pcap',
 62 Device= $pcap_opts{dev},
 63 Dispatch= 'handle_packet',
 64 Session   = 'processor',
 65   );
 66   $kernel-post( pcap = open_live = @pcap_opts{qw(dev snaplen promisc 
timeout)} );
 67
 68   $kernel-post( pcap = 'run' );
 69  }
 70  ##
 71
 72  ##
 73  # stop the processor
 74  sub stop_processor {
 75   my ($kernel,$heap) = @_[KERNEL,HEAP];
 76
 77   #
 78   # Stop pcap
 79   $kernel-post( 'pcap' = 'shutdown' );
 80  }
 81  ##
 82
 83  ##
 84  sub handle_packet {
 85   my $offset = 0;
 86   my $linechars = 0;
 87   my $hexpacket;
 88
 89   $_[HEAP]-{i}++;
 90   print sub handle_packet called $_[HEAP]-{i} times\n;
 91   my ($kernel,$heap,$packets) = @_[KERNEL,HEAP,ARG0];
 92
 93   foreach my $inst ( @{ $packets } )  {
 94 foreach my $char (split(//, $inst-[1])) {
 95   if ( $linechars == 0 ) {
 96 $hexpacket .= sprintf( %04X , $offset );
 97   }
 98   $linechars++;
 99   $hexpacket .= sprintf( %02X , ord($char) );
100   if ( $linechars == 16 ) {
101 $hexpacket .= \n;
102 $linechars = 0;
103 $offset += 16;
104   }
105 }
106 $hexpacket .= \n\n;
107   }
108   print $hexpacket;
109   undef($hexpacket);
110  }
111
112  ##



Re: Continuous packet capture

2009-03-27 Thread Jonathan S. Polacheck

Nosing around in the mailing list archive I find;


Re: Prioritizing Event Loops

Martijn van Beers
Fri, 18 Jan 2008 11:37:22 -0800
snip
In POE, all your external data, whether from a socket or a file, or
something else entirely, enters your app through a POE::Wheel (you might
not be aware of having one, since it is mostly hidden inside
POE::Component::Server::TCP). How the wheel gets the data is supposed to be
abstracted away.
/snip

So POE::Component::Pcap is a wheel?

Jon

__

Brad,

Great stuff.  Thanks.  I'm going on the assumption that $inst-[1] (line
94) is the raw packet, headers and all.  I plan to test by pointing pcap at
a capture file and comparing output to input.  My next plan is to add a sql
insert of $hexpacket at line 108.  My goal is to keep up with an incoming
data stream of 20-30 k-bytes a second.  After the hex data is safely stored
in the database I can go back and insert whatever fields (layer 3-4, packet
length, etc) I want.  Then do a gui to extract traces and do other analysis
from the stored data.   Here is my code;

  1  use strict;
  2  use warnings;
  3
  4  use Data::Dumper;
  5  use Carp;
  6
  7  #
  8  # POE Environment
  9  # use POE qw(
 10  #  Component::Pcap
 11  #  Component::Daemon
 12  # );
 13
 14  use POE qw(
 15   Component::Pcap
 16  );
 17
 18  #
 19  # PCAP Options
 20  my %pcap_opts = (
 21   dev = 'eth0',
 22   snaplen   = 1514,
 23   promisc   = 1,
 24   timeout   = 100,
 25  );
 26
 27  ##
 28  # POE Environment Setup
 29  ##
 30  #POE::Component::Daemon-spawn( detach = 1, babysit = 600, max_children 
= 5 );
 31
 32  POE::Session-create(
 33   inline_states = {
 34 _start  = \start_processor,
 35 _stop = \stop_processor,
 36 handle_packet   = \handle_packet,
 37   },
 38  );
 39
 40  $_[HEAP]-{i} = 0;
 41
 42  ##
 43  # Run the POE Sessions
 44  ##
 45  POE::Kernel-run;
 46
 47  ##
 48  exit 0;
 49  ##
 50
 51  ##
 52  # Start the Processor
 53  sub start_processor {
 54   my ($kernel, $heap) = @_[KERNEL, HEAP];
 55
 56   $kernel-alias_set('processor');
 57
 58   #
 59   # Start Packet Capturing
 60   POE::Component::Pcap-spawn(
 61 Alias   = 'pcap',
 62 Device= $pcap_opts{dev},
 63 Dispatch= 'handle_packet',
 64 Session   = 'processor',
 65   );
 66   $kernel-post( pcap = open_live = @pcap_opts{qw(dev snaplen promisc 
timeout)} );
 67
 68   $kernel-post( pcap = 'run' );
 69  }
 70  ##
 71
 72  ##
 73  # stop the processor
 74  sub stop_processor {
 75   my ($kernel,$heap) = @_[KERNEL,HEAP];
 76
 77   #
 78   # Stop pcap
 79   $kernel-post( 'pcap' = 'shutdown' );
 80  }
 81  ##
 82
 83  ##
 84  sub handle_packet {
 85   my $offset = 0;
 86   my $linechars = 0;
 87   my $hexpacket;
 88
 89   $_[HEAP]-{i}++;
 90   print sub handle_packet called $_[HEAP]-{i} times\n;
 91   my ($kernel,$heap,$packets) = @_[KERNEL,HEAP,ARG0];
 92
 93   foreach my $inst ( @{ $packets } )  {
 94 foreach my $char (split(//, $inst-[1])) {
 95   if ( $linechars == 0 ) {
 96 $hexpacket .= sprintf( %04X , $offset );
 97   }
 98   $linechars++;
 99   $hexpacket .= sprintf( %02X , ord($char) );
100   if ( $linechars == 16 ) {
101 $hexpacket .= \n;
102 $linechars = 0;
103 $offset += 16;
104   }
105 }
106 $hexpacket .= \n\n;
107   }
108   print $hexpacket;
109   undef($hexpacket);
110  }
111
112  ##



Re: Continuous packet capture

2009-03-27 Thread Brad Lhotsky


Sorry, I thought I found a bug in the code, but it turns out my code was 
correct.  $inst-[0] is the Packet Header, $inst-[1] is the packet in 
raw form.


Jonathan S. Polacheck wrote:

Brad,

Great stuff.  Thanks.  I'm going on the assumption that $inst-[1] (line
94) is the raw packet, headers and all.  I plan to test by pointing pcap at
a capture file and comparing output to input.  My next plan is to add a sql
insert of $hexpacket at line 108.  My goal is to keep up with an incoming
data stream of 20-30 k-bytes a second.  After the hex data is safely stored
in the database I can go back and insert whatever fields (layer 3-4, packet
length, etc) I want.  Then do a gui to extract traces and do other analysis
from the stored data.   Here is my code;

  1  use strict;
  2  use warnings;
  3
  4  use Data::Dumper;
  5  use Carp;
  6
  7  #
  8  # POE Environment
  9  # use POE qw(
 10  #  Component::Pcap
 11  #  Component::Daemon
 12  # );
 13
 14  use POE qw(
 15   Component::Pcap
 16  );
 17
 18  #
 19  # PCAP Options
 20  my %pcap_opts = (
 21   dev = 'eth0',
 22   snaplen   = 1514,
 23   promisc   = 1,
 24   timeout   = 100,
 25  );
 26
 27  ##
 28  # POE Environment Setup
 29  ##
 30  #POE::Component::Daemon-spawn( detach = 1, babysit = 600, max_children 
= 5 );
 31
 32  POE::Session-create(
 33   inline_states = {
 34 _start  = \start_processor,
 35 _stop = \stop_processor,
 36 handle_packet   = \handle_packet,
 37   },
 38  );
 39
 40  $_[HEAP]-{i} = 0;
 41
 42  ##
 43  # Run the POE Sessions
 44  ##
 45  POE::Kernel-run;
 46
 47  ##
 48  exit 0;
 49  ##
 50
 51  ##
 52  # Start the Processor
 53  sub start_processor {
 54   my ($kernel, $heap) = @_[KERNEL, HEAP];
 55
 56   $kernel-alias_set('processor');
 57
 58   #
 59   # Start Packet Capturing
 60   POE::Component::Pcap-spawn(
 61 Alias   = 'pcap',
 62 Device= $pcap_opts{dev},
 63 Dispatch= 'handle_packet',
 64 Session   = 'processor',
 65   );
 66   $kernel-post( pcap = open_live = @pcap_opts{qw(dev snaplen promisc 
timeout)} );
 67
 68   $kernel-post( pcap = 'run' );
 69  }
 70  ##
 71
 72  ##
 73  # stop the processor
 74  sub stop_processor {
 75   my ($kernel,$heap) = @_[KERNEL,HEAP];
 76
 77   #
 78   # Stop pcap
 79   $kernel-post( 'pcap' = 'shutdown' );
 80  }
 81  ##
 82
 83  ##
 84  sub handle_packet {
 85   my $offset = 0;
 86   my $linechars = 0;
 87   my $hexpacket;
 88
 89   $_[HEAP]-{i}++;
 90   print sub handle_packet called $_[HEAP]-{i} times\n;
 91   my ($kernel,$heap,$packets) = @_[KERNEL,HEAP,ARG0];
 92
 93   foreach my $inst ( @{ $packets } )  {
 94 foreach my $char (split(//, $inst-[1])) {
 95   if ( $linechars == 0 ) {
 96 $hexpacket .= sprintf( %04X , $offset );
 97   }
 98   $linechars++;
 99   $hexpacket .= sprintf( %02X , ord($char) );
100   if ( $linechars == 16 ) {
101 $hexpacket .= \n;
102 $linechars = 0;
103 $offset += 16;
104   }
105 }
106 $hexpacket .= \n\n;
107   }
108   print $hexpacket;
109   undef($hexpacket);
110  }
111
112  ##



--
Brad Lhotsky lhots...@mail.nih.gov
NCTS Computer Specialist  -- 410.558.8006
..  WAR IS PEACE,
FREEDOM IS SLAVERY,
IGNORANCE IS STRENGTH ..


Re: Continuous packet capture

2009-03-27 Thread Brad Lhotsky


I'm not sure that POE::Component::Pcap works like the 
POE::Component::Server::TCP.  It appears to be implemented as a separate 
POE::Session and uses select() with an internal file descriptor to poll 
the device for new packets and fire the events specified by the dispath 
argument.


Jonathan S. Polacheck wrote:

Nosing around in the mailing list archive I find;


Re: Prioritizing Event Loops

Martijn van Beers
Fri, 18 Jan 2008 11:37:22 -0800
snip
In POE, all your external data, whether from a socket or a file, or
something else entirely, enters your app through a POE::Wheel (you might
not be aware of having one, since it is mostly hidden inside
POE::Component::Server::TCP). How the wheel gets the data is supposed to be
abstracted away.
/snip

So POE::Component::Pcap is a wheel?

Jon

__

Brad,

Great stuff.  Thanks.  I'm going on the assumption that $inst-[1] (line
94) is the raw packet, headers and all.  I plan to test by pointing pcap at
a capture file and comparing output to input.  My next plan is to add a sql
insert of $hexpacket at line 108.  My goal is to keep up with an incoming
data stream of 20-30 k-bytes a second.  After the hex data is safely stored
in the database I can go back and insert whatever fields (layer 3-4, packet
length, etc) I want.  Then do a gui to extract traces and do other analysis
from the stored data.   Here is my code;

  1  use strict;
  2  use warnings;
  3
  4  use Data::Dumper;
  5  use Carp;
  6
  7  #
  8  # POE Environment
  9  # use POE qw(
 10  #  Component::Pcap
 11  #  Component::Daemon
 12  # );
 13
 14  use POE qw(
 15   Component::Pcap
 16  );
 17
 18  #
 19  # PCAP Options
 20  my %pcap_opts = (
 21   dev = 'eth0',
 22   snaplen   = 1514,
 23   promisc   = 1,
 24   timeout   = 100,
 25  );
 26
 27  ##
 28  # POE Environment Setup
 29  ##
 30  #POE::Component::Daemon-spawn( detach = 1, babysit = 600, max_children 
= 5 );
 31
 32  POE::Session-create(
 33   inline_states = {
 34 _start  = \start_processor,
 35 _stop = \stop_processor,
 36 handle_packet   = \handle_packet,
 37   },
 38  );
 39
 40  $_[HEAP]-{i} = 0;
 41
 42  ##
 43  # Run the POE Sessions
 44  ##
 45  POE::Kernel-run;
 46
 47  ##
 48  exit 0;
 49  ##
 50
 51  ##
 52  # Start the Processor
 53  sub start_processor {
 54   my ($kernel, $heap) = @_[KERNEL, HEAP];
 55
 56   $kernel-alias_set('processor');
 57
 58   #
 59   # Start Packet Capturing
 60   POE::Component::Pcap-spawn(
 61 Alias   = 'pcap',
 62 Device= $pcap_opts{dev},
 63 Dispatch= 'handle_packet',
 64 Session   = 'processor',
 65   );
 66   $kernel-post( pcap = open_live = @pcap_opts{qw(dev snaplen promisc 
timeout)} );
 67
 68   $kernel-post( pcap = 'run' );
 69  }
 70  ##
 71
 72  ##
 73  # stop the processor
 74  sub stop_processor {
 75   my ($kernel,$heap) = @_[KERNEL,HEAP];
 76
 77   #
 78   # Stop pcap
 79   $kernel-post( 'pcap' = 'shutdown' );
 80  }
 81  ##
 82
 83  ##
 84  sub handle_packet {
 85   my $offset = 0;
 86   my $linechars = 0;
 87   my $hexpacket;
 88
 89   $_[HEAP]-{i}++;
 90   print sub handle_packet called $_[HEAP]-{i} times\n;
 91   my ($kernel,$heap,$packets) = @_[KERNEL,HEAP,ARG0];
 92
 93   foreach my $inst ( @{ $packets } )  {
 94 foreach my $char (split(//, $inst-[1])) {
 95   if ( $linechars == 0 ) {
 96 $hexpacket .= sprintf( %04X , $offset );
 97   }
 98   $linechars++;
 99   $hexpacket .= sprintf( %02X , ord($char) );
100   if ( $linechars == 16 ) {
101 $hexpacket .= \n;
102 $linechars = 0;
103 $offset += 16;
104   }
105 }
106 $hexpacket .= \n\n;
107   }
108   print $hexpacket;
109   undef($hexpacket);
110  }
111
112  ##



--
Brad Lhotsky lhots...@mail.nih.gov
NCTS Computer Specialist  -- 410.558.8006
..  WAR IS PEACE,
FREEDOM IS SLAVERY,
IGNORANCE IS STRENGTH ..


Re: Continuous packet capture

2009-03-26 Thread Brad Lhotsky
I don't know if this will help you or not, but here's a script I have  
running to monitor and track recursive DNS Queries on my network.  You  
can ignore the database stuff, but it might help.


http://divisionbyzero.net/~brad/code/dns_snoop.pl.html

I process the packets as they come in, but I could be using  
POE::Wheel::Run on them as well...  The key part of the tutorial (http://poe.perl.org/?POE_Cookbook/Child_Processes_3 
) seems to be the while() loop in the start_tasks routine.


It doesn't sound like you need the feedback from the child tasks  
because you'll be feeding them via the heap.  The Filter::Reference  
stuff is being used to return status information from the child tasks  
to the main processor.


Here's another script I've written that needs some reworking as well.   
It listens on our egress link, and collects statistics inside the  
heap.  At intervals (POE::Component::Cron), the heap is processed  
written to a database (or RRD) and then cleared. The processing  
continues.


http://divisionbyzero.net/~brad/code/traffic_detection.pl.html

I hope there's something in there that helps.

On Mar 24, 2009, at 4:25 PM, Jonathan S. Polacheck wrote:



I have spent a couple of days casting about, looking at examples and
perldoc.  I don't seem to be able to get the data from 'tcpdump' (or
POE::Component::PCAP) to the wheel that will process the data.  For  
my last
attempt, I removed Filter::Referece and tried with just the wheel.   
Still

no luck.  Any suggestions?

#!/usr/bin/perl

use warnings;
use strict;
use POE qw( Wheel::Run ); #Filter::Reference );
use Data::Dumper;

our $offset = 0;
our $linechars = '';

POE::Session-create
 ( inline_states =
 {
   _start = sub {
 my ($heap) = $_[HEAP];
 my $gp = POE::Wheel::Run-new
   ( Program = '/usr/sbin/tcpdump -i eth0 -w - '
#   , Conduit = pipe
#   , StdoutFilter = POE::Filter::Reference- 
new()

#   , StdinEvent  = 'process_packet'
   , StdinEvent  = 'stdin'
#   , StdoutEvent = 'print'
#   , InputEvent = 'process_packet'
   );
print gp compleate\n;
 $heap-{gp} = $gp;
# my $pp = POE::Wheel::Run-new
#   ( Program = process_packet
#   , StdoutEvent = 'stdout'
#   );

   }
 }
 );

sub process_packet {
 print process_packet called\n;
# my ($heap) = $_[HEAP];

# my $filter = POE::Filter::Reference-new();
# my $pdump = $filter-get( [ $heap-{gp} ] );
 my $pdump = $_[ARG0];
 foreach my $char (split(//, $pdump)) {
   if($char !~ /\n/) {
 dump_char($char) ;
   } else {
 print \n\n;
 $offset = 0;
 $linechars = '';
   }
   1;
 }


 dump_char( ' ', 1 ) while length($linechars) != 0;

}

sub dump_char {
 my ( $char ) = shift;
 if ( length( $linechars ) == 0 ) {
   printf( %06X , $offset );
 }
 $linechars .= ( $char =~ m#[!-~ ]# ) ? $char : '.';
printf( %02X , ord($char) );
  if ( length( $linechars ) == 16 ) {
   print( \n );
   $linechars = '';
   $offset += 16;
 }
}

$poe_kernel-run();
exit 0;



--
Brad Lhotsky  lhots...@mail.nih.gov
Security Administrator / NIA Alt. ISSO
.. WAR IS PEACE
   FREEDOM IS SLAVERY
   IGNORANCE IS STRENGTH ..






Re: Continuous packet capture

2009-03-24 Thread Jonathan S. Polacheck

I have spent a couple of days casting about, looking at examples and
perldoc.  I don't seem to be able to get the data from 'tcpdump' (or
POE::Component::PCAP) to the wheel that will process the data.  For my last
attempt, I removed Filter::Referece and tried with just the wheel.  Still
no luck.  Any suggestions?

#!/usr/bin/perl

use warnings;
use strict;
use POE qw( Wheel::Run ); #Filter::Reference );
use Data::Dumper;

our $offset = 0;
our $linechars = '';

POE::Session-create
  ( inline_states =
  {
_start = sub {
  my ($heap) = $_[HEAP];
  my $gp = POE::Wheel::Run-new
( Program = '/usr/sbin/tcpdump -i eth0 -w - '
#   , Conduit = pipe
#   , StdoutFilter = POE::Filter::Reference-new()
#   , StdinEvent  = 'process_packet'
, StdinEvent  = 'stdin'
#   , StdoutEvent = 'print'
#   , InputEvent = 'process_packet'
);
print gp compleate\n;
  $heap-{gp} = $gp;
# my $pp = POE::Wheel::Run-new
#   ( Program = process_packet
#   , StdoutEvent = 'stdout'
#   );

}
  }
  );

sub process_packet {
  print process_packet called\n;
# my ($heap) = $_[HEAP];

# my $filter = POE::Filter::Reference-new();
# my $pdump = $filter-get( [ $heap-{gp} ] );
  my $pdump = $_[ARG0];
  foreach my $char (split(//, $pdump)) {
if($char !~ /\n/) {
  dump_char($char) ;
} else {
  print \n\n;
  $offset = 0;
  $linechars = '';
}
1;
  }


  dump_char( ' ', 1 ) while length($linechars) != 0;

}

sub dump_char {
  my ( $char ) = shift;
  if ( length( $linechars ) == 0 ) {
printf( %06X , $offset );
  }
  $linechars .= ( $char =~ m#[!-~ ]# ) ? $char : '.';
 printf( %02X , ord($char) );
   if ( length( $linechars ) == 16 ) {
print( \n );
$linechars = '';
$offset += 16;
  }
}

$poe_kernel-run();
exit 0;



Re: Continuous packet capture

2009-03-15 Thread Jon Polacheck

What I get out the the example;

Wheel::Run is used to create tasks (as opposed to processes or sessions)

Filter::Reference is used to create a communications channel between the 
tasks


What I am still wondering is if the communications channel would buffer 
or act as a fifo for the data coming out of the enque task and if 
prioritizing would be needed to make sure that the enque task would not 
drop any packets.

___
Alex _
Fri, 13 Mar 2009 15:49:37 -0700

heres an example of producer/consumer with wheel::run
 http://poe.perl.org/?POE_Cookbook/Child_Processes_3





From: Jonathan S. Polacheck jpola...@texasmutual.com
To: poe@perl.org
Sent: Friday, March 13, 2009 1:13:55 PM
Subject: Re: Continuous packet capture


ch...@fedde.us wrote;

Your first step is going to be to make sure your code is 'use strict; use
warnings;' clean.  I'm not saying that your code is not, but since I don't
see the strictures I'm making the knee jerk comment.  Second,  POE might be
a fine way to go.  There are lots of components available that'll make
coding this up easier.   Third, what's wrong with using one of the packages
you list?

and jpola...@texasmutual.com replied;

strict and warnings is definitely a good idea. But if I port the whole
thing to POE, I guess I'll start using them on that code.  The two included
scripts are just a sort of proof of concept I did to get things going.  I
ultimately may not be able to pull this off in Perl, but it's what I know
so I starting there.

As for the packages, if you are referring to Infinistrream, Gigastor,
etc, the problem in my view is that they are both proprietary and
expensive.  I believe that continuous packet capture will become a standard
way of doing things, supplanting ad-hoc capture (pcap, wireshark, etc), at
least in any production environment large enough to require staff
knowledgeable to use such tools.  That, I think, is the time when open
source solutions break into to market.

We have Infinistreams in the production environment I work at.  We have the
lowest end devices at our remote sites. We paid in excess of $10k each for
them, plus ongoing support contract costs.  They work find, but the vendor
(now Netscout) has dropped them from the product line (no replacements, no
further updates, end-of-life on the horizon).  Netscout has a track record
of going for the high end of the market with product development and
pricing to match.

So I decided that wireshark should evolve to include cpc capabilities.  I
sent my code to wireshark-dev and was roundly ignored (no time for Perl
programmers, perhaps).  But no matter, communities are where you find them.
So I tried the POE list, and here we are.

I agree that there are lots of components.  Here's where my POE solution
stands;

use POE;
use strict;
use warnings;
use Net::Pcap;
use POE::Component::Pcap;
use Data::Hexdumper qw( hexdump );
use Data::Dumper;
use lib 't';

my $dev = eth0;
my $i = 0;

POE::Session-create(
  inline_states = {
_start  = \start,
got_packet  = \got_packet,
  },

);

POE::Kernel-run;

sub start {

  #diag [POE:start] spawning new Pcap session , $_[SESSION]-ID, 
on device $dev;
  POE::Component::Pcap-spawn(
Alias = 'pcap',
Device = $dev,
Dispatch = 'got_packet',
Session = $_[SESSION],
  );

  $_[KERNEL]-post(pcap = open_live = $dev, 1514, 1);
  $_[KERNEL]-post(pcap = 'run');

}

# sub stop {
# #diag [POE:stop];
# $_[KERNEL]-post(pcap = 'shutdown');
# }

sub got_packet {
  #diag [POE:got_packet];
# $i++;
# print got_packet run $i\n;

  my $packets = $_[ARG0];

  # process the first packet only
  process_packet(@{ $packets-[0] });

  # send a message to stop the capture
  #$_[KERNEL]-post(pcap = 'shutdown');
}

sub process_packet {
# my ($pkt) = $_[1];
  my $results = hexdump( data = $_[1]
, number_format = 'C',
  );
# print Dumper($header);
  print $results;
}

#start;
exit;

So I have the hexdump moved into process_packet and out of got_packet.
And it;'s easy enough to change print $results to a SQL insert statement.
But I think I need a que or fifo (HEAP?) to hold the packets and a priority
on get_packet to make sure it keeps up with POE::Component::Pcap and the
incoming traffic.  Or is there a better way?

Thanks for your interest,



Re: Continuous packet capture

2009-03-15 Thread Alex _
the tasks is the queue. Wheel::run pops of tasks and runs it in a separate 
process





From: Jon Polacheck jon...@grandecom.net
To: poe@perl.org
Sent: Sunday, March 15, 2009 7:08:01 AM
Subject: Re: Continuous packet capture

What I get out the the example;

Wheel::Run is used to create tasks (as opposed to processes or sessions)

Filter::Reference is used to create a communications channel between the tasks

What I am still wondering is if the communications channel would buffer or act 
as a fifo for the data coming out of the enque task and if prioritizing would 
be needed to make sure that the enque task would not drop any packets.
___
Alex _
Fri, 13 Mar 2009 15:49:37 -0700

heres an example of producer/consumer with wheel::run
http://poe.perl.org/?POE_Cookbook/Child_Processes_3





From: Jonathan S. Polacheck jpola...@texasmutual.com
To: poe@perl.org
Sent: Friday, March 13, 2009 1:13:55 PM
Subject: Re: Continuous packet capture


ch...@fedde.us wrote;

Your first step is going to be to make sure your code is 'use strict; use
warnings;' clean.  I'm not saying that your code is not, but since I don't
see the strictures I'm making the knee jerk comment.  Second,  POE might be
a fine way to go.  There are lots of components available that'll make
coding this up easier.   Third, what's wrong with using one of the packages
you list?

and jpola...@texasmutual.com replied;

strict and warnings is definitely a good idea. But if I port the whole
thing to POE, I guess I'll start using them on that code.  The two included
scripts are just a sort of proof of concept I did to get things going.  I
ultimately may not be able to pull this off in Perl, but it's what I know
so I starting there.

As for the packages, if you are referring to Infinistrream, Gigastor,
etc, the problem in my view is that they are both proprietary and
expensive.  I believe that continuous packet capture will become a standard
way of doing things, supplanting ad-hoc capture (pcap, wireshark, etc), at
least in any production environment large enough to require staff
knowledgeable to use such tools.  That, I think, is the time when open
source solutions break into to market.

We have Infinistreams in the production environment I work at.  We have the
lowest end devices at our remote sites. We paid in excess of $10k each for
them, plus ongoing support contract costs.  They work find, but the vendor
(now Netscout) has dropped them from the product line (no replacements, no
further updates, end-of-life on the horizon).  Netscout has a track record
of going for the high end of the market with product development and
pricing to match.

So I decided that wireshark should evolve to include cpc capabilities.  I
sent my code to wireshark-dev and was roundly ignored (no time for Perl
programmers, perhaps).  But no matter, communities are where you find them.
So I tried the POE list, and here we are.

I agree that there are lots of components.  Here's where my POE solution
stands;

use POE;
use strict;
use warnings;
use Net::Pcap;
use POE::Component::Pcap;
use Data::Hexdumper qw( hexdump );
use Data::Dumper;
use lib 't';

my $dev = eth0;
my $i = 0;

POE::Session-create(
  inline_states = {
_start  = \start,
got_packet  = \got_packet,
  },

);

POE::Kernel-run;

sub start {

  #diag [POE:start] spawning new Pcap session , $_[SESSION]-ID, 
on device $dev;
  POE::Component::Pcap-spawn(
Alias = 'pcap',
Device = $dev,
Dispatch = 'got_packet',
Session = $_[SESSION],
  );

  $_[KERNEL]-post(pcap = open_live = $dev, 1514, 1);
  $_[KERNEL]-post(pcap = 'run');

}

# sub stop {
# #diag [POE:stop];
# $_[KERNEL]-post(pcap = 'shutdown');
# }

sub got_packet {
  #diag [POE:got_packet];
# $i++;
# print got_packet run $i\n;

  my $packets = $_[ARG0];

  # process the first packet only
  process_packet(@{ $packets-[0] });

  # send a message to stop the capture
  #$_[KERNEL]-post(pcap = 'shutdown');
}

sub process_packet {
# my ($pkt) = $_[1];
  my $results = hexdump( data = $_[1]
, number_format = 'C',
  );
# print Dumper($header);
  print $results;
}

#start;
exit;

So I have the hexdump moved into process_packet and out of got_packet.
And it;'s easy enough to change print $results to a SQL insert statement.
But I think I need a que or fifo (HEAP?) to hold the packets and a priority
on get_packet to make sure it keeps up with POE::Component::Pcap and the
incoming traffic.  Or is there a better way?

Thanks for your interest,

Continuous packet capture

2009-03-13 Thread Jonathan S. Polacheck

Perhaps this is a case of premature optimization.  I am working toward a
continuous packet capture application (as in Infinistream, Gigastor,
NetVCR, etc).  So far, I have two perl scripts.  One takes Net::Pcap output
and Hexdumps it to a fifo file.  The other reads the fifo and inserts the
hexdump into a database table.

This is all well and good, but when I tried to dump the pcap output
directly into the fifo and convert to hex as the fifo was read things got
ugly.  So now I am considering rewriting the whole thing in POE.

I want some kind of buffer between pcap and the database inserts to reduce
the chance of dropped packets.  It seems to me that the process that has
the pcap session should have a higher priority than the db insert
process.

Is POE the way to go?  Are there existing examples of POE code that does
something similar?

Thanks for your interest,

Jon Polacheck

Used mkfifo to create the named pipe.  Perl sees it as a disk file
(that I called qtfifo).  ENQUE.pl dumps packet hexdumps to the fifo.
DEQUE.pl reads lines from the fifo.  /^ / acts as the delimiter. mysql
compression worked with the standard OpenSuSE install, no recompiling or
other mucking about necessary.

Lines used for debugging marked as such.

ENQUE.pl

use Net::Pcap;
use Data::Hexdumper qw(hexdump);

$dev = eth0;

# used a 50 packet cap file to make sure what came out matched what went in
#$dump = ip.cap;
#$pcap = Net::Pcap::open_offline($dump, \$err) or die Can't read
'$dump': $err\n;

# live, real-time feed
$pcap = Net::Pcap::open_live($dev, 1514, 1, 0, \$err);

Net::Pcap::loop($pcap, -1, \process_pkt, ); # - subroutine call

sub process_pkt {
   open(QT,  qtfifo);
# $_[2] is the third element of the default array @_ which was created
# by the subroutine call process_pkt
   my $pkt=$_[2];
   $results = hexdump( data = $pkt
   , number_format = 'C',
   );
   print QT $results;
   close(QT);
$i++; # debug
stop_run if $i  100; #debug
}

# all debug below
sub stop_run {
 print stop_run\n;
 open(QT,  qtfifo);
 print QT \nx\n;
 close(QT);
 print enque ended\n;
 exit;
}


DEQUE.pl

use Time::HiRes ( nanosleep );
use DBI;

$hostname=127.0.0.1;
$database=cpc;
$port=3306;

$dsn = DBI:mysql:database=$database;host=$hostname;port=$port;

$dbh = DBI-connect($dsn,
   root,
   ,
   {'RaiseError' = 1});

# call the Net::Packet collector script
system(q{perl ENQUE.pl});

open(EQT,   qtfifo);

$i = 0; # debug
$pc = 0; # debug

while(1) {
   $i++; # debug
   $line = readline(EQT);
   if ($line =~ /^ / ) {
   $dbh-do(qq{INSERT INTO cpc VALUES ( compress($pkt))});
   $pc++ if defined($pkt); # debug
   print packet $pc:\n$pkt\n if defined($pkt); # debug
   undef($pkt);
   $pkt .= $line;
   } else {
   $pkt .= $line;
   theend if $pkt =~ /x/; # debug
   }
   nanosleep(1); # would not work without this!
}

# all debug below
sub theend {
   close(EQT);
   print $i loops\ndeque ended\n;
   exit;
}

This generated a cap file that looks just fine in Wireshark.

mysql -Br -D cpc -e select uncompress(packet) from cpc; | text2pcap -
m_cap.cap




Re: Continuous packet capture

2009-03-13 Thread Alex _
heres an example of producer/consumer with wheel::run
 http://poe.perl.org/?POE_Cookbook/Child_Processes_3





From: Jonathan S. Polacheck jpola...@texasmutual.com
To: poe@perl.org
Sent: Friday, March 13, 2009 1:13:55 PM
Subject: Re: Continuous packet capture


ch...@fedde.us wrote;

Your first step is going to be to make sure your code is 'use strict; use
warnings;' clean.  I'm not saying that your code is not, but since I don't
see the strictures I'm making the knee jerk comment.  Second,  POE might be
a fine way to go.  There are lots of components available that'll make
coding this up easier.   Third, what's wrong with using one of the packages
you list?

and jpola...@texasmutual.com replied;

strict and warnings is definitely a good idea. But if I port the whole
thing to POE, I guess I'll start using them on that code.  The two included
scripts are just a sort of proof of concept I did to get things going.  I
ultimately may not be able to pull this off in Perl, but it's what I know
so I starting there.

As for the packages, if you are referring to Infinistrream, Gigastor,
etc, the problem in my view is that they are both proprietary and
expensive.  I believe that continuous packet capture will become a standard
way of doing things, supplanting ad-hoc capture (pcap, wireshark, etc), at
least in any production environment large enough to require staff
knowledgeable to use such tools.  That, I think, is the time when open
source solutions break into to market.

We have Infinistreams in the production environment I work at.  We have the
lowest end devices at our remote sites. We paid in excess of $10k each for
them, plus ongoing support contract costs.  They work find, but the vendor
(now Netscout) has dropped them from the product line (no replacements, no
further updates, end-of-life on the horizon).  Netscout has a track record
of going for the high end of the market with product development and
pricing to match.

So I decided that wireshark should evolve to include cpc capabilities.  I
sent my code to wireshark-dev and was roundly ignored (no time for Perl
programmers, perhaps).  But no matter, communities are where you find them.
So I tried the POE list, and here we are.

I agree that there are lots of components.  Here's where my POE solution
stands;

use POE;
use strict;
use warnings;
use Net::Pcap;
use POE::Component::Pcap;
use Data::Hexdumper qw( hexdump );
use Data::Dumper;
use lib 't';

my $dev = eth0;
my $i = 0;

POE::Session-create(
  inline_states = {
_start  = \start,
got_packet  = \got_packet,
  },

);

POE::Kernel-run;

sub start {

  #diag [POE:start] spawning new Pcap session , $_[SESSION]-ID, 
on device $dev;
  POE::Component::Pcap-spawn(
Alias = 'pcap',
Device = $dev,
Dispatch = 'got_packet',
Session = $_[SESSION],
  );

  $_[KERNEL]-post(pcap = open_live = $dev, 1514, 1);
  $_[KERNEL]-post(pcap = 'run');

}

# sub stop {
# #diag [POE:stop];
# $_[KERNEL]-post(pcap = 'shutdown');
# }

sub got_packet {
  #diag [POE:got_packet];
# $i++;
# print got_packet run $i\n;

  my $packets = $_[ARG0];

  # process the first packet only
  process_packet(@{ $packets-[0] });

  # send a message to stop the capture
  #$_[KERNEL]-post(pcap = 'shutdown');
}

sub process_packet {
# my ($pkt) = $_[1];
  my $results = hexdump( data = $_[1]
, number_format = 'C',
  );
# print Dumper($header);
  print $results;
}

#start;
exit;

So I have the hexdump moved into process_packet and out of got_packet.
And it;'s easy enough to change print $results to a SQL insert statement.
But I think I need a que or fifo (HEAP?) to hold the packets and a priority
on get_packet to make sure it keeps up with POE::Component::Pcap and the
incoming traffic.  Or is there a better way?

Thanks for your interest,