Berkeley Packet Filter для выражения фильтрации высокого уровня

У меня есть программа на C, которая устанавливает фильтр для сеанса WinPcap вручную с помощью Berkeley Filter. Теперь я хочу перенести этот инструмент на C# с помощью Pcap.Net. Pcap.Net предлагает в качестве аргумента не необработанный фильтр Беркли, а выражение фильтрации высокого уровня (также используемое, например, в wireshark/tcpdump, например ip and tcp)

Есть ли способ

  1. "Декомпилировать" пакетный фильтр Беркли в выражение фильтрации высокого уровня
  2. Используйте необработанный поток байтов для фильтра в pcap.net

Необработанная программа bpf_program:

struct bpf_program bpf_program;
static struct bpf_insn bpf_insn [] =
{
    {
        BPF_LD + BPF_H + BPF_ABS,
        0,
        0,
        12
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        18,
        0
    },
    {
        BPF_LD + BPF_B + BPF_ABS,
        0,
        0,
        0
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        10,
        0
    },
    {
        BPF_LD + BPF_B + BPF_ABS,
        0,
        0,
        1
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        8,
        0
    },
    {
        BPF_LD + BPF_B + BPF_ABS,
        0,
        0,
        2
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        6,
        0
    },
    {
        BPF_LD + BPF_B + BPF_ABS,
        0,
        0,
        3
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        4,
        0
    },
    {
        BPF_LD + BPF_B + BPF_ABS,
        0,
        0,
        4
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        2,
        0
    },
    {
        BPF_LD + BPF_B + BPF_ABS,
        0,
        0,
        5
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        4,
        0,
        0
    },
    {
        BPF_LD + BPF_W + BPF_ABS,
        0,
        0,
        0
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        4,
        0xFFFFFFFF
    },
    {
        BPF_LD + BPF_H + BPF_ABS,
        0,
        0,
        4
    },
    {
        BPF_JMP + BPF_JEQ + BPF_K,
        0,
        2,
        0xFFFF
    },
    {
        BPF_LD + BPF_W + BPF_LEN,
        0,
        0,
        0
    },
    {
        BPF_RET + BPF_A,
        0,
        0,
        0
    },
    {
        BPF_RET + BPF_K,
        0,
        0,
        0
    }
};
bpf_program.bf_len = sizeof (bpf_insn)/sizeof (struct bpf_insn);
bpf_program.bf_insns = bpf_insn;
if (channel->type == ETH_P_802_2)
{
    bpf_insn [1].code = BPF_JMP + BPF_JGT + BPF_K;
    bpf_insn [1].jt = 18;
    bpf_insn [1].jf = 0;
    bpf_insn [1].k = ETHERMTU;
}
else
{
    bpf_insn [1].code = BPF_JMP + BPF_JEQ + BPF_K;
    bpf_insn [1].jt = 0;
    bpf_insn [1].jf = 18;
    bpf_insn [1].k = channel->type;
}
bpf_insn [3].k = channel->host [0];
bpf_insn [5].k = channel->host [1];
bpf_insn [7].k = channel->host [2];
bpf_insn [9].k = channel->host [3];
bpf_insn [11].k = channel->host [4];
bpf_insn [13].k = channel->host [5];

Отредактируйте, чтобы уточнить: Berkeley Packet Filter — это интерфейс для системы на основе Unix. WinPcap использует этот BPF, как и Pcap.Net. Pcap.Net имеет класс для обработки BPF, который также называется BarkeleyPacketFilter. Класс принимает только выражения фильтрации высокого уровня (например, tcp port 80).

Я ищу способ накормить BPF-класс необработанным фильтром (см. блок кода выше), а не выражением высокого уровня.


person Max R.    schedule 28.11.2017    source источник
comment
что такое raw berkeley filter? эта ссылка поможет? pcapdotnet.codeplex.com/   -  person netaholic    schedule 28.11.2017
comment
Возможный дубликат BerkeleyPacketFilter, фильтрация по TCP и порту   -  person netaholic    schedule 28.11.2017


Ответы (1)


Похоже, что объекты BerkeleyPacketFilter Pcap.Net — это простые обертки вокруг ссылки на структуру bpf_program.

Это явно хак, но вы, вероятно, можете заменить приватное поле этих объектов, используя System.Reflection:

using (BerkeleyPacketFilter filter = communicator.CreateFilter("ip and tcp"))
{
    var prop = filter.GetType().GetField("_bpf",
                                         System.Reflection.BindingFlags.NonPublic
                                         | System.Reflection.BindingFlags.Instance);
    prop.SetValue(filter, &your_bpf_program);

    communicator.SetFilter(filter);
}
person pchaigno    schedule 24.12.2017