это мой первый вопрос здесь @stackoverflow.Функция libpcap setfilter() и потеря пакетов
Я пишу инструмент мониторинга для некоторых серверов производства VoIP, особенно инструмент для обнюхивания, который позволяет захватывать весь трафик (VoIP-вызовы), который соответствует заданному шаблону, используя библиотеку pcap в Perl.
Я не могу использовать плохие избирательные фильтры, например, «udp», а затем выполнить всю фильтрацию в коде моего приложения, потому что это будет связано с слишком большим объемом трафика, и ядро не справится с сообщением о потере пакетов.
Что я делаю тогда, чтобы итеративно создавать более избирательный фильтр во время захвата. Вначале я фиксирую только (все) SIP-сигнальный трафик и IP-фрагменты (совпадение шаблонов должно выполняться на уровне приложения в любом случае), тогда, когда я нахожу некоторую информацию о RTP в SIP-пакетах, я добавляю предложения или предложения к фактическую строку фильтра с конкретными IP и PORT и повторно установить фильтр с помощью setfilter().
Так что в основном что-то вроде этого:
Начальный фильтр "(УДП и порт 5060) или (УДП и ф [6: 2]! & 0x1FFF = 0)" -> захватывает все SIP трафика и IP-фрагменты
Изменено фильтр: -> Захватывает также RTP на: "(ОДП и порт 5060) или или (хост IP и порт PORT) (ОДП и ф [6 2] & 0x1FFF = 0!)" конкретный IP, PORT
Обновлен фильтр: "(udp и порт 5060) или (udp и ip [6: 2] & 0x1fff! = 0) или (хост IP и порт PORT) или (хост IP2 и порт PORT2) "-> Захватывает второй поток RTP, а также
И так далее.
Это работает достаточно хорошо, так как я могу получить «реальную» потерю пакетов потоков RTP для целей мониторинга, тогда как при плохой выборочной версии фильтра моего инструмента процент потерь RTP-пакетов был ненадежным, некоторые пакеты отсутствовали из-за падения пакета по ядру.
Но давайте обратимся к недостатку этого подхода.
Вызов setfilter() во время захвата включает в себя тот факт, что libpcap отбрасывает пакеты, полученные «при смене фильтра», как указано в комментариях кода для функции set_kernel_filter() в pcap-linux.c (проверены версии libpcap версии 0.9 и 1.1).
Итак, что происходит, когда я вызываю setfilter(), и некоторые пакеты поступают в IP-фрагментацию, я теряю некоторые фрагменты, и об этом не сообщается статистикой libpcap в конце: я заметил, что он копает в следы.
Теперь я понимаю причину, по которой это действие выполняется libpcap, но в моем случае мне определенно не нужно отказываться от пакета (я не хочу получать какой-то несвязанный трафик).
У вас есть идея по решению этой проблемы, которая не изменяет код libpcap?
Привет, спасибо за ответ. Я думал о нерестационных процессах каждый раз, когда нужен «новый фильтр», но в итоге я получаю довольно много процессов, а также задачу слияния захватов в конце. Честно говоря, это было то, чего я бы избегал ..: P – Guido 2010-12-03 10:06:18