1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#!/usr/bin/perl
#
# Author: Jordan Ritter <jpr5@darkridge.com>
# Date: Thu Jul 5 17:08:18 PDT 2001
#
# Input file format:
#
# Rulename1 file1.gz rule1 bpf_filter1
# Rulename2 file2.gz rule2 bpf_filter2
# Rulename3 file3.gz rule3 bpf_filter3
#
# Output:
#
# ./ngrepped.Rulename1
# ./ngrepped.Rulename2
# ./ngrepped.Rulename3
#
# Considerations:
#
# 1. Not sure how previous script was able to get the pcap filters with spaces using split...
# 2. Don't forget to tweak $max_procs in CONFIG section.
# 3. Blank lines in rule file are bad bad bad.
# 4. Assumes bash.
#
##########
# CONFIG #
##########
require 5.004;
use POSIX qw(:signal_h);
my($sig_set) = POSIX::SigSet->new(SIGINT);
my($old_sig_set) = POSIX::SigSet->new();
my($max_procs) = 10;
my($rules_file,%rules, @rules);
my($fork_level);
my($loops);
$|++;
#############
# FUNCTIONS #
#############
sub go {
my($rule_name) = shift @_;
return unless $rule_name;
my(%rule) = %{$rules{$rule_name}};
$fork_level++;
sigprocmask(SIG_BLOCK, $sig_set, $old_sig_set);
my($pipe) = "pipe-$rule-$fork_level";
my($daddy) = open($pipe, "-|");
if (not defined $daddy) {
warn "[$rule_name] fork() error: $!\n";
sigprocmask(SIG_UNBLOCK, $old_sig_set);
sleep(1);
} elsif (not $daddy) {
my(@args);
$SIG{INT} = 'IGNORE';
sigprocmask(SIG_UNBLOCK, $old_sig_set);
system("zcat $rule{'file'} | " .
"ngrep -qtI - $rule{'regex'} $rule{'filter'} 2&>1 > " .
"ngrepped.$rule_name");
exit;
} else {
sigprocmask(SIG_UNBLOCK, $old_sig_set);
}
&go(@_);
close($pipe);
print "[$rule_name] finished\n";
}
########
# MAIN #
########
$rules_file = $ARGV[0];
open(RULES, $rules_file) || die "Couldn't open rules file $rules_file: $!.\n";
my(@lines) = <RULES>;
close(RULES);
if (($loops = scalar(@lines)) == 0) {
die "Rules file $rules_file empty, exiting.\n";
}
%rules = map { chomp(local(@fields) = split / /, $_);
$fields[0] => { "file" => $fields[1],
"regex" => $fields[2],
"filter" => $fields[3] }; } @lines;
@rules = keys %rules;
print "Hi, I'm ngrepper, and here we go.\n";
for ( 0 .. int($loops / $max_procs) ) {
$fork_level = 1;
@rules_for_this_pass = splice(@rules, 0, $max_procs);
&go(@rules_for_this_pass);
}
print "Welp, I'm done.\n";
exit;
|