I'm trying to figure out the best way to share objects.  I've got a etst
program that has 2 threads.  

Thread 1:
  Look for SYN packets and create a Packet object
  Add that object to a list.

Thread 2:
  Look through list looking for any Packet objects
  Display to stdout the packet.


I am not getting the sharing part done write.  In order to share Packet
do I have to create the constructor like I did?  What is the best
practice for what I'm trying to do?


--- [ Cut Here ] ---------------------------------
use Net::PcapUtils;
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use threads;
use threads::shared;
use Data::Dumper;
use strict;

{
        package Packet;

        sub new {
                shift;
                my ($v1, $v2 ) = @_;
                my $pkt;
                threads::shared::share($pkt);
                $pkt = &threads::shared::share({});
                bless $pkt, 'Packet';   # Tag object with pkg name
                $pkt->{'packet'} = $v1;
                $pkt->{'timestamp'} = $v2;

                return $pkt;                     # Return object
        }

        sub get_timestamp {
                my $self=shift;
                return $self->{'timestamp'};
        }

        sub get_packet {
                my $self= shift;
                return $self->{'packet'};
        }
}

$| = 1;
my @objs  : shared = ();
my $prog = "tcp[13] = 2 and src net not 192.168.2";

sub get_timestamp {
        my $ti = shift;
        $ti = time() unless $ti;
        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                localtime($ti);

        my $text = sprintf("%02d-%02d %02d:%02d:%02d",
                ($mon+1), $mday, $hour, $min, $sec);
        return $text;

}

sub usleep {
        my $time = shift;
        $time = $time * 0.000001;
        select(undef, undef, undef, $time);
        return;
}

sub now {
        return time();
}


sub redir {
        my $file = shift;
        return unless $file;
        open STDOUT, ">> $file" or return;
        open STDERR, ">&STDOUT";
        open STDIN, "</dev/null";
        return;
}

sub resolv {
        my $addr = shift;

        my $host = `host $addr`;
        chomp $host;

        return $addr if $host =~ m/not found/;
        return $addr unless $host =~ m/pointer\s(.+?)\.$/;

        $addr = $1;
        return $addr;

}

sub process_thread {

        while(1) {
                
                # We do not want to consume much CPU and
                # we do not want to sleep too long.  Just
                # sleep a bit then test again.
                while($#objs == -1 ) { usleep(250000); }

                # Get the packet off the list and unpack the time
                my %p = shift @objs;
                my $pkt = $p->get_packet();
                my $ti = $p->get_timestamp();
                
                #my ($ti, $pkt) = unpack "Ia*", $pkt;

                # get the source IP adrress
                my $src_ip = NetPacket::IP->decode(
                        NetPacket::Ethernet::strip($pkt))->{src_ip};

                # I want incoming
                next if $src_ip =~ m/209\.168\.246\.233/;

                my $pt = NetPacket::TCP->decode(
                         NetPacket::IP::strip(
                                 NetPacket::Ethernet::strip($pkt)));

                print get_timestamp($ti)." SYN ".resolv($src_ip)."($src_ip) -> 
$pt->{'dest_port'}\n";
        }
}

sub catch {
        my ($arg,$hdr,$pkt) = @_ ;
        #my $data = pack "Ia*", now(), $pkt;
        push @objs, Packet->new($pkt, now());
}

sub main {
        #my $pid = fork();
        #return 0 if $pid;
        
        # in Child
        #redir "/opt/SAM/logs/syn.log";
        my $pthr = threads->new(\&process_thread);
        Net::PcapUtils::loop(\&catch, FILTER=> $prog);
        return 0;

}

exit main;

Reply via email to