[prev in list] [next in list] [prev in thread] [next in thread] 

List:       dhcp-hackers
Subject:    [PATCH V3] Add support for RFC2855 (DHCP over 1394)
From:       Maxim Levitsky <maximlevitsky () gmail ! com>
Date:       2011-01-10 1:34:18
Message-ID: 1294623258.25633.2.camel () maxim-laptop
[Download RAW message or body]

On Mon, 2011-01-10 at 03:25 +0200, Maxim Levitsky wrote:
> Hi,
> 
> This is version of my patch ported to 4.1.1 
> (also tested on 4.1-ESV, 4.2.0-P2, 4.1.2)
> 
> 4.2.0-P2 need trivial makefile fix for patch to apply.
> 
> 
> Best regards,
> 	Maxim Levitsky

CC'ing the list, not yet familiar with how the bugzilla works.
(Maybe I shouldn't change the subject line?)


Best regards,
	Maxim Levitsky

["dhcp4_firewire.patch" (dhcp4_firewire.patch)]

commit 98e32a495bda760602dc02c7bbe5da6ca8070e1a
Author: Maxim Levitsky <maximlevitsky@gmail.com>
Date:   Mon Jan 10 02:25:01 2011 +0200

    Add support for RFC2855, DHCP over IEEE1394
    
    Patch against version 4.1.1-P1
    
    Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com>

diff --git a/client/dhclient.c b/client/dhclient.c
index 69dcc91..e40607f 100644
--- a/client/dhclient.c
+++ b/client/dhclient.c
@@ -2220,6 +2220,24 @@ make_client_options(struct client_state *client, struct client_lease *lease,
 		client -> requested_address.len = 0;
 	}
 
+#ifdef HAVE_ARPHRD_IEEE1394
+	/* To comply with RFC2855, send hardware address (which is really the
+		node GUID) inside client indentifier*/
+	if (client -> interface -> hw_address.hbuf [0] == ARPHRD_IEEE1394) {
+		i = DHO_DHCP_CLIENT_IDENTIFIER;
+		if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash,
+						&i, 0, MDL) &&
+			make_const_option_cache(&oc, NULL,
+				&client -> interface -> hw_address.hbuf [1], 8,
+						option, MDL)))
+			log_error ("can't set default client indentifier");
+		else {
+			save_option (&dhcp_universe, *op, oc);
+			option_cache_dereference (&oc, MDL);
+		}
+		option_dereference(&option, MDL);
+	}
+#endif
 	i = DHO_DHCP_MESSAGE_TYPE;
 	if (!(option_code_hash_lookup(&option, dhcp_universe.code_hash, &i, 0,
 				      MDL) &&
diff --git a/common/Makefile.am b/common/Makefile.am
index 8b2f2a9..7b55a4a 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -3,9 +3,10 @@ AM_CPPFLAGS = -I.. -DLOCALSTATEDIR='"@localstatedir@"'
 noinst_LIBRARIES = libdhcp.a
 libdhcp_a_SOURCES = alloc.c bpf.c comapi.c conflex.c ctrace.c discover.c \
 		    dispatch.c dlpi.c dns.c ethernet.c execute.c fddi.c \
-		    icmp.c inet.c lpf.c memory.c nit.c options.c packet.c \
-		    parse.c print.c raw.c resolv.c socket.c tables.c tr.c \
-		    tree.c upf.c heap.c
+		    firewire.c icmp.c inet.c lpf.c memory.c nit.c options.c \
+		    packet.c parse.c print.c raw.c resolv.c socket.c tables.c \
+		    tr.c tree.c upf.c heap.c
+
 man_MANS = dhcp-eval.5 dhcp-options.5
 EXTRA_DIST = $(man_MANS)
 
diff --git a/common/bpf.c b/common/bpf.c
index a9681bb..540b9a1 100644
--- a/common/bpf.c
+++ b/common/bpf.c
@@ -218,6 +218,38 @@ struct bpf_insn dhcp_bpf_tr_filter [] = {
 int dhcp_bpf_tr_filter_len = (sizeof dhcp_bpf_tr_filter /
 			      sizeof (struct bpf_insn));
 #endif /* HAVE_TR_SUPPORT */
+
+#if defined (HAVE_ARPHRD_IEEE1394)
+struct bpf_insn dhcp_bpf_filter_firewire [] = {
+	/* Make sure this is an IP packet... */
+	BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 8),
+	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
+
+	/* Make sure it's a UDP packet... */
+	BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 19),
+	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
+
+	/* Make sure this isn't a fragment... */
+	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 16),
+	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
+
+	/* Get the IP header length... */
+	BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 10),
+
+	/* Make sure it's to the right port... */
+	BPF_STMT (BPF_LD + BPF_H + BPF_IND, 12),
+	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),             /* patch */
+
+	/* If we passed all the tests, ask for the whole packet. */
+	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
+
+	/* Otherwise, drop it. */
+	BPF_STMT(BPF_RET+BPF_K, 0),
+};
+int dhcp_bpf_filter_firewire_len =
+		sizeof dhcp_bpf_filter_firewire / sizeof (struct bpf_insn);
+#endif
+
 #endif /* USE_LPF_RECEIVE || USE_BPF_RECEIVE */
 
 #if defined (USE_BPF_RECEIVE)
diff --git a/common/firewire.c b/common/firewire.c
new file mode 100644
index 0000000..c12f304
--- /dev/null
+++ b/common/firewire.c
@@ -0,0 +1,88 @@
+/* firewire.c
+ * Based on ethernet.c
+ *
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This software has been written for Internet Systems Consortium
+ * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
+ * To learn more about Internet Systems Consortium, see
+ * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
+ * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
+ * ``http://www.nominum.com''.
+ */
+
+
+#include "dhcpd.h"
+
+#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
+#include "includes/netinet/if_ether.h"
+#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
+
+#define FWNET_ALEN 8
+struct fwnet_header {
+	unsigned char h_dest[FWNET_ALEN];	/* destination address */
+	uint16_t h_proto;		/* packet type ID field */
+} __attribute__((packed));
+
+#if defined (PACKET_ASSEMBLY)
+/* Assemble an hardware header... */
+
+void assemble_fw_header (struct interface_info *interface,
+			unsigned char *buf,
+			unsigned *bufix,
+			struct hardware *to)
+{
+  struct fwnet_header hdr;
+
+  /* Always send broadcast, because firewire hardware header
+	is fake which meand that
+	untill device has an IP it can't be reached via unicast */
+  memset(hdr.h_dest, 0xFF, FWNET_ALEN);
+  hdr.h_proto = htons (ETHERTYPE_IP);
+  memcpy (&buf [*bufix], &hdr, sizeof(hdr));
+  *bufix += sizeof(hdr);
+}
+
+#endif /* PACKET_ASSEMBLY */
+
+#ifdef PACKET_DECODING
+/* 'Decodes' firewire header. Since FW headers are fake, just skip it */
+
+ssize_t decode_fw_header(struct interface_info *interface,
+				unsigned char *buf,
+				unsigned bufix,
+				struct hardware *from)
+{
+  struct fwnet_header hdr;
+  memcpy(&hdr, buf + bufix, sizeof(hdr));
+
+#ifdef USERLAND_FILTER
+  if (ntohs (hdr.h_proto) != ETHERTYPE_IP)
+	  return -1;
+#endif
+
+  from->hlen = 1;
+  from -> hbuf [0] = ARPHRD_IEEE1394;
+  return sizeof(hdr);
+}
+
+#endif /* PACKET_DECODING */
diff --git a/common/lpf.c b/common/lpf.c
index e5dd1e2..eb43087 100644
--- a/common/lpf.c
+++ b/common/lpf.c
@@ -165,6 +165,12 @@ extern int dhcp_bpf_tr_filter_len;
 static void lpf_tr_filter_setup (struct interface_info *);
 #endif
 
+#if defined (HAVE_ARPHRD_IEEE1394)
+extern struct sock_filter dhcp_bpf_filter_firewire [];
+extern int dhcp_bpf_filter_firewire_len;
+static void lpf_firewire_filter_setup (struct interface_info *);
+#endif
+
 static void lpf_gen_filter_setup (struct interface_info *);
 
 void if_register_receive (info)
@@ -178,6 +184,11 @@ void if_register_receive (info)
 		lpf_tr_filter_setup (info);
 	else
 #endif
+#if defined (HAVE_ARPHRD_IEEE1394)
+	if (info -> hw_address.hbuf[0] == ARPHRD_IEEE1394)
+		lpf_firewire_filter_setup (info);
+	else
+#endif
 		lpf_gen_filter_setup (info);
 
 	if (!quiet_interface_discovery)
@@ -278,6 +289,43 @@ static void lpf_tr_filter_setup (info)
 	}
 }
 #endif /* HAVE_TR_SUPPORT */
+
+#if defined (HAVE_ARPHRD_IEEE1394)
+static void lpf_firewire_filter_setup (info)
+	struct interface_info *info;
+{
+	struct sock_fprog p;
+
+	memset(&p, 0, sizeof(p));
+
+	/* Set up the bpf filter program structure.    This is defined in
+	   bpf.c */
+	p.len = dhcp_bpf_filter_firewire_len;
+	p.filter = dhcp_bpf_filter_firewire;
+
+        /* Patch the server port into the LPF  program...
+	   XXX changes to filter program may require changes
+	   to the insn number(s) used below! XXX */
+	dhcp_bpf_filter_firewire [8].k = ntohs ((short)local_port);
+
+
+	if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
+			sizeof p) < 0) {
+		if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+		    errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
+		    errno == EAFNOSUPPORT) {
+			log_error ("socket: %m - make sure");
+			log_error ("CONFIG_PACKET (Packet socket) %s",
+				   "and CONFIG_FILTER");
+			log_error ("(Socket Filtering) are enabled %s",
+				   "in your kernel");
+			log_fatal ("configuration!");
+		}
+		log_fatal ("Can't install packet filter program: %m");
+	}
+}
+#endif
+
 #endif /* USE_LPF_RECEIVE */
 
 #ifdef USE_LPF_SEND
@@ -454,6 +502,16 @@ get_hw_addr(const char *name, struct hardware *hw) {
 			hw->hbuf[0] = HTYPE_FDDI;
 			memcpy(&hw->hbuf[1], sa->sa_data, 16);
 			break;
+#ifdef HAVE_ARPHRD_IEEE1394
+		case ARPHRD_IEEE1394:
+			/* According to RFC2855, we set hlen to 0,
+			but store hardware address in the client ID,
+			so store hardware address but set len to 0 */
+			hw->hlen = 1;
+			hw->hbuf[0] = ARPHRD_IEEE1394;
+			memcpy(&hw->hbuf[1], sa->sa_data, 8);
+			break;
+#endif
 		default:
 			log_fatal("Unsupported device type %ld for \"%s\"",
 				  (long int)sa->sa_family, name);
diff --git a/common/packet.c b/common/packet.c
index 42bca69..b80cff6 100644
--- a/common/packet.c
+++ b/common/packet.c
@@ -115,6 +115,11 @@ void assemble_hw_header (interface, buf, bufix, to)
 		     assemble_fddi_header (interface, buf, bufix, to);
 	else
 #endif
+#if defined (HAVE_ARPHRD_IEEE1394)
+	     if (interface -> hw_address.hbuf [0] == ARPHRD_IEEE1394)
+		     assemble_fw_header(interface, buf, bufix, to);
+	else
+#endif
 		assemble_ethernet_header (interface, buf, bufix, to);
 
 }
@@ -202,6 +207,11 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
 		     return decode_fddi_header (interface, buf, bufix, from);
 	else
 #endif
+#if defined (HAVE_ARPHRD_IEEE1394)
+	     if (interface -> hw_address.hbuf [0] == ARPHRD_IEEE1394)
+		     return decode_fw_header (interface, buf, bufix, from);
+	else
+#endif
 		return decode_ethernet_header (interface, buf, bufix, from);
 }
 
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index 90f8a73..b547c5b 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -2602,6 +2602,13 @@ ssize_t decode_tr_header PROTO ((struct interface_info *,
 				 unsigned char *,
 				 unsigned, struct hardware *));
 
+/* firewire.c */
+void assemble_fw_header PROTO ((struct interface_info *, unsigned char *,
+				unsigned *, struct hardware *));
+ssize_t decode_fw_header PROTO ((struct interface_info *,
+				 unsigned char *,
+				 unsigned, struct hardware *));
+
 /* dhxpxlt.c */
 void convert_statement PROTO ((struct parse *));
 void convert_host_statement PROTO ((struct parse *, jrefproto));


_______________________________________________
dhcp-hackers mailing list
dhcp-hackers@lists.isc.org
https://lists.isc.org/mailman/listinfo/dhcp-hackers

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic