Isn't the signature for that method:

Code:
int pcap_setfilter(pcap_t *, struct bpf_program *);
If so, you're P/Invoke is incorrect. It should be:

Code:
public static extern int pcap_setfilter(IntPtr p,IntPtr fp);
Alternatively, it may be possible to use something like this:

Code:
public struct pcap_t
{
    // contents should mirror the native struct
}

public struct bpf_program
{
    // this should match the native version too
}

// Your P/Invoke can look like this now
public static extern int pcap_setfilter(ref pcap_t p, ref bpf_program fp);
Though not everything can be rewritten 'nicely' like this. It depends on the method signature you're trying to wrap. Also if you write the code like this, you *cannot* store the pointer in native code. If you want to store a copy of the data in native code, you'll have to use the IntPtr method like you originally did.