aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2014-02-03 18:03:42 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2014-02-03 18:03:42 +0100
commite4785ca653d0e219926692c229673b2c1b8d6ac4 (patch)
tree69fc8a0a892bde0a0a9c83adf7567bbcbc8a9f74 /networking/udhcp
parentfe8390e0fe7106aed9f586b3cf08215effc4450b (diff)
downloadbusybox-w32-e4785ca653d0e219926692c229673b2c1b8d6ac4.tar.gz
busybox-w32-e4785ca653d0e219926692c229673b2c1b8d6ac4.tar.bz2
busybox-w32-e4785ca653d0e219926692c229673b2c1b8d6ac4.zip
udhcpc: don't use BPF filter, users report problems (bugs 4598, 6746)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/udhcp')
-rw-r--r--networking/udhcp/dhcpc.c93
1 files changed, 46 insertions, 47 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index 8dee916d9..ee19f5578 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -976,53 +976,6 @@ static int udhcp_raw_socket(int ifindex)
976 int fd; 976 int fd;
977 struct sockaddr_ll sock; 977 struct sockaddr_ll sock;
978 978
979 /*
980 * Comment:
981 *
982 * I've selected not to see LL header, so BPF doesn't see it, too.
983 * The filter may also pass non-IP and non-ARP packets, but we do
984 * a more complete check when receiving the message in userspace.
985 *
986 * and filter shamelessly stolen from:
987 *
988 * http://www.flamewarmaster.de/software/dhcpclient/
989 *
990 * There are a few other interesting ideas on that page (look under
991 * "Motivation"). Use of netlink events is most interesting. Think
992 * of various network servers listening for events and reconfiguring.
993 * That would obsolete sending HUP signals and/or make use of restarts.
994 *
995 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>.
996 * License: GPL v2.
997 *
998 * TODO: make conditional?
999 */
1000 static const struct sock_filter filter_instr[] = {
1001 /* load 9th byte (protocol) */
1002 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
1003 /* jump to L1 if it is IPPROTO_UDP, else to L4 */
1004 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
1005 /* L1: load halfword from offset 6 (flags and frag offset) */
1006 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
1007 /* jump to L4 if any bits in frag offset field are set, else to L2 */
1008 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
1009 /* L2: skip IP header (load index reg with header len) */
1010 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
1011 /* load udp destination port from halfword[header_len + 2] */
1012 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
1013 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */
1014 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
1015 /* L3: accept packet */
1016 BPF_STMT(BPF_RET|BPF_K, 0xffffffff),
1017 /* L4: discard packet */
1018 BPF_STMT(BPF_RET|BPF_K, 0),
1019 };
1020 static const struct sock_fprog filter_prog = {
1021 .len = sizeof(filter_instr) / sizeof(filter_instr[0]),
1022 /* casting const away: */
1023 .filter = (struct sock_filter *) filter_instr,
1024 };
1025
1026 log1("Opening raw socket on ifindex %d", ifindex); //log2? 979 log1("Opening raw socket on ifindex %d", ifindex); //log2?
1027 980
1028 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); 981 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
@@ -1033,13 +986,59 @@ static int udhcp_raw_socket(int ifindex)
1033 sock.sll_ifindex = ifindex; 986 sock.sll_ifindex = ifindex;
1034 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 987 xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
1035 988
989#if 0 /* Several users reported breakage when BPF filter is used */
1036 if (CLIENT_PORT == 68) { 990 if (CLIENT_PORT == 68) {
1037 /* Use only if standard port is in use */ 991 /* Use only if standard port is in use */
992 /*
993 * I've selected not to see LL header, so BPF doesn't see it, too.
994 * The filter may also pass non-IP and non-ARP packets, but we do
995 * a more complete check when receiving the message in userspace.
996 *
997 * and filter shamelessly stolen from:
998 *
999 * http://www.flamewarmaster.de/software/dhcpclient/
1000 *
1001 * There are a few other interesting ideas on that page (look under
1002 * "Motivation"). Use of netlink events is most interesting. Think
1003 * of various network servers listening for events and reconfiguring.
1004 * That would obsolete sending HUP signals and/or make use of restarts.
1005 *
1006 * Copyright: 2006, 2007 Stefan Rompf <sux@loplof.de>.
1007 * License: GPL v2.
1008 *
1009 * TODO: make conditional?
1010 */
1011 static const struct sock_filter filter_instr[] = {
1012 /* load 9th byte (protocol) */
1013 BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
1014 /* jump to L1 if it is IPPROTO_UDP, else to L4 */
1015 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6),
1016 /* L1: load halfword from offset 6 (flags and frag offset) */
1017 BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6),
1018 /* jump to L4 if any bits in frag offset field are set, else to L2 */
1019 BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0),
1020 /* L2: skip IP header (load index reg with header len) */
1021 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
1022 /* load udp destination port from halfword[header_len + 2] */
1023 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
1024 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */
1025 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
1026 /* L3: accept packet */
1027 BPF_STMT(BPF_RET|BPF_K, 0xffffffff),
1028 /* L4: discard packet */
1029 BPF_STMT(BPF_RET|BPF_K, 0),
1030 };
1031 static const struct sock_fprog filter_prog = {
1032 .len = sizeof(filter_instr) / sizeof(filter_instr[0]),
1033 /* casting const away: */
1034 .filter = (struct sock_filter *) filter_instr,
1035 };
1038 /* Ignoring error (kernel may lack support for this) */ 1036 /* Ignoring error (kernel may lack support for this) */
1039 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, 1037 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
1040 sizeof(filter_prog)) >= 0) 1038 sizeof(filter_prog)) >= 0)
1041 log1("Attached filter to raw socket fd"); // log? 1039 log1("Attached filter to raw socket fd"); // log?
1042 } 1040 }
1041#endif
1043 1042
1044 if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, 1043 if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA,
1045 &const_int_1, sizeof(int)) < 0 1044 &const_int_1, sizeof(int)) < 0