Oh, Bernhard...

Why do you make my life so much more complicated than it already is ;)

On Thu, 17 Jan 2008, Bernhard Fischer wrote:

> Can you please separate the whitespace fixes from actual changes
> (diff -rdupbBw or the like to filter out the noise).

Wasn' much of that.  Attached is the result.  You could cherry pick if
you wanted to.

I made some small changes, compared to the patch I previously sent.
The BPF-filter will match on both sport and dport.  Moved some code
back into it's original position as it (curiously) saved 24 bytes.

> What is the size(1) change with your patch?

Looks like some +420 bytes.
Bigest size increase (as expected) clientsocket.o: +328 bytes.
But that's, IMO, such a small price compared to the performance
benefits :)

Here you go:

svn:
   text    data     bss     dec     hex filename
   1012       0       0    1012     3f4 arpping.o
   2668       0       4    2672     a70 clientpacket.o
    224       0       0     224      e0 clientsocket.o
      6       0       0       6       6 common.o
   5460       4      20    5484    156c dhcpc.o
   1492       0       0    1492     5d4 domain_codec.o
   1460       0       0    1460     5b4 options.o
   2116       0       0    2116     844 packet.o
   2600       0       0    2600     a28 script.o
    556       0       8     564     234 signalpipe.o
    960       0       0     960     3c0 socket.o

mine:

   text    data     bss     dec     hex filename
   1016       0       0    1016     3f8 arpping.o
   2692       0       4    2696     a88 clientpacket.o
    552       0       0     552     228 clientsocket.o
      6       0       0       6       6 common.o
   5488       4      20    5512    1588 dhcpc.o
   1492       0       0    1492     5d4 domain_codec.o
   1464       0       0    1464     5b8 options.o
   2128       0       0    2128     850 packet.o
   2604       0       0    2604     a2c script.o
    556       0       8     564     234 signalpipe.o
    976       0       0     976     3d0 socket.o


Cheers,

-- 
Cristian
diff -rdupbBw networking/udhcp.orig/clientsocket.c networking/udhcp.mine/clientsocket.c
--- networking/udhcp.orig/clientsocket.c	2006-12-20 08:30:32.000000000 +0100
+++ networking/udhcp.mine/clientsocket.c	2008-01-17 14:11:21.000000000 +0100
@@ -30,22 +30,71 @@
 #include <linux/if_packet.h>
 #include <linux/if_ether.h>
 #endif
+#include <linux/filter.h>
 
 #include "common.h"
 
+#define SERVER_AND_CLIENT_PORTS	((SERVER_PORT << 16) + CLIENT_PORT)
 
 int raw_socket(int ifindex)
 {
 	int fd;
 	struct sockaddr_ll sock;
 
-	DEBUG("Opening raw socket on ifindex %d", ifindex);
+	/*
+	 * Comment:
+	 *
+	 *	I've selected not to see LL header, so BPF doesn't see it, too.
+	 *	The filter may also pass non-IP and non-ARP packets, but we do
+	 *	a more complete check when receiving the message in userspace.
+	 *
+	 * and filter shamelessly stolen from:
+	 *
+	 *	http://www.flamewarmaster.de/software/dhcpclient/
+	 *
+	 * There are a few other interesting ideas on that page (look under
+	 * "Motivation").  Use of netlink events is most interesting.  Think
+	 * of various network servers listening for events and reconfiguring.
+	 * That would obsolete sending HUP signals and/or make use of restarts.
+	 *
+	 * Copyright: 2006, 2007 Stefan Rompf <[EMAIL PROTECTED]>.
+	 * License: GPL v2.
+	 */
+	struct sock_filter filter_instr[] = {
+		/* check for udp */
+		BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 2, 0),	/* L5, L1, is UDP? */
+		/* ugly check for arp on ethernet-like and IPv4 */
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2),					/* L1: */
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x08000604, 3, 4),	/* L3, L4 */
+		/* skip IP header */
+		BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),					/* L5: */
+		/* check udp source and destination ports */
+		BPF_STMT(BPF_LD|BPF_W|BPF_IND, 0),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, SERVER_AND_CLIENT_PORTS, 0, 1),	/* L3, L4 */
+		/* returns */
+		BPF_STMT(BPF_RET|BPF_K, ~0UL),						/* L3: pass */
+		BPF_STMT(BPF_RET|BPF_K, 0),							/* L4: reject */
+	};
+	struct sock_fprog filter_prog;
+
+	DEBUG("opening raw socket on ifindex %d", ifindex);
+
 	fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
+	DEBUG("got raw socket fd %d", fd);
+
+	filter_prog.len	= sizeof(filter_instr) / sizeof(filter_instr[0]);
+	filter_prog.filter	= filter_instr;
+	if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
+				sizeof(filter_prog)) < 0)
+		bb_perror_msg_and_die("setsockopt");
+	DEBUG("attached filter to raw socket fdr %d", fd);
 
 	sock.sll_family = AF_PACKET;
 	sock.sll_protocol = htons(ETH_P_IP);
 	sock.sll_ifindex = ifindex;
 	xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
+	DEBUG("bound to raw socket fd %d", fd);
 
 	return fd;
 }
diff -rdupbBw networking/udhcp.orig/common.h networking/udhcp.mine/common.h
--- networking/udhcp.orig/common.h	2007-12-21 08:30:26.000000000 +0100
+++ networking/udhcp.mine/common.h	2008-01-16 14:36:29.000000000 +0100
@@ -14,6 +14,9 @@
 
 #define DEFAULT_SCRIPT  "/usr/share/udhcpc/default.script"
 
+#define SERVER_PORT		67
+#define CLIENT_PORT		68
+
 extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */
 
 /*** packet.h ***/
@@ -93,7 +96,7 @@ int listen_socket(/*uint32_t ip,*/ int p
 int arpping(uint32_t test_ip, uint32_t from_ip, uint8_t *from_mac, const char *interface);
 
 #if ENABLE_FEATURE_UDHCP_DEBUG
-# define DEBUG(str, args...) bb_info_msg(str, ## args)
+# define DEBUG(str, args...) bb_info_msg("### " str, ## args)
 #else
 # define DEBUG(str, args...) do {;} while (0)
 #endif
diff -rdupbBw networking/udhcp.orig/dhcpc.c networking/udhcp.mine/dhcpc.c
--- networking/udhcp.orig/dhcpc.c	2007-12-25 08:30:28.000000000 +0100
+++ networking/udhcp.mine/dhcpc.c	2008-01-15 16:09:32.000000000 +0100
@@ -452,7 +452,8 @@ int udhcpc_main(int argc, char **argv)
 
 			if (listen_mode == LISTEN_KERNEL)
 				len = udhcp_recv_packet(&packet, sockfd);
-			else len = get_raw_packet(&packet, sockfd);
+			else
+				len = get_raw_packet(&packet, sockfd);
 
 			if (len == -1) { /* error is severe, reopen socket */
 				DEBUG("error on read, %s, reopening socket", strerror(errno));
diff -rdupbBw networking/udhcp.orig/dhcprelay.c networking/udhcp.mine/dhcprelay.c
--- networking/udhcp.orig/dhcprelay.c	2007-12-21 08:30:26.000000000 +0100
+++ networking/udhcp.mine/dhcprelay.c	2008-01-16 12:53:21.000000000 +0100
@@ -155,12 +155,12 @@ static int init_sockets(char **client, i
 	int i, n;
 
 	/* talk to real server on bootps */
-	fds[0] = listen_socket(/*INADDR_ANY,*/ 67, server);
+	fds[0] = listen_socket(/*INADDR_ANY,*/ SERVER_PORT, server);
 	n = fds[0];
 
 	for (i = 1; i < num_clients; i++) {
 		/* listen for clients on bootps */
-		fds[i] = listen_socket(/*INADDR_ANY,*/ 67, client[i-1]);
+		fds[i] = listen_socket(/*INADDR_ANY,*/ SERVER_PORT, client[i-1]);
 		if (fds[i] > n)
 			n = fds[i];
 	}
@@ -289,7 +289,7 @@ int dhcprelay_main(int argc, char **argv
 	struct sockaddr_in server_addr;
 
 	server_addr.sin_family = AF_INET;
-	server_addr.sin_port = htons(67);
+	server_addr.sin_port = htons(SERVER_PORT);
 	if (argc == 4) {
 		if (!inet_aton(argv[3], &server_addr.sin_addr))
 			bb_perror_msg_and_die("didn't grok server");
diff -rdupbBw networking/udhcp.orig/options.h networking/udhcp.mine/options.h
--- networking/udhcp.orig/options.h	2007-11-30 08:30:29.000000000 +0100
+++ networking/udhcp.mine/options.h	2008-01-16 12:43:36.000000000 +0100
@@ -28,9 +28,6 @@ enum {
 /*****************************************************************/
 
 /* DHCP protocol -- see RFC 2131 */
-#define SERVER_PORT		67
-#define CLIENT_PORT		68
-
 #define DHCP_MAGIC		0x63825363
 
 
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to