【问题标题】:Berkeley Packet Filter to high level filtering expressionBerkeley Packet Filter 到高级过滤表达式
【发布时间】:2018-05-11 23:22:08
【问题描述】:

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

有没有办法

  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 类的方法。

【问题讨论】:

标签: c# c winpcap pcap.net bpf


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2017-11-07
    • 2023-03-08
    相关资源
    最近更新 更多