URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID1
Нить номер: 67447
[ Назад ]

Исходное сообщение
"Обработка файла статистики NetFlow"

Отправлено tuxper , 07-Июл-06 23:59 
Оцените следующий скрипт для обработки файла статистики. Цель определение мирового трафика от внутреннего. А также определение доменных имен.
Файл статистики называется traf.log, файл списка внутренних сетей называется KG.

#!/usr/bin/perl
#######################################
#  Script for statistic from NetFlow  #
#      May be used for statistic      #
#       from KyrgyzTelecom          #
#          Made by Tuxper.            #
#  Send all notes to me:              #
#                     tuxper@mail.ru  #
#######################################

use Socket;
print "What is your native IP? ";
$my_ip=<STDIN>;
chomp ($my_ip);
### Открываем traf.log и считываем dst IP: в файл dstip
system "grep 'dst IP:' traf.log > dstip" ||die "Can't create dstip file! $!\n";
### Открываем traf.log и считываем src IP: в файл srcip
system "grep 'src IP:' traf.log > srcip" ||die "Can't create srcip file! $!\n";    
### Открываем traf.log и считываем bytes:  в файл bytes
system "grep 'bytes:'  traf.log > bytes" ||die "Can't create bytes file! $!\n";    
open (SRC, "srcip")  || die "can't open srcip: $!\n";     
open (BYTES, "bytes")|| die "can't open bytes: $!\n";     
@src=<SRC>;
@bytes=<BYTES>;    
close (SRC);    
close (BYTE);    
$size_src=@src;    
$size_byte=@bytes;    
### Проверка на равенство строк файлов srcip и bytes
if ($size_src != $size_byte) {
    die "Количество строк srcip и bytes не равны! Процесс будет убит!\n";
}
### Создаем список IP-адресов хостов и байты, исключая наш IP-адрес (my_ip)
open (SRC_LIST, ">traf_list")|| die "Can't create traf_list! $!\n";
$i=0;
$lim=$size_src;
while ($i < $lim) {
    @ip=split(/\s+/,$src[$i]);
    $x=pop(@ip);
      @byt=split(/\s+/,$bytes[$i]);
      $y=pop(@byt);
        unless ($x eq $my_ip) {
              print SRC_LIST "$x\t$y\n";
    }
  $i=$i+1;
}
close (SRC_LIST);
### Отсортируем по одинаковым IP
system "sort traf_list > sorted_list" || die "Can't create sorted_list! $!\n";
### Добавить строчку END FILE в конец sorted_list, в дальнейшем она нам понадобиться
system "echo END FILE >> sorted_list" || die "can't add END FILE line to sorted_list: $!\n";
### Складываем байты с одинаковых IP
open (LIST, "sorted_list") || die "Can't open sorted_list: $!\n";
open (SUM, ">sum_list") || die "Can't create sum_list! $!\n";
@list=<LIST>;
close (LIST);
$i=0;
$lim=@list;
$byte_l=0;
chomp ($list[0]);
@ip_l=split (/\s+/, $list[0]);
$ip_l=shift(@ip_l);
### В этом цикде нам и понадобиться строчка END FILE, чтобы последний IPшник был также учтен
while ($i < $lim) {
       ($ip, $byte)=split(/\s+/, $list[$i]);
               if ($ip eq $ip_l) {
                       $byte_l=$byte_l+$byte;
               } else {
                       print SUM "$ip_l, $byte_l\n";
                       $ip_l=$ip;
                       $byte_l=$byte;
               }
       $i=$i+1;
}
close (SUM);
### Вычищаем зону kg, трафик с kg не учитываю. Механизм прост, разбиваем IP адрес на отдельные числа
###
open (SUM, "sum_list")|| die "Can't open sum_list! $!\n";    
open (KGNET, "kg")|| die "Can't open kg! $!\n";
### Мировые IP адреса будут хранится здесь
open (IPS, ">world_ips")|| die "Can't create world_list! $!\n";
@kg=<KGNET>;
close (KGNET);
@ips=<SUM>;
close (SUM);
$i=0;
$lim=@ips;
while ($i < $lim) {
    @ip=split (/\s+/,$ips[$i]);
    $y=shift(@ip); # IP адрес хоста
    $x=pop(@ip);   # Байты переданные
            ($ip_1, $ip_2, $ip_3)=split (/\./, $y);
    $k=0;
    $lim_kg=@kg;
    while ($k < $lim_kg) {
                ($kg_1, $kg_2, $kg_3, $kg_4)=split (/\./, $kg[$k]); ### Здесь, разбиваем IP адреса зоны kg
        chomp ($kg_1, $kg_2, $kg_3, $kg_4);
       ### Переменная $true защищает от проверки уже найденного адреса в зоне kg
         if ($true ne "yes") {
         ### Проверка по первому числу
                    if ($ip_1 eq $kg_1) {
            ### Проверка по второму числу
            if ($ip_2 eq $kg_2) {
                                ### сверяем значение подсети, для /20 и /19
                                if ($kg_4 eq "0/20") {
                     @kgs_3 = ($kg_3 .. $kg_3+15);
                }
                elsif ($kg_4 eq "0/19") {
                    @kgs_3 = ($kg_3 .. $kg_3+30);
                }
                $lim_3=@kgs_3;
                $l=0;
                                while ($l < $lim_3) {
                    if ($ip_3 eq $kgs_3[$l]) {
                             $true="yes";
                         }
                     $l=$l+1;
                 }
             }
            }
                    $k=$k+1;
                } else {
                $k=$k+1;
                }
            }
    if ($true ne "yes") {
    print IPS "$y\t$x\n";
    }
    $true="no";
    $i=$i+1;        
}
close (IPS);
### Переведем IP адреса в доменные имена, не все распознаются, но kg должен полностью.
open (IPS, "world_ips")||die "Can't open sum_list: $!\n";
open (HOSTS, ">hosts_list") || die "Can't create hosts_list! $!\n";
@ips=<IPS>;
close (IPS);
$i=0;
$lim=@ips;
while ($i<$lim) {
    @ip=split (/\s+/,$ips[$i]);
    $y=shift(@ip);
    $x=pop(@ip);
    my $packed_binary_addr = inet_aton($y);
    my $ip_name = gethostbyaddr( $packed_binary_addr, AF_INET );
        print HOSTS "$y\t$ip_name\t$x\n";
        $i=$i+1;
}
close (HOSTS);
### Подсчитаем общий объем трафика с мира
open (WORLD, "world_traf")||die "Can't open world_traf file: $!\n";
    while (<WORLD>) {
        @byte=split (/\s+/);
        $byte=pop(@byte);
        $bytes=$bytes+$byte;
    }
$kbyte=$bytes/1024;
print "$kbyte\n";
close (WORLD);
### Пихаем это все в формат.
open(WORLD, "world_traf")||die "Can't open world_traf file: $!\n";
while (<WORLD>) {
    ($ip, $host, $bytes)=(split /\t/)[0,1,2];
    write;
}
close (WORLD);
format STDOUT_TOP =
IP-address        Host                Bytes
================== =========================== =========
.
format STDOUT =
@<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<
$ip, $host, $bytes


Содержание

Сообщения в этом обсуждении
"Обработка файла статистики NetFlow"
Отправлено v.i.t , 08-Июл-06 13:12 
лучше укажи цифры
- сколько  времени обрабатывается лог размером 1Гб
- колличество внутренних сетей


"Обработка файла статистики NetFlow"
Отправлено tuxper , 08-Июл-06 14:36 
>лучше укажи цифры
>- сколько  времени обрабатывается лог размером 1Гб
>- колличество внутренних сетей

У меня лог был размером 215 Мб. Это составляло 8,5 млн строк всякой лабуды
Количество внутренних ip-сетей 10:
81.20.16.0/20
81.88.192.0/20
85.113.0.0/19
85.115.192.0/19
195.38.160.0/19
195.254.160.0/19
212.42.96.0/19
212.112.96.0/19
213.145.128.0/19
217.29.16.0/20

При таком раскладе, если из скрипта вычесть раздел определения доменных имен, то обработка такого лог файла составляла 3-4 минуты на среднем по мощности компьютере.
Точность подсчета зарубежного трафика потвердилась с провайдерской статистикой.

Но при определении доменных имен скрипт занимал продолжительный период времени... может сутки или полсуток, я ушел домой не вытерпел... =)

Вот в этом и заключается вся проблема... в gethostbyaddr... слишком долго он работает... =(