0

I have a C program which sets the filter for a WinPcap session manually by Berkeley Filter. Now I want to transfer this tool in C# with Pcap.Net. Pcap.Net doesn't offer the raw berkeley filter as argument but the high level filtering expression (also used in e.g. wireshark/tcpdump like ip and tcp)

Is there a way to

  1. "Decompile" the Berkeley Packet Filter to an high level filtering expression
  2. Use a raw byte stream for the filter in pcap.net

The raw 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];

Edit to clarify: Berkeley Packet Filter is an interface for unix based system. WinPcap uses this BPF and so does Pcap.Net. Pcap.Net has a class to handle the BPF which is also called BarkeleyPacketFilter. The Class only accepts high level filtering expression (like tcp port 80).

I search for a way to feed the BPF-Class with the raw filter (see code block above) not with the high level expression.

Max R.
  • 811
  • 1
  • 13
  • 31
  • what is a `raw berkeley filter`? does that link help? https://pcapdotnet.codeplex.com/wikipage?title=Pcap.Net%20Tutorial%20-%20Filtering%20the%20traffic – netaholic Nov 28 '17 at 14:05
  • 1
    Possible duplicate of [BerkeleyPacketFilter, filter by TCP and port](https://stackoverflow.com/questions/25675476/berkeleypacketfilter-filter-by-tcp-and-port) – netaholic Nov 28 '17 at 14:06

1 Answers1

0

Looks like the BerkeleyPacketFilter objects of Pcap.Net are simple wrappers around a reference to the bpf_program structure.

It's clearly a hack, but you can probably replace the private field of those objects using 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);
}
pchaigno
  • 11,313
  • 2
  • 29
  • 54