我有一个 C 程序,它通过 Berkeley Filter 手动设置 WinPcap session 的过滤器。现在我想用Pcap.Net在C#中移植这个工具。 Pcap.Net 不提供原始伯克利过滤器作为参数,而是提供高级过滤表达式(也用于例如 ip 和 tcp
等wireshark/tcpdump)
有没有办法
- 将伯克利数据包过滤器“反编译”为高级过滤表达式
- 在 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系统的接口(interface)。 WinPcap 使用此 BPF,Pcap.Net 也是如此。 Pcap.Net 有一个类来处理 BPF,也称为 BarkeleyPacketFilter。该类仅接受高级过滤表达式(例如tcp port 80
)。
我寻找一种使用原始过滤器(参见上面的代码块)而不是高级表达式来为 BPF 类提供数据的方法。
最佳答案
看起来 Pcap.Net 的 BerkeleyPacketFilter
对象是 simple wrappers around a reference to the bpf_program
structure .
这显然是一种黑客攻击,但您可以使用System.Reflection
替换这些对象的私有(private)字段:
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);
}
关于c# - Berkeley Packet Filter 到高级过滤表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47532651/