Berkeley Packet Filter到高级过滤表达式

时间:2017-11-28 13:21:35

标签: c# c winpcap pcap.net bpf

我有一个C程序,它通过Berkeley Filter手动设置WinPcap会话的过滤器。现在我想用Pcap.Net在C#中传输这个工具。 Pcap.Net不提供原始berkeley过滤器作为参数,而是提供高级过滤表达式(也用于例如wireshark / tcpdump,如ip and tcp

有没有办法

  1. 将Berkeley Packet Filter“反编译”为高级过滤表达式
  2. 在pcap.net
  3. 中使用原始字节流作为过滤器

    原始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。 Class只接受高级过滤表达式(如tcp port 80)。

    我搜索了一种使用原始过滤器(参见上面的代码块)而不是高级表达式来提供BPF-Class的方法。

1 个答案:

答案 0 :(得分:0)

看起来Pcap.Net的BerkeleyPacketFilter个对象是simple wrappers around a reference to the bpf_program structure

这显然是一个黑客,但您可以使用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);
}