Каковы возможные коды возврата bpf_filter() в ядре FreeBSD? Что означает каждый код возврата?

Каковы возможные коды возврата bpf_filter() в ядре FreeBSD?

Что означает каждый код возврата?

справочная страница (ссылка) в этом вопросе не ясно.

Функция bpf_filter() выполняет программу фильтрации, начиная с pc в пакете pkt. Аргумент wirelen — это длина исходного пакета, а buflen — количество имеющихся данных. Значение buflen 0 является особым; это указывает, что pkt на самом деле является указателем на цепочку mbuf (struct mbuf *).

Возвращаемые значения

Функция bpf_filter() возвращает -1 (приведение к целому числу без знака), если фильтр отсутствует. В противном случае он возвращает результат программы фильтра.

Я получаю 65535, когда есть совпадение, и 0, когда совпадений нет. Не уверен, что означает возвращаемое значение 65535.

Может кто-нибудь подробно объяснить код возврата bpf_filter()?


person KrishnamRaju raju    schedule 25.08.2016    source источник


Ответы (2)


Возвращаемое значение bpf_filter() является результатом работы программы фильтра. Результатом является число байтов отфильтрованного пакета, которые необходимо скопировать в буфер для задачи (значение инструкции возврата фильтра).

Значение будет равно 0, если пакет не соответствует фильтру. Если пакет соответствует фильтру, это будет длина моментального снимка (snaplen), которая была определена в вызове pcap_open_.

Значение по умолчанию — 65 535 байт, поскольку максимальный размер TCP-пакета — 64 КБ (65 535 байт).

person C.Sutherland    schedule 31.08.2017

Функция bpf_filter() принимает в качестве аргумента указатель на структуру, содержащую инструкции BPF (pc на справочной странице), и запускает их на пакетах для их фильтрации.

Функция bpf_filter() возвращает -1 (приведение к целому числу без знака), если фильтр отсутствует.

Мы можем проверить в исходном коде что когда pc, структура, которая должна содержать инструкции BPF, имеет значение null, тогда bpf_filter() немедленно возвращает -1, преобразованное в u_int:

if (pc == 0)
    /*
     * No filter means accept all.
     */
    return (u_int)-1;

[Отредактировано] Внутренне для целого числа со знаком -1 будет храниться как «максимальное значение целого числа минус один». С 32 битами, поскольку здесь возвращаемое значение приводится к целому числу без знака, это будет 2^32 - 1.
Поскольку здесь возвращаемое значение приводится к целому числу без знака, это значение, которое вы получаете: 65535 равно 2**16 - 1, поэтому -1 приводится к беззнаковому 16-битному целому числу (a u_int). Поэтому я склонен полагать, что, когда вы видите это значение 65535, вы на самом деле не предоставляете какой-либо программе BPF функцию? Согласуется ли это с вашими наблюдениями?

Теперь, когда есть совпадение:

В противном случае он возвращает результат программы фильтра.

Результирующее значение bpf_filter() — это результат, полученный из программы BPF. Итак, когда вы получаете возвращаемое значение 0, это означает, что:

  • Либо ваша программа BPF завершилась и вернула 0.
  • Или, возможно (хотя это и не задокументировано на справочной странице), произошла ошибка при запуске программы BPF. Вот пример, тоже из первоисточника:

    case BPF_ALU|BPF_DIV|BPF_X:
        if (X == 0)
            return 0;
        A /= X;
        continue;
    

«В случае арифметического деления, если знаменатель X равен нулю, то заставить bpf_filter() вернуть 0, в противном случае разделить регистр A на регистр X и перейти к следующей инструкции».

[Отредактировано] (см. комментарии) Как вы узнали, то же самое относится и к значению 65535: это значение, которое вы заставили вернуть ваша программа BPF.

person Qeole    schedule 27.08.2016
comment
Спасибо за ваше объяснение. u_int bpf_filter(const struct bpf_insn *pc, u_char *p, u_int wirelen, u_int buflen) вы могли видеть выше, что возвращаемое значение имеет тип u_int, поэтому его 32-битное целое число без знака. когда вы приводите -1 к беззнаковому 32-битному целому, тогда это: 4294967295. Более того, я провел несколько трассировок вокруг блока if(pc == 0), где возвращается -1. И по этим следам я мог видеть, что он вообще не идет к этому, если блокируется. Я предполагаю, что он должен возвращать длину пакета в случае успеха, но он возвращает 65535 каждый раз, когда происходит совпадение (мой pkt len ​​равен 78) - person KrishnamRaju raju; 29.08.2016
comment
Хм, я не понимаю, почему он все равно будет печатать длину пакета, это должно быть возвращаемое значение BPF. Поскольку вы можете отлаживать функцию, не могли бы вы сказать, какой оператор «return» в bpf_filter() используется на самом деле? Может быть, это могло бы помочь. Кроме того, возможно ли предоставить программу BPF, которую вы используете? - person Qeole; 29.08.2016
comment
Я обнаружил проблему, bpf_filter() возвращает 65535, потому что я указал 65535 для открытия pcap, как показано ниже: pcap_open_dead(DLT_EN10MB, 65535); Теперь bpf_filter() возвращает 1 после замены 65535 на 1. Qeole, спасибо за ответ. Это помогло мне получить больше ясности .. - person KrishnamRaju raju; 15.09.2016
comment
@KrishnamRajuraju: Отлично! Это действительно имеет смысл. Рад узнать, что могу помочь :-). - person Qeole; 16.09.2016