Login Form  

   

Задача: Получить и обработать данные с сенсора netflow v9.

 

Подготовка

Запускаем уже полюбившийся скрипт и захватываем первый пакет, переданный от маршрутизатора:

#!/usr/bin/perl
use IO::Socket::INET;
$| = 1;
my ($socket,$received_data);
my ($peeraddress,$peerport);
$socket = new IO::Socket::INET (
LocalPort => '9999',
Proto => 'udp',
) or die "ERROR in Socket Creation : $!\n";
while(!$recieved_data)
{
$socket->recv($recieved_data,4096);
}

open (MYFILE, '>data.txt');
print MYFILE $recieved_data;
close (MYFILE);

$socket->close();
Анализ

Видим, что нам передалось 1412 байт информации. Вооружаемся спецификацией протокола v9 и смотрим:

00 09 00 1C  93 70 9C B4  51 6B 86 18  00 00 43 6B  00 00 00 00  00 00 00 5C  01 00 00 15  00 15 00 04  00 16 00 04  00 01 00 04  00 02 00 04  00 0A 00 02
00 0E 00 02  00 08 00 04  00 0C 00 04  00 04 00 01  00 05 00 01  00 07 00 02  00 0B 00 02  00 30 00 01  00 33 00 01  00 0F 00 04  00 0D 00 01  00 09 00 01
00 06 00 01  00 3D 00 01  00 11 00 02  00 10 00 02  01 00 05 14  93 70 5B 78  93 70 5B 78  00 00 00 3B  00 00 00 01  00 0B 00 06  0A 4F 24 DD  0A 4F E2 33
11 00 E1 B9  00 35 00 00  C0 A8 22 1D  14 18 10 01  00 00 00 00  93 70 5B 80  93 70 5B 80  00 00 00 96  00 00 00 01  00 06 00 0B  0A 4F E2 33  0A 4F 24 DD
11 00 00 35  E1 B9 00 00  0A 4F 24 DD  18 14 10 00  00 00 00 00  93 70 5B 80  93 70 5B 80  00 00 00 3B  00 00 00 01  00 0B 00 06  0A 4F 24 DD  0A 4F E2 33
11 00 F9 3B  00 35 00 00  C0 A8 22 1D  14 18 10 01  00 00 00 00  93 70 5B 84  93 70 5B 84  00 00 00 96  00 00 00 01  00 06 00 0B  0A 4F E2 33  0A 4F 24 DD
11 00 00 35  F9 3B 00 00  0A 4F 24 DD  18 14 10 00  00 00 00 00  93 70 5F 94  93 70 5B 88  00 00 00 90  00 00 00 03  00 0B 00 06  0A 4F 24 DD  83 FD 22 CF
06 00 CE 7E  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00  93 70 5C 50  93 70 5B C4  00 00 02 BC  00 00 00 02  00 0E 00 06  0A 4F 27 51  0A 4F E3 67
06 00 07 71  1F 90 00 00  C0 A8 22 1D  14 18 18 01  00 00 00 00  93 70 5F 44  93 70 5B C4  00 00 00 9C  00 00 00 03  00 0D 00 06  0A 4F 26 EF  5F A7 8B 06
06 00 0F D9  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00  93 70 5B E0  93 70 5B D0  00 00 0C 81  00 00 00 05  00 06 00 0B  0A 4F E3 67  0A 4F 24 14
06 00 1F 90  0D 56 00 00  0A 4F 24 14  18 14 1A 00  00 00 00 00  93 70 5C 04  93 70 5B EC  00 00 01 80  00 00 00 04  00 0D 00 06  0A 4F 26 5C  0A 4F E2 32
11 00 00 89  00 89 00 00  C0 A8 22 1D  14 18 10 01  00 00 00 00  93 70 5C 0C  93 70 5B F4  00 00 01 68  00 00 00 04  00 06 00 0D  0A 4F E2 32  0A 4F 26 5C
11 00 00 89  00 89 00 00  0A 4F 26 5C  18 14 10 00  00 00 00 00  93 70 5C 4C  93 70 5C 4C  00 00 03 06  00 00 00 02  00 06 00 0E  0A 4F E3 67  0A 4F 27 51
06 00 1F 90  07 71 00 00  0A 4F 27 51  18 14 18 00  00 00 00 00  93 70 5C 54  93 70 5C 54  00 00 00 45  00 00 00 01  00 0E 00 06  0A 4F 27 7D  0A 4F E2 32
11 00 F3 0C  00 35 00 00  C0 A8 22 1D  14 18 10 01  00 00 00 00  93 70 60 DC  93 70 5C 58  00 00 00 98  00 00 00 03  00 0D 00 06  0A 4F 26 37  3E 80 64 4F
06 00 CC 7E  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00  93 70 5C 5C  93 70 5C 5C  00 00 00 55  00 00 00 01  00 06 00 0E  0A 4F E2 32  0A 4F 27 7D
11 00 00 35  F3 0C 00 00  0A 4F 27 7D  18 14 10 00  00 00 00 00  93 70 5C 64  93 70 5C 60  00 00 01 73  00 00 00 02  00 06 00 0E  0A 4F E3 67  0A 4F 27 4E
06 00 1F 90  05 89 00 00  0A 4F 27 4E  18 14 18 00  00 00 00 00  93 70 5C 64  93 70 5C 64  00 00 00 28  00 00 00 01  00 0E 00 06  0A 4F 27 4E  0A 4F E3 67
06 00 05 89  1F 90 00 00  C0 A8 22 1D  14 18 10 01  00 00 00 00  93 70 5C 74  93 70 5C 70  00 00 02 B6  00 00 00 02  00 0E 00 06  0A 4F 27 4E  0A 4F E3 67
06 00 05 3C  1F 90 00 00  C0 A8 22 1D  14 18 18 01  00 00 00 00  93 70 5C 7C  93 70 5C 7C  00 00 00 28  00 00 00 01  00 06 00 0E  0A 4F E3 67  0A 4F 27 4E
06 00 1F 90  05 3C 00 00  0A 4F 27 4E  18 14 10 00  00 00 00 00  93 70 60 54  93 70 5C 88  00 00 00 9C  00 00 00 03  00 0D 00 06  0A 4F 26 24  53 E5 AD 03
06 00 0D BE  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00  93 70 5C 94  93 70 5C 94  00 00 00 1E  00 00 00 01  00 0E 00 06  0A 4F 27 68  CA B1 D8 EC
11 00 DB A4  07 D1 00 00  C0 A8 22 1D  00 18 10 01  00 00 00 00  93 70 5C C4  93 70 5C B0  00 00 0C 9D  00 00 00 06  00 06 00 0B  0A 4F E3 67  0A 4F 24 14
06 00 1F 90  0D 5A 00 00  0A 4F 24 14  18 14 1A 00  00 00 00 00  93 70 5C B8  93 70 5C B8  00 00 00 3B  00 00 00 01  00 0B 00 06  0A 4F 24 D1  0A 4F E2 0A
11 00 FA 7D  00 35 00 00  C0 A8 22 1D  14 18 10 01  00 00 00 00  93 70 60 C8  93 70 5C C0  00 00 00 98  00 00 00 03  00 0E 00 06  0A 4F 27 70  83 FD 22 CF
06 00 C6 F1  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00  93 70 5E 80  93 70 5C D4  00 00 01 65  00 00 00 02  00 0D 00 06  0A 4F 26 D3  0A 4F E3 67
06 00 0B B0  1F 90 00 00  C0 A8 22 1D  14 18 18 01  00 00 00 00  93 70 60 FC  93 70 5C E0  00 00 00 98  00 00 00 03  00 0B 00 06  0A 4F 24 E2  83 FD 22 CF
06 00 DA 21  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00  93 70 60 F4  93 70 5C EC  00 00 00 98  00 00 00 03  00 0E 00 06  0A 4F 27 6C  83 FD 22 CF
06 00 F2 E0  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00  93 70 60 F8  93 70 5C F0  00 00 00 98  00 00 00 03  00 0B 00 06  0A 4F 24 D8  83 FD 22 CF
06 00 C6 CC  00 50 00 00  C0 A8 22 1D  00 18 02 01  00 00 00 00

Первые 5х32 бит это заголовок, в котором указаны следующие данные:
00 09 — версия протокола
00 1D — количество записей, включая шаблон и данные.
93 70 9C B4 — Время в миллисекундах с начала запуска устройства.
51 6B 86 18 — Время в секундах с начала эпохи.
00 00 43 6B — Номер последовательности. Счетчик, который позволяет вычислить потери.
00 00 00 00 — идентификатор устройства.

Заметьте! Отказались от наносекунд!

Далее идет передача шаблонов и данных. Разберем по порядку.
00 00 — FlowSet ID. Идентификатор записи. Используется для того что бы различать заголовки от записей. 0 — означает, что это заголовок. Остальное — данные. В данном случае у нас заголовок;
00 5C — Размер заголовка. Точнее его описательной части. То есть 92 байта будут посвящены описанию данных;
01 00 — Идентификатор шаблона;
00 15 — Количество полей в таблице; Следующие 84 байта (0x15 * 4 -> 21 * 4 = 84)

  1. 00 15 00 04 — поле типа LAST_SWITCHED, 4 байта
  2. 00 16 00 04 — поле типа FIRST_SWITCHED, 4 байта
  3. 00 01 00 04 — IN_BYTES, 4 байт
  4. 00 02 00 04 — IN_PKTS, 4 байт
  5. 00 0A 00 02 — INPUT_SNMP, 2 байта
  6. 00 0E 00 02 — OUTPUT_SNMP, 2 байта
  7. 00 08 00 04 — IPV4_SRC_ADDR, 4 байт
  8. 00 0C 00 04 — IPV4_DST_ADDR, 4 байт
  9. 00 04 00 01 — PROTOCOL, 1 байт
  10. 00 05 00 01 — SRC_TOS, 1 байт
  11. 00 07 00 02 — L4_SRC_PORT, 2 байта
  12. 00 0B 00 02 — L4_DST_PORT, 2 байта
  13. 00 30 00 01 — FLOW_SAMPLER_ID, 1 байт
  14. 00 33 00 01 — *Vendor Proprietary*, 1 байт
  15. 00 0F 00 04 — IPV4_NEXT_HOP, 4 байт
  16. 00 0D 00 01 — DST_MASK, 1 байт
  17. 00 09 00 01 — SRC_MASK, 1 байт
  18. 00 06 00 01 — TCP_FLAGS, 1 байт
  19. 00 3D 00 01 — DIRECTION, 1 байт
  20. 00 11 00 02 — DST_AS, 2 байт
  21. 00 10 00 02 — SRC_AS, 2 байт

Данные взяты из таблицы соответствий протокола netflow v9 (см табл №6)
Итак фактически мы выхватили описательную часть шаблона для протокола IPv4. По структуре очень похоже на структуру таблицы netflow v5 с некоторыми дополнениями.

Далее очевидно идут данные. Так как в заголовке 01 00 — номер шаблона, который был только что описан (вполне себе ожидаемо). Итак разберем структуру данных.
01 00 — Номер шаблона;
05 14 — Размер данных (1300 байт);

  1. 93 70 5B 78 — время окончания передачи данных;
  2. 93 70 5B 78 — время начала передачи данных;
  3. 00 00 00 3B — байты;
  4. 00 00 00 01 — пакеты;
  5. 00 0B — входящий интерфейс;
  6. 00 06 — исходящий интерфейс;
  7. 0A 4F 24 DD — IP источника (отправитель);
  8. 0A 4F E2 33 — IP назначения (получатель);
  9. 11 — Протокол (в данном случае 17 — UDP);
  10. 00 — TOS (тип сервиса);
  11. E1 B9 — порт источника (отправитель);
  12. 00 35 — порт назначения (получатель);
  13. 00 — идентификатор сэмплера;
  14. 00 — типа байт, добавленный производителем, но мы то знаем что добавили чисто для эстетики и удобочитаемости В данном случае будет 0 всегда.
  15. C0 A8 22 1D — IP адрес маршрутизатора;
  16. 14 — маска назначения (получатель);
  17. 18 — маска источника (отправитель);
  18. 10 — TCP флаг;
  19. 01 — направление пакета. 0 — входяший, 1 — исходящий;
  20. 00 00 — номер автономной системы назначения
  21. 00 00 — номер автономной системы источника
Дополнительные данные

У меня под рукой был ASA5520, раздающий интернет. И для закрепления я решил снять данные и с него. Сначала полученные данные меня очень смутили. Но затем они мне дали более полное понимание сути netflow v9.

00 09 00 0D  ED 3D DD 50  51 72 08 7D  00 00 00 0D  00 00 00 00  00 00 03 E0  01 00 00 15  00 94 00 04  00 08 00 04  00 07 00 02  00 0A 00 02
00 0C 00 04  00 0B 00 02  00 0E 00 02  00 04 00 01  00 B0 00 01  00 B1 00 01  9C 41 00 04  9C 42 00 04  9C 43 00 02  9C 44 00 02  9C 45 00 01
80 EA 00 02  01 43 00 08  00 55 00 04  80 E8 00 0C  80 E9 00 0C  9C 40 00 14  01 01 00 15  00 94 00 04  00 08 00 04  00 07 00 02  00 0A 00 02
00 0C 00 04  00 0B 00 02  00 0E 00 02  00 04 00 01  00 B0 00 01  00 B1 00 01  9C 41 00 04  9C 42 00 04  9C 43 00 02  9C 44 00 02  9C 45 00 01
80 EA 00 02  01 43 00 08  00 55 00 04  80 E8 00 0C  80 E9 00 0C  9C 40 00 41  01 02 00 11  00 94 00 04  00 1B 00 10  00 07 00 02  00 0A 00 02
00 1C 00 10  00 0B 00 02  00 0E 00 02  00 04 00 01  00 B2 00 01  00 B3 00 01  9C 45 00 01  80 EA 00 02  01 43 00 08  00 55 00 04  80 E8 00 0C
80 E9 00 0C  9C 40 00 14  01 03 00 11  00 94 00 04  00 1B 00 10  00 07 00 02  00 0A 00 02  00 1C 00 10  00 0B 00 02  00 0E 00 02  00 04 00 01
00 B2 00 01  00 B3 00 01  9C 45 00 01  80 EA 00 02  01 43 00 08  00 55 00 04  80 E8 00 0C  80 E9 00 0C  9C 40 00 41  01 04 00 12  00 08 00 04
00 07 00 02  00 0A 00 02  00 0C 00 04  00 0B 00 02  00 0E 00 02  00 04 00 01  00 B0 00 01  00 B1 00 01  9C 41 00 04  9C 42 00 04  9C 43 00 02
9C 44 00 02  9C 45 00 01  80 EA 00 02  01 43 00 08  80 E8 00 0C  80 E9 00 0C  01 05 00 0E  00 08 00 04  00 07 00 02  00 0A 00 02  00 0C 00 04
00 0B 00 02  00 0E 00 02  00 04 00 01  00 B0 00 01  00 B1 00 01  9C 45 00 01  80 EA 00 02  01 43 00 08  80 E8 00 0C  80 E9 00 0C  01 06 00 0E
00 1B 00 10  00 07 00 02  00 0A 00 02  00 1C 00 10  00 0B 00 02  00 0E 00 02  00 04 00 01  00 B2 00 01  00 B3 00 01  9C 45 00 01  80 EA 00 02
01 43 00 08  80 E8 00 0C  80 E9 00 0C  01 07 00 12  00 94 00 04  00 08 00 04  00 07 00 02  00 0A 00 02  00 0C 00 04  00 0B 00 02  00 0E 00 02
00 04 00 01  00 B0 00 01  00 B1 00 01  9C 41 00 04  9C 42 00 04  9C 43 00 02  9C 44 00 02  9C 45 00 01  80 EA 00 02  01 43 00 08  00 55 00 04
01 08 00 0E  00 94 00 04  00 1B 00 10  00 07 00 02  00 0A 00 02  00 1C 00 10  00 0B 00 02  00 0E 00 02  00 04 00 01  00 B2 00 01  00 B3 00 01
9C 45 00 01  80 EA 00 02  01 43 00 08  00 55 00 04  01 09 00 16  00 94 00 04  00 08 00 04  00 07 00 02  00 0A 00 02  00 0C 00 04  00 0B 00 02
00 0E 00 02  00 04 00 01  00 B0 00 01  00 B1 00 01  9C 41 00 04  9C 42 00 04  9C 43 00 02  9C 44 00 02  9C 45 00 01  80 EA 00 02  01 43 00 08
00 55 00 04  00 98 00 08  80 E8 00 0C  80 E9 00 0C  9C 40 00 14  01 0A 00 16  00 94 00 04  00 08 00 04  00 07 00 02  00 0A 00 02  00 0C 00 04
00 0B 00 02  00 0E 00 02  00 04 00 01  00 B0 00 01  00 B1 00 01  9C 41 00 04  9C 42 00 04  9C 43 00 02  9C 44 00 02  9C 45 00 01  80 EA 00 02
01 43 00 08  00 55 00 04  00 98 00 08  80 E8 00 0C  80 E9 00 0C  9C 40 00 41  01 0B 00 12  00 94 00 04  00 1B 00 10  00 07 00 02  00 0A 00 02
00 1C 00 10  00 0B 00 02  00 0E 00 02  00 04 00 01  00 B2 00 01  00 B3 00 01  9C 45 00 01  80 EA 00 02  01 43 00 08  00 55 00 04  00 98 00 08
80 E8 00 0C  80 E9 00 0C  9C 40 00 14  01 0C 00 12  00 94 00 04  00 1B 00 10  00 07 00 02  00 0A 00 02  00 1C 00 10  00 0B 00 02  00 0E 00 02
00 04 00 01  00 B2 00 01  00 B3 00 01  9C 45 00 01  80 EA 00 02  01 43 00 08  00 55 00 04  00 98 00 08  80 E8 00 0C  80 E9 00 0C  9C 40 00 41

Первые 5х32 бит заголовка сами по себе ничего нового мне не сказали.
00 09 — версия протокола
00 0D — количество записей, включая шаблон и данные.
ED 3D DD 50 — Время в миллисекундах с начала запуска устройства.
51 72 08 7D — Время в секундах с начала эпохи.
00 00 00 0D — Номер последовательности. Счетчик, который позволяет вычислить потери.
00 00 00 00 — идентификатор устройства.
Тут все понятно. Но дальнейшее ввело меня в ступор:
00 00 — это передача шаблона
03 E0 — размер шаблона 992 байта. То есть весь пакет это шаблон!
01 00 — описание шаблона 0x100
00 15 — кол-во записей 21
… после описания полей шаблона, началось описание другого шаблона. 01 01 00 15 — шаблон 0х101, в котором тоже 21 поле.
В общем этот пакет содержал в себе только заголовки шаблонов. Учтем это на будущее. Так же стоит учесть, что одинаковые номера шаблонов даже в Cisco совсем не означают какую то схожесть. Фактически нам Router в 9й версии протокола передал данные для IPv4 почти в том же виде, что в версии 5. — Разработчики особо морочиться не стали. Зато шаблон ASA отличается весьма ощутимо.
Кстати кое что общее между шаблонами 0х100 есть. Они оба описывают IPv4.
И да: Похоже к разработке netflow v9 подпустили SQL разработчиков. т.к. чувствуется рука мастера.

Кодирование

С чего начать?.. Проще и правильней разбить программу на составляющие. Для начала считаем данные.

#!/usr/bin/perl
use IO::Socket::INET;
use POSIX;
use feature qw { switch };
# Initialisation
$| = 1;
%templates_fmt = ();
%templates = ();
my ($socket,$received_data);
my ($peeraddress,$peerport);
#Opening Socket
$socket = new IO::Socket::INET (
        LocalPort => '9999',
        Proto => 'udp',
) or die "ERROR in Socket Creation : $!\n";
#Reading socket
while(1) {
my ($recieved_data);
#while((!$recieved_data) || (length($recieved_data) == 1416)) {
while(!$recieved_data) {
        $socket->recv($recieved_data,4096);
        $peer_address = unpack("N", $socket->peeraddr());
}
        $version = unpack("n", substr($recieved_data,0,2));
        given ( $version ) {
                when ( 5 ) { fv5($recieved_data,$peer_address); }
                when ( 9 ) { fv9($recieved_data,$peer_address); }
        }
}
#Closing Socket
$socket->close();

Тут я думаю все просто и расшифровывать не надо. Порт читается, данные направляются в зависимости от версии протокола. При такой конструкции мы можем принимать на порт все что ни попадя.

Далее обработаем пятую версию. По ней я особо комментировать ничего не буду. Тема достаточно раскрыта в предыдущей статье.

sub fv5 {
        my (@header) = unpack("nnN4NNNHHH2", substr($_[0],0,24));
        for ($i=0; substr($_[0], 24+48*$i, 48); $i++) {
                @substr = unpack("N3n2N4n2C4n2C2n", substr($_[0], 24+48*$i, 48));
                $fmt = "%08x0100 %08x%08x %08x %08x %08x %02x %02x %08x %08x %s %s %04x %04x %02x %02x %02x %02x %04x %04x %02x %02x %02x\n";
                printf ("$fmt", $_[1], $header[3], $header[2], @substr);
        }
}

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

sub fv9 {
        @header = unpack("n2N4", substr($_[0],0,20));
        my ($marker) = 20;
        for ($i=0; $i < $header[1]; $i++) {
                @template_id = unpack("n2", substr($_[0],$marker,4));
                if ($template_id[0] == 0) {
                        $i += &fv9_templates(substr($_[0], $marker+4, $template_id[1]-4),$_[1], $template_id[1]);
                } else {
                        $i += &fv9_records(substr($_[0], $marker+4, $template_id[1]-4), $_[1], $template_id[0], $template_id[1], $header[3], $header[2]);
                }
                $marker += $template_id[1];
        }
#       print $marker . " bytes in ", $i+1, " records processed\n";
}

Если у нас пришли данные по шаблонам, обработаем их в следующей процедуре.

sub fv9_templates {
        my (@template_id, @template_val, @templates_id, @templates_val);
        my ($marker, $field_count) = 0;
        my ($i,$j) = -1;
        if (exists($templates{"$_[1]"})) {
                @templates_val = split(",", $templates{"$_[1]"});
                @template_val = split(",", $templates_fmt{"$_[1]"});
        } else {
                @templates_val = ();
                @template_val = ();
        }
        my ($count) = $_[2];
        while ($count>4) {
                @templates_id = unpack("n2", substr($_[0],$marker,4));
                $templates_val[$templates_id[0]] = unpack("H".($templates_id[1]*8+8), substr($_[0],$marker,($templates_id[1]*4+4)));
                $templates {"$_[1]"} = join (",", @templates_val);
                my ($template, $template_len) = "";
                $field_count = hex(substr($templates_val[$templates_id[0]],4,4));
                for ($j=1; $j<=$field_count; $j++) {
                        $template .= "H".(hex(substr($templates_val[$templates_id[0]],$j*8+4,4))*2);
                        $template_len += hex(substr($templates_val[$templates_id[0]],$j*8+4,4));
                }
                $template_val[$templates_id[0]] = sprintf "%04x$template", $template_len;
                $templates_fmt {"$_[1]"} = join(",", @template_val);
                $count -= $templates_id[1]*4+4;
                $marker += $templates_id[1]*4+4;
                $i++;
        }
return $i;
};

Если пришли данные, то обработаем их в следующей подпрограмме:

sub fv9_records {
        my (@template_id);
        my ($template, $template_len, $j);
        if (exists($templates{"$_[1]"})) {
                my (@template_val) = split(",", $templates_fmt{"$_[1]"});
                if (exists($template_val[$_[2]])) {
                        $template_len = hex(substr($template_val[$_[2]],0,4));
                        $template = substr($template_val[$_[2]],4,length($template_val[$_[2]]));
                        $record_count = (length($_[0])-4)/$template_len;
                        for ($j=0; $j<$record_count; $j++) {
                                my (@mass) = unpack("$template", substr($_[0],$j*$template_len,$template_len)), "\n";
                                printf "%08x%04x %04x%04x @mass\n",$_[1],$_[2],$_[4],$_[5];
                        }
                };
        } else {
                last;
        }
return $j-1;
};

Ну вот собственно и весь коллектор. Конечно это не совсем коллектор. Эта программа будет выводить все на экран в шеснадцатеричном виде. Но в функционале заложен задел под SQL базу.
На мой взгляд крайне желательно хранить данные упакованными, так они будут занимать меньше дискового пространства.
Еще пришлось добавить дополнительное поле, в котором содержится время получения данных. Это связанно с тем, что далеко не всегда в полученных данных может иметься информация о времени и вычисление таких полей даст дополнительную нагрузку на процессор.
Скрипт работал всю ночь, на него спаммили устройства с разными версиями Netflow и вроде он отработал нормально. (память не съел). Признаюсь честно: код весьма далек от совершенства. И оптимизировать его очень желательно. т.к. когда я посмотрел чем сыпет Asa5520 плюс пара роутеров, я серьезно задумался об этом — поток был нешуточный, а средняя нагрузка на процессор — 10-15%.
Еще я думал о утилизации оперативной памяти. Думаю, что неплохо будет сперва загонять данные в память, а при наборе нужного объема — выгружать их. В общем будем думать…

Вывод:
Netflow v9 обладает огромным потенциалом и гибкостью, но он очень тяжел для сети и процессора. Лично я бы рекоммендовал использовать пятую версию там/пока это возможно. Конечно, если у вас ASA (в функционале которой только 9 версия) или вы уже работаете с протоколом IPv6, ну или вам необходима статистика не только по переданным данным, то конечно без Netflow v9 вам не обойтись.
Пятой версии протокола я пожалуй дам сроку 3-4 года. Потом он потеряет свою востребованность.

Список литературы:
1. NetFlow Version 9 Flow-Record Format
2. IP Flow Information Export (IPFIX) Entities
3. http://perldoc.perl.org/

   
© it-answer.ru