Hello,
Everyone knows that with PF_PACKET sockets one can "sniff" a determinated frame from the network device, but just that, see the frame without altering its action on the receiving host. What i want is to "intercept" the incoming frame and pass it through some rules, and if it doesn't pass the rules, then DROP it without efecting its action on the host.
Let's say an ARP Request message, normally, the receiving host will create an entry on the ARP cache when it receives the ARP Request frame. If i use a PF_PACKET socket, i'll be able to see the packet, but not to intercept it, so however it passes my program rules or doesn't, its action will be the same, CREATE THE ARP ENTRY.
I know a little about netfilter and LKM programming, and i know that it does exactily what i want to do (intercept frames before it takes any action on the host), but from what i've seen, it just allows the programmer to handle IP level packets, so, what if i want to use netfilter to filter an ARP frame? Is it possible? And how is it done?
Yes, it is possible to do what you wish to do. How you do it depends on the particular platform you are on. If you are on Solaris, BSD or Mac OS-X, you would use the Berkeley Packet Filter (BPF). If you are on GNU/Linux you need to use Linux Socket Filter (LSF). Their APIs are totally different but fortunately LSF uses the BPF format syntax.
I can't even imagine what does that piece of code. :S
But, with this LSF interface, can i "catch/intercept" the ARP message and deceide if DROP it or PASS to the host, BEFORE it takes effect on the host?
No more difficult than using the Berkeley Socket Filter.
Yes, if you know what you are doing. Look at a bpf(4) man page on any BSD platform for a detailed explanation of the filter machine syntax and read the seminal paper on this topic, i.e. The BSD Packet Filter: A New Architecture for User-level Packet Capture by Steven McCanne and Van Jacobson. It is available on the Internet.
This user-defined filter decides whether a packet
is to be accepted and how many bytes of each packet should
be saved. For each filter that accepts the packet, BPF copies
the requested amount of data to the buffer associated with that
filter. The device driver then regains control. If the packet
was not addressed to the local host, the driver returns from the
interrupt. Otherwise, normal protocol processing proceeds.
LSF and BPF are just a filter for deceiding what packets to show and what packet not to. If the frame doesn't pass the filter, then it's returned to the device driver and it will process it normally (so, in my example, the ARP frame will take effect on the host's cache).
It seems i'll have to keep looking for arp support on netfilter.
By the way, i tried to make a module for blocking all ARP frames with netfilter, and it seems it's not possible. Does anyone know why?
This is the normal netfilter_hook_ops structure, i fill it with the funcion name (hook_func), the hook type NF_ARP_IN (0) and the protocol family (NF_ARP) and then register the hook. Since hook_func is "return NF_DROP" it should drop every single ARP frame it receives, but it doesn't. Could some one give me a clue about this?
Hello, Corona688.
No, that's not what i want. What i want is to filter the traffic, something like NETFILTER modules do, a way to DROP or ACCEPT frames.
Your problem is that ARP is not an IP protocol, it is a layer below IP. The ethertype is not ip, and as a result, the packets never get into the netfilter hooks. arp is processed by the kernel without the ip layer.
Recent kernels have a config option ARPD that allows for substitution of a daemon for the kernel's arp resolution. That should enable you to do whatever you want to the arp packets.
There is also a BRIDGE_NETFILTER option that enables mac layer firewalls. By creating a virtual device in a bridge configuration you should be able to get those pesky arp packets into the netfilter framework.