Пример самописного агрегатора на перле, использующего бинарное дерево для хранения данных. Работает очень быстро на любых объемах информации и количестве пользователей/зон. Думаю кому нужно - разберется куда его прикрутить :)
#!/usr/bin/perl -w
use Net::Patricia;
use strict;
my %users = (
"192.168.100.1" => 1,
"192.168.58.11" => 58,
"192.168.100.0/24" => 111,
"192.168.100.128/25" => 11,
);
my $tree_users = new Net::Patricia;
foreach (keys %users){
$tree_users->add_string($_, [ $users{$_} ]);
}
my %zones = (
"255.255.10.0/24" => 1,
"255.255.20.0/24" => 2,
"255.255.30.0/24" => 3,
"255.255.0.0/24" => 3,
"255.255.1.0/24" => 1,
"255.255.5.0/24" => 1,
"255.255.6.0/24" => 6,
"10.0.0.0/22" => 6,
"0.0.0.0/0" => 5,
);
my $tree_zones = new Net::Patricia;
foreach (keys %zones){
$tree_zones->add_string($_, $zones{$_});
}
# count mode:
# 1 - input
# 2 - output
# 3 - input + output
my $mode = 3;
my ($user, $zone, @cols);
open F, "/tmp/flow-tools.out";
while(<F>){
if(/^#/){next;}
@cols = split/\s+/,$_;
# первый айпи - юзер?
if($user = $tree_users->match_string($cols[0])){
# да
# считаем исходящий?
if($mode != 1){
# да, получаем зону и агрегируем
if($zone = $tree_zones->match_string($cols[1])){
$user->[$zone] += $cols[3];
}
}
}
# второй айпи - юзер?
if($user = $tree_users->match_string($cols[1])){
# да
# считаем входящий?
if($mode != 2){
# да, получаем зону и агрегируем
if($zone = $tree_zones->match_string($cols[0])){
$user->[$zone] += $cols[3];
}
}
}
}
close F;
# Получаем максимальный номер зоны
my $max_zone = 0;
foreach my $zone (keys %zones){
if($zones{$zone} > $max_zone){ $max_zone = $zones{$zone}; }
}
# Перебираем всех юзверей
$tree_users->climb( \&climb_users );
sub climb_users {
print "user ", $_[0][0], ":\n";
for( my $zone = 1; $zone <= $max_zone ; $zone++){
print $zone, ": ", defined $_[0][$zone]?$_[0][$zone]:0,"\n";
}
}