summaryrefslogtreecommitdiffstats
path: root/collector_sample/pq_tracesplit.pl
diff options
context:
space:
mode:
Diffstat (limited to 'collector_sample/pq_tracesplit.pl')
-rw-r--r--collector_sample/pq_tracesplit.pl294
1 files changed, 294 insertions, 0 deletions
diff --git a/collector_sample/pq_tracesplit.pl b/collector_sample/pq_tracesplit.pl
new file mode 100644
index 0000000..3d03731
--- /dev/null
+++ b/collector_sample/pq_tracesplit.pl
@@ -0,0 +1,294 @@
+#!/usr/bin/perl
+# usage:
+# start daemon using /etc/packetq.conf:
+# pq_tracesplit.pl
+
+# stop daemon:
+# pq_tracesplit.pl stop
+
+# run in foreground with conf file
+# pq_tracesplit.pl -f -c my.conf
+
+# stop with custom conf file
+# pq_tracesplit.pl -c my.conf stop
+
+
+
+
+use POSIX;
+use POSIX qw(setsid);
+use Sys::Syslog qw(:DEFAULT setlogsock); # default set, plus setlogsock()
+use File::Path;
+use File::Copy;
+use Getopt::Std;
+use Data::Dumper;
+use strict;
+no strict "subs";
+
+my $conffile = "/etc/packetq.conf";
+my %opts;
+getopts('fc:', \%opts);
+if (defined $opts{c})
+{
+ $conffile = $opts{c};
+}
+my $foreground = undef;
+$foreground = 1 if (defined $opts{f});
+
+openlog('pqcollector','pid,perror','LOG_USER');
+
+######### read config file
+
+my %config;
+open(CONFIG,$conffile) or die "error reading config file $conffile exiting";
+while (<CONFIG>)
+{
+ chomp;
+ next if /^\s*\#/;
+ next unless /=/;
+ my ($key, $variable) = split(/=/,$_,2);
+ $variable =~ s/(\$(\w+))/$config{$2}/g;
+ $config{$key} = $variable;
+}
+close CONFIG;
+
+my $pidfile = $config{'pidfile'};
+my $logfile = "/dev/null";
+
+##### start daemon
+
+if (-e $pidfile)
+{
+ open (PFILE, $pidfile);
+ my $pidfromfile = <PFILE>;
+ close PFILE;
+
+ if (($pidfromfile =~ /[0-9]+/) && kill( 0, $pidfromfile))
+ {
+ if ($ARGV[0] eq 'stop')
+ {
+ syslog 'info',"Stopping daemon pid: $pidfromfile\n";
+ while (kill( 0, $pidfromfile))
+ {
+ kill( - SIGQUIT, $pidfromfile);
+ sleep(1);
+ }
+ exit;
+ }
+ else
+ {
+ syslog LOG_INFO,"Pid file $pidfile exist and the program ($pidfromfile) is running ! exiting ...\n";
+ }
+ exit;
+ }
+ else
+ {
+ unlink($pidfile);
+ }
+}
+
+if ($ARGV[0] eq 'stop')
+{
+ syslog 'info',"Cannot stop packetq.pl as it's not running\n";
+ exit;
+}
+&daemonize() unless defined $foreground;
+open FILE, ">$pidfile" or die "unable to open pidfile : $pidfile $!";
+print FILE $$."\n";
+close FILE;
+
+##### catch signals
+
+my $keep_going = 1;
+$SIG{HUP} = sub { print("Caught SIGHUP: exiting gracefully\n"); $keep_going = 0; };
+$SIG{INT} = sub { print("Caught SIGINT: exiting gracefully\n"); $keep_going = 0; };
+$SIG{QUIT} = sub { print("Caught SIGQUIT: exiting gracefully\n"); $keep_going = 0; };
+$SIG{TERM} = sub { print("Caught SIGTERM: exiting gracefully\n"); $keep_going = 0; };
+
+########## start collection
+foreach my $k (keys %config)
+{
+ print $k."=".$config{$k}."\n";
+ $config{$k} =~ s/^\"(.*)\"$/$1/;
+}
+
+my $interval = $config{'interval'};
+my $interface = $config{'interface'};
+my @interfaces = split(/,/,$interface);
+my $filter = $config{'filter'};
+my $server = $config{'server'};
+my $destdir = $config{'destdir'};
+
+my $stime = floor(time()/$interval) * $interval + $interval;
+
+syslog LOG_INFO,"Starting packetq collector daemon (pid:".$$.") destdir: $config{'destdir'}\n";
+
+my @tdpid;
+my @tspid;
+my $ifcnt = 0;
+foreach my $if (@interfaces)
+{
+ if ($config{'bsdpromischack'} eq "YES")
+ {
+ my $pid;
+ #my $tcpdumpcmd="$config{'tcpdump'} -i $if port 100 2>/dev/null";
+ my $tcpdumpcmd="$config{'tcpdump'} -i $if port 100";
+ $pid = spawn ($tcpdumpcmd);
+ print "tcp pid $pid";
+ if ($pid == 0)
+ {
+ syslog LOG_ERROR,"Cannot run $tcpdumpcmd exiting \n";
+ exit;
+ }
+ syslog LOG_INFO,"Keeping the interface ($if) in promisc mode by letting tcpdump ($pid) listen on port 100 \n";
+ @tdpid[$ifcnt] = $pid;
+ }
+
+ my $tracesplitcmd = $config{'tracesplit'}." pcapint:$if -s $stime -z $config{'compression_level'} -i $interval -f \"$filter\" pcapfile:$destdir/$server-$if";
+ my $tspid = spawn($tracesplitcmd);
+ print "ts pid $tspid";
+ if ($tspid == 0)
+ {
+ syslog LOG_ERROR,"Cannot run $tracesplitcmd exiting \n";
+ exit;
+ }
+ syslog LOG_INFO,"Starting tracesplit \"$tracesplitcmd\"(pid:$tspid)\n";
+ @tspid[$ifcnt] = $tspid;
+
+ $ifcnt++;
+}
+
+########## infinite loop
+reaper();
+
+while($keep_going == 1)
+{
+ foreach my $if (@interfaces)
+ {
+ opendir(DIR, $destdir) or last;
+ my @files;
+
+ while (my $file = readdir(DIR))
+ {
+ # Use a regular expression to ignore files beginning with a period
+ next if ($file =~ m/^\./);
+ next unless ($file =~ m/^$server-$if.*/);
+ push(@files,$file);
+ }
+ @files= sort(@files);
+ if (@files>1)
+ {
+ pop @files;
+ #print "files: \n".join("\n",@files)."\n";
+ foreach my $f (@files)
+ {
+ if($f =~ /^$server-$if-(.*)\.gz/)
+ {
+ ##my ($sec, $min, $hour, $day,$month,$year) = (localtime($1))[0,1,2,3,4,5,6];
+ my ($sec, $min, $hour, $day,$month,$year) = (gmtime($1))[0,1,2,3,4,5,6];
+ $year+=1900;
+ $month++;
+ $sec = "0".$sec if $sec <10;
+ $min = "0".$min if $min <10;
+ $hour = "0".$hour if $hour <10;
+ $day = "0".$day if $day <10;
+ $month = "0".$month if $month<10;
+
+ my $file = "$server-$year$month$day-$hour$min$sec-$if.pcap.gz";
+ my $dir = "$year/$month/$day/$hour";
+ my $cmd = $config{command};
+ $cmd =~ s/%F/$file/g;
+ $cmd =~ s/%S/$server/g;
+ $cmd =~ s/%I/$if/g;
+ $cmd =~ s/%P/$dir/g;
+ $cmd =~ s/%Y/$year/g;
+ $cmd =~ s/%M/$month/g;
+ $cmd =~ s/%D/$day/g;
+ $cmd =~ s/%h/$hour/g;
+ $cmd =~ s/%m/$min/g;
+ $cmd =~ s/%s/$sec/g;
+
+ #print "$cmd\n";
+
+ mkpath "$destdir/$dir";
+ move ("$destdir/$f","$destdir/$dir/$file");
+ spawn($cmd);
+ #print "hello $hour, $min, $sec,-- $day,$month,$year\n";
+ #print "mkdir $dir\n";
+ #print "mv $destdir/$f $destdir/$dir/$file\n";
+ }
+ }
+ }
+ closedir(DIR);
+ }
+ #printf("blipp\n");
+ sleep(5);
+}
+
+########## exit cleanup
+
+syslog 'info',"Shutting down collector ...\n";
+foreach my $pid (@tspid)
+{
+ if ($pid ne 0)
+ {
+ print "Stopping tracesplit ($pid)\n";
+ syslog LOG_INFO,"Stopping tracesplit ($pid)\n";
+ kill( - SIGABRT, $pid);
+ }
+}
+
+foreach my $pid (@tdpid)
+{
+ if ($pid ne 0)
+ {
+ syslog LOG_INFO,"Stopping tcpdump ($pid)\n";
+ kill( - SIGABRT, $pid);
+ }
+}
+
+syslog LOG_INFO,"removing pidfile\n";
+unlink($pidfile);
+
+syslog LOG_INFO,"bye bye\n";
+closelog;
+exit;
+
+########## functions
+
+sub spawn
+{
+ my $cmd = shift;
+ defined(my $pid = fork) or die "Can't fork: $!";
+ if ($pid == 0)
+ {
+ exec $cmd;
+ syslog LOG_ERROR,"Couldn't run $cmd\n";
+ die "Couldn't run $cmd";
+ }
+ return $pid;
+}
+
+sub daemonize
+{
+ chdir '/' or die "Can't chdir to /: $!";
+ defined(my $pid = fork) or die "Can't fork: $!";
+ exit if $pid;
+ setsid or die "Can't start a new session: $!";
+ umask 0;
+
+ open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
+ open STDOUT, ">>$logfile" or die "Can't write to $logfile: $!";
+ open STDERR, ">>$logfile" or die "Can't write to $logfile: $!";
+}
+
+sub reaper {
+ my $stiff;
+ while ( ($stiff = waitpid(-1, &WNOHANG) ) > 0 )
+ {
+ #print "child $stiff terminated -- status $?";
+ }
+ $SIG{CHLD} = \&reaper;
+}
+
+