[strongSwan-dev] farp plugin bpf filter
Sven Kuhnert
sven.qnerd at googlemail.com
Mon May 31 20:24:04 CEST 2010
Hi list.
I tried to use charons new farp plugin. Unfortunately it does not work
in my environment. If I sniff the network traffic, I can see an ARP
request to the broadcast but the ipsec gateway do not answer that. The
UML-Test for this module seems to work. By viewing the source code I
found out, that the BPF filter in farp_spoofer.c does not work properly
for me. I am not a pro in kernel based socket programming but I thought
that this filter is used for performance reasons to capture only ARP
requests? So I tried to replace that filter rules with some more basic
ones (see the end of this mail) and the module works fine. The new
ruleset is quite similar to this:
http://dhcpcd.sourcearchive.com/documentation/3.2.3/socket_8c-source.html
It seems to be important, that these two lines are present:
arp_request_filter_code[1].jf = 0; /* skip the IP packet type check */
arp_request_filter_code[2].k -= ETH_HLEN;
The next strange thing for me is, that the old rules worked at all,
because I interpret these rules, that only IP packets (and even NOT arp)
are captured:
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, offsetof(arp_t, protocol_type)),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_P_IP, 0, 9),
Maybe this behaviour comes form some settings on the ipsec gateway
system (this is btw. a brand new Ubuntu 10.04 LTS)?
Greetings from Germany,
Sven Kuhnert
--- strongswan-4.4.0/src/libcharon/plugins/farp/farp_spoofer.c
2010-03-28 14:06:04.000000000 +0200
+++ farp_spoofer.c_final 2010-05-31 17:51:24.000000000 +0200
@@ -21,6 +21,7 @@
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/filter.h>
+#include <net/ethernet.h>
#include <sys/ioctl.h>
#include <daemon.h>
@@ -147,19 +148,25 @@
{
private_farp_spoofer_t *this;
struct sock_filter arp_request_filter_code[] = {
- BPF_STMT(BPF_LD+BPF_H+BPF_ABS, offsetof(arp_t, protocol_type)),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ETH_P_IP, 0, 9),
- BPF_STMT(BPF_LD+BPF_B+BPF_ABS, offsetof(arp_t, hardware_size)),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 7),
- BPF_STMT(BPF_LD+BPF_B+BPF_ABS, offsetof(arp_t, protocol_size)),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 4, 0, 4),
- BPF_STMT(BPF_LD+BPF_H+BPF_ABS, offsetof(arp_t, opcode)),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARPOP_REQUEST, 0, 3),
- BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 28, 0, 1),
- BPF_STMT(BPF_RET+BPF_A, 0),
- BPF_STMT(BPF_RET+BPF_K, 0),
+ /* Make sure this is an ARP packet... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_ARP, 0, 3),
+
+ /* Make sure this is an ARP REPLY... */
+ BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 20),
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ARPOP_REQUEST, 0, 1),
+
+ /* If we passed all the tests, ask for the whole packet. */
+ BPF_STMT (BPF_RET + BPF_K, ~0U),
+
+ /* Otherwise, drop it. */
+ BPF_STMT (BPF_RET + BPF_K, 0),
};
+
+
+ arp_request_filter_code[1].jf = 0; /* skip the IP packet type check */
+ arp_request_filter_code[2].k -= ETH_HLEN;
+
struct sock_fprog arp_request_filter = {
sizeof(arp_request_filter_code) / sizeof(struct sock_filter),
arp_request_filter_code,
More information about the Dev
mailing list