FastNetMon

Thursday 25 February 2016

Fake TCP service which accepts any connections

Sometimes for testing purposes (for example, tshark protocol capture) could be useful to run fake tcp service which receive all connections.

This task could be achieve with this code:

while true ;do nc -v -t -l -p 179 > /dev/null;done
Dependencies:
apt-get install -y netcat-traditional

How to filter out only BGP update or open messages with tshark?


Filter our BGP update messages:
tshark -i lo -n  -Y "bgp.type==2"
 Filter out BGP open messages:

tshark -i lo -n  -Y "bgp.type==1"

Tuesday 9 February 2016

Фильтрация по номеру vlan в tshark - почему не работает?

Итак, Вы изучили все дебри фильтров Wireshark и смогли написать фильтр для отображения только трафика с тегом vlan.

Итак, он выглядит примерно так:

tshark -n -i eth4 -c 1000 -Y "vlan"
Но он упорно не работает, хотя Вы четко уверены - vlan трафика там куча!

Вот решение:

ethtool -K eth4 rxvlan off
Вот так вот :) 

Как отключить относительные номера seq для tshark/wireshark

Всем, кто занимается глубокой работой с TCP, уверен, знакома проблема, что tshark/wireshark вместо реальных номеров seq (длиннющих чисел) отображает относительные (начинающиеся с нуля при старте сессии).

Это далеко не всегда нужно, поэтому будем отключать!

Было вот так:
tshark -r ../raw_packets_data/ip_packet_with_telnet_to_22_port_with_dropbear_from_mac_os_el_capitan.pcap -V |grep Seq    Sequence number: 0    (relative sequence number)


Стало:
tshark -r ../raw_packets_data/ip_packet_with_telnet_to_22_port_with_dropbear_from_mac_os_el_capitan.pcap -V -o "tcp.relative_sequence_numbers: FALSE" |grep seq -iTransmission Control Protocol, Src Port: 52500 (52500), Dst Port: ssh (22), Seq: 1133079759, Len: 0    Sequence number: 1133079759
Как можно видеть, помог нам флаг:  -o "tcp.relative_sequence_numbers: FALSE"

Monday 8 February 2016

Проблемы при использовании union и bit fields в C++

Очень часто, когда речь заходит об оптимизации потребления памяти и скорости обработки данных все вспоминают про битовые поля и union структуры.

Но, к сожалению, при их совместном использовании возможны очень неприятные проблемы, от которых довольно сложно защититься - кейс странный и неоднозначный.

Вот пример проблемного кода, который выглядит на первый взгляд нормально и корректно: https://gist.github.com/pavel-odintsov/71538a198a0ba53ea156

Для удобства привожу основную структуру данных здесь:
typedef union __attribute__((__packed__)) {
    uint16_t reserved_flag : 1, dont_fragment_flag : 1, more_fragments_flag : 1, fragment_offset : 13;
    uint16_t fragmentation_details_as_integer;
} fragmentation_details_t;

Как можно видеть, идея была в том, чтобы иметь доступ к блоку из 4х битовых полей как к одному 16 битному целому (для удобства операций и оптимизации).

Но на деле этот код работает вовсе не так. А работать он будет так, что все 5 переменных будут разделять общую память с одинаковым смещением! То есть, установив одно из однобитовых битовых полей мы сразу же установим все прочие - так как они использую один и тот же адрес.

Как выглядит верное решение данной задачи?

Выглядит оно так - нужно внести дополнительную структур:
typedef union __attribute__((__packed__)) {
     struct { uint16_t fragment_offset : 13, more_fragments_flag : 1, dont_fragment_flag : 1, reserved_flag : 1;
    } fragmentation_details_pretty;

    uint16_t fragmentation_details_as_integer;
} fragmentation_details_t;

Такой подход не так красив, как задуманный ранее, потому что С и С++ не позволяют делать анонимные структуры и добавляется отдельный уровень вложенности. Но вот задачу данный подход решает на отлично! 

Update: как подсказал Andrew Stromnov, можно сделать намного круче - использовать GCC расширение и сделать анонимную структуру:

typedef union __attribute__((__packed__)) {
  struct {
    uint16_t fragment_offset : 13, more_fragments_flag : 1, dont_fragment_flag : 1, reserved_flag : 1; };
    uint16_t fragmentation_details_as_integer
} fragmentation_details_t;

В таком случае при доступе к полям нам не нужно будет добавлять вложенную структуру! НА мой взгляд, это серьезное удобство и ради него я согласен пойти на использование расширений стандарта :) Хотя, вроде бы в С11 эта фича в стандарте! Но не в С++, увы, пока такой фичи в С++ нету.

Учтите, в режиме pedantic будут жалобы "../isolated_example.cpp:13:5: warning: ISO C++ prohibits anonymous structs [-Wpedantic]" и "warning: anonymous structs are a GNU extension [-Wgnu-anonymous-struct]".




Friday 5 February 2016

Запуск tshark без root привилегий

Почти каждый, кто пользовался tshark сталкивался со следующей штукой при запуске:
tshark: Lua: Error during loading:
 [string "/usr/share/wireshark/init.lua"]:46: dofile has been disabled due to running Wireshark as superuser. See http://wiki.wireshark.org/CaptureSetup/CapturePrivileges for help in running Wireshark as an unprivileged user.
Running as user "root" and group "root". This could be dangerous.
Почти всегда можно было обойтись без этой lua обвязки, но не тогда, когда Вам нужно сделать нечто поистине необычное с трафиком!

Но тут есть фишка, Wireshark (и tshark) используют отдельную программу для запуска захвата трафика и особые capabilities нужно навешивать не на /usr/bin/tshark, а на /usr/bin/dumpcap.

Итак, попробуем научить tshark работать не от root:
sudo groupadd wireshark
sudo usermod -a -G wireshark имя_вашего_юзера
# This command should be called without sudo!
newgrp wireshark
Выставляем заданные права на спец файл, используемый для запуск захвата трафика:
sudo chgrp wireshark /usr/bin/dumpcap
sudo chmod 750   /usr/bin/dumpcap
Наконец, выставляем полномочия для использования фичи захвата трафика:
sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap
Запускаемся:
tshark -i sflow1 -n  -c 1 Capturing on 'sflow1'  1   0.000000 xxx -> yyy TCP 64 34426 > 80 [ACK] Seq=1 Ack=1 Win=8712 Len=0


Thursday 4 February 2016

Как узнать, на какой позиции в файле находится приложение, читающее этот файл?

Вот сижу я бездельничаю в ожидании пока tshark прожует 8 гигабайтный pcap дамп.

Но tshark мало того, что тормозной, так еще и не дает никакой информации о прогрессе.

Но как добиться информации о прогрессе, если очень хочется?

Вспоминаем чудную книгу Linux API interfaces. Там как раз целая глава про файловые дескрипторы и что линукс внутри себя хранит позицию, на которой приложение читает файл!

Итак, достанем ее :)

Для начала узнаем, какие файлы открыты нашим приложением:
sudo ls -la /proc/4487/fd
total 0
dr-x------ 2 administrator administrator  0 февр.  4 18:11 .
dr-xr-xr-x 9 administrator administrator  0 февр.  4 18:08 ..
lrwx------ 1 administrator administrator 64 февр.  4 18:11 0 -> /dev/pts/4
l-wx------ 1 administrator administrator 64 февр.  4 18:11 1 -> pipe:[896628024]
lrwx------ 1 administrator administrator 64 февр.  4 18:11 2 -> /dev/pts/4
lr-x------ 1 administrator administrator 64 февр.  4 18:11 3 -> /dev/urandom

lr-x------ 1 administrator administrator 64 февр.  4 18:11 4 -> /megadump.pcap

Отлично, нам здесь нужна цифра 4 (это номер дескриптора нашего чудо-файла)!

Итак, получаем информацию о позиции чтения в файле:
cat /proc/4487/fdinfo/4 pos: 7641444352flags: 0100000mnt_id: 22
Получаем общий размер файла:
stat -c "%s" /megadump.pcap
8437696302
Ну что же, получим прогресс в процентах:
perl -e 'print scalar 8050094080/8437696302*100, " %\n"'95.4063027617132 %

Ну что же, обнадеживает! 

Host to enable full debug log in Bird routing daemon?

Just add this into configuration:
log "/var/log/debug.log" all;debug protocols all;
And change permissions for it:
touch  /var/log/debug.log
chmod 777 /var/log/debug.log

Wednesday 3 February 2016

Самый удобный способ использования Virtualbox - Vagrant

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

Но есть отличное решение, ускоряющее процесс в тысячи раз! Vagrant!

Сначала ставим VirtualBox,  это обязательно. Но запускать и что-либо делать внутри него нам не требуется :)

Потом ставим Vagrant под Вашу ОС (у меня MacOS): https://www.vagrantup.com/downloads.html

Далее указываем, Vagrant'у, что мы хотим - а хотим мы виртуальную машину на Убунту 14:
mkdir vagrant
cd vagrant
vagrant init ubuntu/trusty64
vagrant up
Весь процесс займет от силы 5-7 минут, после чего входим в свеже установленную машину машину:
vagrant ssh
Ура! Даже не придумаешь проще :)

Tuesday 2 February 2016

Что делать, если perf top забит вызовами vfprintf и у вас есть исходники провинившейся программы?

Я столкнулся с данной проблемой и исключительно just for fun попытался ее решать не внося правок в код.

Что же, это почти удалось.

Во-первых, я бы рекомендовал прочесть данный пост на тему ущербности дизайна sprintf/snprintf-like функций: http://blog.kazuhooku.com/2014/10/announcing-qrintf-and-qrintf-gcc.html

Решение очень простое, использовать препроцессор кода qrintf (https://github.com/h2o/qrintf) и заменить вызов gcc на вызов qrintf,  который в свою очередь автоматически заменит все вызовы snprintf на оптимизированные.

Оптимизированные выглядят страшно:
     as = (comval >> 16) & 0xFFFF;
      val = comval & 0xFFFF;
      _qrintf_chk_finalize (_qrintf_chk_d(_qrintf_chk_c(_qrintf_chk_d(_qrintf_chk_c(_qrintf_chk_init(buf + strlen (buf), BUFSIZ - strlen (buf))
            , ' '), as), ':'), val));
      break;
Но этот подход дает реальное ускорение кода где-то на 65%.

До:
real 2m12.445s
user 0m58.696s
sys 0m33.264s

После:
real 1m25.934s
user 0m33.288s
sys 0m26.848s

Ставим плюсики на репозитории qrintf и благодарим его автора :)

Размер полной BGP таблицы

По данным вики, в январе 2016 года было 600,000 префиксов.

А вот картинка с отображением динамики роста полной BGP таблицы до наших дней.
http://bgp.potaroo.net/

А вот актуальные в данный момент данные по размеру таблицы в цифрах: http://bgp.potaroo.net/index-bgp.html