On Wed, Mar 13, 2002 at 08:44:05PM -0800, Raghu Angadi wrote: > On Linux, code compiled with pcap_compile() in libpcap 0.6.2 (RPM > libpcap-0.6.2-9) works only with sockets opened with socket(PF_PACKET, > SOCK_RAW, ..). How do I get filter code for sockets opened with > socket(PF_SOCKET, SOCK_DGRAM, ..)?
Do you mean "code compiled with 'pcap_compile()' doesn't work on a 'pcap_t' for a device for which libpcap uses PF_PACKET/SOCK_DGRAM", or do you mean "code compiled with 'pcap_compile()' doesn't work on a socket directly opened, outside of libpcap, with 'socket(PF_PACKET, SOCK_DGRAM, ...)'? If you mean the former, then what symptoms are you seeing? libpcap 0.6.2 - and 0.7.1 - from tcpdump.org can generate code for "pcap_t"s that have a link-layer type of DLT_LINUX_SLL; that's the link-layer type returned by libpcap if the underlying socket was opened with PF_PACKET/SOCK_DGRAM. That code works (or, at least, worked when I tried it; maybe bit rot has affected the code, but I don't think so). I.e., it certainly worked for *me*. If you mean the latter, however, the code generated by "pcap_compile()" is *not* code you can directly attach to a socket with SO_ATTACH_FILTER; instead, it's code that works with capture files of type DLT_LINUX_SLL. If you have a "pcap_t" and use "pcap_setfilter()" to set the filter on the "pcap_t", libpcap makes a copy of the code, and modifies the code to work on a PF_PACKET/SOCK_DGRAM socket (the data on the socket doesn't have a DLT_LINUX_SLL header on it, so you have to use special kernel socket filter hacks to get at the fields in the header; libpcap transforms references to fields in the packet either by subtracting the length of the DLT_LINUX_SLL header from the offset, or by turning references to the protocol field in that header into the special hack offset to get at that field). "pcap_compile()" cannot, in all circumstances, know whether the code it generates will be used by a userland BPF or by the kernel - that's not necessarily known until you actually call "pcap_setfilter()". If the "pcap_t" you pass to "pcap_compile()" came from "pcap_open_offline()", the code will be used by a userland BPF, and "pcap_compile()" could determine that by looking at the "pcap_t" to see that it refers to a savefile. If the "pcap_t" you pass to "pcap_compile()" came from "pcap_open_live()", however, there's no guarantee that you will be able to attach the filter to the socket - the kernel might not have CONFIG_FILTER enabled, or the filter program might be too large for the kernel, or the attempt to attach the filter might fail for some *other* reason. So the fixup for in-kernel filtering is done on a copy of the filter, and if the attempt to set the filter fails, the original unmodified filter is used. If the "pcap_t" you pass to "pcap_compile()" came from "pcap_open_dead()", libpcap cannot know for certain why you want to generate BPF code; it could perhaps *infer* that the most likely reason for using "pcap_open_dead()" is to get BPF code generated for a socket rather than for a userland BPF interpreter - but I'm not sure there's any *guarantee* of that. - This is the TCPDUMP workers list. It is archived at http://www.tcpdump.org/lists/workers/index.html To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe
