Функция libpcap setfilter () и потеря пакетов - PullRequest
4 голосов
/ 02 декабря 2010

это мой первый вопрос здесь @ stackoverflow.

Я пишу инструмент мониторинга для некоторых производственных серверов VoIP, в частности инструмент анализа, который позволяет захватывать весь трафик (вызовы VoIP), который соответствует заданному шаблонуиспользуя библиотеку pcap в Perl.

Я не могу использовать плохие селективные фильтры, такие как, например, "udp", а затем выполнять всю фильтрацию в коде моего приложения, потому что это потребует слишком много трафика, а ядро ​​не справится с отчетным пакетом.потеря.

Что я делаю, так это итеративно создаю более избирательный фильтр, возможный во время захвата.Вначале я собираю только (все) сигнальный трафик SIP и фрагменты IP (сопоставление с образцом должно выполняться на уровне приложения в любом случае), затем, когда я нахожу некоторую информацию о RTP в пакеты SIP, я добавляю предложения 'или' кфактическая строка фильтра с определенными IP и PORT и переустановка фильтра с помощью setfilter ().

Так что в основном это выглядит примерно так:

  1. Исходный фильтр: "(udpи порт 5060) или (udp и ip [6: 2] & 0x1fff! = 0) "-> перехватывает весь SIP-трафик и фрагменты IP

  2. Обновленный фильтр:" (udp и порт5060) или (udp и ip [6: 2] & 0x1fff! = 0) или (IP-адрес хоста и порт PORT) "-> Записывает также RTP на определенный IP-адрес, PORT

  3. Обновлен фильтр: "(udp и порт 5060) или (udp и ip [6: 2] & 0x1fff! = 0) или (IP-адрес хоста и порт PORT) или (IP2 хоста и порт PORT2)" -> Захватывает второй поток RTPа также

и т. д.

Это работает довольно хорошо, так как я могу получить «реальную» потерю пакетов RTP streaмс для целей мониторинга, в то время как в случае плохой версии селективного фильтра моего инструмента процент потери пакетов RTP был ненадежным, поскольку некоторые пакеты отсутствовали из-за сброса пакетов ядром.

Но давайте перейдем к недостаткуэтого подхода.

Вызов setfilter () во время захвата включает в себя тот факт, что libpcap отбрасывает пакеты, полученные «при изменении фильтра», как указано в комментариях к коду для функции set_kernel_filter (), в pcap-linux.c (проверенная версия libpcap0.9 и 1.1).

Итак, когда я вызываю setfilter () и некоторые пакеты приходят фрагментированными по IP, я теряю некоторые фрагменты, и это не сообщается статистикой libpcap в конце: я заметилон копается в следах.

Теперь я понимаю причину, по которой это действие выполняет libpcap, но в моем случае мне определенно не нужно сбрасывать пакеты (меня не волнует получение некоторого несвязанного трафика).

Не могли бы вы знать, как решить эту проблему, которая не является модифицированной?Ин код libpcap?

Ответы [ 3 ]

1 голос
/ 04 декабря 2010

Можете ли вы просто захватить весь трафик RTP?

С фильтры захвата предложение для трафика RTP:

udp[1] & 1 != 1 && udp[3] & 1 != 1 && udp[8] & 0x80 == 0x80 && length < 250

Как указывает ссылка, вы получите несколько ложных срабатываний, где DNS и, возможно, другие UDP-пакеты иногда содержат байт заголовка, 0x80, используемый RTP-пакетами, однако это число должно быть незначительным и недостаточным, чтобы вызвать падение ядра. 1008 *

1 голос
/ 18 декабря 2010

Круглое отверстие, квадратный колышек.

У вас есть инструмент, который не совсем соответствует вашим потребностям.

Другим вариантом является создание фильтра первого уровня (как описано выше, который захватывает намного больше, чем нужно) и передача его в другой инструмент, который реализует более тонкий фильтр, который вы хотите (вплоть до случая для каждого вызова)).Если этот фильтр первого уровня слишком велик для ядра из-за интенсивного RTP-трафика, то вам может потребоваться сделать что-то еще, например, сохранить стабильность процессов для захвата отдельных вызовов (поэтому вы не меняете фильтр на «основном»).процесс, он просто инструктирует других, как устанавливать свои фильтры.)

Да, это может означать слияние захватов, либо на лету (передать их всем в процесс «сохранения захвата»), либо после факта.

Вы действительно понимаете, что вы все равно можете пропустить пакеты RTP, если не установите свои фильтры fast .Не забывайте, что RTP-пакеты могут поступить отправителю до того, как 200 OK придет (или сразу), и они могут вернуться к ответчику перед ACK (или поверх него).Также не забудьте ПРИГЛАСИТЬ без SDP (предложение в 200 OK, ответ в ACK).И т. Д.: -)

1 голос
/ 02 декабря 2010

Как насчет запуска нового процесса с более конкретным фильтром.Вы можете сделать два параллельных захвата PCAP одновременно.Через некоторое время (или проверка того, что оба получили одинаковые пакеты) вы можете остановить оригинал.

...