Улучшенный вариант utm5_load_tc.pl

Форум для размещения материалов по реализации различных схем использования ПО, решению частых проблем и предупреждению частых ошибок
Закрыто
Аватара пользователя
XoRe
Сообщения: 458
Зарегистрирован: Ср янв 10, 2007 16:04

Улучшенный вариант utm5_load_tc.pl

Сообщение XoRe »

В составе utm5 идет скрипт для автоматического занесения в класс трафика нескольких подсетей.

Мною этот скрипт был дополнен.
Добавлены опции:
[-p] our_port - для указания порта нашей сети (по аналогии с -n our_net, -m our_mask).

[-s] skip - для указания, пропускать класс или нет.

[-i] ip from - ип адрес компьютера-источника потока netflow.

[-z] file2 - второй файл, откуда будут браться адреса. Если указан, то будут генерироваться строчки, в которых каждый адрес из первого файла будет скрещен с каждым адресом из второго файла.
И всего получится n*m записей, где n - количество адресов из первого файла, m - из второго.
Адреса из -f будут идти как source, адреса из -z будут идти как dest, если не указана опция -r.

Кроме того в файле сетей (указываемого опцией -f file) можно указывать маску, а можно не указывать (тогда будет считаться /32).
И можно писать через пробел порт.
Может кому-то пригодится.

Сам скрипт:

Код: Выделить всё

#!/usr/bin/perl

use DBD::mysql;
use DBI();
use Time::Local;
use Getopt::Std;
use Socket;

#Load command line args
getopts('f:c:n:m:p:i:z:sdrle', \%opts);
$opt_f = $opts{f};
$opt_c = $opts{c};
$opt_r = $opts{r};
$opt_n = $opts{n};
$opt_m = $opts{m};
$opt_p = $opts{p};
$opt_s = $opts{s};
$opt_i = $opts{i};
$opt_d = $opts{d};
$opt_z = $opts{z};

if ($opt_c eq "" or ($opt_n eq "" and $opt_m eq "" and $opt_z eq "")){
  print "usage: $0\n";
  print "\t-f file1\n";
  print "\t-c tc_class\n";
  print "\t-n our_net\n";
  print "\t-m our_mask \n";
  print "\t[-z] file2\n";
  print "\t[-p] our_port \n";
  print "\t[-r] incoming \n";
  print "\t[-l] local nets\n";
  print "\t[-s] skip\n";
  print "\t[-i] ip from\n";
  print "\t[-e] clean traffic class before insert\n";
  print "\t[-d] debug\n";
  exit (0);
};

#Load settings from config
open (CONFIG, "/netup/utm5/utm5.cfg");
@config = <CONFIG>;
close &#40;CONFIG&#41;;
foreach $line &#40;@config&#41; &#123;
  if &#40;$line =~ m/^&#40;&#91;^#&#93;.+?&#41;=&#40;.*&#41;$/&#41; &#123;
    $$1 = $2;
  &#125;;
&#125;;

# Connect to the database
if &#40;$database_type eq "mysql"&#41; &#123;
  $DBI_data="DBI&#58;$database_type&#58;database=$database;host=$database_host;mysql_socket=$database_sock_path;";
&#125; elsif &#40;$database_type eq "postgres"&#41; &#123;
  $DBI_data="DBI&#58;$database_type&#58;dbname=$database";
&#125; else &#123;
  print "Unknown database $database_type! Stopped. \n";
  exit &#40;1&#41;;
&#125;;
$dbh = DBI->connect&#40;"$DBI_data","$database_login","$database_password",&#123;'RaiseError' => 1&#125;&#41;;

%locals = &#40;&#41;;
$skip = &#40;$opt_s > 0&#41; ? 1 &#58; 0;
$opt_d = &#40;$opt_d > 0&#41; ? 1 &#58; 0;
$ip_from = &#40;$opt_i > 0&#41; ? $opt_i &#58; 0;
$ip_from = unpack&#40;"N",inet_aton&#40;$ip_from&#41;&#41;;
$ip_from = $ip_from > 2147483647 ? &#40;$ip_from - 0xFFFFFFFF - 1&#41;&#58;$ip_from;

# OPEN FILE AND PARSE
open &#40;NETS,"$opt_f"&#41;;
@nets1 = <NETS>;
close &#40;NETS&#41;;

# OPEN FILE AND PARSE
open &#40;NETS,"$opt_z"&#41;;
@nets2 = <NETS>;
close &#40;NETS&#41;;

if&#40;$opts&#123;e&#125;&#41;&#123;
        # erase all in tlcass
        if &#40;$opt_d&#41;
        &#123;
                print "DELETE FROM t_class_detail WHERE t_class_id='$opt_c'\n";
        &#125;
        else
        &#123;
                $dbh->do&#40;"DELETE FROM t_class_detail WHERE t_class_id='$opt_c'"&#41;;
        &#125;
&#125;;

foreach &#40;@nets1&#41;&#123;
  if &#40;$_ =~ m/^&#40;&#91;0-9&#93;*\.&#91;0-9&#93;*\.&#91;0-9&#93;*\.&#91;0-9&#93;*&#41;&#91;\/&#93;*&#40;&#91;0-9&#93;*&#41;&#91;\s\t&#93;+&#40;&#91;0-9&#93;*&#41;$/&#41; &#123;
    $net = "$1";
    $mask = &#40;$2 > 0&#41; ? "$2" &#58; "32";
    $port = &#40;$3 > 0&#41; ? "$3" &#58; "0";

        $bin_net = unpack&#40;"N",inet_aton&#40;$net&#41;&#41;;
        $bin_mask = unpack &#40;"N", pack&#40;"B32","1"x$mask . "0"x &#40;32-$mask&#41;&#41;&#41;;
        $bin_net =  $bin_net > 2147483647 ? &#40;$bin_net - 0xFFFFFFFF - 1&#41;&#58;$bin_net;
        $bin_mask =  $bin_mask > 2147483647 ? &#40;$bin_mask - 0xFFFFFFFF - 1&#41;&#58;$bin_mask;
        $bin_port = $port * 1;

        if&#40;$opts&#123;z&#125;&#41;&#123;
          foreach &#40;@nets2&#41;&#123;
            if &#40;$_ =~ m/^&#40;&#91;0-9&#93;*\.&#91;0-9&#93;*\.&#91;0-9&#93;*\.&#91;0-9&#93;*&#41;&#91;\/&#93;*&#40;&#91;0-9&#93;*&#41;&#91;\s\t&#93;+&#40;&#91;0-9&#93;*&#41;$/&#41; &#123;
              $net2 = "$1";
              $mask2 = &#40;$2 > 0&#41; ? "$2" &#58; "32";
              $port2 = &#40;$3 > 0&#41; ? "$3" &#58; "0";

              $bin_our_net = unpack&#40;"N",inet_aton&#40;$net2&#41;&#41;;
              $bin_our_net =  $bin_our_net > 2147483647 ? &#40;$bin_our_net - 0xFFFFFFFF - 1&#41;&#58;$bin_our_net;
              $bin_our_mask = unpack &#40;"N", pack&#40;"B32","1"x$mask2 . "0"x &#40;32-$mask2&#41;&#41;&#41;;
              $bin_our_mask =  $bin_our_mask > 2147483647 ? &#40;$bin_our_mask - 0xFFFFFFFF - 1&#41;&#58;$bin_our_mask;
              $bin_our_port = $port2 * 1;

              if &#40;$opts&#123;r&#125;&#41;&#123;
                insert_row&#40;$opt_c, $bin_our_net, $bin_our_mask, $bin_our_port, $bin_net, $bin_mask, $bin_port, $skip, $ip_from&#41;;
              &#125;else&#123;
                insert_row&#40;$opt_c, $bin_net, $bin_mask, $bin_port, $bin_our_net, $bin_our_mask, $bin_our_port, $skip, $ip_from&#41;;
              &#125;;
            &#125;;
          &#125;;
        &#125;
        else&#123;

        $bin_our_net = unpack&#40;"N",inet_aton&#40;$opt_n&#41;&#41;;
        $bin_our_mask = unpack&#40;"N",inet_aton&#40;$opt_m&#41;&#41;;
        $bin_our_net =  $bin_our_net > 2147483647 ? &#40;$bin_our_net - 0xFFFFFFFF - 1&#41;&#58;$bin_our_net;
        $bin_our_mask =  $bin_our_mask > 2147483647 ? &#40;$bin_our_mask - 0xFFFFFFFF - 1&#41;&#58;$bin_our_mask;
        $bin_our_port = $opt_p * 1;

        if&#40;$opts&#123;l&#125;&#41;&#123;
                # local nets !

                # rotating
                insert_row&#40;$opt_c, $bin_net, $bin_mask, $bin_port, $bin_net, $bin_mask, $bin_port, $skip, $ip_from&#41;;
                while &#40;&#40;$key, $value&#41; = each&#40;%locals&#41;&#41;&#123;
                        &#40;$bin_our_net, $bin_our_mask, $bin_our_port&#41; = split /&#91;\s\t&#93;+/, $value;
                        insert_row&#40;$opt_c, $bin_net, $bin_mask, $bin_port, $bin_our_net, $bin_our_mask, $bin_our_port, $skip, $ip_from&#41;;
                        insert_row&#40;$opt_c, $bin_our_net, $bin_our_mask, $bin_our_port, $bin_net, $bin_mask, $bin_port, $skip, $ip_from&#41;;
                &#125;;
                $locals&#123;$bin_net&#125; = "$bin_net $bin_mask $bin_port";
        &#125;else&#123;
                if &#40;$opts&#123;r&#125;&#41;&#123;
                        insert_row&#40;$opt_c, $bin_net, $bin_mask, $bin_port, $bin_our_net, $bin_our_mask, $bin_our_port,$skip, $ip_from&#41;;
                &#125;else&#123;
                        insert_row&#40;$opt_c, $bin_our_net, $bin_our_mask, $bin_our_port, $bin_net, $bin_mask, $bin_port,$skip, $ip_from&#41;;
                &#125;;
        &#125;;
        &#125;;
  &#125;;
&#125;;

sub insert_row&#123;
        my $tclass = shift;
        my $bin_net = shift;
        my $bin_mask = shift;
        my $bin_port = shift;
        my $bin_our_net = shift;
        my $bin_our_mask = shift;
        my $bin_our_port = shift;
        my $skip = shift;
        my $ip_from = shift;
        my $use_sport = &#40; $bin_port > 0 &#41; ? 1 &#58; 0;
        my $use_dport = &#40; $bin_our_port > 0 &#41; ? 1 &#58; 0;
        if &#40;$opt_d&#41;
        &#123;
                print "INSERT INTO t_class_detail&#40;t_class_id,saddr,saddr_mask,daddr,daddr_mask,sport,dport,use_sport,use_dport,skip,ip_from&#41; VALUES &#40;'$opt_c', '$bin_net', '$bin_mask', '$bin_our_net', '$bin_our_mask', '$bin_port', '$bin_our_port', '$use_sport', '$use_dport', '$skip', '$ip_from'&#41;\n"
        &#125;
        else
        &#123;
                $dbh->do&#40;"INSERT INTO t_class_detail&#40;t_class_id,saddr,saddr_mask,daddr,daddr_mask,sport,dport,use_sport,use_dport,skip,ip_from&#41; VALUES &#40;'$opt_c', '$bin_net', '$bin_mask', '$bin_our_net', '$bin_our_mask', '$bin_port', '$bin_our_port', '$use_sport', '$use_dport', '$skip', '$ip_from'&#41;"&#41;;
        &#125;
&#125;;
Последний раз редактировалось XoRe Вс фев 25, 2007 17:23, всего редактировалось 1 раз.

Аватара пользователя
XoRe
Сообщения: 458
Зарегистрирован: Ср янв 10, 2007 16:04

Сообщение XoRe »

Добавил пару фич, теперь скрипт делает все, что мне нужно.
Может кому-то ещё пригодится.
Код выше.

mavka
Сообщения: 84
Зарегистрирован: Вт ноя 13, 2007 20:13

Сообщение mavka »

$ip_from = $ip_from > 2147483647 ? ($ip_from - 0xFFFFFFFF - 1):$ip_from;
вот эта строка мне очень пригодилась, спасибо
Но вот по какой логике делать такими расчетами, а не просто int(11) unsigned и inet_aton?

Аватара пользователя
XoRe
Сообщения: 458
Зарегистрирован: Ср янв 10, 2007 16:04

Сообщение XoRe »

Хрен его знает =)
Я делал по принципу "чтоб работало".

Смею предположить, что это сделано по 2 причинам:
1. Чтоб можно было легко вытащить и преобразовать в ip адрес.
2. Разработчики utm тоже в свое время делали по принципу "чтоб работало" )

Закрыто