+++ /dev/null
-Building DHCP over IPoIB
-1/11/11
-
-This directory contains the source RPMs and patches for RHEL 5.4,
-RHEL 5.5 (two src rpms), RHEL6 Beta, SLES11, and SLES11 SP1 as follows:
-RHEL5.4: dhcp-3.0.5-21.el5.src.rpm
-RHEL5.5: dhcp-3.0.5-23.el5_5.2.src.rpm, dhcp-3.0.5-23.el5.src.rpm
-(based on which dhcp rpm version is being used with RHEL5.5)
-RHEL6 Beta: dhcp-4.1.0p1-15.el6.src.rpm
-SLES11: dhcp-3.1.1-7.12.src.rpm
-SLES11 SP1: dhcp-3.1.3.ESV-0.3.38.src.rpm
-
-It also contains the patches for the (production) dhcp sources for 4.2.0 and
-4.1.1-P1.
-
-
-Building from SRPM
-
-The directory also contains 4 patches per source RPM:
-1. Basic LPF based IB patch for dhcp-<version> (along the lines of
-Sébastien Dugue (<sebastien.dugue@bull.net>)
-patch: http://lists.openfabrics.org/pipermail/ewg/2010-May/015266.html) -
-a few bug fixes and also stripped out default client ID for IB for dhclient
-
-dhcp-3.0.5-lpf-ib.patch
-dhcp-4.1.0p1-lpf-ib.patch
-dhcp-3.1.1-lpf-ib.dif
-
-2. Better transaction ID support for dhclient which is important for IB
-(trivial change from Matthieu Hattreux
-<matthieu.hautreux@cea.fr>: https://lists.isc.org/mailman/htdig/dhcp-hackers/2009-January/001773.html)
-
-dhcp-3.0.5-improved-xid.patch
-dhcp-4.1.0p1-improved-xid.patch
-dhcp-3.1.1-improved-xid.dif
-
-3. gpxe style default client ID for dhclient (needed for anaconda
-builds; optional for normal builds)
-
-dhcp-3.0.5-gpxe-cid.patch
-dhcp-4.1.0p1-gpxe-cid.patch
-dhcp-3.1.1-gpxe-cid.dif
-
-4. Source RPM patch to dhcp.spec
-
-For normal builds:
-dhcp-3.0.5-rhel54.patch
-dhcp-3.0.5-rhel55-2.patch
-dhcp-3.0.5-rhel55.patch
-dhcp-4.1.0p1-rhel6.patch
-dhcp-3.1.1-sles11.dif
-dhcp-3.1.3-sles11sp1.dif
-
-For anaconda builds:
-dhcp-3.0.5-rhel54-gpxe.patch
-dhcp-3.0.5-rhel55-2-gpxe.patch
-dhcp-3.0.5-rhel55-gpxe.patch
-dhcp-4.1.0p1-rhel6-gpxe.patch
-dhcp-3.1.1-sles11-gpxe.dif
-dhcp-3.1.3-sles11sp1-gpxe.dif
-
-
-Build Procedure:
-
-1. Have the rpmbuild command use another directory (e.g. /home/your_userid/rpm)
-
-2. Create the following subdirectories in that directory:
-
-cd /home/your_userid/rpm
-mkdir SOURCES SPECS BUILD SRPMS
-mkdir -p RPMS/i386 RPMS/i486 RPMS/i586 RPMS/i686 RPMS/x86_64 RPMS/noarch
-
-3. Install the .src.rpm file this way:
-
-rpm -i dhcp-<ver>.src.rpm
-
-This will create files in the SOURCES directory of your RPM building directory tree, and a .spec file in the SPECS directory.
-
-4. Copy the lpf-ib.[patch or dif], improved-xid.[patch or dif], and
-gxpe-cid.[patch or dif] for the appropriate version to
-/home/your_userid/rpm/SOURCES
-
-5. Copy dhcp.spec patch for the appropriate version to /home/your_userid/rpm/SPECS and apply to dhcp.spec via patch command (patch <dhcp-<version>.patch)
-
-6. Go the SPECS directory and give the command to build the RPM:
-
-cd /home/your_userid/rpm/SPECS
-rpmbuild --define '%_topdir /home/your_userid/rpm' -bb dhcp.spec
-
-NOTE: The build should be performed on a machine with the appropriate distro.
-With SLES(11), the build will not succeed without doing this.
-
-7. Install rpms from RPMS/<arch>
-or alternatively executables are:
-BUILD/dhcp-3.0.5/work.linux-2.2/server/dhcpd
-BUILD/dhcp-3.0.5/work.linux-2.2/client/dhclient
-or
-BUILD/dhcp-4.1.0p1/server/dhcpd
-BUILD/dhcp-4.1.0p1/client/dhclient
-or
-BUILD/dhcp-3.1.1/work.linux-2.2/server/dhcpd
-BUILD/dhcp-3.1.1/work.linux-2.2/client/dhclient
-or
-BUILD/dhcp-3.1-ESV/work.linux-2.2/server/dhcpd
-BUILD/dhcp-3.1-ESV/work.linux-2.2/client/dhclient
-depending on version
-
-
-Building from DHCP Source
-
-There are 5 patches for the two supported versions of the DHCP source.
-They are:
-dhcp-<version>-xen-checksum.patch
-dhcp-<version>-options.patch
-dhcp-<version>-lpf-ib.patch
-dhcp-<version>-improved-xid.patch
-dhcp-<version>-gpxe-cid.patch
-The first two are variants of the RedHat supplied patches in the srpms.
-
-1. Download and install the DHCP source from http://ftp.isc.org/isc/dhcp/
-
-2. Apply patches in order listed above
-
-3. Follow build and install instructions in dhcp README
+++ /dev/null
-From 37cb19b5b3da9a8c3f61eeb3c4fa5885c70a4375 Mon Sep 17 00:00:00 2001
-From: Eli Cohen <eli@mellanox.co.il>
-Date: Tue, 23 Jun 2009 10:11:55 +0300
-Subject: [PATCH] Make DHCP server print HW info
-
-When the DHCP server gets a request, it prints to the log file the HW address
-which sent the request. Since for IPoIB the HW address is not conveyed on
-messages, this patch will put the client identifer in the HW address. This is
-fine since we put the HW address in the client identifier.
-
-Signed-off-by: Eli Cohen <eli@mellanox.co.il>
----
- common/discover.c | 4 ++--
- server/dhcp.c | 12 ++++++++++++
- 2 files changed, 14 insertions(+), 2 deletions(-)
-
-diff --git a/common/discover.c b/common/discover.c
-index b0387d0..c4f7200 100644
---- a/common/discover.c
-+++ b/common/discover.c
-@@ -533,9 +533,9 @@ void discover_interfaces (state)
- #endif
-
- case ARPHRD_INFINIBAND:
-- tmp -> hw_address.hlen = 1;
-+ tmp -> hw_address.hlen = 16;
- tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-- memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 20);
-+ memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 16);
- break;
-
- default:
-diff --git a/server/dhcp.c b/server/dhcp.c
-index 1c90a6c..b558cfb 100644
---- a/server/dhcp.c
-+++ b/server/dhcp.c
-@@ -262,6 +262,18 @@ void dhcpdiscover (packet, ms_nulltp)
- #if defined (FAILOVER_PROTOCOL)
- dhcp_failover_state_t *peer;
- #endif
-+ struct option_cache *oc;
-+
-+ if (packet->raw->htype == ARPHRD_INFINIBAND) {
-+ oc = lookup_option (&dhcp_universe, packet->options, DHO_DHCP_CLIENT_IDENTIFIER);
-+ if (oc) {
-+ int len;
-+
-+ len = oc->data.len > 16 ? 16 : oc->data.len;
-+ packet->raw->hlen = len;
-+ memcpy(packet->raw->chaddr, oc->data.data, len);
-+ }
-+ }
-
- find_lease (&lease, packet, packet -> shared_network,
- 0, &peer_has_leases, (struct lease *)0, MDL);
---
-1.6.3.2
-
+++ /dev/null
-Index: dhcp-3.0.4/includes/site.h
-===================================================================
---- dhcp-3.0.4.orig/includes/site.h 2002-03-12 20:33:39.000000000 +0200
-+++ dhcp-3.0.4/includes/site.h 2006-05-23 11:34:38.000000000 +0300
-@@ -135,7 +135,7 @@
- the aforementioned problems do not matter to you, or if no other
- API is supported for your system, you may want to go with it. */
-
--/* #define USE_SOCKETS */
-+#define USE_SOCKETS
-
- /* Define this to use the Sun Streams NIT API.
-
-Index: dhcp-3.0.4/common/discover.c
-===================================================================
---- dhcp-3.0.4.orig/common/discover.c 2006-02-23 00:43:27.000000000 +0200
-+++ dhcp-3.0.4/common/discover.c 2006-05-23 11:45:16.000000000 +0300
-@@ -532,6 +532,12 @@ void discover_interfaces (state)
- break;
- #endif
-
-+ case ARPHRD_INFINIBAND:
-+ tmp -> hw_address.hlen = 1;
-+ tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 20);
-+ break;
-+
- default:
- log_error ("%s: unknown hardware address type %d",
- ifr.ifr_name, sa.sa_family);
+++ /dev/null
-diff -up dhcp-4.1.1-P1/client/dhclient.c.xid dhcp-4.1.1-P1/client/dhclient.c\r
---- dhcp-4.1.1-P1/client/dhclient.c.xid 2010-09-23 06:23:02.000000000 -0400\r
-+++ dhcp-4.1.1-P1/client/dhclient.c 2010-09-23 09:18:10.000000000 -0400\r
-@@ -784,6 +784,26 @@ main(int argc, char **argv) {\r
- }\r
- }\r
- \r
-+ /* We create a backup seed before rediscovering interfaces in order to\r
-+ have a seed built using all of the available interfaces\r
-+ It's interesting if required interfaces doesn't let us defined\r
-+ a really unique seed due to a lack of valid HW addr later\r
-+ (this is the case with DHCP over IB)\r
-+ We only use the last device as using a sum could broke the\r
-+ uniqueness of the seed among multiple nodes\r
-+ */\r
-+ unsigned backup_seed = 0;\r
-+ for (ip = interfaces; ip; ip = ip -> next) {\r
-+ int junk;\r
-+ if ( ip -> hw_address.hlen <= sizeof seed )\r
-+ continue;\r
-+ memcpy (&junk,\r
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -\r
-+ sizeof seed], sizeof seed);\r
-+ backup_seed = junk;\r
-+ }\r
-+\r
-+\r
- /* At this point, all the interfaces that the script thinks\r
- are relevant should be running, so now we once again call\r
- discover_interfaces(), and this time ask it to actually set\r
-@@ -798,14 +818,36 @@ main(int argc, char **argv) {\r
- Not much entropy, but we're booting, so we're not likely to\r
- find anything better. */\r
- seed = 0;\r
-+ int seed_flag = 0;\r
- for (ip = interfaces; ip; ip = ip->next) {\r
- int junk;\r
-+ if ( ip -> hw_address.hlen <= sizeof seed )\r
-+ continue;\r
- memcpy(&junk,\r
- &ip->hw_address.hbuf[ip->hw_address.hlen -\r
- sizeof seed], sizeof seed);\r
- seed += junk;\r
-+ seed_flag = 1;\r
- }\r
-- srandom(seed + cur_time);\r
-+ if ( seed_flag == 0 ) {\r
-+ if ( backup_seed != 0 ) {\r
-+ seed = backup_seed;\r
-+ log_info ("xid: rand init seed (0x%x) built using all"\r
-+ " available interfaces",seed);\r
-+ }\r
-+ else {\r
-+ seed = cur_time^((unsigned) gethostid()) ;\r
-+ log_info ("xid: warning: no netdev with useable HWADDR found"\r
-+ " for seed's uniqueness enforcement");\r
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",\r
-+ seed);\r
-+ }\r
-+ /* we only use seed and no current time as a broadcast reply */\r
-+ /* will certainly be used by the hwaddrless interface */\r
-+ srandom(seed);\r
-+ }\r
-+ else\r
-+ srandom(seed + cur_time);\r
- \r
- /* Setup specific Infiniband options */\r
- for (ip = interfaces; ip; ip = ip->next) {\r
-@@ -1289,7 +1331,7 @@ void dhcpack (packet)\r
- return;\r
- }\r
- \r
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));\r
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);\r
- \r
- lease = packet_to_lease (packet, client);\r
- if (!lease) {\r
-@@ -1988,7 +2030,7 @@ void dhcpnak (packet)\r
- return;\r
- }\r
- \r
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));\r
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);\r
- \r
- if (!client -> active) {\r
- #if defined (DEBUG)\r
-@@ -2114,10 +2156,10 @@ void send_discover (cpp)\r
- client -> packet.secs = htons (65535);\r
- client -> secs = client -> packet.secs;\r
- \r
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",\r
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (sockaddr_broadcast.sin_addr),\r
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));\r
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);\r
- \r
- /* Send out a packet. */\r
- result = send_packet (client -> interface, (struct packet *)0,\r
-@@ -2372,10 +2414,10 @@ void send_request (cpp)\r
- client -> packet.secs = htons (65535);\r
- }\r
- \r
-- log_info ("DHCPREQUEST on %s to %s port %d",\r
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (destination.sin_addr),\r
-- ntohs (destination.sin_port));\r
-+ ntohs (destination.sin_port), client -> xid);\r
- \r
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&\r
- fallback_interface)\r
-@@ -2405,10 +2447,10 @@ void send_decline (cpp)\r
- \r
- int result;\r
- \r
-- log_info ("DHCPDECLINE on %s to %s port %d",\r
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (sockaddr_broadcast.sin_addr),\r
-- ntohs (sockaddr_broadcast.sin_port));\r
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);\r
- \r
- /* Send out a packet. */\r
- result = send_packet (client -> interface, (struct packet *)0,\r
-@@ -2448,10 +2490,10 @@ void send_release (cpp)\r
- return;\r
- }\r
- \r
-- log_info ("DHCPRELEASE on %s to %s port %d",\r
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (destination.sin_addr),\r
-- ntohs (destination.sin_port));\r
-+ ntohs (destination.sin_port), client -> xid);\r
- \r
- if (fallback_interface)\r
- result = send_packet (fallback_interface,\r
+++ /dev/null
-diff -up dhcp-4.1.1-P1/common/lpf.c.ib dhcp-4.1.1-P1/common/lpf.c\r
---- dhcp-4.1.1-P1/common/lpf.c.ib 2010-09-23 05:32:12.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/lpf.c 2010-09-23 06:23:57.000000000 -0400\r
-@@ -42,6 +42,7 @@\r
- #include "includes/netinet/udp.h"\r
- #include "includes/netinet/if_ether.h"\r
- #include <net/if.h>\r
-+#include <ifaddrs.h>\r
- \r
- #ifndef PACKET_AUXDATA\r
- #define PACKET_AUXDATA 8\r
-@@ -59,6 +60,15 @@ struct tpacket_auxdata\r
- /* Reinitializes the specified interface after an address change. This\r
- is not required for packet-filter APIs. */\r
- \r
-+/* Default broadcast address for IPoIB */\r
-+static unsigned char default_ib_bcast_addr[20] = {\r
-+ 0x00, 0xff, 0xff, 0xff,\r
-+ 0xff, 0x12, 0x40, 0x1b,\r
-+ 0x00, 0x00, 0x00, 0x00,\r
-+ 0x00, 0x00, 0x00, 0x00,\r
-+ 0xff, 0xff, 0xff, 0xff\r
-+};\r
-+\r
- #ifdef USE_LPF_SEND\r
- void if_reinitialize_send (info)\r
- struct interface_info *info;\r
-@@ -86,10 +96,21 @@ int if_register_lpf (info)\r
- struct sockaddr common;\r
- } sa;\r
- struct ifreq ifr;\r
-+ int type;\r
-+ int protocol;\r
- \r
- /* Make an LPF socket. */\r
-- if ((sock = socket(PF_PACKET, SOCK_RAW,\r
-- htons((short)ETH_P_ALL))) < 0) {\r
-+ get_hw_addr(info);\r
-+\r
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ type = SOCK_DGRAM;\r
-+ protocol = ETHERTYPE_IP;\r
-+ } else {\r
-+ type = SOCK_RAW;\r
-+ protocol = ETH_P_ALL;\r
-+ }\r
-+\r
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||\r
- errno == EAFNOSUPPORT || errno == EINVAL) {\r
-@@ -111,6 +132,7 @@ int if_register_lpf (info)\r
- /* Bind to the interface name */\r
- memset (&sa, 0, sizeof sa);\r
- sa.ll.sll_family = AF_PACKET;\r
-+ sa.ll.sll_protocol = htons(protocol);\r
- sa.ll.sll_ifindex = ifr.ifr_ifindex;\r
- if (bind (sock, &sa.common, sizeof sa)) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
-@@ -126,8 +148,6 @@ int if_register_lpf (info)\r
- log_fatal ("Bind socket to interface: %m");\r
- }\r
- \r
-- get_hw_addr(info->name, &info->hw_address);\r
--\r
- return sock;\r
- }\r
- #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */\r
-@@ -182,6 +202,8 @@ void if_deregister_send (info)\r
- in bpf includes... */\r
- extern struct sock_filter dhcp_bpf_filter [];\r
- extern int dhcp_bpf_filter_len;\r
-+extern struct sock_filter dhcp_ib_bpf_filter [];\r
-+extern int dhcp_ib_bpf_filter_len;\r
- \r
- #if defined (HAVE_TR_SUPPORT)\r
- extern struct sock_filter dhcp_bpf_tr_filter [];\r
-@@ -199,11 +221,13 @@ void if_register_receive (info)\r
- /* Open a LPF device and hang it on this interface... */\r
- info -> rfdesc = if_register_lpf (info);\r
- \r
-- val = 1;\r
-- if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,\r
-- sizeof val) < 0) {\r
-- if (errno != ENOPROTOOPT)\r
-- log_fatal ("Failed to set auxiliary packet data: %m");\r
-+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {\r
-+ val = 1;\r
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA,\r
-+ &val, sizeof val) < 0) {\r
-+ if (errno != ENOPROTOOPT)\r
-+ log_fatal ("Failed to set auxiliary packet data: %m");\r
-+ }\r
- }\r
- \r
- #if defined (HAVE_TR_SUPPORT)\r
-@@ -249,15 +273,28 @@ static void lpf_gen_filter_setup (info)\r
- \r
- memset(&p, 0, sizeof(p));\r
- \r
-- /* Set up the bpf filter program structure. This is defined in\r
-- bpf.c */\r
-- p.len = dhcp_bpf_filter_len;\r
-- p.filter = dhcp_bpf_filter;\r
--\r
-- /* Patch the server port into the LPF program...\r
-- XXX changes to filter program may require changes\r
-- to the insn number(s) used below! XXX */\r
-- dhcp_bpf_filter [8].k = ntohs ((short)local_port);\r
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ /* Set up the bpf filter program structure. */\r
-+ p.len = dhcp_ib_bpf_filter_len;\r
-+ p.filter = dhcp_ib_bpf_filter;\r
-+\r
-+ /* Patch the server port into the LPF program...\r
-+ XXX\r
-+ changes to filter program may require changes\r
-+ to the insn number(s) used below!\r
-+ XXX */\r
-+ dhcp_ib_bpf_filter[6].k = ntohs ((short)local_port);\r
-+ } else {\r
-+ /* Set up the bpf filter program structure.\r
-+ This is defined in bpf.c */\r
-+ p.len = dhcp_bpf_filter_len;\r
-+ p.filter = dhcp_bpf_filter;\r
-+\r
-+ /* Patch the server port into the LPF program...\r
-+ XXX changes to filter program may require changes\r
-+ to the insn number(s) used below! XXX */\r
-+ dhcp_bpf_filter [8].k = ntohs ((short)local_port);\r
-+ }\r
- \r
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,\r
- sizeof p) < 0) {\r
-@@ -314,6 +351,54 @@ static void lpf_tr_filter_setup (info)\r
- #endif /* USE_LPF_RECEIVE */\r
- \r
- #ifdef USE_LPF_SEND\r
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)\r
-+ struct interface_info *interface;\r
-+ struct packet *packet;\r
-+ struct dhcp_packet *raw;\r
-+ size_t len;\r
-+ struct in_addr from;\r
-+ struct sockaddr_in *to;\r
-+ struct hardware *hto;\r
-+{\r
-+ unsigned ibufp = 0;\r
-+ double ih [1536 / sizeof (double)];\r
-+ unsigned char *buf = (unsigned char *)ih;\r
-+ ssize_t result;\r
-+\r
-+ union sockunion {\r
-+ struct sockaddr sa;\r
-+ struct sockaddr_ll sll;\r
-+ struct sockaddr_storage ss;\r
-+ } su;\r
-+\r
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,\r
-+ to->sin_addr.s_addr, to->sin_port,\r
-+ (unsigned char *)raw, len);\r
-+ memcpy (buf + ibufp, raw, len);\r
-+\r
-+ memset(&su, 0, sizeof(su));\r
-+ su.sll.sll_family = AF_PACKET;\r
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);\r
-+\r
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {\r
-+ errno = ENOENT;\r
-+ log_error ("send_packet_ib: %m - failed to get if index");\r
-+ return -1;\r
-+ }\r
-+\r
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);\r
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);\r
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);\r
-+\r
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,\r
-+ &su.sa, sizeof(su));\r
-+\r
-+ if (result < 0)\r
-+ log_error ("send_packet_ib: %m");\r
-+\r
-+ return result;\r
-+}\r
-+\r
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)\r
- struct interface_info *interface;\r
- struct packet *packet;\r
-@@ -334,6 +419,11 @@ ssize_t send_packet (interface, packet, \r
- return send_fallback (interface, packet, raw,\r
- len, from, to, hto);\r
- \r
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ return send_packet_ib(interface, packet, raw, len, from,\r
-+ to, hto);\r
-+ }\r
-+\r
- /* Assemble the headers... */\r
- assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto);\r
- fudge = hbufp % 4; /* IP header must be word-aligned. */\r
-@@ -352,6 +442,42 @@ ssize_t send_packet (interface, packet, \r
- #endif /* USE_LPF_SEND */\r
- \r
- #ifdef USE_LPF_RECEIVE\r
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)\r
-+ struct interface_info *interface;\r
-+ unsigned char *buf;\r
-+ size_t len;\r
-+ struct sockaddr_in *from;\r
-+ struct hardware *hfrom;\r
-+{\r
-+ int length = 0;\r
-+ int offset = 0;\r
-+ unsigned char ibuf [1536];\r
-+ unsigned bufix = 0;\r
-+ unsigned paylen;\r
-+\r
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));\r
-+\r
-+ if (length <= 0)\r
-+ return length;\r
-+\r
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,\r
-+ (unsigned)length, &paylen, 0);\r
-+\r
-+ if (offset < 0)\r
-+ return 0;\r
-+\r
-+ bufix += offset;\r
-+ length -= offset;\r
-+\r
-+ if (length < paylen)\r
-+ log_fatal("Internal inconsistency at %s:%d.", MDL);\r
-+\r
-+ /* Copy out the data in the packet... */\r
-+ memcpy(buf, &ibuf[bufix], paylen);\r
-+\r
-+ return (ssize_t)paylen;\r
-+}\r
-+\r
- ssize_t receive_packet (interface, buf, len, from, hfrom)\r
- struct interface_info *interface;\r
- unsigned char *buf;\r
-@@ -378,6 +504,10 @@ ssize_t receive_packet (interface, buf, \r
- };\r
- struct cmsghdr *cmsg;\r
- \r
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ return receive_packet_ib(interface, buf, len, from, hfrom);\r
-+ }\r
-+\r
- length = recvmsg (interface -> rfdesc, &msg, 0);\r
- if (length <= 0)\r
- return length;\r
-@@ -458,33 +588,41 @@ void maybe_setup_fallback ()\r
- }\r
- \r
- void\r
--get_hw_addr(const char *name, struct hardware *hw) {\r
-- int sock;\r
-- struct ifreq tmp;\r
-- struct sockaddr *sa;\r
-+get_hw_addr(struct interface_info *info)\r
-+{\r
-+ struct hardware *hw = &info->hw_address;\r
-+ char *name = info->name;\r
-+ struct ifaddrs *ifaddrs;\r
-+ struct ifaddrs *ifa;\r
-+ struct sockaddr_ll *sll = NULL;\r
- \r
-- if (strlen(name) >= sizeof(tmp.ifr_name)) {\r
-- log_fatal("Device name too long: \"%s\"", name);\r
-- }\r
-+ if (getifaddrs(&ifaddrs) == -1)\r
-+ log_fatal("Failed to get interfaces");\r
-+\r
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {\r
-+\r
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)\r
-+ continue;\r
- \r
-- sock = socket(AF_INET, SOCK_DGRAM, 0);\r
-- if (sock < 0) {\r
-- log_fatal("Can't create socket for \"%s\": %m", name);\r
-+ if (ifa->ifa_flags & IFF_LOOPBACK)\r
-+ continue;\r
-+\r
-+ if (strcmp(ifa->ifa_name, name) == 0) {\r
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;\r
-+ break;\r
-+ }\r
- }\r
- \r
-- memset(&tmp, 0, sizeof(tmp));\r
-- strcpy(tmp.ifr_name, name);\r
-- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {\r
-- log_fatal("Error getting hardware address for \"%s\": %m", \r
-- name);\r
-+ if (sll == NULL) {\r
-+ freeifaddrs(ifaddrs);\r
-+ log_fatal("Failed to get HW address for %s\n", name);\r
- }\r
- \r
-- sa = &tmp.ifr_hwaddr;\r
-- switch (sa->sa_family) {\r
-+ switch (sll->sll_hatype) {\r
- case ARPHRD_ETHER:\r
- hw->hlen = 7;\r
- hw->hbuf[0] = HTYPE_ETHER;\r
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);\r
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);\r
- break;\r
- case ARPHRD_IEEE802:\r
- #ifdef ARPHRD_IEEE802_TR\r
-@@ -492,18 +630,36 @@ get_hw_addr(const char *name, struct har\r
- #endif /* ARPHRD_IEEE802_TR */\r
- hw->hlen = 7;\r
- hw->hbuf[0] = HTYPE_IEEE802;\r
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);\r
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);\r
- break;\r
- case ARPHRD_FDDI:\r
- hw->hlen = 17;\r
- hw->hbuf[0] = HTYPE_FDDI;\r
-- memcpy(&hw->hbuf[1], sa->sa_data, 16);\r
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 16);\r
-+ break;\r
-+ case ARPHRD_INFINIBAND:\r
-+ /* For Infiniband, save the broadcast address and store\r
-+ * the port GUID into the hardware address.\r
-+ */\r
-+ if (ifa->ifa_flags & IFF_BROADCAST) {\r
-+ struct sockaddr_ll *bll;\r
-+\r
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;\r
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);\r
-+ } else {\r
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,\r
-+ 20);\r
-+ }\r
-+\r
-+ hw->hlen = 1;\r
-+ hw->hbuf[0] = HTYPE_INFINIBAND;\r
- break;\r
- default:\r
-+ freeifaddrs(ifaddrs);\r
- log_fatal("Unsupported device type %ld for \"%s\"",\r
-- (long int)sa->sa_family, name);\r
-+ (long int)sll->sll_family, name);\r
- }\r
- \r
-- close(sock);\r
-+ freeifaddrs(ifaddrs);\r
- }\r
- #endif\r
-diff -up dhcp-4.1.1-P1/includes/dhcp.h.ib dhcp-4.1.1-P1/includes/dhcp.h\r
---- dhcp-4.1.1-P1/includes/dhcp.h.ib 2009-07-24 18:04:52.000000000 -0400\r
-+++ dhcp-4.1.1-P1/includes/dhcp.h 2010-09-23 06:23:02.000000000 -0400\r
-@@ -79,6 +79,7 @@ struct dhcp_packet {\r
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */\r
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */\r
- #define HTYPE_FDDI 8 /* FDDI... */\r
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */\r
- \r
- /* Magic cookie validating dhcp options field (and bootp vendor\r
- extensions field). */\r
-diff -up dhcp-4.1.1-P1/client/dhclient.c.ib dhcp-4.1.1-P1/client/dhclient.c\r
---- dhcp-4.1.1-P1/client/dhclient.c.ib 2010-09-23 06:12:26.000000000 -0400\r
-+++ dhcp-4.1.1-P1/client/dhclient.c 2010-09-23 06:23:02.000000000 -0400\r
-@@ -98,6 +98,29 @@ static void usage(void);\r
- \r
- static isc_result_t write_duid(struct data_string *duid);\r
- \r
-+static void setup_ib_interface(struct interface_info *ip)\r
-+{\r
-+ struct group *g;\r
-+\r
-+ /* Set the broadcast flag */\r
-+ ip->client->config->bootp_broadcast_always = 1;\r
-+\r
-+ /*\r
-+ * Find out if a dhcp-client-identifier option was specified either\r
-+ * in the config file or on the command line\r
-+ */\r
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {\r
-+ if ((g->statements != NULL) &&\r
-+ (strcmp(g->statements->data.option->option->name,\r
-+ "dhcp-client-identifier") == 0)) {\r
-+ return;\r
-+ }\r
-+ }\r
-+\r
-+ /* No client ID specified */\r
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");\r
-+}\r
-+\r
- int\r
- main(int argc, char **argv) {\r
- int fd;\r
-@@ -784,6 +807,14 @@ main(int argc, char **argv) {\r
- }\r
- srandom(seed + cur_time);\r
- \r
-+ /* Setup specific Infiniband options */\r
-+ for (ip = interfaces; ip; ip = ip->next) {\r
-+ if (ip->client &&\r
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {\r
-+ setup_ib_interface(ip);\r
-+ }\r
-+ }\r
-+\r
- /* Start a configuration state machine for each interface. */\r
- #ifdef DHCPv6\r
- if (local_family == AF_INET6) {\r
-diff -up dhcp-4.1.1-P1/common/bpf.c.ib dhcp-4.1.1-P1/common/bpf.c\r
---- dhcp-4.1.1-P1/common/bpf.c.ib 2010-09-23 05:32:12.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/bpf.c 2010-09-23 06:38:35.000000000 -0400\r
-@@ -116,7 +116,7 @@ int if_register_bpf (info)\r
- log_fatal ("Can't attach interface %s to bpf device %s: %m",\r
- info -> name, filename);\r
- \r
-- get_hw_addr(info->name, &info->hw_address);\r
-+ get_hw_addr(info);\r
- \r
- return sock;\r
- }\r
-@@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = {\r
- BPF_STMT(BPF_RET+BPF_K, 0),\r
- };\r
- \r
-+/* Packet filter program for DHCP over Infiniband.\r
-+ *\r
-+ * XXX\r
-+ * Changes to the filter program may require changes to the constant offsets\r
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!\r
-+ * XXX\r
-+ */\r
-+struct bpf_insn dhcp_ib_bpf_filter [] = {\r
-+ /* Packet filter for Infiniband */\r
-+ /* Make sure it's a UDP packet... */\r
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),\r
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),\r
-+\r
-+ /* Make sure this isn't a fragment... */\r
-+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),\r
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),\r
-+\r
-+ /* Get the IP header length... */\r
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),\r
-+\r
-+ /* Make sure it's to the right port... */\r
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),\r
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),\r
-+\r
-+ /* If we passed all the tests, ask for the whole packet. */\r
-+ BPF_STMT(BPF_RET + BPF_K, (u_int)-1),\r
-+\r
-+ /* Otherwise, drop it. */\r
-+ BPF_STMT(BPF_RET + BPF_K, 0),\r
-+};\r
-+\r
- #if defined (DEC_FDDI)\r
- struct bpf_insn *bpf_fddi_filter;\r
- #endif\r
- \r
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);\r
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);\r
-+\r
- #if defined (HAVE_TR_SUPPORT)\r
- struct bpf_insn dhcp_bpf_tr_filter [] = {\r
- /* accept all token ring packets due to variable length header */\r
-@@ -549,7 +582,9 @@ void maybe_setup_fallback ()\r
- }\r
- \r
- void\r
--get_hw_addr(const char *name, struct hardware *hw) {\r
-+get_hw_addr(struct interface_info *info) {\r
-+ struct hardware *hw = &info->hw_address;\r
-+ char *name = info->name;\r
- struct ifaddrs *ifa;\r
- struct ifaddrs *p;\r
- struct sockaddr_dl *sa;\r
-diff -up dhcp-4.1.1-P1/common/socket.c.ib dhcp-4.1.1-P1/common/socket.c\r
---- dhcp-4.1.1-P1/common/socket.c.ib 2009-07-24 18:04:52.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/socket.c 2010-09-23 06:23:02.000000000 -0400\r
-@@ -276,7 +276,7 @@ if_register_socket(struct interface_info\r
- \r
- /* If this is a normal IPv4 address, get the hardware address. */\r
- if ((local_family == AF_INET) && (strcmp(info->name, "fallback") != 0))\r
-- get_hw_addr(info->name, &info->hw_address);\r
-+ get_hw_addr(info);\r
- \r
- return sock;\r
- }\r
-@@ -422,7 +422,7 @@ if_register6(struct interface_info *info\r
- if (req_multi)\r
- if_register_multicast(info);\r
- \r
-- get_hw_addr(info->name, &info->hw_address);\r
-+ get_hw_addr(info);\r
- \r
- if (!quiet_interface_discovery) {\r
- if (info->shared_network != NULL) {\r
-diff -up dhcp-4.1.1-P1/includes/dhcpd.h.ib dhcp-4.1.1-P1/includes/dhcpd.h\r
---- dhcp-4.1.1-P1/includes/dhcpd.h.ib 2010-09-23 06:07:35.000000000 -0400\r
-+++ dhcp-4.1.1-P1/includes/dhcpd.h 2010-09-23 06:23:02.000000000 -0400\r
-@@ -1111,6 +1111,7 @@ struct interface_info {\r
- struct shared_network *shared_network;\r
- /* Networks connected to this interface. */\r
- struct hardware hw_address; /* Its physical address. */\r
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */\r
- struct in_addr *addresses; /* Addresses associated with this\r
- * interface.\r
- */\r
-@@ -2143,7 +2144,7 @@ void print_dns_status (int, ns_updque *)\r
- #endif\r
- const char *print_time(TIME);\r
- \r
--void get_hw_addr(const char *name, struct hardware *hw);\r
-+void get_hw_addr(struct interface_info *info);\r
- \r
- /* socket.c */\r
- #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \\r
-diff -up dhcp-4.1.1-P1/common/dlpi.c.ib dhcp-4.1.1-P1/common/dlpi.c\r
---- dhcp-4.1.1-P1/common/dlpi.c.ib 2010-09-23 05:32:12.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/dlpi.c 2010-09-23 06:39:04.000000000 -0400\r
-@@ -1339,7 +1339,9 @@ void maybe_setup_fallback ()\r
- #endif /* USE_DLPI_SEND */\r
- \r
- void \r
--get_hw_addr(const char *name, struct hardware *hw) {\r
-+get_hw_addr(struct interface_info *info) {\r
-+ struct hardware *hw = &info->hw_address;\r
-+ char *name = info->name;\r
- int sock, unit;\r
- long buf[DLPI_MAXDLBUF];\r
- union DL_primitives *dlp;\r
+++ /dev/null
-diff -up dhcp-4.1.1-P1/client/clparse.c.options dhcp-4.1.1-P1/client/clparse.c\r
---- dhcp-4.1.1-P1/client/clparse.c.options 2009-07-24 18:04:51.000000000 -0400\r
-+++ dhcp-4.1.1-P1/client/clparse.c 2010-09-23 06:07:35.000000000 -0400\r
-@@ -136,6 +136,7 @@ isc_result_t read_client_conf ()\r
- /* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)\r
- */\r
- top_level_config.requested_lease = 7200;\r
-+ top_level_config.bootp_broadcast_always = 0;\r
- \r
- group_allocate (&top_level_config.on_receipt, MDL);\r
- if (!top_level_config.on_receipt)\r
-@@ -303,7 +304,8 @@ void read_client_leases ()\r
- interface-declaration |\r
- LEASE client-lease-statement |\r
- ALIAS client-lease-statement |\r
-- KEY key-definition */\r
-+ KEY key-definition |\r
-+ BOOTP_BROADCAST_ALWAYS */\r
- \r
- void parse_client_statement (cfile, ip, config)\r
- struct parse *cfile;\r
-@@ -706,6 +708,12 @@ void parse_client_statement (cfile, ip, \r
- parse_reject_statement (cfile, config);\r
- return;\r
- \r
-+ case BOOTP_BROADCAST_ALWAYS:\r
-+ token = next_token(&val, (unsigned*)0, cfile);\r
-+ config -> bootp_broadcast_always = 1;\r
-+ parse_semi (cfile);\r
-+ return;\r
-+\r
- default:\r
- lose = 0;\r
- stmt = (struct executable_statement *)0;\r
-diff -up dhcp-4.1.1-P1/client/dhclient.c.options dhcp-4.1.1-P1/client/dhclient.c\r
---- dhcp-4.1.1-P1/client/dhclient.c.options 2010-01-07 16:53:52.000000000 -0500\r
-+++ dhcp-4.1.1-P1/client/dhclient.c 2010-09-23 06:12:26.000000000 -0400\r
-@@ -38,6 +38,12 @@\r
- #include <sys/wait.h>\r
- #include <limits.h>\r
- \r
-+/*\r
-+ * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define\r
-+ * that when building ISC code.\r
-+ */\r
-+extern int asprintf(char **strp, const char *fmt, ...);\r
-+\r
- TIME default_lease_time = 43200; /* 12 hours... */\r
- TIME max_lease_time = 86400; /* 24 hours... */\r
- \r
-@@ -82,6 +88,9 @@ int wanted_ia_na = -1; /* the absolute \r
- int wanted_ia_ta = 0;\r
- int wanted_ia_pd = 0;\r
- char *mockup_relay = NULL;\r
-+int bootp_broadcast_always = 0;\r
-+\r
-+extern u_int32_t default_requested_options[];\r
- \r
- void run_stateless(int exit_mode);\r
- \r
-@@ -112,6 +121,15 @@ main(int argc, char **argv) {\r
- int local_family_set = 0;\r
- #endif /* DHCPv6 */\r
- char *s;\r
-+ char *dhcp_client_identifier_arg = NULL;\r
-+ char *dhcp_host_name_arg = NULL;\r
-+ char *dhcp_fqdn_arg = NULL;\r
-+ char *dhcp_vendor_class_identifier_arg = NULL;\r
-+ char *dhclient_request_options = NULL;\r
-+\r
-+ int timeout_arg = 0;\r
-+ char *arg_conf = NULL;\r
-+ int arg_conf_len = 0;\r
- \r
- /* Initialize client globals. */\r
- memset(&default_duid, 0, sizeof(default_duid));\r
-@@ -276,6 +294,88 @@ main(int argc, char **argv) {\r
- } else if (!strcmp(argv[i], "--version")) {\r
- log_info("isc-dhclient-%s", PACKAGE_VERSION);\r
- exit(0);\r
-+ } else if (!strcmp(argv[i], "-I")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-I option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_client_identifier_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-B")) {\r
-+ bootp_broadcast_always = 1;\r
-+ } else if (!strcmp(argv[i], "-H")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-H option host-name string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (dhcp_host_name_arg != NULL) {\r
-+ log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_host_name_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-F")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (dhcp_fqdn_arg != NULL) {\r
-+ log_error("Only one -F <fqdn> argument can be specified");\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (dhcp_host_name_arg != NULL) {\r
-+ log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_fqdn_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-timeout")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if ((timeout_arg = atoi(argv[i])) <= 0) {\r
-+ log_error("-T timeout option must be > 0 - bad value: %s",argv[i]);\r
-+ exit(1);\r
-+ }\r
-+ } else if (!strcmp(argv[i], "-V")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_vendor_class_identifier_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-R")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhclient_request_options = argv[i];\r
- } else if (argv[i][0] == '-') {\r
- usage();\r
- } else if (interfaces_requested < 0) {\r
-@@ -445,6 +545,166 @@ main(int argc, char **argv) {\r
- /* Parse the dhclient.conf file. */\r
- read_client_conf();\r
- \r
-+ /* Parse any extra command line configuration arguments: */\r
-+ if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -I option dhcp-client-identifier");\r
-+ }\r
-+\r
-+ if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -H option host-name");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -H option host-name");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -F option fqdn.fqdn");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -F option fqdn.fqdn");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if (timeout_arg) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "timeout %d;", timeout_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to process -timeout timeout argument");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len == 0))\r
-+ log_fatal("Unable to process -timeout timeout argument");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -V option vendor-class-identifier");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -V option vendor-class-identifier");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if (dhclient_request_options != NULL) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "request %s;", dhclient_request_options);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to parse -R <request options list> argument");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to parse -R <request options list> argument");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if (arg_conf) {\r
-+ if (arg_conf_len == 0)\r
-+ if ((arg_conf_len = strlen(arg_conf)) == 0)\r
-+ /* huh ? cannot happen ! */\r
-+ log_fatal("Unable to process -I/-H/-F/-timeout/-V/-R configuration arguments");\r
-+\r
-+ /* parse the extra dhclient.conf configuration arguments\r
-+ * into top level config: */\r
-+ struct parse *cfile = (struct parse *)0;\r
-+ const char *val = NULL;\r
-+ int token;\r
-+\r
-+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -I/-H/-F/-timeout/-V/-R configuration arguments", 0);\r
-+\r
-+ if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))\r
-+ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R configuration arguments !");\r
-+ /* more detailed parse failures will be logged */\r
-+\r
-+ do {\r
-+ token = peek_token(&val, (unsigned *)0, cfile);\r
-+ if (token == END_OF_FILE)\r
-+ break;\r
-+\r
-+ parse_client_statement(cfile, (struct interface_info *)0, &top_level_config);\r
-+ } while (1);\r
-+\r
-+ if (cfile -> warnings_occurred)\r
-+ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R configuration arguments !");\r
-+ end_parse(&cfile);\r
-+\r
-+ if (timeout_arg) {\r
-+ /* we just set the toplevel timeout, but per-client\r
-+ * timeouts may still be at defaults. Also, it makes no\r
-+ * sense having the reboot_timeout or backoff_cutoff\r
-+ * greater than the timeout:\r
-+ */\r
-+ if ((top_level_config.backoff_cutoff == 15) && (top_level_config.backoff_cutoff > (timeout_arg / 2)))\r
-+ top_level_config.backoff_cutoff = (((unsigned long)(timeout_arg / 2)) == 0) ? timeout_arg : (unsigned long)(timeout_arg / 2);\r
-+\r
-+ for (ip=interfaces; ip; ip = ip->next) {\r
-+ if (ip->client->config->timeout == 60)\r
-+ ip->client->config->timeout = timeout_arg;\r
-+\r
-+ if ((ip->client->config->reboot_timeout == 10) && (ip->client->config->reboot_timeout > ip->client->config->timeout))\r
-+ ip->client->config->reboot_timeout = ip->client->config->timeout;\r
-+ if ((ip->client->config->backoff_cutoff == 15) && (ip->client->config->backoff_cutoff > top_level_config.backoff_cutoff))\r
-+ ip->client->config->backoff_cutoff = top_level_config.backoff_cutoff;\r
-+ }\r
-+ }\r
-+\r
-+ if ((dhclient_request_options != 0) && (top_level_config.requested_options != (void *) default_requested_options)) {\r
-+ for (ip=interfaces; ip; ip = ip->next) {\r
-+ if (ip->client->config->requested_options == (void *) default_requested_options)\r
-+ ip->client->config->requested_options = top_level_config.requested_options;\r
-+ }\r
-+ }\r
-+\r
-+ free(arg_conf);\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = 0;\r
-+ }\r
-+\r
- /* Parse the lease database. */\r
- read_client_leases();\r
- \r
-@@ -2315,7 +2575,8 @@ void make_discover (client, lease)\r
- client -> packet.xid = random ();\r
- client -> packet.secs = 0; /* filled in by send_discover. */\r
- \r
-- if (can_receive_unicast_unconfigured (client -> interface))\r
-+ if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always))\r
-+ && can_receive_unicast_unconfigured(client->interface))\r
- client -> packet.flags = 0;\r
- else\r
- client -> packet.flags = htons (BOOTP_BROADCAST);\r
-@@ -2399,7 +2660,9 @@ void make_request (client, lease)\r
- } else {\r
- memset (&client -> packet.ciaddr, 0,\r
- sizeof client -> packet.ciaddr);\r
-- if (can_receive_unicast_unconfigured (client -> interface))\r
-+ if ((!(bootp_broadcast_always ||\r
-+ client ->config->bootp_broadcast_always)) &&\r
-+ can_receive_unicast_unconfigured (client -> interface))\r
- client -> packet.flags = 0;\r
- else\r
- client -> packet.flags = htons (BOOTP_BROADCAST);\r
-@@ -2461,7 +2724,8 @@ void make_decline (client, lease)\r
- client -> packet.hops = 0;\r
- client -> packet.xid = client -> xid;\r
- client -> packet.secs = 0; /* Filled in by send_request. */\r
-- if (can_receive_unicast_unconfigured (client -> interface))\r
-+ if ((!(bootp_broadcast_always || client->config-> bootp_broadcast_always))\r
-+ && can_receive_unicast_unconfigured (client->interface))\r
- client -> packet.flags = 0;\r
- else\r
- client -> packet.flags = htons (BOOTP_BROADCAST);\r
-diff -up dhcp-4.1.1-P1/common/conflex.c.options dhcp-4.1.1-P1/common/conflex.c\r
---- dhcp-4.1.1-P1/common/conflex.c.options 2009-07-23 15:02:09.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/conflex.c 2010-09-23 06:07:35.000000000 -0400\r
-@@ -774,6 +774,8 @@ intern(char *atom, enum dhcp_token dfv) \r
- return BALANCE;\r
- if (!strcasecmp (atom + 1, "ound"))\r
- return BOUND;\r
-+ if (!strcasecmp (atom + 1, "ootp-broadcast-always"))\r
-+ return BOOTP_BROADCAST_ALWAYS;\r
- break;\r
- case 'c':\r
- if (!strcasecmp(atom + 1, "ase"))\r
-diff -up dhcp-4.1.1-P1/includes/dhcpd.h.options dhcp-4.1.1-P1/includes/dhcpd.h\r
---- dhcp-4.1.1-P1/includes/dhcpd.h.options 2010-09-23 05:32:12.000000000 -0400\r
-+++ dhcp-4.1.1-P1/includes/dhcpd.h 2010-09-23 06:07:35.000000000 -0400\r
-@@ -1024,6 +1024,9 @@ struct client_config {\r
- int do_forward_update; /* If nonzero, and if we have the\r
- information we need, update the\r
- A record for the address we get. */\r
-+\r
-+ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST\r
-+ flag in requests */\r
- };\r
- \r
- /* Per-interface state used in the dhcp client... */\r
-diff -up dhcp-4.1.1-P1/includes/dhctoken.h.options dhcp-4.1.1-P1/includes/dhctoken.h\r
---- dhcp-4.1.1-P1/includes/dhctoken.h.options 2009-07-23 15:02:09.000000000 -0400\r
-+++ dhcp-4.1.1-P1/includes/dhctoken.h 2010-09-23 06:09:00.000000000 -0400\r
-@@ -353,7 +353,8 @@ enum dhcp_token {\r
- TEMPORARY = 656,\r
- PREFIX6 = 657,\r
- FIXED_PREFIX6 = 658,\r
-- CONFLICT_DONE = 660\r
-+ CONFLICT_DONE = 660,\r
-+ BOOTP_BROADCAST_ALWAYS = 661\r
- };\r
- \r
- #define is_identifier(x) ((x) >= FIRST_TOKEN && \\r
+++ /dev/null
-diff -up dhcp-4.1.1-P1/common/bpf.c.xen dhcp-4.1.1-P1/common/bpf.c\r
---- dhcp-4.1.1-P1/common/bpf.c.xen 2009-07-24 18:04:52.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/bpf.c 2010-09-23 05:32:12.000000000 -0400\r
-@@ -482,7 +482,7 @@ ssize_t receive_packet (interface, buf, \r
- offset = decode_udp_ip_header (interface,\r
- interface -> rbuf,\r
- interface -> rbuf_offset,\r
-- from, hdr.bh_caplen, &paylen);\r
-+ from, hdr.bh_caplen, &paylen, 0);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0) {\r
-diff -up dhcp-4.1.1-P1/common/dlpi.c.xen dhcp-4.1.1-P1/common/dlpi.c\r
---- dhcp-4.1.1-P1/common/dlpi.c.xen 2009-07-23 15:02:09.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/dlpi.c 2010-09-23 05:32:12.000000000 -0400\r
-@@ -691,7 +691,7 @@ ssize_t receive_packet (interface, buf, \r
- length -= offset;\r
- #endif\r
- offset = decode_udp_ip_header (interface, dbuf, bufix,\r
-- from, length, &paylen);\r
-+ from, length, &paylen, 0);\r
- \r
- /*\r
- * If the IP or UDP checksum was bad, skip the packet...\r
-diff -up dhcp-4.1.1-P1/common/lpf.c.xen dhcp-4.1.1-P1/common/lpf.c\r
---- dhcp-4.1.1-P1/common/lpf.c.xen 2009-07-23 15:02:09.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/lpf.c 2010-09-23 05:32:12.000000000 -0400\r
-@@ -29,18 +29,33 @@\r
- #include "dhcpd.h"\r
- #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)\r
- #include <sys/ioctl.h>\r
-+#include <sys/socket.h>\r
- #include <sys/uio.h>\r
- #include <errno.h>\r
- \r
- #include <asm/types.h>\r
- #include <linux/filter.h>\r
- #include <linux/if_ether.h>\r
-+#include <linux/if_packet.h>\r
- #include <netinet/in_systm.h>\r
- #include "includes/netinet/ip.h"\r
- #include "includes/netinet/udp.h"\r
- #include "includes/netinet/if_ether.h"\r
- #include <net/if.h>\r
- \r
-+#ifndef PACKET_AUXDATA\r
-+#define PACKET_AUXDATA 8\r
-+\r
-+struct tpacket_auxdata\r
-+{\r
-+ __u32 tp_status;\r
-+ __u32 tp_len;\r
-+ __u32 tp_snaplen;\r
-+ __u16 tp_mac;\r
-+ __u16 tp_net;\r
-+};\r
-+#endif\r
-+\r
- /* Reinitializes the specified interface after an address change. This\r
- is not required for packet-filter APIs. */\r
- \r
-@@ -66,10 +81,14 @@ int if_register_lpf (info)\r
- struct interface_info *info;\r
- {\r
- int sock;\r
-- struct sockaddr sa;\r
-+ union {\r
-+ struct sockaddr_ll ll;\r
-+ struct sockaddr common;\r
-+ } sa;\r
-+ struct ifreq ifr;\r
- \r
- /* Make an LPF socket. */\r
-- if ((sock = socket(PF_PACKET, SOCK_PACKET,\r
-+ if ((sock = socket(PF_PACKET, SOCK_RAW,\r
- htons((short)ETH_P_ALL))) < 0) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||\r
-@@ -84,11 +103,16 @@ int if_register_lpf (info)\r
- log_fatal ("Open a socket for LPF: %m");\r
- }\r
- \r
-+ memset (&ifr, 0, sizeof ifr);\r
-+ strncpy (ifr.ifr_name, (const char *)info -> ifp, sizeof ifr.ifr_name);\r
-+ if (ioctl (sock, SIOCGIFINDEX, &ifr))\r
-+ log_fatal ("Failed to get interface index: %m");\r
-+\r
- /* Bind to the interface name */\r
- memset (&sa, 0, sizeof sa);\r
-- sa.sa_family = AF_PACKET;\r
-- strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data);\r
-- if (bind (sock, &sa, sizeof sa)) {\r
-+ sa.ll.sll_family = AF_PACKET;\r
-+ sa.ll.sll_ifindex = ifr.ifr_ifindex;\r
-+ if (bind (sock, &sa.common, sizeof sa)) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||\r
- errno == EAFNOSUPPORT || errno == EINVAL) {\r
-@@ -170,9 +194,18 @@ static void lpf_gen_filter_setup (struct\r
- void if_register_receive (info)\r
- struct interface_info *info;\r
- {\r
-+ int val;\r
-+\r
- /* Open a LPF device and hang it on this interface... */\r
- info -> rfdesc = if_register_lpf (info);\r
- \r
-+ val = 1;\r
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,\r
-+ sizeof val) < 0) {\r
-+ if (errno != ENOPROTOOPT)\r
-+ log_fatal ("Failed to set auxiliary packet data: %m");\r
-+ }\r
-+\r
- #if defined (HAVE_TR_SUPPORT)\r
- if (info -> hw_address.hbuf [0] == HTYPE_IEEE802)\r
- lpf_tr_filter_setup (info);\r
-@@ -294,7 +327,6 @@ ssize_t send_packet (interface, packet, \r
- double hh [16];\r
- double ih [1536 / sizeof (double)];\r
- unsigned char *buf = (unsigned char *)ih;\r
-- struct sockaddr sa;\r
- int result;\r
- int fudge;\r
- \r
-@@ -312,15 +344,7 @@ ssize_t send_packet (interface, packet, \r
- (unsigned char *)raw, len);\r
- memcpy (buf + ibufp, raw, len);\r
- \r
-- /* For some reason, SOCK_PACKET sockets can't be connected,\r
-- so we have to do a sentdo every time. */\r
-- memset (&sa, 0, sizeof sa);\r
-- sa.sa_family = AF_PACKET;\r
-- strncpy (sa.sa_data,\r
-- (const char *)interface -> ifp, sizeof sa.sa_data);\r
--\r
-- result = sendto (interface -> wfdesc,\r
-- buf + fudge, ibufp + len - fudge, 0, &sa, sizeof sa);\r
-+ result = write (interface -> wfdesc, buf + fudge, ibufp + len - fudge);\r
- if (result < 0)\r
- log_error ("send_packet: %m");\r
- return result;\r
-@@ -337,14 +361,35 @@ ssize_t receive_packet (interface, buf, \r
- {\r
- int length = 0;\r
- int offset = 0;\r
-+ int nocsum = 0;\r
- unsigned char ibuf [1536];\r
- unsigned bufix = 0;\r
- unsigned paylen;\r
-+ unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];\r
-+ struct iovec iov = {\r
-+ .iov_base = ibuf,\r
-+ .iov_len = sizeof ibuf,\r
-+ };\r
-+ struct msghdr msg = {\r
-+ .msg_iov = &iov,\r
-+ .msg_iovlen = 1,\r
-+ .msg_control = cmsgbuf,\r
-+ .msg_controllen = sizeof(cmsgbuf),\r
-+ };\r
-+ struct cmsghdr *cmsg;\r
- \r
-- length = read (interface -> rfdesc, ibuf, sizeof ibuf);\r
-+ length = recvmsg (interface -> rfdesc, &msg, 0);\r
- if (length <= 0)\r
- return length;\r
- \r
-+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {\r
-+ if (cmsg->cmsg_level == SOL_PACKET &&\r
-+ cmsg->cmsg_type == PACKET_AUXDATA) {\r
-+ struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);\r
-+ nocsum = aux->tp_status & TP_STATUS_CSUMNOTREADY;\r
-+ }\r
-+ }\r
-+\r
- bufix = 0;\r
- /* Decode the physical header... */\r
- offset = decode_hw_header (interface, ibuf, bufix, hfrom);\r
-@@ -361,7 +406,7 @@ ssize_t receive_packet (interface, buf, \r
- \r
- /* Decode the IP and UDP headers... */\r
- offset = decode_udp_ip_header (interface, ibuf, bufix, from,\r
-- (unsigned)length, &paylen);\r
-+ (unsigned)length, &paylen, nocsum);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0)\r
-diff -up dhcp-4.1.1-P1/common/nit.c.xen dhcp-4.1.1-P1/common/nit.c\r
---- dhcp-4.1.1-P1/common/nit.c.xen 2009-07-24 18:04:52.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/nit.c 2010-09-23 05:32:12.000000000 -0400\r
-@@ -366,7 +366,7 @@ ssize_t receive_packet (interface, buf, \r
- \r
- /* Decode the IP and UDP headers... */\r
- offset = decode_udp_ip_header (interface, ibuf, bufix,\r
-- from, length, &paylen);\r
-+ from, length, &paylen, 0);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0)\r
-diff -up dhcp-4.1.1-P1/common/packet.c.xen dhcp-4.1.1-P1/common/packet.c\r
---- dhcp-4.1.1-P1/common/packet.c.xen 2009-07-23 15:02:09.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/packet.c 2010-09-23 05:32:12.000000000 -0400\r
-@@ -211,7 +211,7 @@ ssize_t\r
- decode_udp_ip_header(struct interface_info *interface,\r
- unsigned char *buf, unsigned bufix,\r
- struct sockaddr_in *from, unsigned buflen,\r
-- unsigned *rbuflen)\r
-+ unsigned *rbuflen, int nocsum)\r
- {\r
- unsigned char *data;\r
- struct ip ip;\r
-@@ -322,7 +322,7 @@ decode_udp_ip_header(struct interface_in\r
- 8, IPPROTO_UDP + ulen))));\r
- \r
- udp_packets_seen++;\r
-- if (usum && usum != sum) {\r
-+ if (!nocsum && usum && usum != sum) {\r
- udp_packets_bad_checksum++;\r
- if (udp_packets_seen > 4 &&\r
- (udp_packets_seen / udp_packets_bad_checksum) < 2) {\r
-diff -up dhcp-4.1.1-P1/common/upf.c.xen dhcp-4.1.1-P1/common/upf.c\r
---- dhcp-4.1.1-P1/common/upf.c.xen 2009-07-24 18:04:52.000000000 -0400\r
-+++ dhcp-4.1.1-P1/common/upf.c 2010-09-23 05:32:12.000000000 -0400\r
-@@ -317,7 +317,7 @@ ssize_t receive_packet (interface, buf, \r
- \r
- /* Decode the IP and UDP headers... */\r
- offset = decode_udp_ip_header (interface, ibuf, bufix,\r
-- from, length, &paylen);\r
-+ from, length, &paylen, 0);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0)\r
-diff -up dhcp-4.1.1-P1/includes/dhcpd.h.xen dhcp-4.1.1-P1/includes/dhcpd.h\r
---- dhcp-4.1.1-P1/includes/dhcpd.h.xen 2009-07-23 15:02:09.000000000 -0400\r
-+++ dhcp-4.1.1-P1/includes/dhcpd.h 2010-09-23 05:32:12.000000000 -0400\r
-@@ -2586,7 +2586,7 @@ ssize_t decode_hw_header PROTO ((struct \r
- unsigned, struct hardware *));\r
- ssize_t decode_udp_ip_header PROTO ((struct interface_info *, unsigned char *,\r
- unsigned, struct sockaddr_in *,\r
-- unsigned, unsigned *));\r
-+ unsigned, unsigned *, int));\r
- \r
- /* ethernet.c */\r
- void assemble_ethernet_header PROTO ((struct interface_info *, unsigned char *,\r
+++ /dev/null
-diff -up dhcp-4.2.0/client/dhclient.c.xid dhcp-4.2.0/client/dhclient.c\r
---- dhcp-4.2.0/client/dhclient.c.xid 2010-09-23 06:21:03.000000000 -0400\r
-+++ dhcp-4.2.0/client/dhclient.c 2010-09-23 09:14:09.000000000 -0400\r
-@@ -805,6 +805,26 @@ main(int argc, char **argv) {\r
- }\r
- }\r
- \r
-+ /* We create a backup seed before rediscovering interfaces in order to\r
-+ have a seed built using all of the available interfaces\r
-+ It's interesting if required interfaces doesn't let us defined\r
-+ a really unique seed due to a lack of valid HW addr later\r
-+ (this is the case with DHCP over IB)\r
-+ We only use the last device as using a sum could broke the\r
-+ uniqueness of the seed among multiple nodes\r
-+ */\r
-+ unsigned backup_seed = 0;\r
-+ for (ip = interfaces; ip; ip = ip -> next) {\r
-+ int junk;\r
-+ if ( ip -> hw_address.hlen <= sizeof seed )\r
-+ continue;\r
-+ memcpy (&junk,\r
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -\r
-+ sizeof seed], sizeof seed);\r
-+ backup_seed = junk;\r
-+ }\r
-+\r
-+\r
- /* At this point, all the interfaces that the script thinks\r
- are relevant should be running, so now we once again call\r
- discover_interfaces(), and this time ask it to actually set\r
-@@ -819,14 +839,36 @@ main(int argc, char **argv) {\r
- Not much entropy, but we're booting, so we're not likely to\r
- find anything better. */\r
- seed = 0;\r
-+ int seed_flag = 0;\r
- for (ip = interfaces; ip; ip = ip->next) {\r
- int junk;\r
-+ if ( ip -> hw_address.hlen <= sizeof seed )\r
-+ continue;\r
- memcpy(&junk,\r
- &ip->hw_address.hbuf[ip->hw_address.hlen -\r
- sizeof seed], sizeof seed);\r
- seed += junk;\r
-+ seed_flag = 1;\r
- }\r
-- srandom(seed + cur_time);\r
-+ if ( seed_flag == 0 ) {\r
-+ if ( backup_seed != 0 ) {\r
-+ seed = backup_seed;\r
-+ log_info ("xid: rand init seed (0x%x) built using all"\r
-+ " available interfaces",seed);\r
-+ }\r
-+ else {\r
-+ seed = cur_time^((unsigned) gethostid()) ;\r
-+ log_info ("xid: warning: no netdev with useable HWADDR found"\r
-+ " for seed's uniqueness enforcement");\r
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",\r
-+ seed);\r
-+ }\r
-+ /* we only use seed and no current time as a broadcast reply */\r
-+ /* will certainly be used by the hwaddrless interface */\r
-+ srandom(seed);\r
-+ }\r
-+ else\r
-+ srandom(seed + cur_time);\r
- \r
- /* Setup specific Infiniband options */\r
- for (ip = interfaces; ip; ip = ip->next) {\r
-@@ -1310,7 +1352,7 @@ void dhcpack (packet)\r
- return;\r
- }\r
- \r
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));\r
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);\r
- \r
- lease = packet_to_lease (packet, client);\r
- if (!lease) {\r
-@@ -2010,7 +2052,7 @@ void dhcpnak (packet)\r
- return;\r
- }\r
- \r
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));\r
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);\r
- \r
- if (!client -> active) {\r
- #if defined (DEBUG)\r
-@@ -2136,10 +2178,10 @@ void send_discover (cpp)\r
- client -> packet.secs = htons (65535);\r
- client -> secs = client -> packet.secs;\r
- \r
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",\r
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (sockaddr_broadcast.sin_addr),\r
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));\r
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);\r
- \r
- /* Send out a packet. */\r
- result = send_packet (client -> interface, (struct packet *)0,\r
-@@ -2394,10 +2436,10 @@ void send_request (cpp)\r
- client -> packet.secs = htons (65535);\r
- }\r
- \r
-- log_info ("DHCPREQUEST on %s to %s port %d",\r
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (destination.sin_addr),\r
-- ntohs (destination.sin_port));\r
-+ ntohs (destination.sin_port), client -> xid);\r
- \r
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&\r
- fallback_interface)\r
-@@ -2427,10 +2469,10 @@ void send_decline (cpp)\r
- \r
- int result;\r
- \r
-- log_info ("DHCPDECLINE on %s to %s port %d",\r
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (sockaddr_broadcast.sin_addr),\r
-- ntohs (sockaddr_broadcast.sin_port));\r
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);\r
- \r
- /* Send out a packet. */\r
- result = send_packet (client -> interface, (struct packet *)0,\r
-@@ -2470,10 +2512,10 @@ void send_release (cpp)\r
- return;\r
- }\r
- \r
-- log_info ("DHCPRELEASE on %s to %s port %d",\r
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",\r
- client -> name ? client -> name : client -> interface -> name,\r
- inet_ntoa (destination.sin_addr),\r
-- ntohs (destination.sin_port));\r
-+ ntohs (destination.sin_port), client -> xid);\r
- \r
- if (fallback_interface)\r
- result = send_packet (fallback_interface,\r
+++ /dev/null
-diff -up dhcp-4.2.0/common/lpf.c.ib dhcp-4.2.0/common/lpf.c\r
---- dhcp-4.2.0/common/lpf.c.ib 2010-09-23 05:24:09.000000000 -0400\r
-+++ dhcp-4.2.0/common/lpf.c 2010-09-23 06:21:03.000000000 -0400\r
-@@ -42,6 +42,7 @@\r
- #include "includes/netinet/udp.h"\r
- #include "includes/netinet/if_ether.h"\r
- #include <net/if.h>\r
-+#include <ifaddrs.h>\r
- \r
- #ifndef PACKET_AUXDATA\r
- #define PACKET_AUXDATA 8\r
-@@ -59,6 +60,15 @@ struct tpacket_auxdata\r
- /* Reinitializes the specified interface after an address change. This\r
- is not required for packet-filter APIs. */\r
- \r
-+/* Default broadcast address for IPoIB */\r
-+static unsigned char default_ib_bcast_addr[20] = {\r
-+ 0x00, 0xff, 0xff, 0xff,\r
-+ 0xff, 0x12, 0x40, 0x1b,\r
-+ 0x00, 0x00, 0x00, 0x00,\r
-+ 0x00, 0x00, 0x00, 0x00,\r
-+ 0xff, 0xff, 0xff, 0xff\r
-+};\r
-+\r
- #ifdef USE_LPF_SEND\r
- void if_reinitialize_send (info)\r
- struct interface_info *info;\r
-@@ -86,10 +96,21 @@ int if_register_lpf (info)\r
- struct sockaddr common;\r
- } sa;\r
- struct ifreq ifr;\r
-+ int type;\r
-+ int protocol;\r
- \r
- /* Make an LPF socket. */\r
-- if ((sock = socket(PF_PACKET, SOCK_RAW,\r
-- htons((short)ETH_P_ALL))) < 0) {\r
-+ get_hw_addr(info);\r
-+\r
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ type = SOCK_DGRAM;\r
-+ protocol = ETHERTYPE_IP;\r
-+ } else {\r
-+ type = SOCK_RAW;\r
-+ protocol = ETH_P_ALL;\r
-+ }\r
-+\r
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||\r
- errno == EAFNOSUPPORT || errno == EINVAL) {\r
-@@ -111,6 +132,7 @@ int if_register_lpf (info)\r
- /* Bind to the interface name */\r
- memset (&sa, 0, sizeof sa);\r
- sa.ll.sll_family = AF_PACKET;\r
-+ sa.ll.sll_protocol = htons(protocol);\r
- sa.ll.sll_ifindex = ifr.ifr_ifindex;\r
- if (bind (sock, &sa.common, sizeof sa)) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
-@@ -126,8 +148,6 @@ int if_register_lpf (info)\r
- log_fatal ("Bind socket to interface: %m");\r
- }\r
- \r
-- get_hw_addr(info->name, &info->hw_address);\r
--\r
- return sock;\r
- }\r
- #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */\r
-@@ -182,6 +202,8 @@ void if_deregister_send (info)\r
- in bpf includes... */\r
- extern struct sock_filter dhcp_bpf_filter [];\r
- extern int dhcp_bpf_filter_len;\r
-+extern struct sock_filter dhcp_ib_bpf_filter [];\r
-+extern int dhcp_ib_bpf_filter_len;\r
- \r
- #if defined (HAVE_TR_SUPPORT)\r
- extern struct sock_filter dhcp_bpf_tr_filter [];\r
-@@ -199,11 +221,13 @@ void if_register_receive (info)\r
- /* Open a LPF device and hang it on this interface... */\r
- info -> rfdesc = if_register_lpf (info);\r
- \r
-- val = 1;\r
-- if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,\r
-- sizeof val) < 0) {\r
-- if (errno != ENOPROTOOPT)\r
-- log_fatal ("Failed to set auxiliary packet data: %m");\r
-+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {\r
-+ val = 1;\r
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA,\r
-+ &val, sizeof val) < 0) {\r
-+ if (errno != ENOPROTOOPT)\r
-+ log_fatal ("Failed to set auxiliary packet data: %m");\r
-+ }\r
- }\r
- \r
- #if defined (HAVE_TR_SUPPORT)\r
-@@ -249,15 +273,28 @@ static void lpf_gen_filter_setup (info)\r
- \r
- memset(&p, 0, sizeof(p));\r
- \r
-- /* Set up the bpf filter program structure. This is defined in\r
-- bpf.c */\r
-- p.len = dhcp_bpf_filter_len;\r
-- p.filter = dhcp_bpf_filter;\r
--\r
-- /* Patch the server port into the LPF program...\r
-- XXX changes to filter program may require changes\r
-- to the insn number(s) used below! XXX */\r
-- dhcp_bpf_filter [8].k = ntohs ((short)local_port);\r
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ /* Set up the bpf filter program structure. */\r
-+ p.len = dhcp_ib_bpf_filter_len;\r
-+ p.filter = dhcp_ib_bpf_filter;\r
-+\r
-+ /* Patch the server port into the LPF program...\r
-+ XXX\r
-+ changes to filter program may require changes\r
-+ to the insn number(s) used below!\r
-+ XXX */\r
-+ dhcp_ib_bpf_filter[6].k = ntohs ((short)local_port);\r
-+ } else {\r
-+ /* Set up the bpf filter program structure.\r
-+ This is defined in bpf.c */\r
-+ p.len = dhcp_bpf_filter_len;\r
-+ p.filter = dhcp_bpf_filter;\r
-+\r
-+ /* Patch the server port into the LPF program...\r
-+ XXX changes to filter program may require changes\r
-+ to the insn number(s) used below! XXX */\r
-+ dhcp_bpf_filter [8].k = ntohs ((short)local_port);\r
-+ }\r
- \r
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,\r
- sizeof p) < 0) {\r
-@@ -314,6 +351,54 @@ static void lpf_tr_filter_setup (info)\r
- #endif /* USE_LPF_RECEIVE */\r
- \r
- #ifdef USE_LPF_SEND\r
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)\r
-+ struct interface_info *interface;\r
-+ struct packet *packet;\r
-+ struct dhcp_packet *raw;\r
-+ size_t len;\r
-+ struct in_addr from;\r
-+ struct sockaddr_in *to;\r
-+ struct hardware *hto;\r
-+{\r
-+ unsigned ibufp = 0;\r
-+ double ih [1536 / sizeof (double)];\r
-+ unsigned char *buf = (unsigned char *)ih;\r
-+ ssize_t result;\r
-+\r
-+ union sockunion {\r
-+ struct sockaddr sa;\r
-+ struct sockaddr_ll sll;\r
-+ struct sockaddr_storage ss;\r
-+ } su;\r
-+\r
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,\r
-+ to->sin_addr.s_addr, to->sin_port,\r
-+ (unsigned char *)raw, len);\r
-+ memcpy (buf + ibufp, raw, len);\r
-+\r
-+ memset(&su, 0, sizeof(su));\r
-+ su.sll.sll_family = AF_PACKET;\r
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);\r
-+\r
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {\r
-+ errno = ENOENT;\r
-+ log_error ("send_packet_ib: %m - failed to get if index");\r
-+ return -1;\r
-+ }\r
-+\r
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);\r
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);\r
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);\r
-+\r
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,\r
-+ &su.sa, sizeof(su));\r
-+\r
-+ if (result < 0)\r
-+ log_error ("send_packet_ib: %m");\r
-+\r
-+ return result;\r
-+}\r
-+\r
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)\r
- struct interface_info *interface;\r
- struct packet *packet;\r
-@@ -334,6 +419,11 @@ ssize_t send_packet (interface, packet, \r
- return send_fallback (interface, packet, raw,\r
- len, from, to, hto);\r
- \r
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ return send_packet_ib(interface, packet, raw, len, from,\r
-+ to, hto);\r
-+ }\r
-+\r
- if (hto == NULL && interface->anycast_mac_addr.hlen)\r
- hto = &interface->anycast_mac_addr;\r
- \r
-@@ -355,6 +445,42 @@ ssize_t send_packet (interface, packet, \r
- #endif /* USE_LPF_SEND */\r
- \r
- #ifdef USE_LPF_RECEIVE\r
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)\r
-+ struct interface_info *interface;\r
-+ unsigned char *buf;\r
-+ size_t len;\r
-+ struct sockaddr_in *from;\r
-+ struct hardware *hfrom;\r
-+{\r
-+ int length = 0;\r
-+ int offset = 0;\r
-+ unsigned char ibuf [1536];\r
-+ unsigned bufix = 0;\r
-+ unsigned paylen;\r
-+\r
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));\r
-+\r
-+ if (length <= 0)\r
-+ return length;\r
-+\r
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,\r
-+ (unsigned)length, &paylen, 0);\r
-+\r
-+ if (offset < 0)\r
-+ return 0;\r
-+\r
-+ bufix += offset;\r
-+ length -= offset;\r
-+\r
-+ if (length < paylen)\r
-+ log_fatal("Internal inconsistency at %s:%d.", MDL);\r
-+\r
-+ /* Copy out the data in the packet... */\r
-+ memcpy(buf, &ibuf[bufix], paylen);\r
-+\r
-+ return (ssize_t)paylen;\r
-+}\r
-+\r
- ssize_t receive_packet (interface, buf, len, from, hfrom)\r
- struct interface_info *interface;\r
- unsigned char *buf;\r
-@@ -381,6 +507,10 @@ ssize_t receive_packet (interface, buf, \r
- };\r
- struct cmsghdr *cmsg;\r
- \r
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {\r
-+ return receive_packet_ib(interface, buf, len, from, hfrom);\r
-+ }\r
-+\r
- length = recvmsg (interface -> rfdesc, &msg, 0);\r
- if (length <= 0)\r
- return length;\r
-@@ -461,33 +591,41 @@ void maybe_setup_fallback ()\r
- }\r
- \r
- void\r
--get_hw_addr(const char *name, struct hardware *hw) {\r
-- int sock;\r
-- struct ifreq tmp;\r
-- struct sockaddr *sa;\r
-+get_hw_addr(struct interface_info *info)\r
-+{\r
-+ struct hardware *hw = &info->hw_address;\r
-+ char *name = info->name;\r
-+ struct ifaddrs *ifaddrs;\r
-+ struct ifaddrs *ifa;\r
-+ struct sockaddr_ll *sll = NULL;\r
- \r
-- if (strlen(name) >= sizeof(tmp.ifr_name)) {\r
-- log_fatal("Device name too long: \"%s\"", name);\r
-- }\r
-+ if (getifaddrs(&ifaddrs) == -1)\r
-+ log_fatal("Failed to get interfaces");\r
-+\r
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {\r
-+\r
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)\r
-+ continue;\r
- \r
-- sock = socket(AF_INET, SOCK_DGRAM, 0);\r
-- if (sock < 0) {\r
-- log_fatal("Can't create socket for \"%s\": %m", name);\r
-+ if (ifa->ifa_flags & IFF_LOOPBACK)\r
-+ continue;\r
-+\r
-+ if (strcmp(ifa->ifa_name, name) == 0) {\r
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;\r
-+ break;\r
-+ }\r
- }\r
- \r
-- memset(&tmp, 0, sizeof(tmp));\r
-- strcpy(tmp.ifr_name, name);\r
-- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {\r
-- log_fatal("Error getting hardware address for \"%s\": %m", \r
-- name);\r
-+ if (sll == NULL) {\r
-+ freeifaddrs(ifaddrs);\r
-+ log_fatal("Failed to get HW address for %s\n", name);\r
- }\r
- \r
-- sa = &tmp.ifr_hwaddr;\r
-- switch (sa->sa_family) {\r
-+ switch (sll->sll_hatype) {\r
- case ARPHRD_ETHER:\r
- hw->hlen = 7;\r
- hw->hbuf[0] = HTYPE_ETHER;\r
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);\r
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);\r
- break;\r
- case ARPHRD_IEEE802:\r
- #ifdef ARPHRD_IEEE802_TR\r
-@@ -495,18 +633,36 @@ get_hw_addr(const char *name, struct har\r
- #endif /* ARPHRD_IEEE802_TR */\r
- hw->hlen = 7;\r
- hw->hbuf[0] = HTYPE_IEEE802;\r
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);\r
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);\r
- break;\r
- case ARPHRD_FDDI:\r
- hw->hlen = 17;\r
- hw->hbuf[0] = HTYPE_FDDI;\r
-- memcpy(&hw->hbuf[1], sa->sa_data, 16);\r
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 16);\r
-+ break;\r
-+ case ARPHRD_INFINIBAND:\r
-+ /* For Infiniband, save the broadcast address and store\r
-+ * the port GUID into the hardware address.\r
-+ */\r
-+ if (ifa->ifa_flags & IFF_BROADCAST) {\r
-+ struct sockaddr_ll *bll;\r
-+\r
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;\r
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);\r
-+ } else {\r
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,\r
-+ 20);\r
-+ }\r
-+\r
-+ hw->hlen = 1;\r
-+ hw->hbuf[0] = HTYPE_INFINIBAND;\r
- break;\r
- default:\r
-+ freeifaddrs(ifaddrs);\r
- log_fatal("Unsupported device type %ld for \"%s\"",\r
-- (long int)sa->sa_family, name);\r
-+ (long int)sll->sll_family, name);\r
- }\r
- \r
-- close(sock);\r
-+ freeifaddrs(ifaddrs);\r
- }\r
- #endif\r
-diff -up dhcp-4.2.0/includes/dhcp.h.ib dhcp-4.2.0/includes/dhcp.h\r
---- dhcp-4.2.0/includes/dhcp.h.ib 2009-11-19 20:49:01.000000000 -0500\r
-+++ dhcp-4.2.0/includes/dhcp.h 2010-09-23 06:21:03.000000000 -0400\r
-@@ -79,6 +79,7 @@ struct dhcp_packet {\r
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */\r
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */\r
- #define HTYPE_FDDI 8 /* FDDI... */\r
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */\r
- \r
- /* Magic cookie validating dhcp options field (and bootp vendor\r
- extensions field). */\r
-diff -up dhcp-4.2.0/client/dhclient.c.ib dhcp-4.2.0/client/dhclient.c\r
---- dhcp-4.2.0/client/dhclient.c.ib 2010-09-23 06:11:14.000000000 -0400\r
-+++ dhcp-4.2.0/client/dhclient.c 2010-09-23 06:21:03.000000000 -0400\r
-@@ -98,6 +98,29 @@ static void usage(void);\r
- \r
- static isc_result_t write_duid(struct data_string *duid);\r
- \r
-+static void setup_ib_interface(struct interface_info *ip)\r
-+{\r
-+ struct group *g;\r
-+\r
-+ /* Set the broadcast flag */\r
-+ ip->client->config->bootp_broadcast_always = 1;\r
-+\r
-+ /*\r
-+ * Find out if a dhcp-client-identifier option was specified either\r
-+ * in the config file or on the command line\r
-+ */\r
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {\r
-+ if ((g->statements != NULL) &&\r
-+ (strcmp(g->statements->data.option->option->name,\r
-+ "dhcp-client-identifier") == 0)) {\r
-+ return;\r
-+ }\r
-+ }\r
-+\r
-+ /* No client ID specified */\r
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");\r
-+}\r
-+\r
- int\r
- main(int argc, char **argv) {\r
- int fd;\r
-@@ -805,6 +828,14 @@ main(int argc, char **argv) {\r
- }\r
- srandom(seed + cur_time);\r
- \r
-+ /* Setup specific Infiniband options */\r
-+ for (ip = interfaces; ip; ip = ip->next) {\r
-+ if (ip->client &&\r
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {\r
-+ setup_ib_interface(ip);\r
-+ }\r
-+ }\r
-+\r
- /* Start a configuration state machine for each interface. */\r
- #ifdef DHCPv6\r
- if (local_family == AF_INET6) {\r
-diff -up dhcp-4.2.0/common/bpf.c.ib dhcp-4.2.0/common/bpf.c\r
---- dhcp-4.2.0/common/bpf.c.ib 2010-09-23 05:24:01.000000000 -0400\r
-+++ dhcp-4.2.0/common/bpf.c 2010-09-23 06:37:48.000000000 -0400\r
-@@ -116,7 +116,7 @@ int if_register_bpf (info)\r
- log_fatal ("Can't attach interface %s to bpf device %s: %m",\r
- info -> name, filename);\r
- \r
-- get_hw_addr(info->name, &info->hw_address);\r
-+ get_hw_addr(info);\r
- \r
- return sock;\r
- }\r
-@@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = {\r
- BPF_STMT(BPF_RET+BPF_K, 0),\r
- };\r
- \r
-+/* Packet filter program for DHCP over Infiniband.\r
-+ *\r
-+ * XXX\r
-+ * Changes to the filter program may require changes to the constant offsets\r
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!\r
-+ * XXX\r
-+ */\r
-+struct bpf_insn dhcp_ib_bpf_filter [] = {\r
-+ /* Packet filter for Infiniband */\r
-+ /* Make sure it's a UDP packet... */\r
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),\r
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),\r
-+\r
-+ /* Make sure this isn't a fragment... */\r
-+ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),\r
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),\r
-+\r
-+ /* Get the IP header length... */\r
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),\r
-+\r
-+ /* Make sure it's to the right port... */\r
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),\r
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),\r
-+\r
-+ /* If we passed all the tests, ask for the whole packet. */\r
-+ BPF_STMT(BPF_RET + BPF_K, (u_int)-1),\r
-+\r
-+ /* Otherwise, drop it. */\r
-+ BPF_STMT(BPF_RET + BPF_K, 0),\r
-+};\r
-+\r
- #if defined (DEC_FDDI)\r
- struct bpf_insn *bpf_fddi_filter;\r
- #endif\r
- \r
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);\r
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);\r
-+\r
- #if defined (HAVE_TR_SUPPORT)\r
- struct bpf_insn dhcp_bpf_tr_filter [] = {\r
- /* accept all token ring packets due to variable length header */\r
-@@ -552,7 +585,9 @@ void maybe_setup_fallback ()\r
- }\r
- \r
- void\r
--get_hw_addr(const char *name, struct hardware *hw) {\r
-+get_hw_addr(struct interface_info *info) {\r
-+ struct hardware *hw = &info->hw_address;\r
-+ char *name = info->name;\r
- struct ifaddrs *ifa;\r
- struct ifaddrs *p;\r
- struct sockaddr_dl *sa;\r
-diff -up dhcp-4.2.0/common/socket.c.ib dhcp-4.2.0/common/socket.c\r
---- dhcp-4.2.0/common/socket.c.ib 2009-11-19 20:49:01.000000000 -0500\r
-+++ dhcp-4.2.0/common/socket.c 2010-09-23 06:21:03.000000000 -0400\r
-@@ -283,7 +283,7 @@ if_register_socket(struct interface_info\r
- \r
- /* If this is a normal IPv4 address, get the hardware address. */\r
- if ((local_family == AF_INET) && (strcmp(info->name, "fallback") != 0))\r
-- get_hw_addr(info->name, &info->hw_address);\r
-+ get_hw_addr(info);\r
- \r
- return sock;\r
- }\r
-@@ -429,7 +429,7 @@ if_register6(struct interface_info *info\r
- if (req_multi)\r
- if_register_multicast(info);\r
- \r
-- get_hw_addr(info->name, &info->hw_address);\r
-+ get_hw_addr(info);\r
- \r
- if (!quiet_interface_discovery) {\r
- if (info->shared_network != NULL) {\r
-diff -up dhcp-4.2.0/includes/dhcpd.h.ib dhcp-4.2.0/includes/dhcpd.h\r
---- dhcp-4.2.0/includes/dhcpd.h.ib 2010-09-23 06:07:17.000000000 -0400\r
-+++ dhcp-4.2.0/includes/dhcpd.h 2010-09-23 06:21:03.000000000 -0400\r
-@@ -1214,6 +1214,7 @@ struct interface_info {\r
- struct shared_network *shared_network;\r
- /* Networks connected to this interface. */\r
- struct hardware hw_address; /* Its physical address. */\r
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */\r
- struct in_addr *addresses; /* Addresses associated with this\r
- * interface.\r
- */\r
-@@ -2324,7 +2325,7 @@ void print_dns_status (int, struct dhcp_\r
- #endif\r
- const char *print_time(TIME);\r
- \r
--void get_hw_addr(const char *name, struct hardware *hw);\r
-+void get_hw_addr(struct interface_info *info);\r
- \r
- /* socket.c */\r
- #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \\r
-diff -up dhcp-4.2.0/common/dlpi.c.ib dhcp-4.2.0/common/dlpi.c\r
---- dhcp-4.2.0/common/dlpi.c.ib 2010-09-23 05:24:05.000000000 -0400\r
-+++ dhcp-4.2.0/common/dlpi.c 2010-09-23 06:39:26.000000000 -0400\r
-@@ -1342,7 +1342,9 @@ void maybe_setup_fallback ()\r
- #endif /* USE_DLPI_SEND */\r
- \r
- void \r
--get_hw_addr(const char *name, struct hardware *hw) {\r
-+get_hw_addr(struct interface_info *info) {\r
-+ struct hardware *hw = &info->hw_address;\r
-+ char *name = info->name;\r
- int sock, unit;\r
- long buf[DLPI_MAXDLBUF];\r
- union DL_primitives *dlp;\r
+++ /dev/null
-diff -up dhcp-4.2.0/client/clparse.c.options dhcp-4.2.0/client/clparse.c\r
---- dhcp-4.2.0/client/clparse.c.options 2009-11-19 20:48:58.000000000 -0500\r
-+++ dhcp-4.2.0/client/clparse.c 2010-09-23 06:07:17.000000000 -0400\r
-@@ -136,6 +136,7 @@ isc_result_t read_client_conf ()\r
- /* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)\r
- */\r
- top_level_config.requested_lease = 7200;\r
-+ top_level_config.bootp_broadcast_always = 0;\r
- \r
- group_allocate (&top_level_config.on_receipt, MDL);\r
- if (!top_level_config.on_receipt)\r
-@@ -303,7 +304,8 @@ void read_client_leases ()\r
- interface-declaration |\r
- LEASE client-lease-statement |\r
- ALIAS client-lease-statement |\r
-- KEY key-definition */\r
-+ KEY key-definition |\r
-+ BOOTP_BROADCAST_ALWAYS */\r
- \r
- void parse_client_statement (cfile, ip, config)\r
- struct parse *cfile;\r
-@@ -717,6 +719,12 @@ void parse_client_statement (cfile, ip, \r
- parse_reject_statement (cfile, config);\r
- return;\r
- \r
-+ case BOOTP_BROADCAST_ALWAYS:\r
-+ token = next_token(&val, (unsigned*)0, cfile);\r
-+ config -> bootp_broadcast_always = 1;\r
-+ parse_semi (cfile);\r
-+ return;\r
-+\r
- default:\r
- lose = 0;\r
- stmt = (struct executable_statement *)0;\r
-diff -up dhcp-4.2.0/client/dhclient.c.options dhcp-4.2.0/client/dhclient.c\r
---- dhcp-4.2.0/client/dhclient.c.options 2010-02-17 15:33:55.000000000 -0500\r
-+++ dhcp-4.2.0/client/dhclient.c 2010-09-23 06:11:14.000000000 -0400\r
-@@ -39,6 +39,12 @@\r
- #include <limits.h>\r
- #include <dns/result.h>\r
- \r
-+/*\r
-+ * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define\r
-+ * that when building ISC code.\r
-+ */\r
-+extern int asprintf(char **strp, const char *fmt, ...);\r
-+\r
- TIME default_lease_time = 43200; /* 12 hours... */\r
- TIME max_lease_time = 86400; /* 24 hours... */\r
- \r
-@@ -82,6 +88,9 @@ int wanted_ia_na = -1; /* the absolute \r
- int wanted_ia_ta = 0;\r
- int wanted_ia_pd = 0;\r
- char *mockup_relay = NULL;\r
-+int bootp_broadcast_always = 0;\r
-+\r
-+extern u_int32_t default_requested_options[];\r
- \r
- void run_stateless(int exit_mode);\r
- \r
-@@ -112,6 +121,15 @@ main(int argc, char **argv) {\r
- int local_family_set = 0;\r
- #endif /* DHCPv6 */\r
- char *s;\r
-+ char *dhcp_client_identifier_arg = NULL;\r
-+ char *dhcp_host_name_arg = NULL;\r
-+ char *dhcp_fqdn_arg = NULL;\r
-+ char *dhcp_vendor_class_identifier_arg = NULL;\r
-+ char *dhclient_request_options = NULL;\r
-+\r
-+ int timeout_arg = 0;\r
-+ char *arg_conf = NULL;\r
-+ int arg_conf_len = 0;\r
- \r
- /* Initialize client globals. */\r
- memset(&default_duid, 0, sizeof(default_duid));\r
-@@ -297,6 +315,88 @@ main(int argc, char **argv) {\r
- } else if (!strcmp(argv[i], "--version")) {\r
- log_info("isc-dhclient-%s", PACKAGE_VERSION);\r
- exit(0);\r
-+ } else if (!strcmp(argv[i], "-I")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-I option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_client_identifier_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-B")) {\r
-+ bootp_broadcast_always = 1;\r
-+ } else if (!strcmp(argv[i], "-H")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-H option host-name string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (dhcp_host_name_arg != NULL) {\r
-+ log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_host_name_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-F")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (dhcp_fqdn_arg != NULL) {\r
-+ log_error("Only one -F <fqdn> argument can be specified");\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (dhcp_host_name_arg != NULL) {\r
-+ log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_fqdn_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-timeout")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if ((timeout_arg = atoi(argv[i])) <= 0) {\r
-+ log_error("-T timeout option must be > 0 - bad value: %s",argv[i]);\r
-+ exit(1);\r
-+ }\r
-+ } else if (!strcmp(argv[i], "-V")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {\r
-+ log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhcp_vendor_class_identifier_arg = argv[i];\r
-+ } else if (!strcmp(argv[i], "-R")) {\r
-+ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {\r
-+ usage();\r
-+ exit(1);\r
-+ }\r
-+\r
-+ dhclient_request_options = argv[i];\r
- } else if (argv[i][0] == '-') {\r
- usage();\r
- } else if (interfaces_requested < 0) {\r
-@@ -466,6 +566,166 @@ main(int argc, char **argv) {\r
- /* Parse the dhclient.conf file. */\r
- read_client_conf();\r
- \r
-+ /* Parse any extra command line configuration arguments: */\r
-+ if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -I option dhcp-client-identifier");\r
-+ }\r
-+\r
-+ if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -H option host-name");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -H option host-name");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -F option fqdn.fqdn");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -F option fqdn.fqdn");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if (timeout_arg) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "timeout %d;", timeout_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to process -timeout timeout argument");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len == 0))\r
-+ log_fatal("Unable to process -timeout timeout argument");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -V option vendor-class-identifier");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to send -V option vendor-class-identifier");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if (dhclient_request_options != NULL) {\r
-+ if (arg_conf == 0) {\r
-+ arg_conf_len = asprintf(&arg_conf, "request %s;", dhclient_request_options);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to parse -R <request options list> argument");\r
-+ } else {\r
-+ char *last_arg_conf = arg_conf;\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);\r
-+\r
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))\r
-+ log_fatal("Unable to parse -R <request options list> argument");\r
-+\r
-+ free(last_arg_conf);\r
-+ }\r
-+ }\r
-+\r
-+ if (arg_conf) {\r
-+ if (arg_conf_len == 0)\r
-+ if ((arg_conf_len = strlen(arg_conf)) == 0)\r
-+ /* huh ? cannot happen ! */\r
-+ log_fatal("Unable to process -I/-H/-F/-timeout/-V/-R configuration arguments");\r
-+\r
-+ /* parse the extra dhclient.conf configuration arguments\r
-+ * into top level config: */\r
-+ struct parse *cfile = (struct parse *)0;\r
-+ const char *val = NULL;\r
-+ int token;\r
-+\r
-+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -I/-H/-F/-timeout/-V/-R configuration arguments", 0);\r
-+\r
-+ if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))\r
-+ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R configuration arguments !");\r
-+ /* more detailed parse failures will be logged */\r
-+\r
-+ do {\r
-+ token = peek_token(&val, (unsigned *)0, cfile);\r
-+ if (token == END_OF_FILE)\r
-+ break;\r
-+\r
-+ parse_client_statement(cfile, (struct interface_info *)0, &top_level_config);\r
-+ } while (1);\r
-+\r
-+ if (cfile -> warnings_occurred)\r
-+ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R configuration arguments !");\r
-+ end_parse(&cfile);\r
-+\r
-+ if (timeout_arg) {\r
-+ /* we just set the toplevel timeout, but per-client\r
-+ * timeouts may still be at defaults. Also, it makes no\r
-+ * sense having the reboot_timeout or backoff_cutoff\r
-+ * greater than the timeout:\r
-+ */\r
-+ if ((top_level_config.backoff_cutoff == 15) && (top_level_config.backoff_cutoff > (timeout_arg / 2)))\r
-+ top_level_config.backoff_cutoff = (((unsigned long)(timeout_arg / 2)) == 0) ? timeout_arg : (unsigned long)(timeout_arg / 2);\r
-+\r
-+ for (ip=interfaces; ip; ip = ip->next) {\r
-+ if (ip->client->config->timeout == 60)\r
-+ ip->client->config->timeout = timeout_arg;\r
-+\r
-+ if ((ip->client->config->reboot_timeout == 10) && (ip->client->config->reboot_timeout > ip->client->config->timeout))\r
-+ ip->client->config->reboot_timeout = ip->client->config->timeout;\r
-+ if ((ip->client->config->backoff_cutoff == 15) && (ip->client->config->backoff_cutoff > top_level_config.backoff_cutoff))\r
-+ ip->client->config->backoff_cutoff = top_level_config.backoff_cutoff;\r
-+ }\r
-+ }\r
-+\r
-+ if ((dhclient_request_options != 0) && (top_level_config.requested_options != (void *) default_requested_options)) {\r
-+ for (ip=interfaces; ip; ip = ip->next) {\r
-+ if (ip->client->config->requested_options == (void *) default_requested_options)\r
-+ ip->client->config->requested_options = top_level_config.requested_options;\r
-+ }\r
-+ }\r
-+\r
-+ free(arg_conf);\r
-+ arg_conf = NULL;\r
-+ arg_conf_len = 0;\r
-+ }\r
-+\r
- /* Parse the lease database. */\r
- read_client_leases();\r
- \r
-@@ -2337,7 +2597,8 @@ void make_discover (client, lease)\r
- client -> packet.xid = random ();\r
- client -> packet.secs = 0; /* filled in by send_discover. */\r
- \r
-- if (can_receive_unicast_unconfigured (client -> interface))\r
-+ if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always))\r
-+ && can_receive_unicast_unconfigured(client->interface))\r
- client -> packet.flags = 0;\r
- else\r
- client -> packet.flags = htons (BOOTP_BROADCAST);\r
-@@ -2421,7 +2682,9 @@ void make_request (client, lease)\r
- } else {\r
- memset (&client -> packet.ciaddr, 0,\r
- sizeof client -> packet.ciaddr);\r
-- if (can_receive_unicast_unconfigured (client -> interface))\r
-+ if ((!(bootp_broadcast_always ||\r
-+ client ->config->bootp_broadcast_always)) &&\r
-+ can_receive_unicast_unconfigured (client -> interface))\r
- client -> packet.flags = 0;\r
- else\r
- client -> packet.flags = htons (BOOTP_BROADCAST);\r
-@@ -2483,7 +2746,8 @@ void make_decline (client, lease)\r
- client -> packet.hops = 0;\r
- client -> packet.xid = client -> xid;\r
- client -> packet.secs = 0; /* Filled in by send_request. */\r
-- if (can_receive_unicast_unconfigured (client -> interface))\r
-+ if ((!(bootp_broadcast_always || client->config-> bootp_broadcast_always))\r
-+ && can_receive_unicast_unconfigured (client->interface))\r
- client -> packet.flags = 0;\r
- else\r
- client -> packet.flags = htons (BOOTP_BROADCAST);\r
-diff -up dhcp-4.2.0/common/conflex.c.options dhcp-4.2.0/common/conflex.c\r
---- dhcp-4.2.0/common/conflex.c.options 2010-03-24 17:49:47.000000000 -0400\r
-+++ dhcp-4.2.0/common/conflex.c 2010-09-23 06:07:17.000000000 -0400\r
-@@ -803,6 +803,8 @@ intern(char *atom, enum dhcp_token dfv) \r
- return BALANCE;\r
- if (!strcasecmp (atom + 1, "ound"))\r
- return BOUND;\r
-+ if (!strcasecmp (atom + 1, "ootp-broadcast-always"))\r
-+ return BOOTP_BROADCAST_ALWAYS;\r
- break;\r
- case 'c':\r
- if (!strcasecmp(atom + 1, "ase"))\r
-diff -up dhcp-4.2.0/includes/dhcpd.h.options dhcp-4.2.0/includes/dhcpd.h\r
---- dhcp-4.2.0/includes/dhcpd.h.options 2010-09-23 05:24:32.000000000 -0400\r
-+++ dhcp-4.2.0/includes/dhcpd.h 2010-09-23 06:07:17.000000000 -0400\r
-@@ -1119,6 +1119,9 @@ struct client_config {\r
- int do_forward_update; /* If nonzero, and if we have the\r
- information we need, update the\r
- A record for the address we get. */\r
-+\r
-+ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST\r
-+ flag in requests */\r
- };\r
- \r
- /* Per-interface state used in the dhcp client... */\r
-diff -up dhcp-4.2.0/includes/dhctoken.h.options dhcp-4.2.0/includes/dhctoken.h\r
---- dhcp-4.2.0/includes/dhctoken.h.options 2010-02-17 15:33:55.000000000 -0500\r
-+++ dhcp-4.2.0/includes/dhctoken.h 2010-09-23 06:08:18.000000000 -0400\r
-@@ -357,7 +357,8 @@ enum dhcp_token {\r
- CONFLICT_DONE = 660,\r
- AUTO_PARTNER_DOWN = 661,\r
- GETHOSTNAME = 662,\r
-- REWIND = 663\r
-+ REWIND = 663,\r
-+ BOOTP_BROADCAST_ALWAYS = 664\r
- };\r
- \r
- #define is_identifier(x) ((x) >= FIRST_TOKEN && \\r
+++ /dev/null
-diff -up dhcp-4.2.0/common/bpf.c.xen dhcp-4.2.0/common/bpf.c\r
---- dhcp-4.2.0/common/bpf.c.xen 2009-11-19 20:48:59.000000000 -0500\r
-+++ dhcp-4.2.0/common/bpf.c 2010-09-23 05:24:01.000000000 -0400\r
-@@ -485,7 +485,7 @@ ssize_t receive_packet (interface, buf, \r
- offset = decode_udp_ip_header (interface,\r
- interface -> rbuf,\r
- interface -> rbuf_offset,\r
-- from, hdr.bh_caplen, &paylen);\r
-+ from, hdr.bh_caplen, &paylen, 0);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0) {\r
-diff -up dhcp-4.2.0/common/dlpi.c.xen dhcp-4.2.0/common/dlpi.c\r
---- dhcp-4.2.0/common/dlpi.c.xen 2009-11-19 20:49:00.000000000 -0500\r
-+++ dhcp-4.2.0/common/dlpi.c 2010-09-23 05:24:05.000000000 -0400\r
-@@ -694,7 +694,7 @@ ssize_t receive_packet (interface, buf, \r
- length -= offset;\r
- #endif\r
- offset = decode_udp_ip_header (interface, dbuf, bufix,\r
-- from, length, &paylen);\r
-+ from, length, &paylen, 0);\r
- \r
- /*\r
- * If the IP or UDP checksum was bad, skip the packet...\r
-diff -up dhcp-4.2.0/common/lpf.c.xen dhcp-4.2.0/common/lpf.c\r
---- dhcp-4.2.0/common/lpf.c.xen 2009-07-23 14:52:19.000000000 -0400\r
-+++ dhcp-4.2.0/common/lpf.c 2010-09-23 05:24:09.000000000 -0400\r
-@@ -29,18 +29,33 @@\r
- #include "dhcpd.h"\r
- #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)\r
- #include <sys/ioctl.h>\r
-+#include <sys/socket.h>\r
- #include <sys/uio.h>\r
- #include <errno.h>\r
- \r
- #include <asm/types.h>\r
- #include <linux/filter.h>\r
- #include <linux/if_ether.h>\r
-+#include <linux/if_packet.h>\r
- #include <netinet/in_systm.h>\r
- #include "includes/netinet/ip.h"\r
- #include "includes/netinet/udp.h"\r
- #include "includes/netinet/if_ether.h"\r
- #include <net/if.h>\r
- \r
-+#ifndef PACKET_AUXDATA\r
-+#define PACKET_AUXDATA 8\r
-+\r
-+struct tpacket_auxdata\r
-+{\r
-+ __u32 tp_status;\r
-+ __u32 tp_len;\r
-+ __u32 tp_snaplen;\r
-+ __u16 tp_mac;\r
-+ __u16 tp_net;\r
-+};\r
-+#endif\r
-+\r
- /* Reinitializes the specified interface after an address change. This\r
- is not required for packet-filter APIs. */\r
- \r
-@@ -66,10 +81,14 @@ int if_register_lpf (info)\r
- struct interface_info *info;\r
- {\r
- int sock;\r
-- struct sockaddr sa;\r
-+ union {\r
-+ struct sockaddr_ll ll;\r
-+ struct sockaddr common;\r
-+ } sa;\r
-+ struct ifreq ifr;\r
- \r
- /* Make an LPF socket. */\r
-- if ((sock = socket(PF_PACKET, SOCK_PACKET,\r
-+ if ((sock = socket(PF_PACKET, SOCK_RAW,\r
- htons((short)ETH_P_ALL))) < 0) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||\r
-@@ -84,11 +103,16 @@ int if_register_lpf (info)\r
- log_fatal ("Open a socket for LPF: %m");\r
- }\r
- \r
-+ memset (&ifr, 0, sizeof ifr);\r
-+ strncpy (ifr.ifr_name, (const char *)info -> ifp, sizeof ifr.ifr_name);\r
-+ if (ioctl (sock, SIOCGIFINDEX, &ifr))\r
-+ log_fatal ("Failed to get interface index: %m");\r
-+\r
- /* Bind to the interface name */\r
- memset (&sa, 0, sizeof sa);\r
-- sa.sa_family = AF_PACKET;\r
-- strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data);\r
-- if (bind (sock, &sa, sizeof sa)) {\r
-+ sa.ll.sll_family = AF_PACKET;\r
-+ sa.ll.sll_ifindex = ifr.ifr_ifindex;\r
-+ if (bind (sock, &sa.common, sizeof sa)) {\r
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||\r
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||\r
- errno == EAFNOSUPPORT || errno == EINVAL) {\r
-@@ -170,9 +194,18 @@ static void lpf_gen_filter_setup (struct\r
- void if_register_receive (info)\r
- struct interface_info *info;\r
- {\r
-+ int val;\r
-+\r
- /* Open a LPF device and hang it on this interface... */\r
- info -> rfdesc = if_register_lpf (info);\r
- \r
-+ val = 1;\r
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,\r
-+ sizeof val) < 0) {\r
-+ if (errno != ENOPROTOOPT)\r
-+ log_fatal ("Failed to set auxiliary packet data: %m");\r
-+ }\r
-+\r
- #if defined (HAVE_TR_SUPPORT)\r
- if (info -> hw_address.hbuf [0] == HTYPE_IEEE802)\r
- lpf_tr_filter_setup (info);\r
-@@ -294,7 +327,6 @@ ssize_t send_packet (interface, packet, \r
- double hh [16];\r
- double ih [1536 / sizeof (double)];\r
- unsigned char *buf = (unsigned char *)ih;\r
-- struct sockaddr sa;\r
- int result;\r
- int fudge;\r
- \r
-@@ -315,15 +347,7 @@ ssize_t send_packet (interface, packet, \r
- (unsigned char *)raw, len);\r
- memcpy (buf + ibufp, raw, len);\r
- \r
-- /* For some reason, SOCK_PACKET sockets can't be connected,\r
-- so we have to do a sentdo every time. */\r
-- memset (&sa, 0, sizeof sa);\r
-- sa.sa_family = AF_PACKET;\r
-- strncpy (sa.sa_data,\r
-- (const char *)interface -> ifp, sizeof sa.sa_data);\r
--\r
-- result = sendto (interface -> wfdesc,\r
-- buf + fudge, ibufp + len - fudge, 0, &sa, sizeof sa);\r
-+ result = write (interface -> wfdesc, buf + fudge, ibufp + len - fudge);\r
- if (result < 0)\r
- log_error ("send_packet: %m");\r
- return result;\r
-@@ -340,14 +364,35 @@ ssize_t receive_packet (interface, buf, \r
- {\r
- int length = 0;\r
- int offset = 0;\r
-+ int nocsum = 0;\r
- unsigned char ibuf [1536];\r
- unsigned bufix = 0;\r
- unsigned paylen;\r
-+ unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];\r
-+ struct iovec iov = {\r
-+ .iov_base = ibuf,\r
-+ .iov_len = sizeof ibuf,\r
-+ };\r
-+ struct msghdr msg = {\r
-+ .msg_iov = &iov,\r
-+ .msg_iovlen = 1,\r
-+ .msg_control = cmsgbuf,\r
-+ .msg_controllen = sizeof(cmsgbuf),\r
-+ };\r
-+ struct cmsghdr *cmsg;\r
- \r
-- length = read (interface -> rfdesc, ibuf, sizeof ibuf);\r
-+ length = recvmsg (interface -> rfdesc, &msg, 0);\r
- if (length <= 0)\r
- return length;\r
- \r
-+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {\r
-+ if (cmsg->cmsg_level == SOL_PACKET &&\r
-+ cmsg->cmsg_type == PACKET_AUXDATA) {\r
-+ struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);\r
-+ nocsum = aux->tp_status & TP_STATUS_CSUMNOTREADY;\r
-+ }\r
-+ }\r
-+\r
- bufix = 0;\r
- /* Decode the physical header... */\r
- offset = decode_hw_header (interface, ibuf, bufix, hfrom);\r
-@@ -364,7 +409,7 @@ ssize_t receive_packet (interface, buf, \r
- \r
- /* Decode the IP and UDP headers... */\r
- offset = decode_udp_ip_header (interface, ibuf, bufix, from,\r
-- (unsigned)length, &paylen);\r
-+ (unsigned)length, &paylen, nocsum);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0)\r
-diff -up dhcp-4.2.0/common/nit.c.xen dhcp-4.2.0/common/nit.c\r
---- dhcp-4.2.0/common/nit.c.xen 2009-11-19 20:49:01.000000000 -0500\r
-+++ dhcp-4.2.0/common/nit.c 2010-09-23 05:24:18.000000000 -0400\r
-@@ -369,7 +369,7 @@ ssize_t receive_packet (interface, buf, \r
- \r
- /* Decode the IP and UDP headers... */\r
- offset = decode_udp_ip_header (interface, ibuf, bufix,\r
-- from, length, &paylen);\r
-+ from, length, &paylen, 0);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0)\r
-diff -up dhcp-4.2.0/common/packet.c.xen dhcp-4.2.0/common/packet.c\r
---- dhcp-4.2.0/common/packet.c.xen 2009-07-23 14:52:20.000000000 -0400\r
-+++ dhcp-4.2.0/common/packet.c 2010-09-23 05:24:21.000000000 -0400\r
-@@ -211,7 +211,7 @@ ssize_t\r
- decode_udp_ip_header(struct interface_info *interface,\r
- unsigned char *buf, unsigned bufix,\r
- struct sockaddr_in *from, unsigned buflen,\r
-- unsigned *rbuflen)\r
-+ unsigned *rbuflen, int nocsum)\r
- {\r
- unsigned char *data;\r
- struct ip ip;\r
-@@ -322,7 +322,7 @@ decode_udp_ip_header(struct interface_in\r
- 8, IPPROTO_UDP + ulen))));\r
- \r
- udp_packets_seen++;\r
-- if (usum && usum != sum) {\r
-+ if (!nocsum && usum && usum != sum) {\r
- udp_packets_bad_checksum++;\r
- if (udp_packets_seen > 4 &&\r
- (udp_packets_seen / udp_packets_bad_checksum) < 2) {\r
-diff -up dhcp-4.2.0/common/upf.c.xen dhcp-4.2.0/common/upf.c\r
---- dhcp-4.2.0/common/upf.c.xen 2009-11-19 20:49:01.000000000 -0500\r
-+++ dhcp-4.2.0/common/upf.c 2010-09-23 05:24:25.000000000 -0400\r
-@@ -320,7 +320,7 @@ ssize_t receive_packet (interface, buf, \r
- \r
- /* Decode the IP and UDP headers... */\r
- offset = decode_udp_ip_header (interface, ibuf, bufix,\r
-- from, length, &paylen);\r
-+ from, length, &paylen, 0);\r
- \r
- /* If the IP or UDP checksum was bad, skip the packet... */\r
- if (offset < 0)\r
-diff -up dhcp-4.2.0/includes/dhcpd.h.xen dhcp-4.2.0/includes/dhcpd.h\r
---- dhcp-4.2.0/includes/dhcpd.h.xen 2010-06-01 13:29:59.000000000 -0400\r
-+++ dhcp-4.2.0/includes/dhcpd.h 2010-09-23 05:24:32.000000000 -0400\r
-@@ -2769,7 +2769,7 @@ ssize_t decode_hw_header PROTO ((struct \r
- unsigned, struct hardware *));\r
- ssize_t decode_udp_ip_header PROTO ((struct interface_info *, unsigned char *,\r
- unsigned, struct sockaddr_in *,\r
-- unsigned, unsigned *));\r
-+ unsigned, unsigned *, int));\r
- \r
- /* ethernet.c */\r
- void assemble_ethernet_header PROTO ((struct interface_info *, unsigned char *,\r
+++ /dev/null
-diff -up dhcp-3.0.5/client/dhclient.c.gpxe dhcp-3.0.5/client/dhclient.c
---- dhcp-3.0.5/client/dhclient.c.gpxe 2010-11-22 21:30:34.968005000 +0200
-+++ dhcp-3.0.5/client/dhclient.c 2010-11-22 21:30:34.978006000 +0200
-@@ -47,6 +47,13 @@ const char *path_dhclient_pid = _PATH_DH
- static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
- char *path_dhclient_script = path_dhclient_script_array;
-
-+/* Default Prefix */
-+static unsigned char default_prefix[12] = {
-+ 0xff, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x02, 0x00,
-+ 0x00, 0x02, 0xc9, 0x00
-+};
-+
- int dhcp_max_agent_option_packet_length = 0;
-
- int interfaces_requested = 0;
-@@ -1133,6 +1140,12 @@ extern omapi_io_object_t omapi_io_states
- static void setup_ib_interface(struct interface_info *ip)
- {
- struct group *g;
-+ struct hardware *hw = &ip->hw_address;
-+ char client_id[64];
-+ char *arg_conf = NULL;
-+ int arg_conf_len = 0;
-+ isc_result_t status;
-+ struct parse *cfile = (struct parse *)0;
-
- /* Set the broadcast flag */
- bootp_broadcast_always = 1;
-@@ -1149,8 +1162,39 @@ static void setup_ib_interface(struct in
- }
- }
-
-- /* No client ID specified */
-- log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+ /*
-+ * No client ID specified, make up one based on a default
-+ * "prefix" and the port GUID.
-+ *
-+ * NOTE: This is compatible with what gpxe does.
-+ */
-+ sprintf(client_id, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
-+ default_prefix[0], default_prefix[1], default_prefix[2],
-+ default_prefix[3], default_prefix[4], default_prefix[5],
-+ default_prefix[6], default_prefix[7], default_prefix[8],
-+ default_prefix[9], default_prefix[10], default_prefix[11],
-+ hw->hbuf[1], hw->hbuf[2], hw->hbuf[3], hw->hbuf[4],
-+ hw->hbuf[5], hw->hbuf[6], hw->hbuf[7], hw->hbuf[8]);
-+
-+ arg_conf_len = asprintf(&arg_conf,
-+ "send dhcp-client-identifier %s;",
-+ client_id);
-+
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))
-+ log_fatal("Unable to send option dhcp-client-identifier");
-+
-+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len,
-+ "Automatic Infiniband client identifier", 0);
-+
-+ if ((status != ISC_R_SUCCESS) || (cfile->warnings_occurred))
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ parse_client_statement(cfile, NULL, ip->client->config);
-+
-+ if (cfile->warnings_occurred)
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ end_parse(&cfile);
- }
-
- static void usage ()
-diff -up dhcp-3.0.5/common/discover.c.gpxe dhcp-3.0.5/common/discover.c
---- dhcp-3.0.5/common/discover.c.gpxe 2010-11-22 21:30:34.940009000 +0200
-+++ dhcp-3.0.5/common/discover.c 2010-11-22 23:36:49.550178000 +0200
-@@ -120,6 +120,34 @@ void interface_trace_setup ()
- trace_outpacket_stop, MDL);
- }
- #endif
-+static unsigned char * get_ib_hw_addr(char * name)
-+{
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+ static unsigned char hw_addr[8];
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ return NULL;
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ return NULL;
-+ }
-+ memcpy(hw_addr, &sll->sll_addr[sll->sll_halen - 8], 8);
-+ freeifaddrs(ifaddrs);
-+ return (unsigned char *)&hw_addr;
-+}
-
- isc_result_t interface_initialize (omapi_object_t *ipo,
- const char *file, int line)
-@@ -158,6 +186,7 @@ void discover_interfaces (state)
- #endif
- isc_result_t status;
- int wifcount = 0;
-+ unsigned char *hw_addr;
-
- /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
- if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-@@ -553,6 +582,10 @@ void discover_interfaces (state)
- setup_ib_bcast_addr ( tmp );
- tmp -> hw_address.hlen = 1;
- tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ hw_addr = get_ib_hw_addr(tmp -> name);
-+ if (!hw_addr)
-+ log_fatal("Failed getting %s hw addr", tmp -> name);
-+ memcpy (&tmp -> hw_address.hbuf [1], hw_addr, 8);
- break;
-
- default:
+++ /dev/null
-diff -up dhcp-3.0.5/client/dhclient.c.xid dhcp-3.0.5/client/dhclient.c
---- dhcp-3.0.5/client/dhclient.c.xid 2010-09-17 12:59:33.000000000 +0200
-+++ dhcp-3.0.5/client/dhclient.c 2010-09-18 14:24:09.000000000 +0200
-@@ -880,6 +880,26 @@ int main
- }
- }
-
-+ /* We create a backup seed before rediscovering interfaces in order to
-+ have a seed built using all of the available interfaces
-+ It's interesting if required interfaces doesn't let us defined
-+ a really unique seed due to a lack of valid HW addr later
-+ (this is the case with DHCP over IB)
-+ We only use the last device as using a sum could broke the
-+ uniqueness of the seed among multiple nodes
-+ */
-+ unsigned backup_seed = 0;
-+ for (ip = interfaces; ip; ip = ip -> next) {
-+ int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
-+ memcpy (&junk,
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
-+ sizeof seed], sizeof seed);
-+ backup_seed = junk;
-+ }
-+
-+
- /* At this point, all the interfaces that the script thinks
- are relevant should be running, so now we once again call
- discover_interfaces(), and this time ask it to actually set
-@@ -894,14 +914,36 @@ int main
- Not much entropy, but we're booting, so we're not likely to
- find anything better. */
- seed = 0;
-+ int seed_flag = 0;
- for (ip = interfaces; ip; ip = ip -> next) {
- int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
- memcpy (&junk,
- &ip -> hw_address.hbuf [ip -> hw_address.hlen -
- sizeof seed], sizeof seed);
- seed += junk;
-+ seed_flag = 1;
-+ }
-+ if ( seed_flag == 0 ) {
-+ if ( backup_seed != 0 ) {
-+ seed = backup_seed;
-+ log_info ("xid: rand init seed (0x%x) built using all"
-+ " available interfaces",seed);
-+ }
-+ else {
-+ seed = cur_time^((unsigned) gethostid()) ;
-+ log_info ("xid: warning: no netdev with useable HWADDR found"
-+ " for seed's uniqueness enforcement");
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",
-+ seed);
-+ }
-+ /* we only use seed and no current time as a broadcast reply */
-+ /* will certainly be used by the hwaddrless interface */
-+ srandom(seed);
- }
-- srandom (seed + cur_time);
-+ else
-+ srandom (seed + cur_time);
-
- /* Setup specific Infiniband options */
- for (ip = interfaces; ip; ip = ip->next) {
-@@ -1388,7 +1430,7 @@ void dhcpack (packet)
- return;
- }
-
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- lease = packet_to_lease (packet, client);
- if (!lease) {
-@@ -2009,7 +2051,7 @@ void dhcpnak (packet)
- return;
- }
-
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- if (!client -> active) {
- #if defined (DEBUG)
-@@ -2135,10 +2177,10 @@ void send_discover (cpp)
- client -> packet.secs = htons (65535);
- client -> secs = client -> packet.secs;
-
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -2392,10 +2434,10 @@ void send_request (cpp)
- client -> packet.secs = htons (65535);
- }
-
-- log_info ("DHCPREQUEST on %s to %s port %d",
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
- fallback_interface)
-@@ -2424,10 +2466,10 @@ void send_decline (cpp)
-
- int result;
-
-- log_info ("DHCPDECLINE on %s to %s port %d",
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port));
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -2467,10 +2509,10 @@ void send_release (cpp)
- return;
- }
-
-- log_info ("DHCPRELEASE on %s to %s port %d",
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (fallback_interface)
- result = send_packet (fallback_interface,
+++ /dev/null
-diff -up dhcp-3.0.5/common/lpf.c.ib dhcp-3.0.5/common/lpf.c
---- dhcp-3.0.5/common/lpf.c.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/common/lpf.c 2010-09-17 21:13:46.000000000 +0200
-@@ -89,10 +89,19 @@ int if_register_lpf (info)
- struct sockaddr common;
- } sa;
- struct ifreq ifr;
-+ int type;
-+ int protocol;
-
- /* Make an LPF socket. */
-- if ((sock = socket(PF_PACKET, SOCK_RAW,
-- htons((short)ETH_P_ALL))) < 0) {
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ type = SOCK_DGRAM;
-+ protocol = ETHERTYPE_IP;
-+ } else {
-+ type = SOCK_RAW;
-+ protocol = ETH_P_ALL;
-+ }
-+
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -114,6 +123,7 @@ int if_register_lpf (info)
- /* Bind to the interface name */
- memset (&sa, 0, sizeof sa);
- sa.ll.sll_family = AF_PACKET;
-+ sa.ll.sll_protocol = htons(protocol);
- sa.ll.sll_ifindex = ifr.ifr_ifindex;
- if (bind (sock, &sa.common, sizeof sa)) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
-@@ -183,6 +193,8 @@ void if_deregister_send (info)
- in bpf includes... */
- extern struct sock_filter dhcp_bpf_filter [];
- extern int dhcp_bpf_filter_len;
-+extern struct sock_filter dhcp_ib_bpf_filter [];
-+extern int dhcp_ib_bpf_filter_len;
-
- #if defined (HAVE_TR_SUPPORT)
- extern struct sock_filter dhcp_bpf_tr_filter [];
-@@ -200,11 +212,13 @@ void if_register_receive (info)
- /* Open a LPF device and hang it on this interface... */
- info -> rfdesc = if_register_lpf (info);
-
-- val = 1;
-- if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,
-- sizeof val) < 0) {
-- if (errno != ENOPROTOOPT)
-- log_fatal ("Failed to set auxiliary packet data: %m");
-+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
-+ val = 1;
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA,
-+ &val, sizeof val) < 0) {
-+ if (errno != ENOPROTOOPT)
-+ log_fatal ("Failed to set auxiliary packet data: %m");
-+ }
- }
-
- #if defined (HAVE_TR_SUPPORT)
-@@ -249,15 +263,28 @@ static void lpf_gen_filter_setup (info)
- struct sock_fprog p;
- memset(&p,'\0', sizeof(struct sock_fprog));
-
-- /* Set up the bpf filter program structure. This is defined in
-- bpf.c */
-- p.len = dhcp_bpf_filter_len;
-- p.filter = dhcp_bpf_filter;
--
-- /* 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 [8].k = ntohs ((short)local_port);
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ /* Set up the bpf filter program structure. */
-+ p.len = dhcp_ib_bpf_filter_len;
-+ p.filter = dhcp_ib_bpf_filter;
-+
-+ /* 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_ib_bpf_filter[6].k = ntohs ((short)local_port);
-+ } else {
-+ /* Set up the bpf filter program structure.
-+ This is defined in bpf.c */
-+ p.len = dhcp_bpf_filter_len;
-+ p.filter = dhcp_bpf_filter;
-+
-+ /* 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 [8].k = ntohs ((short)local_port);
-+ }
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
-@@ -312,6 +339,54 @@ static void lpf_tr_filter_setup (info)
- #endif /* USE_LPF_RECEIVE */
-
- #ifdef USE_LPF_SEND
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
-+ struct interface_info *interface;
-+ struct packet *packet;
-+ struct dhcp_packet *raw;
-+ size_t len;
-+ struct in_addr from;
-+ struct sockaddr_in *to;
-+ struct hardware *hto;
-+{
-+ unsigned ibufp = 0;
-+ double ih [1536 / sizeof (double)];
-+ unsigned char *buf = (unsigned char *)ih;
-+ ssize_t result;
-+
-+ union sockunion {
-+ struct sockaddr sa;
-+ struct sockaddr_ll sll;
-+ struct sockaddr_storage ss;
-+ } su;
-+
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
-+ to->sin_addr.s_addr, to->sin_port,
-+ (unsigned char *)raw, len);
-+ memcpy (buf + ibufp, raw, len);
-+
-+ memset(&su, 0, sizeof(su));
-+ su.sll.sll_family = AF_PACKET;
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
-+
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
-+ errno = ENOENT;
-+ log_error ("send_packet_ib: %m - failed to get if index");
-+ return -1;
-+ }
-+
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
-+
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
-+ &su.sa, sizeof(su));
-+
-+ if (result < 0)
-+ log_error ("send_packet_ib: %m");
-+
-+ return result;
-+}
-+
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
-@@ -332,6 +407,11 @@ ssize_t send_packet (interface, packet,
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return send_packet_ib(interface, packet, raw, len, from,
-+ to, hto);
-+ }
-+
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto);
- fudge = hbufp % 4; /* IP header must be word-aligned. */
-@@ -350,6 +430,38 @@ ssize_t send_packet (interface, packet,
- #endif /* USE_LPF_SEND */
-
- #ifdef USE_LPF_RECEIVE
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
-+ struct interface_info *interface;
-+ unsigned char *buf;
-+ size_t len;
-+ struct sockaddr_in *from;
-+ struct hardware *hfrom;
-+{
-+ int length = 0;
-+ int offset = 0;
-+ unsigned char ibuf [1536];
-+ unsigned bufix = 0;
-+
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
-+
-+ if (length <= 0)
-+ return length;
-+
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
-+ (unsigned)length, 0);
-+
-+ if (offset < 0)
-+ return 0;
-+
-+ bufix += offset;
-+ length -= offset;
-+
-+ /* Copy out the data in the packet... */
-+ memcpy(buf, &ibuf[bufix], length);
-+
-+ return length;
-+}
-+
- ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
-@@ -375,6 +487,10 @@ ssize_t receive_packet (interface, buf,
- };
- struct cmsghdr *cmsg;
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return receive_packet_ib(interface, buf, len, from, hfrom);
-+ }
-+
- length = recvmsg (interface -> rfdesc, &msg, 0);
- if (length <= 0)
- return length;
-diff -up dhcp-3.0.5/includes/dhcp.h.ib dhcp-3.0.5/includes/dhcp.h
---- dhcp-3.0.5/includes/dhcp.h.ib 2005-10-10 18:52:13.000000000 +0200
-+++ dhcp-3.0.5/includes/dhcp.h 2010-09-17 11:48:50.000000000 +0200
-@@ -74,6 +74,7 @@ struct dhcp_packet {
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
- #define HTYPE_FDDI 8 /* FDDI... */
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */
-
- /* Magic cookie validating dhcp options field (and bootp vendor
- extensions field). */
-diff -up dhcp-3.0.5/client/dhclient.c.ib dhcp-3.0.5/client/dhclient.c
---- dhcp-3.0.5/client/dhclient.c.ib 2010-09-16 21:16:13.000000000 +0200
-+++ dhcp-3.0.5/client/dhclient.c 2010-09-17 12:59:33.000000000 +0200
-@@ -82,6 +82,7 @@ int bootp_broadcast_always = 0;
- FILE *leaseFile=0;
- #endif
- static void usage PROTO ((void));
-+static void setup_ib_interface(struct interface_info *ip);
-
- void do_release(struct client_state *);
-
-@@ -902,6 +903,14 @@ int main
- }
- srandom (seed + cur_time);
-
-+ /* Setup specific Infiniband options */
-+ for (ip = interfaces; ip; ip = ip->next) {
-+ if (ip->client &&
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
-+ setup_ib_interface(ip);
-+ }
-+ }
-+
- /* Start a configuration state machine for each interface. */
- for (ip = interfaces; ip; ip = ip -> next) {
- ip -> flags |= INTERFACE_RUNNING;
-@@ -1083,6 +1092,29 @@ extern omapi_io_object_t omapi_io_states
- return 0;
- }
-
-+static void setup_ib_interface(struct interface_info *ip)
-+{
-+ struct group *g;
-+
-+ /* Set the broadcast flag */
-+ bootp_broadcast_always = 1;
-+
-+ /*
-+ * Find out if a dhcp-client-identifier option was specified either
-+ * in the config file or on the command line
-+ */
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
-+ if ((g->statements != NULL) &&
-+ (strcmp(g->statements->data.option->option->name,
-+ "dhcp-client-identifier") == 0)) {
-+ return;
-+ }
-+ }
-+
-+ /* No client ID specified */
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+}
-+
- static void usage ()
- {
- printf ("%s %s\n", message, DHCP_VERSION);
-diff -up dhcp-3.0.5/common/bpf.c.ib dhcp-3.0.5/common/bpf.c
---- dhcp-3.0.5/common/bpf.c.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/common/bpf.c 2010-09-17 11:49:08.000000000 +0200
-@@ -194,11 +194,44 @@ struct bpf_insn dhcp_bpf_filter [] = {
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
-+/* Packet filter program for DHCP over Infiniband.
-+ *
-+ * XXX
-+ * Changes to the filter program may require changes to the constant offsets
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
-+ * XXX
-+ */
-+struct bpf_insn dhcp_ib_bpf_filter [] = {
-+ /* Packet filter for Infiniband */
-+ /* Make sure it's a UDP packet... */
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
-+ 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, 6),
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-+
-+ /* Get the IP header length... */
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
-+
-+ /* Make sure it's to the right port... */
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
-+
-+ /* 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),
-+};
-+
- #if defined (DEC_FDDI)
- struct bpf_insn *bpf_fddi_filter;
- #endif
-
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
-+
- #if defined (HAVE_TR_SUPPORT)
- struct bpf_insn dhcp_bpf_tr_filter [] = {
- /* accept all token ring packets due to variable length header */
-diff -up dhcp-3.0.5/common/discover.c.ib dhcp-3.0.5/common/discover.c
---- dhcp-3.0.5/common/discover.c.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/common/discover.c 2010-09-17 21:13:04.000000000 +0200
-@@ -39,6 +39,8 @@ static char copyright[] =
-
- #include "dhcpd.h"
- #include <sys/ioctl.h>
-+#include <ifaddrs.h>
-+#include <linux/if_packet.h>
-
- struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
- int interfaces_invalidated;
-@@ -58,6 +60,8 @@ void (*bootp_packet_handler) PROTO ((str
- unsigned int,
- struct iaddr, struct hardware *));
-
-+void setup_ib_bcast_addr(struct interface_info *info);
-+
- omapi_object_type_t *dhcp_type_interface;
- #if defined (TRACING)
- trace_type_t *interface_trace;
-@@ -70,6 +74,15 @@ int interface_max;
-
- OMAPI_OBJECT_ALLOC (interface, struct interface_info, dhcp_type_interface)
-
-+/* Default broadcast address for IPoIB */
-+unsigned char default_ib_bcast_addr[20] = {
-+ 0x00, 0xff, 0xff, 0xff,
-+ 0xff, 0x12, 0x40, 0x1b,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0xff, 0xff, 0xff, 0xff
-+};
-+
- isc_result_t interface_setup ()
- {
- isc_result_t status;
-@@ -533,6 +546,15 @@ void discover_interfaces (state)
- break;
- #endif
-
-+#ifndef HAVE_ARPHRD_INFINIBAND
-+# define ARPHRD_INFINIBAND HTYPE_INFINIBAND
-+#endif
-+ case ARPHRD_INFINIBAND:
-+ setup_ib_bcast_addr ( tmp );
-+ tmp -> hw_address.hlen = 1;
-+ tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ break;
-+
- default:
- log_error ("%s: unknown hardware address type %d",
- ifr.ifr_name, sa.sa_family);
-@@ -718,6 +740,57 @@ void discover_interfaces (state)
- #endif
- }
-
-+void setup_ib_bcast_addr (struct interface_info *info)
-+{
-+ char *name = info->name;
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ log_fatal("Failed to get interfaces");
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ log_fatal("Failed to get HW address for %s\n", name);
-+ }
-+
-+ switch (sll->sll_hatype) {
-+ case ARPHRD_INFINIBAND:
-+ /* For Infiniband, save the broadcast address and store
-+ * the port GUID into the hardware address.
-+ */
-+ if (ifa->ifa_flags & IFF_BROADCAST) {
-+ struct sockaddr_ll *bll;
-+
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
-+ } else {
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
-+ 20);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ freeifaddrs(ifaddrs);
-+}
-+
- int if_readsocket (h)
- omapi_object_t *h;
- {
-diff -up dhcp-3.0.5/includes/dhcpd.h.ib dhcp-3.0.5/includes/dhcpd.h
---- dhcp-3.0.5/includes/dhcpd.h.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/includes/dhcpd.h 2010-09-17 11:57:32.000000000 +0200
-@@ -781,6 +781,7 @@ struct interface_info {
- struct shared_network *shared_network;
- /* Networks connected to this interface. */
- struct hardware hw_address; /* Its physical address. */
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
- struct in_addr primary_address; /* Primary interface address. */
-
- u_int8_t *circuit_id; /* Circuit ID associated with this
-diff -up dhcp-3.0.5/includes/osdep.h.ib dhcp-3.0.5/includes/osdep.h
---- dhcp-3.0.5/includes/osdep.h.ib 2005-09-28 21:58:27.000000000 +0300
-+++ dhcp-3.0.5/includes/osdep.h 2010-09-17 13:32:59.000000000 +0200
-@@ -307,6 +307,10 @@
- # define HAVE_ARPHRD_METRICOM
- #endif
-
-+#if defined (ARPHRD_INFINIBAND) && !defined (HAVE_ARPHRD_INFINIBAND)
-+# define HAVE_ARPHRD_INFINIBAND
-+#endif
-+
- #if defined (SO_BINDTODEVICE) && !defined (HAVE_SO_BINDTODEVICE)
- # define HAVE_SO_BINDTODEVICE
- #endif
-diff -up dhcp-3.0.5/server/dhcp.c.ib dhcp-3.0.5/server/dhcp.c
---- dhcp-3.0.5/server/dhcp.c.ib 2010-09-17 17:31:09.000000000 +0200
-+++ dhcp-3.0.5/server/dhcp.c 2010-09-17 21:16:43.000000000 +0200
-@@ -2935,7 +2935,10 @@ void dhcp_reply (lease)
- unicastp = 0;
- }
-
-- memcpy (&from, state -> from.iabuf, sizeof from);
-+ if (state -> ip -> hw_address.hbuf [0] != HTYPE_INFINIBAND)
-+ memcpy (&from, state -> from.iabuf, sizeof from);
-+ else
-+ from = state ->ip -> primary_address;
-
- result = send_packet (state -> ip,
- (struct packet *)0, &raw, packet_length,
+++ /dev/null
---- dhcp.spec.ib 2009-07-02 10:27:27.000000000 +0300
-+++ dhcp.spec 2010-09-20 12:48:15.559809000 +0200
-@@ -52,6 +52,9 @@ Patch17: %{name}-3.0.5-RES_OPTIONS.patch
- Patch18: %{name}-3.0.5-emergency-relay-agent-options-hologram.patch
- Patch19: %{name}-3.0.5-honor-peer-vars.patch
- Patch20: %{name}-3.0.5-IFNAMSIZ.patch
-+Patch21: %{name}-3.0.5-lpf-ib.patch
-+Patch22: %{name}-3.0.5-improved-xid.patch
-+Patch23: %{name}-3.0.5-gpxe-cid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- Requires(post): chkconfig, coreutils
-@@ -198,6 +200,12 @@ esac
- # dhcpd (RHBZ #441524)
- %patch20 -p1 -b .ifnamsiz
-
-+%patch21 -p1 -b .ib
-+
-+%patch22 -p1 -b .xid
-+
-+%patch23 -p1 -b .gpxe
-+
- %build
- %{__cp} %SOURCE1 .
- %{__cat} << EOF > site.conf
+++ /dev/null
---- dhcp.spec.ib 2009-07-02 10:27:27.000000000 +0300
-+++ dhcp.spec 2010-09-20 12:48:15.559809000 +0200
-@@ -52,6 +52,8 @@ Patch17: %{name}-3.0.5-RES_OPTIONS.patch
- Patch18: %{name}-3.0.5-emergency-relay-agent-options-hologram.patch
- Patch19: %{name}-3.0.5-honor-peer-vars.patch
- Patch20: %{name}-3.0.5-IFNAMSIZ.patch
-+Patch21: %{name}-3.0.5-lpf-ib.patch
-+Patch22: %{name}-3.0.5-improved-xid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- Requires(post): chkconfig, coreutils
-@@ -198,6 +200,10 @@ esac
- # dhcpd (RHBZ #441524)
- %patch20 -p1 -b .ifnamsiz
-
-+%patch21 -p1 -b .ib
-+
-+%patch22 -p1 -b .xid
-+
- %build
- %{__cp} %SOURCE1 .
- %{__cat} << EOF > site.conf
+++ /dev/null
-diff -up dhcp-3.0.5/client/dhclient.c.gpxe dhcp-3.0.5/client/dhclient.c
---- dhcp-3.0.5/client/dhclient.c.gpxe 2010-11-22 21:30:34.968005000 +0200
-+++ dhcp-3.0.5/client/dhclient.c 2010-11-22 21:30:34.978006000 +0200
-@@ -47,6 +47,13 @@ const char *path_dhclient_pid = _PATH_DH
- static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
- char *path_dhclient_script = path_dhclient_script_array;
-
-+/* Default Prefix */
-+static unsigned char default_prefix[12] = {
-+ 0xff, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x02, 0x00,
-+ 0x00, 0x02, 0xc9, 0x00
-+};
-+
- int dhcp_max_agent_option_packet_length = 0;
-
- int interfaces_requested = 0;
-@@ -1133,6 +1140,12 @@ extern omapi_io_object_t omapi_io_states
- static void setup_ib_interface(struct interface_info *ip)
- {
- struct group *g;
-+ struct hardware *hw = &ip->hw_address;
-+ char client_id[64];
-+ char *arg_conf = NULL;
-+ int arg_conf_len = 0;
-+ isc_result_t status;
-+ struct parse *cfile = (struct parse *)0;
-
- /* Set the broadcast flag */
- bootp_broadcast_always = 1;
-@@ -1149,8 +1162,39 @@ static void setup_ib_interface(struct in
- }
- }
-
-- /* No client ID specified */
-- log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+ /*
-+ * No client ID specified, make up one based on a default
-+ * "prefix" and the port GUID.
-+ *
-+ * NOTE: This is compatible with what gpxe does.
-+ */
-+ sprintf(client_id, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
-+ default_prefix[0], default_prefix[1], default_prefix[2],
-+ default_prefix[3], default_prefix[4], default_prefix[5],
-+ default_prefix[6], default_prefix[7], default_prefix[8],
-+ default_prefix[9], default_prefix[10], default_prefix[11],
-+ hw->hbuf[1], hw->hbuf[2], hw->hbuf[3], hw->hbuf[4],
-+ hw->hbuf[5], hw->hbuf[6], hw->hbuf[7], hw->hbuf[8]);
-+
-+ arg_conf_len = asprintf(&arg_conf,
-+ "send dhcp-client-identifier %s;",
-+ client_id);
-+
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))
-+ log_fatal("Unable to send option dhcp-client-identifier");
-+
-+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len,
-+ "Automatic Infiniband client identifier", 0);
-+
-+ if ((status != ISC_R_SUCCESS) || (cfile->warnings_occurred))
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ parse_client_statement(cfile, NULL, ip->client->config);
-+
-+ if (cfile->warnings_occurred)
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ end_parse(&cfile);
- }
-
- static void usage ()
-diff -up dhcp-3.0.5/common/discover.c.gpxe dhcp-3.0.5/common/discover.c
---- dhcp-3.0.5/common/discover.c.gpxe 2010-11-22 21:30:34.940009000 +0200
-+++ dhcp-3.0.5/common/discover.c 2010-11-22 23:36:49.550178000 +0200
-@@ -120,6 +120,34 @@ void interface_trace_setup ()
- trace_outpacket_stop, MDL);
- }
- #endif
-+static unsigned char * get_ib_hw_addr(char * name)
-+{
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+ static unsigned char hw_addr[8];
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ return NULL;
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ return NULL;
-+ }
-+ memcpy(hw_addr, &sll->sll_addr[sll->sll_halen - 8], 8);
-+ freeifaddrs(ifaddrs);
-+ return (unsigned char *)&hw_addr;
-+}
-
- isc_result_t interface_initialize (omapi_object_t *ipo,
- const char *file, int line)
-@@ -158,6 +186,7 @@ void discover_interfaces (state)
- #endif
- isc_result_t status;
- int wifcount = 0;
-+ unsigned char *hw_addr;
-
- /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
- if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-@@ -553,6 +582,10 @@ void discover_interfaces (state)
- setup_ib_bcast_addr ( tmp );
- tmp -> hw_address.hlen = 1;
- tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ hw_addr = get_ib_hw_addr(tmp -> name);
-+ if (!hw_addr)
-+ log_fatal("Failed getting %s hw addr", tmp -> name);
-+ memcpy (&tmp -> hw_address.hbuf [1], hw_addr, 8);
- break;
-
- default:
+++ /dev/null
-diff -up dhcp-3.0.5/client/dhclient.c.xid dhcp-3.0.5/client/dhclient.c
---- dhcp-3.0.5/client/dhclient.c.xid 2010-09-17 12:59:33.000000000 +0200
-+++ dhcp-3.0.5/client/dhclient.c 2010-09-18 14:24:09.000000000 +0200
-@@ -880,6 +880,26 @@ int main
- }
- }
-
-+ /* We create a backup seed before rediscovering interfaces in order to
-+ have a seed built using all of the available interfaces
-+ It's interesting if required interfaces doesn't let us defined
-+ a really unique seed due to a lack of valid HW addr later
-+ (this is the case with DHCP over IB)
-+ We only use the last device as using a sum could broke the
-+ uniqueness of the seed among multiple nodes
-+ */
-+ unsigned backup_seed = 0;
-+ for (ip = interfaces; ip; ip = ip -> next) {
-+ int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
-+ memcpy (&junk,
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
-+ sizeof seed], sizeof seed);
-+ backup_seed = junk;
-+ }
-+
-+
- /* At this point, all the interfaces that the script thinks
- are relevant should be running, so now we once again call
- discover_interfaces(), and this time ask it to actually set
-@@ -894,14 +914,36 @@ int main
- Not much entropy, but we're booting, so we're not likely to
- find anything better. */
- seed = 0;
-+ int seed_flag = 0;
- for (ip = interfaces; ip; ip = ip -> next) {
- int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
- memcpy (&junk,
- &ip -> hw_address.hbuf [ip -> hw_address.hlen -
- sizeof seed], sizeof seed);
- seed += junk;
-+ seed_flag = 1;
-+ }
-+ if ( seed_flag == 0 ) {
-+ if ( backup_seed != 0 ) {
-+ seed = backup_seed;
-+ log_info ("xid: rand init seed (0x%x) built using all"
-+ " available interfaces",seed);
-+ }
-+ else {
-+ seed = cur_time^((unsigned) gethostid()) ;
-+ log_info ("xid: warning: no netdev with useable HWADDR found"
-+ " for seed's uniqueness enforcement");
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",
-+ seed);
-+ }
-+ /* we only use seed and no current time as a broadcast reply */
-+ /* will certainly be used by the hwaddrless interface */
-+ srandom(seed);
- }
-- srandom (seed + cur_time);
-+ else
-+ srandom (seed + cur_time);
-
- /* Setup specific Infiniband options */
- for (ip = interfaces; ip; ip = ip->next) {
-@@ -1388,7 +1430,7 @@ void dhcpack (packet)
- return;
- }
-
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- lease = packet_to_lease (packet, client);
- if (!lease) {
-@@ -2009,7 +2051,7 @@ void dhcpnak (packet)
- return;
- }
-
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- if (!client -> active) {
- #if defined (DEBUG)
-@@ -2135,10 +2177,10 @@ void send_discover (cpp)
- client -> packet.secs = htons (65535);
- client -> secs = client -> packet.secs;
-
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -2392,10 +2434,10 @@ void send_request (cpp)
- client -> packet.secs = htons (65535);
- }
-
-- log_info ("DHCPREQUEST on %s to %s port %d",
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
- fallback_interface)
-@@ -2424,10 +2466,10 @@ void send_decline (cpp)
-
- int result;
-
-- log_info ("DHCPDECLINE on %s to %s port %d",
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port));
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -2467,10 +2509,10 @@ void send_release (cpp)
- return;
- }
-
-- log_info ("DHCPRELEASE on %s to %s port %d",
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (fallback_interface)
- result = send_packet (fallback_interface,
+++ /dev/null
-diff -up dhcp-3.0.5/common/lpf.c.ib dhcp-3.0.5/common/lpf.c
---- dhcp-3.0.5/common/lpf.c.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/common/lpf.c 2010-09-17 21:13:46.000000000 +0200
-@@ -89,10 +89,19 @@ int if_register_lpf (info)
- struct sockaddr common;
- } sa;
- struct ifreq ifr;
-+ int type;
-+ int protocol;
-
- /* Make an LPF socket. */
-- if ((sock = socket(PF_PACKET, SOCK_RAW,
-- htons((short)ETH_P_ALL))) < 0) {
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ type = SOCK_DGRAM;
-+ protocol = ETHERTYPE_IP;
-+ } else {
-+ type = SOCK_RAW;
-+ protocol = ETH_P_ALL;
-+ }
-+
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -114,6 +123,7 @@ int if_register_lpf (info)
- /* Bind to the interface name */
- memset (&sa, 0, sizeof sa);
- sa.ll.sll_family = AF_PACKET;
-+ sa.ll.sll_protocol = htons(protocol);
- sa.ll.sll_ifindex = ifr.ifr_ifindex;
- if (bind (sock, &sa.common, sizeof sa)) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
-@@ -183,6 +193,8 @@ void if_deregister_send (info)
- in bpf includes... */
- extern struct sock_filter dhcp_bpf_filter [];
- extern int dhcp_bpf_filter_len;
-+extern struct sock_filter dhcp_ib_bpf_filter [];
-+extern int dhcp_ib_bpf_filter_len;
-
- #if defined (HAVE_TR_SUPPORT)
- extern struct sock_filter dhcp_bpf_tr_filter [];
-@@ -200,11 +212,13 @@ void if_register_receive (info)
- /* Open a LPF device and hang it on this interface... */
- info -> rfdesc = if_register_lpf (info);
-
-- val = 1;
-- if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,
-- sizeof val) < 0) {
-- if (errno != ENOPROTOOPT)
-- log_fatal ("Failed to set auxiliary packet data: %m");
-+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
-+ val = 1;
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA,
-+ &val, sizeof val) < 0) {
-+ if (errno != ENOPROTOOPT)
-+ log_fatal ("Failed to set auxiliary packet data: %m");
-+ }
- }
-
- #if defined (HAVE_TR_SUPPORT)
-@@ -249,15 +263,28 @@ static void lpf_gen_filter_setup (info)
- struct sock_fprog p;
- memset(&p,'\0', sizeof(struct sock_fprog));
-
-- /* Set up the bpf filter program structure. This is defined in
-- bpf.c */
-- p.len = dhcp_bpf_filter_len;
-- p.filter = dhcp_bpf_filter;
--
-- /* 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 [8].k = ntohs ((short)local_port);
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ /* Set up the bpf filter program structure. */
-+ p.len = dhcp_ib_bpf_filter_len;
-+ p.filter = dhcp_ib_bpf_filter;
-+
-+ /* 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_ib_bpf_filter[6].k = ntohs ((short)local_port);
-+ } else {
-+ /* Set up the bpf filter program structure.
-+ This is defined in bpf.c */
-+ p.len = dhcp_bpf_filter_len;
-+ p.filter = dhcp_bpf_filter;
-+
-+ /* 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 [8].k = ntohs ((short)local_port);
-+ }
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
-@@ -312,6 +339,54 @@ static void lpf_tr_filter_setup (info)
- #endif /* USE_LPF_RECEIVE */
-
- #ifdef USE_LPF_SEND
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
-+ struct interface_info *interface;
-+ struct packet *packet;
-+ struct dhcp_packet *raw;
-+ size_t len;
-+ struct in_addr from;
-+ struct sockaddr_in *to;
-+ struct hardware *hto;
-+{
-+ unsigned ibufp = 0;
-+ double ih [1536 / sizeof (double)];
-+ unsigned char *buf = (unsigned char *)ih;
-+ ssize_t result;
-+
-+ union sockunion {
-+ struct sockaddr sa;
-+ struct sockaddr_ll sll;
-+ struct sockaddr_storage ss;
-+ } su;
-+
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
-+ to->sin_addr.s_addr, to->sin_port,
-+ (unsigned char *)raw, len);
-+ memcpy (buf + ibufp, raw, len);
-+
-+ memset(&su, 0, sizeof(su));
-+ su.sll.sll_family = AF_PACKET;
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
-+
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
-+ errno = ENOENT;
-+ log_error ("send_packet_ib: %m - failed to get if index");
-+ return -1;
-+ }
-+
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
-+
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
-+ &su.sa, sizeof(su));
-+
-+ if (result < 0)
-+ log_error ("send_packet_ib: %m");
-+
-+ return result;
-+}
-+
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
-@@ -332,6 +407,11 @@ ssize_t send_packet (interface, packet,
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return send_packet_ib(interface, packet, raw, len, from,
-+ to, hto);
-+ }
-+
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto);
- fudge = hbufp % 4; /* IP header must be word-aligned. */
-@@ -350,6 +430,38 @@ ssize_t send_packet (interface, packet,
- #endif /* USE_LPF_SEND */
-
- #ifdef USE_LPF_RECEIVE
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
-+ struct interface_info *interface;
-+ unsigned char *buf;
-+ size_t len;
-+ struct sockaddr_in *from;
-+ struct hardware *hfrom;
-+{
-+ int length = 0;
-+ int offset = 0;
-+ unsigned char ibuf [1536];
-+ unsigned bufix = 0;
-+
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
-+
-+ if (length <= 0)
-+ return length;
-+
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
-+ (unsigned)length, 0);
-+
-+ if (offset < 0)
-+ return 0;
-+
-+ bufix += offset;
-+ length -= offset;
-+
-+ /* Copy out the data in the packet... */
-+ memcpy(buf, &ibuf[bufix], length);
-+
-+ return length;
-+}
-+
- ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
-@@ -375,6 +487,10 @@ ssize_t receive_packet (interface, buf,
- };
- struct cmsghdr *cmsg;
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return receive_packet_ib(interface, buf, len, from, hfrom);
-+ }
-+
- length = recvmsg (interface -> rfdesc, &msg, 0);
- if (length <= 0)
- return length;
-diff -up dhcp-3.0.5/includes/dhcp.h.ib dhcp-3.0.5/includes/dhcp.h
---- dhcp-3.0.5/includes/dhcp.h.ib 2005-10-10 18:52:13.000000000 +0200
-+++ dhcp-3.0.5/includes/dhcp.h 2010-09-17 11:48:50.000000000 +0200
-@@ -74,6 +74,7 @@ struct dhcp_packet {
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
- #define HTYPE_FDDI 8 /* FDDI... */
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */
-
- /* Magic cookie validating dhcp options field (and bootp vendor
- extensions field). */
-diff -up dhcp-3.0.5/client/dhclient.c.ib dhcp-3.0.5/client/dhclient.c
---- dhcp-3.0.5/client/dhclient.c.ib 2010-09-16 21:16:13.000000000 +0200
-+++ dhcp-3.0.5/client/dhclient.c 2010-09-17 12:59:33.000000000 +0200
-@@ -82,6 +82,7 @@ int bootp_broadcast_always = 0;
- FILE *leaseFile=0;
- #endif
- static void usage PROTO ((void));
-+static void setup_ib_interface(struct interface_info *ip);
-
- void do_release(struct client_state *);
-
-@@ -902,6 +903,14 @@ int main
- }
- srandom (seed + cur_time);
-
-+ /* Setup specific Infiniband options */
-+ for (ip = interfaces; ip; ip = ip->next) {
-+ if (ip->client &&
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
-+ setup_ib_interface(ip);
-+ }
-+ }
-+
- /* Start a configuration state machine for each interface. */
- for (ip = interfaces; ip; ip = ip -> next) {
- ip -> flags |= INTERFACE_RUNNING;
-@@ -1083,6 +1092,29 @@ extern omapi_io_object_t omapi_io_states
- return 0;
- }
-
-+static void setup_ib_interface(struct interface_info *ip)
-+{
-+ struct group *g;
-+
-+ /* Set the broadcast flag */
-+ bootp_broadcast_always = 1;
-+
-+ /*
-+ * Find out if a dhcp-client-identifier option was specified either
-+ * in the config file or on the command line
-+ */
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
-+ if ((g->statements != NULL) &&
-+ (strcmp(g->statements->data.option->option->name,
-+ "dhcp-client-identifier") == 0)) {
-+ return;
-+ }
-+ }
-+
-+ /* No client ID specified */
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+}
-+
- static void usage ()
- {
- printf ("%s %s\n", message, DHCP_VERSION);
-diff -up dhcp-3.0.5/common/bpf.c.ib dhcp-3.0.5/common/bpf.c
---- dhcp-3.0.5/common/bpf.c.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/common/bpf.c 2010-09-17 11:49:08.000000000 +0200
-@@ -194,11 +194,44 @@ struct bpf_insn dhcp_bpf_filter [] = {
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
-+/* Packet filter program for DHCP over Infiniband.
-+ *
-+ * XXX
-+ * Changes to the filter program may require changes to the constant offsets
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
-+ * XXX
-+ */
-+struct bpf_insn dhcp_ib_bpf_filter [] = {
-+ /* Packet filter for Infiniband */
-+ /* Make sure it's a UDP packet... */
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
-+ 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, 6),
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-+
-+ /* Get the IP header length... */
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
-+
-+ /* Make sure it's to the right port... */
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
-+
-+ /* 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),
-+};
-+
- #if defined (DEC_FDDI)
- struct bpf_insn *bpf_fddi_filter;
- #endif
-
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
-+
- #if defined (HAVE_TR_SUPPORT)
- struct bpf_insn dhcp_bpf_tr_filter [] = {
- /* accept all token ring packets due to variable length header */
-diff -up dhcp-3.0.5/common/discover.c.ib dhcp-3.0.5/common/discover.c
---- dhcp-3.0.5/common/discover.c.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/common/discover.c 2010-09-17 21:13:04.000000000 +0200
-@@ -39,6 +39,8 @@ static char copyright[] =
-
- #include "dhcpd.h"
- #include <sys/ioctl.h>
-+#include <ifaddrs.h>
-+#include <linux/if_packet.h>
-
- struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
- int interfaces_invalidated;
-@@ -58,6 +60,8 @@ void (*bootp_packet_handler) PROTO ((str
- unsigned int,
- struct iaddr, struct hardware *));
-
-+void setup_ib_bcast_addr(struct interface_info *info);
-+
- omapi_object_type_t *dhcp_type_interface;
- #if defined (TRACING)
- trace_type_t *interface_trace;
-@@ -70,6 +74,15 @@ int interface_max;
-
- OMAPI_OBJECT_ALLOC (interface, struct interface_info, dhcp_type_interface)
-
-+/* Default broadcast address for IPoIB */
-+unsigned char default_ib_bcast_addr[20] = {
-+ 0x00, 0xff, 0xff, 0xff,
-+ 0xff, 0x12, 0x40, 0x1b,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0xff, 0xff, 0xff, 0xff
-+};
-+
- isc_result_t interface_setup ()
- {
- isc_result_t status;
-@@ -533,6 +546,15 @@ void discover_interfaces (state)
- break;
- #endif
-
-+#ifndef HAVE_ARPHRD_INFINIBAND
-+# define ARPHRD_INFINIBAND HTYPE_INFINIBAND
-+#endif
-+ case ARPHRD_INFINIBAND:
-+ setup_ib_bcast_addr ( tmp );
-+ tmp -> hw_address.hlen = 1;
-+ tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ break;
-+
- default:
- log_error ("%s: unknown hardware address type %d",
- ifr.ifr_name, sa.sa_family);
-@@ -718,6 +740,57 @@ void discover_interfaces (state)
- #endif
- }
-
-+void setup_ib_bcast_addr (struct interface_info *info)
-+{
-+ char *name = info->name;
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ log_fatal("Failed to get interfaces");
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ log_fatal("Failed to get HW address for %s\n", name);
-+ }
-+
-+ switch (sll->sll_hatype) {
-+ case ARPHRD_INFINIBAND:
-+ /* For Infiniband, save the broadcast address and store
-+ * the port GUID into the hardware address.
-+ */
-+ if (ifa->ifa_flags & IFF_BROADCAST) {
-+ struct sockaddr_ll *bll;
-+
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
-+ } else {
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
-+ 20);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ freeifaddrs(ifaddrs);
-+}
-+
- int if_readsocket (h)
- omapi_object_t *h;
- {
-diff -up dhcp-3.0.5/includes/dhcpd.h.ib dhcp-3.0.5/includes/dhcpd.h
---- dhcp-3.0.5/includes/dhcpd.h.ib 2010-09-16 19:54:43.000000000 +0200
-+++ dhcp-3.0.5/includes/dhcpd.h 2010-09-17 11:57:32.000000000 +0200
-@@ -781,6 +781,7 @@ struct interface_info {
- struct shared_network *shared_network;
- /* Networks connected to this interface. */
- struct hardware hw_address; /* Its physical address. */
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
- struct in_addr primary_address; /* Primary interface address. */
-
- u_int8_t *circuit_id; /* Circuit ID associated with this
-diff -up dhcp-3.0.5/includes/osdep.h.ib dhcp-3.0.5/includes/osdep.h
---- dhcp-3.0.5/includes/osdep.h.ib 2005-09-28 21:58:27.000000000 +0300
-+++ dhcp-3.0.5/includes/osdep.h 2010-09-17 13:32:59.000000000 +0200
-@@ -307,6 +307,10 @@
- # define HAVE_ARPHRD_METRICOM
- #endif
-
-+#if defined (ARPHRD_INFINIBAND) && !defined (HAVE_ARPHRD_INFINIBAND)
-+# define HAVE_ARPHRD_INFINIBAND
-+#endif
-+
- #if defined (SO_BINDTODEVICE) && !defined (HAVE_SO_BINDTODEVICE)
- # define HAVE_SO_BINDTODEVICE
- #endif
-diff -up dhcp-3.0.5/server/dhcp.c.ib dhcp-3.0.5/server/dhcp.c
---- dhcp-3.0.5/server/dhcp.c.ib 2010-09-17 17:31:09.000000000 +0200
-+++ dhcp-3.0.5/server/dhcp.c 2010-09-17 21:16:43.000000000 +0200
-@@ -2935,7 +2935,10 @@ void dhcp_reply (lease)
- unicastp = 0;
- }
-
-- memcpy (&from, state -> from.iabuf, sizeof from);
-+ if (state -> ip -> hw_address.hbuf [0] != HTYPE_INFINIBAND)
-+ memcpy (&from, state -> from.iabuf, sizeof from);
-+ else
-+ from = state ->ip -> primary_address;
-
- result = send_packet (state -> ip,
- (struct packet *)0, &raw, packet_length,
+++ /dev/null
---- dhcp.spec.ib 2010-08-31 19:50:18.000000000 +0300
-+++ dhcp.spec 2010-09-19 20:30:36.150032000 +0200
-@@ -56,6 +56,9 @@ Patch21: %{name}-3.0.5-failover-leak.pat
- Patch22: %{name}-3.0.5-short-lease.patch
- Patch23: %{name}-3.0.5-partner-down.patch
- Patch24: %{name}-3.0.5-lease-exhaustion.patch
-+Patch25: %{name}-3.0.5-lpf-ib.patch
-+Patch26: %{name}-3.0.5-improved-xid.patch
-+Patch27: %{name}-3.0.5-gpxe-cid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- Requires(post): chkconfig, coreutils
-@@ -221,6 +223,12 @@ esac
- # Backport from dhcp-3.0.6
- %patch24 -p1 -b .exhaustion
-
-+%patch25 -p1 -b .ib
-+
-+%patch26 -p1 -b .xid
-+
-+%patch27 -p1 -b .gpxe
-+
- %build
- %{__cp} %SOURCE1 .
- %{__cat} << EOF > site.conf
+++ /dev/null
---- dhcp.spec.ib 2010-08-31 19:50:18.000000000 +0300
-+++ dhcp.spec 2010-09-19 20:30:36.150032000 +0200
-@@ -56,6 +56,8 @@ Patch21: %{name}-3.0.5-failover-leak.pat
- Patch22: %{name}-3.0.5-short-lease.patch
- Patch23: %{name}-3.0.5-partner-down.patch
- Patch24: %{name}-3.0.5-lease-exhaustion.patch
-+Patch25: %{name}-3.0.5-lpf-ib.patch
-+Patch26: %{name}-3.0.5-improved-xid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- Requires(post): chkconfig, coreutils
-@@ -221,6 +223,10 @@ esac
- # Backport from dhcp-3.0.6
- %patch24 -p1 -b .exhaustion
-
-+%patch25 -p1 -b .ib
-+
-+%patch26 -p1 -b .xid
-+
- %build
- %{__cp} %SOURCE1 .
- %{__cat} << EOF > site.conf
+++ /dev/null
---- dhcp.spec.ib 2010-02-11 12:46:05.000000000 +0200
-+++ dhcp.spec 2010-09-20 12:40:18.617505000 +0200
-@@ -54,6 +54,9 @@ Patch19: %{name}-3.0.5-honor-peer-vars.p
- Patch20: %{name}-3.0.5-IFNAMSIZ.patch
- Patch21: %{name}-3.0.5-failover-leak.patch
- Patch22: %{name}-3.0.5-short-lease.patch
-+Patch23: %{name}-3.0.5-lpf-ib.patch
-+Patch24: %{name}-3.0.5-improved-xid.patch
-+Patch25: %{name}-3.0.5-gpxe-cid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- Requires(post): chkconfig, coreutils
-@@ -206,6 +209,12 @@ esac
- # Fix dhclient to not renew it's lease too often when gets very short lease from server (RHBZ #498658)
- %patch22 -p1 -b .short-lease
-
-+%patch23 -p1 -b .ib
-+
-+%patch24 -p1 -b .xid
-+
-+%patch25 -p1 -b .gpxe
-+
- %build
- %{__cp} %SOURCE1 .
- %{__cat} << EOF > site.conf
+++ /dev/null
---- dhcp.spec.ib 2010-02-11 12:46:05.000000000 +0200
-+++ dhcp.spec 2010-09-20 12:40:18.617505000 +0200
-@@ -54,6 +54,8 @@ Patch19: %{name}-3.0.5-honor-peer-vars.p
- Patch20: %{name}-3.0.5-IFNAMSIZ.patch
- Patch21: %{name}-3.0.5-failover-leak.patch
- Patch22: %{name}-3.0.5-short-lease.patch
-+Patch23: %{name}-3.0.5-lpf-ib.patch
-+Patch24: %{name}-3.0.5-improved-xid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- Requires(post): chkconfig, coreutils
-@@ -206,6 +208,10 @@ esac
- # Fix dhclient to not renew it's lease too often when gets very short lease from server (RHBZ #498658)
- %patch22 -p1 -b .short-lease
-
-+%patch23 -p1 -b .ib
-+
-+%patch24 -p1 -b .xid
-+
- %build
- %{__cp} %SOURCE1 .
- %{__cat} << EOF > site.conf
+++ /dev/null
-diff -up dhcp-4.1.0p1/client/dhclient.c.gpxe dhcp-4.1.0p1/client/dhclient.c
---- dhcp-4.1.0p1/client/dhclient.c.gpxe 2011-01-20 20:36:47.247676000 +0200
-+++ dhcp-4.1.0p1/client/dhclient.c 2011-01-20 20:42:55.094737000 +0200
-@@ -56,6 +56,13 @@ const char *path_dhclient_pid = NULL;
- static char path_dhclient_script_array[] = _PATH_DHCLIENT_SCRIPT;
- char *path_dhclient_script = path_dhclient_script_array;
-
-+/* Default Prefix */
-+static unsigned char default_prefix[12] = {
-+ 0xff, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x02, 0x00,
-+ 0x00, 0x02, 0xc9, 0x00
-+};
-+
- int dhcp_max_agent_option_packet_length = 0;
-
- int interfaces_requested = 0;
-@@ -102,6 +109,12 @@ static isc_result_t write_duid(struct da
- static void setup_ib_interface(struct interface_info *ip)
- {
- struct group *g;
-+ struct hardware *hw = &ip->hw_address;
-+ char client_id[64];
-+ char *arg_conf = NULL;
-+ int arg_conf_len = 0;
-+ isc_result_t status;
-+ struct parse *cfile = (struct parse *)0;
-
- /* Set the broadcast flag */
- ip->client->config->bootp_broadcast_always = 1;
-@@ -118,8 +131,39 @@ static void setup_ib_interface(struct in
- }
- }
-
-- /* No client ID specified */
-- log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+ /*
-+ * No client ID specified, make up one based on a default
-+ * "prefix" and the port GUID.
-+ *
-+ * NOTE: This is compatible with what gpxe does.
-+ */
-+ sprintf(client_id, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
-+ default_prefix[0], default_prefix[1], default_prefix[2],
-+ default_prefix[3], default_prefix[4], default_prefix[5],
-+ default_prefix[6], default_prefix[7], default_prefix[8],
-+ default_prefix[9], default_prefix[10], default_prefix[11],
-+ hw->hbuf[1], hw->hbuf[2], hw->hbuf[3], hw->hbuf[4],
-+ hw->hbuf[5], hw->hbuf[6], hw->hbuf[7], hw->hbuf[8]);
-+
-+ arg_conf_len = asprintf(&arg_conf,
-+ "send dhcp-client-identifier %s;",
-+ client_id);
-+
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))
-+ log_fatal("Unable to send option dhcp-client-identifier");
-+
-+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len,
-+ "Automatic Infiniband client identifier", 0);
-+
-+ if ((status != ISC_R_SUCCESS) || (cfile->warnings_occurred))
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ parse_client_statement(cfile, NULL, ip->client->config);
-+
-+ if (cfile->warnings_occurred)
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ end_parse(&cfile);
- }
-
- int
-diff -up dhcp-4.1.0p1/common/lpf.c.gpxe dhcp-4.1.0p1/common/lpf.c
---- dhcp-4.1.0p1/common/lpf.c.gpxe 2011-01-20 20:36:47.193678000 +0200
-+++ dhcp-4.1.0p1/common/lpf.c 2011-01-20 21:06:17.188352000 +0200
-@@ -589,6 +589,35 @@ void maybe_setup_fallback ()
- }
- }
-
-+static unsigned char * get_ib_hw_addr(char * name)
-+{
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+ static unsigned char hw_addr[8];
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ return NULL;
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ return NULL;
-+ }
-+ memcpy(hw_addr, &sll->sll_addr[sll->sll_halen - 8], 8);
-+ freeifaddrs(ifaddrs);
-+ return (unsigned char *)&hw_addr;
-+}
-+
- void
- get_hw_addr(struct interface_info *info)
- {
-@@ -597,6 +626,7 @@ get_hw_addr(struct interface_info *info)
- struct ifaddrs *ifaddrs;
- struct ifaddrs *ifa;
- struct sockaddr_ll *sll = NULL;
-+ unsigned char *hw_addr;
-
- if (getifaddrs(&ifaddrs) == -1)
- log_fatal("Failed to get interfaces");
-@@ -655,6 +685,10 @@ get_hw_addr(struct interface_info *info)
-
- hw->hlen = 1;
- hw->hbuf[0] = HTYPE_INFINIBAND;
-+ hw_addr = get_ib_hw_addr(name);
-+ if (!hw_addr)
-+ log_fatal("Failed getting %s hw addr", name);
-+ memcpy (&hw->hbuf [1], hw_addr, 8);
- break;
- default:
- freeifaddrs(ifaddrs);
+++ /dev/null
-diff -up dhcp-4.1.0p1/client/dhclient.c.xid dhcp-4.1.0p1/client/dhclient.c
---- dhcp-4.1.0p1/client/dhclient.c.xid 2010-09-15 21:49:10.749354000 +0200
-+++ dhcp-4.1.0p1/client/dhclient.c 2010-09-15 21:59:33.428997000 +0200
-@@ -868,6 +868,26 @@ main(int argc, char **argv) {
- }
- }
-
-+ /* We create a backup seed before rediscovering interfaces in order to
-+ have a seed built using all of the available interfaces
-+ It's interesting if required interfaces doesn't let us defined
-+ a really unique seed due to a lack of valid HW addr later
-+ (this is the case with DHCP over IB)
-+ We only use the last device as using a sum could broke the
-+ uniqueness of the seed among multiple nodes
-+ */
-+ unsigned backup_seed = 0;
-+ for (ip = interfaces; ip; ip = ip -> next) {
-+ int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
-+ memcpy (&junk,
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
-+ sizeof seed], sizeof seed);
-+ backup_seed = junk;
-+ }
-+
-+
- /* At this point, all the interfaces that the script thinks
- are relevant should be running, so now we once again call
- discover_interfaces(), and this time ask it to actually set
-@@ -882,14 +902,36 @@ main(int argc, char **argv) {
- Not much entropy, but we're booting, so we're not likely to
- find anything better. */
- seed = 0;
-+ int seed_flag = 0;
- for (ip = interfaces; ip; ip = ip->next) {
- int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
- memcpy(&junk,
- &ip->hw_address.hbuf[ip->hw_address.hlen -
- sizeof seed], sizeof seed);
- seed += junk;
-+ seed_flag = 1;
- }
-- srandom(seed + cur_time);
-+ if ( seed_flag == 0 ) {
-+ if ( backup_seed != 0 ) {
-+ seed = backup_seed;
-+ log_info ("xid: rand init seed (0x%x) built using all"
-+ " available interfaces",seed);
-+ }
-+ else {
-+ seed = cur_time^((unsigned) gethostid()) ;
-+ log_info ("xid: warning: no netdev with useable HWADDR found"
-+ " for seed's uniqueness enforcement");
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",
-+ seed);
-+ }
-+ /* we only use seed and no current time as a broadcast reply */
-+ /* will certainly be used by the hwaddrless interface */
-+ srandom(seed);
-+ }
-+ else
-+ srandom(seed + cur_time);
-
- /* Setup specific Infiniband options */
- for (ip = interfaces; ip; ip = ip->next) {
-@@ -1388,7 +1430,7 @@ void dhcpack (packet)
- return;
- }
-
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- lease = packet_to_lease (packet, client);
- if (!lease) {
-@@ -2088,7 +2130,7 @@ void dhcpnak (packet)
- return;
- }
-
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- if (!client -> active) {
- #if defined (DEBUG)
-@@ -2214,10 +2256,10 @@ void send_discover (cpp)
- client -> packet.secs = htons (65535);
- client -> secs = client -> packet.secs;
-
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -2489,10 +2531,10 @@ void send_request (cpp)
- client -> packet.secs = htons (65535);
- }
-
-- log_info ("DHCPREQUEST on %s to %s port %d",
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
- fallback_interface)
-@@ -2522,10 +2564,10 @@ void send_decline (cpp)
-
- int result;
-
-- log_info ("DHCPDECLINE on %s to %s port %d",
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port));
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -2565,10 +2607,10 @@ void send_release (cpp)
- return;
- }
-
-- log_info ("DHCPRELEASE on %s to %s port %d",
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (fallback_interface)
- result = send_packet (fallback_interface,
+++ /dev/null
-diff -up dhcp-4.1.0p1/common/lpf.c.ib dhcp-4.1.0p1/common/lpf.c
---- dhcp-4.1.0p1/common/lpf.c.ib 2010-09-15 19:04:15.310680000 +0200
-+++ dhcp-4.1.0p1/common/lpf.c 2010-09-17 21:43:22.976561000 +0200
-@@ -42,6 +42,7 @@
- #include "includes/netinet/udp.h"
- #include "includes/netinet/if_ether.h"
- #include <net/if.h>
-+#include <ifaddrs.h>
-
- #ifndef PACKET_AUXDATA
- #define PACKET_AUXDATA 8
-@@ -59,6 +60,15 @@ struct tpacket_auxdata
- /* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-+/* Default broadcast address for IPoIB */
-+static unsigned char default_ib_bcast_addr[20] = {
-+ 0x00, 0xff, 0xff, 0xff,
-+ 0xff, 0x12, 0x40, 0x1b,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0xff, 0xff, 0xff, 0xff
-+};
-+
- #ifdef USE_LPF_SEND
- void if_reinitialize_send (info)
- struct interface_info *info;
-@@ -86,10 +96,21 @@ int if_register_lpf (info)
- struct sockaddr common;
- } sa;
- struct ifreq ifr;
-+ int type;
-+ int protocol;
-
- /* Make an LPF socket. */
-- if ((sock = socket(PF_PACKET, SOCK_RAW,
-- htons((short)ETH_P_ALL))) < 0) {
-+ get_hw_addr(info);
-+
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ type = SOCK_DGRAM;
-+ protocol = ETHERTYPE_IP;
-+ } else {
-+ type = SOCK_RAW;
-+ protocol = ETH_P_ALL;
-+ }
-+
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -111,6 +132,7 @@ int if_register_lpf (info)
- /* Bind to the interface name */
- memset (&sa, 0, sizeof sa);
- sa.ll.sll_family = AF_PACKET;
-+ sa.ll.sll_protocol = htons(protocol);
- sa.ll.sll_ifindex = ifr.ifr_ifindex;
- if (bind (sock, &sa.common, sizeof sa)) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
-@@ -126,8 +148,6 @@ int if_register_lpf (info)
- log_fatal ("Bind socket to interface: %m");
- }
-
-- get_hw_addr(info->name, &info->hw_address);
--
- return sock;
- }
- #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
-@@ -182,6 +202,8 @@ void if_deregister_send (info)
- in bpf includes... */
- extern struct sock_filter dhcp_bpf_filter [];
- extern int dhcp_bpf_filter_len;
-+extern struct sock_filter dhcp_ib_bpf_filter [];
-+extern int dhcp_ib_bpf_filter_len;
-
- #if defined (HAVE_TR_SUPPORT)
- extern struct sock_filter dhcp_bpf_tr_filter [];
-@@ -199,11 +221,13 @@ void if_register_receive (info)
- /* Open a LPF device and hang it on this interface... */
- info -> rfdesc = if_register_lpf (info);
-
-- val = 1;
-- if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,
-- sizeof val) < 0) {
-- if (errno != ENOPROTOOPT)
-- log_fatal ("Failed to set auxiliary packet data: %m");
-+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
-+ val = 1;
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA,
-+ &val, sizeof val) < 0) {
-+ if (errno != ENOPROTOOPT)
-+ log_fatal ("Failed to set auxiliary packet data: %m");
-+ }
- }
-
- #if defined (HAVE_TR_SUPPORT)
-@@ -249,15 +273,28 @@ static void lpf_gen_filter_setup (info)
-
- memset(&p, 0, sizeof(p));
-
-- /* Set up the bpf filter program structure. This is defined in
-- bpf.c */
-- p.len = dhcp_bpf_filter_len;
-- p.filter = dhcp_bpf_filter;
--
-- /* 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 [8].k = ntohs ((short)local_port);
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ /* Set up the bpf filter program structure. */
-+ p.len = dhcp_ib_bpf_filter_len;
-+ p.filter = dhcp_ib_bpf_filter;
-+
-+ /* 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_ib_bpf_filter[6].k = ntohs ((short)local_port);
-+ } else {
-+ /* Set up the bpf filter program structure.
-+ This is defined in bpf.c */
-+ p.len = dhcp_bpf_filter_len;
-+ p.filter = dhcp_bpf_filter;
-+
-+ /* 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 [8].k = ntohs ((short)local_port);
-+ }
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
-@@ -313,6 +350,54 @@ static void lpf_tr_filter_setup (info)
- #endif /* USE_LPF_RECEIVE */
-
- #ifdef USE_LPF_SEND
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
-+ struct interface_info *interface;
-+ struct packet *packet;
-+ struct dhcp_packet *raw;
-+ size_t len;
-+ struct in_addr from;
-+ struct sockaddr_in *to;
-+ struct hardware *hto;
-+{
-+ unsigned ibufp = 0;
-+ double ih [1536 / sizeof (double)];
-+ unsigned char *buf = (unsigned char *)ih;
-+ ssize_t result;
-+
-+ union sockunion {
-+ struct sockaddr sa;
-+ struct sockaddr_ll sll;
-+ struct sockaddr_storage ss;
-+ } su;
-+
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
-+ to->sin_addr.s_addr, to->sin_port,
-+ (unsigned char *)raw, len);
-+ memcpy (buf + ibufp, raw, len);
-+
-+ memset(&su, 0, sizeof(su));
-+ su.sll.sll_family = AF_PACKET;
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
-+
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
-+ errno = ENOENT;
-+ log_error ("send_packet_ib: %m - failed to get if index");
-+ return -1;
-+ }
-+
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
-+
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
-+ &su.sa, sizeof(su));
-+
-+ if (result < 0)
-+ log_error ("send_packet_ib: %m");
-+
-+ return result;
-+}
-+
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
-@@ -333,6 +418,11 @@ ssize_t send_packet (interface, packet,
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return send_packet_ib(interface, packet, raw, len, from,
-+ to, hto);
-+ }
-+
- if (hto == NULL && interface->anycast_mac_addr.hlen)
- hto = &interface->anycast_mac_addr;
-
-@@ -354,6 +444,42 @@ ssize_t send_packet (interface, packet,
- #endif /* USE_LPF_SEND */
-
- #ifdef USE_LPF_RECEIVE
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
-+ struct interface_info *interface;
-+ unsigned char *buf;
-+ size_t len;
-+ struct sockaddr_in *from;
-+ struct hardware *hfrom;
-+{
-+ int length = 0;
-+ int offset = 0;
-+ unsigned char ibuf [1536];
-+ unsigned bufix = 0;
-+ unsigned paylen;
-+
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
-+
-+ if (length <= 0)
-+ return length;
-+
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
-+ (unsigned)length, &paylen, 0);
-+
-+ if (offset < 0)
-+ return 0;
-+
-+ bufix += offset;
-+ length -= offset;
-+
-+ if (length < paylen)
-+ log_fatal("Internal inconsistency at %s:%d.", MDL);
-+
-+ /* Copy out the data in the packet... */
-+ memcpy(buf, &ibuf[bufix], paylen);
-+
-+ return (ssize_t)paylen;
-+}
-+
- ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
-@@ -380,6 +506,10 @@ ssize_t receive_packet (interface, buf,
- };
- struct cmsghdr *cmsg;
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return receive_packet_ib(interface, buf, len, from, hfrom);
-+ }
-+
- length = recvmsg (interface -> rfdesc, &msg, 0);
- if (length <= 0)
- return length;
-@@ -460,33 +590,41 @@ void maybe_setup_fallback ()
- }
-
- void
--get_hw_addr(const char *name, struct hardware *hw) {
-- int sock;
-- struct ifreq tmp;
-- struct sockaddr *sa;
-+get_hw_addr(struct interface_info *info)
-+{
-+ struct hardware *hw = &info->hw_address;
-+ char *name = info->name;
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-
-- if (strlen(name) >= sizeof(tmp.ifr_name)) {
-- log_fatal("Device name too long: \"%s\"", name);
-- }
-+ if (getifaddrs(&ifaddrs) == -1)
-+ log_fatal("Failed to get interfaces");
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-
-- sock = socket(AF_INET, SOCK_DGRAM, 0);
-- if (sock < 0) {
-- log_fatal("Can't create socket for \"%s\": %m", name);
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
- }
-
-- memset(&tmp, 0, sizeof(tmp));
-- strcpy(tmp.ifr_name, name);
-- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
-- log_fatal("Error getting hardware address for \"%s\": %m",
-- name);
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ log_fatal("Failed to get HW address for %s\n", name);
- }
-
-- sa = &tmp.ifr_hwaddr;
-- switch (sa->sa_family) {
-+ switch (sll->sll_hatype) {
- case ARPHRD_ETHER:
- hw->hlen = 7;
- hw->hbuf[0] = HTYPE_ETHER;
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
- break;
- case ARPHRD_IEEE802:
- #ifdef ARPHRD_IEEE802_TR
-@@ -494,18 +632,36 @@ get_hw_addr(const char *name, struct har
- #endif /* ARPHRD_IEEE802_TR */
- hw->hlen = 7;
- hw->hbuf[0] = HTYPE_IEEE802;
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
- break;
- case ARPHRD_FDDI:
- hw->hlen = 17;
- hw->hbuf[0] = HTYPE_FDDI;
-- memcpy(&hw->hbuf[1], sa->sa_data, 16);
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 16);
-+ break;
-+ case ARPHRD_INFINIBAND:
-+ /* For Infiniband, save the broadcast address and store
-+ * the port GUID into the hardware address.
-+ */
-+ if (ifa->ifa_flags & IFF_BROADCAST) {
-+ struct sockaddr_ll *bll;
-+
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
-+ } else {
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
-+ 20);
-+ }
-+
-+ hw->hlen = 1;
-+ hw->hbuf[0] = HTYPE_INFINIBAND;
- break;
- default:
-+ freeifaddrs(ifaddrs);
- log_fatal("Unsupported device type %ld for \"%s\"",
-- (long int)sa->sa_family, name);
-+ (long int)sll->sll_family, name);
- }
-
-- close(sock);
-+ freeifaddrs(ifaddrs);
- }
- #endif
-diff -up dhcp-4.1.0p1/includes/dhcp.h.ib dhcp-4.1.0p1/includes/dhcp.h
---- dhcp-4.1.0p1/includes/dhcp.h.ib 2008-01-24 04:43:05.000000000 +0200
-+++ dhcp-4.1.0p1/includes/dhcp.h 2010-09-15 20:01:39.398891000 +0200
-@@ -79,6 +79,7 @@ struct dhcp_packet {
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
- #define HTYPE_FDDI 8 /* FDDI... */
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */
-
- /* Magic cookie validating dhcp options field (and bootp vendor
- extensions field). */
-diff -up dhcp-4.1.0p1/client/dhclient.c.ib dhcp-4.1.0p1/client/dhclient.c
---- dhcp-4.1.0p1/client/dhclient.c.ib 2010-09-15 19:39:22.845610000 +0200
-+++ dhcp-4.1.0p1/client/dhclient.c 2010-09-17 22:02:59.154924000 +0200
-@@ -99,6 +99,29 @@ static void usage(void);
-
- static isc_result_t write_duid(struct data_string *duid);
-
-+static void setup_ib_interface(struct interface_info *ip)
-+{
-+ struct group *g;
-+
-+ /* Set the broadcast flag */
-+ ip->client->config->bootp_broadcast_always = 1;
-+
-+ /*
-+ * Find out if a dhcp-client-identifier option was specified either
-+ * in the config file or on the command line
-+ */
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
-+ if ((g->statements != NULL) &&
-+ (strcmp(g->statements->data.option->option->name,
-+ "dhcp-client-identifier") == 0)) {
-+ return;
-+ }
-+ }
-+
-+ /* No client ID specified */
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+}
-+
- int
- main(int argc, char **argv) {
- int fd;
-@@ -866,6 +889,14 @@ main(int argc, char **argv) {
- }
- srandom(seed + cur_time);
-
-+ /* Setup specific Infiniband options */
-+ for (ip = interfaces; ip; ip = ip->next) {
-+ if (ip->client &&
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
-+ setup_ib_interface(ip);
-+ }
-+ }
-+
- /* Start a configuration state machine for each interface. */
- #ifdef DHCPv6
- if (local_family == AF_INET6) {
-diff -up dhcp-4.1.0p1/common/bpf.c.ib dhcp-4.1.0p1/common/bpf.c
---- dhcp-4.1.0p1/common/bpf.c.ib 2010-09-15 19:05:03.429133000 +0200
-+++ dhcp-4.1.0p1/common/bpf.c 2010-09-15 20:01:39.452895000 +0200
-@@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = {
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
-+/* Packet filter program for DHCP over Infiniband.
-+ *
-+ * XXX
-+ * Changes to the filter program may require changes to the constant offsets
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
-+ * XXX
-+ */
-+struct bpf_insn dhcp_ib_bpf_filter [] = {
-+ /* Packet filter for Infiniband */
-+ /* Make sure it's a UDP packet... */
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
-+ 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, 6),
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-+
-+ /* Get the IP header length... */
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
-+
-+ /* Make sure it's to the right port... */
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
-+
-+ /* 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),
-+};
-+
- #if defined (DEC_FDDI)
- struct bpf_insn *bpf_fddi_filter;
- #endif
-
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
-+
- #if defined (HAVE_TR_SUPPORT)
- struct bpf_insn dhcp_bpf_tr_filter [] = {
- /* accept all token ring packets due to variable length header */
-diff -up dhcp-4.1.0p1/common/socket.c.ib dhcp-4.1.0p1/common/socket.c
---- dhcp-4.1.0p1/common/socket.c.ib 2008-08-29 20:48:57.000000000 +0300
-+++ dhcp-4.1.0p1/common/socket.c 2010-09-15 20:01:39.462901000 +0200
-@@ -276,7 +276,7 @@ if_register_socket(struct interface_info
-
- /* If this is a normal IPv4 address, get the hardware address. */
- if ((local_family == AF_INET) && (strcmp(info->name, "fallback") != 0))
-- get_hw_addr(info->name, &info->hw_address);
-+ get_hw_addr(info);
-
- return sock;
- }
-@@ -422,7 +422,7 @@ if_register6(struct interface_info *info
- if (req_multi)
- if_register_multicast(info);
-
-- get_hw_addr(info->name, &info->hw_address);
-+ get_hw_addr(info);
-
- if (!quiet_interface_discovery) {
- if (info->shared_network != NULL) {
-diff -up dhcp-4.1.0p1/includes/dhcpd.h.ib dhcp-4.1.0p1/includes/dhcpd.h
---- dhcp-4.1.0p1/includes/dhcpd.h.ib 2010-09-15 19:09:13.796292000 +0200
-+++ dhcp-4.1.0p1/includes/dhcpd.h 2010-09-15 20:01:39.479891000 +0200
-@@ -1112,6 +1112,7 @@ struct interface_info {
- struct shared_network *shared_network;
- /* Networks connected to this interface. */
- struct hardware hw_address; /* Its physical address. */
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
- struct in_addr *addresses; /* Addresses associated with this
- * interface.
- */
-@@ -2141,7 +2142,7 @@ void print_dns_status (int, ns_updque *)
- #endif
- const char *print_time(TIME);
-
--void get_hw_addr(const char *name, struct hardware *hw);
-+void get_hw_addr(struct interface_info *info);
-
- /* socket.c */
- #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
+++ /dev/null
---- dhcp.spec.ib 2010-01-11 18:04:03.000000000 +0200
-+++ dhcp.spec 2010-09-20 13:11:06.727132000 +0200
-@@ -56,6 +56,9 @@ Patch21: %{name}-4.1.0-64_bit_lease_par
- Patch22: %{name}-4.1.0-CVE-2009-1892.patch
- Patch23: %{name}-4.1.0p1-capability.patch
- Patch24: %{name}-4.1.0p1-failover-leak.patch
-+Patch25: %{name}-4.1.0p1-lpf-ib.patch
-+Patch26: %{name}-4.1.0p1-improved-xid.patch
-+Patch27: %{name}-4.1.0p1-gpxe-cid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- BuildRequires: autoconf
-@@ -222,6 +224,12 @@ libdhcpctl and libomapi static libraries
- # Memory leak in the load_balance_mine() function is fixed (#554384)
- %patch24 -p1
-
-+%patch25 -p1
-+
-+%patch26 -p1
-+
-+%patch27 -p1
-+
- # Copy in documentation and example scripts for LDAP patch to dhcpd
- %{__install} -p -m 0755 ldap-for-dhcp-%{ldappatchver}/dhcpd-conf-to-ldap contrib/
-
+++ /dev/null
---- dhcp.spec.ib 2010-01-11 18:04:03.000000000 +0200
-+++ dhcp.spec 2010-09-20 13:11:06.727132000 +0200
-@@ -56,6 +56,8 @@ Patch21: %{name}-4.1.0-64_bit_lease_par
- Patch22: %{name}-4.1.0-CVE-2009-1892.patch
- Patch23: %{name}-4.1.0p1-capability.patch
- Patch24: %{name}-4.1.0p1-failover-leak.patch
-+Patch25: %{name}-4.1.0p1-lpf-ib.patch
-+Patch26: %{name}-4.1.0p1-improved-xid.patch
-
- BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
- BuildRequires: autoconf
-@@ -222,6 +224,10 @@ libdhcpctl and libomapi static libraries
- # Memory leak in the load_balance_mine() function is fixed (#554384)
- %patch24 -p1
-
-+%patch25 -p1
-+
-+%patch26 -p1
-+
- # Copy in documentation and example scripts for LDAP patch to dhcpd
- %{__install} -p -m 0755 ldap-for-dhcp-%{ldappatchver}/dhcpd-conf-to-ldap contrib/
-
+++ /dev/null
-From b5b30be6a87994e64f8e3ae3819d7bc56d5fd61d Mon Sep 17 00:00:00 2001
-From: root <root@reg-ovm-036-004.lab.mtl.com>
-Date: Tue, 25 Mar 2014 23:15:58 +0200
-Subject: [PATCH 1/2] dhcp 4.2.4p2 lpf ip over ib support
-
----
- client/dhclient.c | 31 +++++++
- common/bpf.c | 33 ++++++++
- common/lpf.c | 236 +++++++++++++++++++++++++++++++++++++++++++++---------
- common/socket.c | 6 +-
- includes/dhcpd.h | 3 +-
- 5 files changed, 265 insertions(+), 44 deletions(-)
-
-diff --git a/client/dhclient.c b/client/dhclient.c
-index 025337a..09ad2ab 100644
---- a/client/dhclient.c
-+++ b/client/dhclient.c
-@@ -100,6 +100,29 @@ static int check_domain_name_list(const char *ptr, size_t len, int dots);
- static int check_option_values(struct universe *universe, unsigned int opt,
- const char *ptr, size_t len);
-
-+static void setup_ib_interface(struct interface_info *ip)
-+{
-+ struct group *g;
-+
-+ /* Set the broadcast flag */
-+ //ip->client->config->bootp_broadcast_always = 1;
-+
-+ /*
-+ * Find out if a dhcp-client-identifier option was specified either
-+ * in the config file or on the command line
-+ */
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
-+ if ((g->statements != NULL) &&
-+ (strcmp(g->statements->data.option->option->name,
-+ "dhcp-client-identifier") == 0)) {
-+ return;
-+ }
-+ }
-+
-+ /* No client ID specified */
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+}
-+
- int
- main(int argc, char **argv) {
- int fd;
-@@ -612,6 +635,14 @@ main(int argc, char **argv) {
- }
- srandom(seed + cur_time + (unsigned)getpid());
-
-+ /* Setup specific Infiniband options */
-+ for (ip = interfaces; ip; ip = ip->next) {
-+ if (ip->client &&
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
-+ setup_ib_interface(ip);
-+ }
-+ }
-+
- /* Start a configuration state machine for each interface. */
- #ifdef DHCPv6
- if (local_family == AF_INET6) {
-diff --git a/common/bpf.c b/common/bpf.c
-index 7b8f1d4..9086bd5 100644
---- a/common/bpf.c
-+++ b/common/bpf.c
-@@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = {
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
-+/* Packet filter program for DHCP over Infiniband.
-+ *
-+ * XXX
-+ * Changes to the filter program may require changes to the constant offsets
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
-+ * XXX
-+ */
-+struct bpf_insn dhcp_ib_bpf_filter [] = {
-+ /* Packet filter for Infiniband */
-+ /* Make sure it's a UDP packet... */
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
-+ 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, 6),
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-+
-+ /* Get the IP header length... */
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
-+
-+ /* Make sure it's to the right port... */
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
-+
-+ /* 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),
-+};
-+
- #if defined (DEC_FDDI)
- struct bpf_insn *bpf_fddi_filter;
- #endif
-
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
-+
- #if defined (HAVE_TR_SUPPORT)
- struct bpf_insn dhcp_bpf_tr_filter [] = {
- /* accept all token ring packets due to variable length header */
-diff --git a/common/lpf.c b/common/lpf.c
-index 4c9799a..4d4a0f8 100644
---- a/common/lpf.c
-+++ b/common/lpf.c
-@@ -42,6 +42,7 @@
- #include "includes/netinet/udp.h"
- #include "includes/netinet/if_ether.h"
- #include <net/if.h>
-+#include <ifaddrs.h>
-
- #ifndef PACKET_AUXDATA
- #define PACKET_AUXDATA 8
-@@ -59,6 +60,15 @@ struct tpacket_auxdata
- /* Reinitializes the specified interface after an address change. This
- is not required for packet-filter APIs. */
-
-+/* Default broadcast address for IPoIB */
-+static unsigned char default_ib_bcast_addr[20] = {
-+ 0x00, 0xff, 0xff, 0xff,
-+ 0xff, 0x12, 0x40, 0x1b,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0xff, 0xff, 0xff, 0xff
-+};
-+
- #ifdef USE_LPF_SEND
- void if_reinitialize_send (info)
- struct interface_info *info;
-@@ -86,10 +96,21 @@ int if_register_lpf (info)
- struct sockaddr common;
- } sa;
- struct ifreq ifr;
-+ int type;
-+ int protocol;
-
- /* Make an LPF socket. */
-- if ((sock = socket(PF_PACKET, SOCK_RAW,
-- htons((short)ETH_P_ALL))) < 0) {
-+ get_hw_addr(info);
-+
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ type = SOCK_DGRAM;
-+ protocol = ETHERTYPE_IP;
-+ } else {
-+ type = SOCK_RAW;
-+ protocol = ETH_P_ALL;
-+ }
-+
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -111,6 +132,7 @@ int if_register_lpf (info)
- /* Bind to the interface name */
- memset (&sa, 0, sizeof sa);
- sa.ll.sll_family = AF_PACKET;
-+ sa.ll.sll_protocol = htons(protocol);
- sa.ll.sll_ifindex = ifr.ifr_ifindex;
- if (bind (sock, &sa.common, sizeof sa)) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
-@@ -126,8 +148,6 @@ int if_register_lpf (info)
- log_fatal ("Bind socket to interface: %m");
- }
-
-- get_hw_addr(info->name, &info->hw_address);
--
- return sock;
- }
- #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
-@@ -182,6 +202,8 @@ void if_deregister_send (info)
- in bpf includes... */
- extern struct sock_filter dhcp_bpf_filter [];
- extern int dhcp_bpf_filter_len;
-+extern struct sock_filter dhcp_ib_bpf_filter [];
-+extern int dhcp_ib_bpf_filter_len;
-
- #if defined (HAVE_TR_SUPPORT)
- extern struct sock_filter dhcp_bpf_tr_filter [];
-@@ -199,11 +221,13 @@ void if_register_receive (info)
- /* Open a LPF device and hang it on this interface... */
- info -> rfdesc = if_register_lpf (info);
-
-- val = 1;
-- if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA, &val,
-- sizeof val) < 0) {
-- if (errno != ENOPROTOOPT)
-- log_fatal ("Failed to set auxiliary packet data: %m");
-+ if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
-+ val = 1;
-+ if (setsockopt (info -> rfdesc, SOL_PACKET, PACKET_AUXDATA,
-+ &val, sizeof val) < 0) {
-+ if (errno != ENOPROTOOPT)
-+ log_fatal ("Failed to set auxiliary packet data: %m");
-+ }
- }
-
- #if defined (HAVE_TR_SUPPORT)
-@@ -249,15 +273,28 @@ static void lpf_gen_filter_setup (info)
-
- memset(&p, 0, sizeof(p));
-
-- /* Set up the bpf filter program structure. This is defined in
-- bpf.c */
-- p.len = dhcp_bpf_filter_len;
-- p.filter = dhcp_bpf_filter;
--
-- /* 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 [8].k = ntohs ((short)local_port);
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ /* Set up the bpf filter program structure. */
-+ p.len = dhcp_ib_bpf_filter_len;
-+ p.filter = dhcp_ib_bpf_filter;
-+
-+ /* 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_ib_bpf_filter[6].k = ntohs ((short)local_port);
-+ } else {
-+ /* Set up the bpf filter program structure.
-+ This is defined in bpf.c */
-+ p.len = dhcp_bpf_filter_len;
-+ p.filter = dhcp_bpf_filter;
-+
-+ /* 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 [8].k = ntohs ((short)local_port);
-+ }
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
-@@ -314,6 +351,54 @@ static void lpf_tr_filter_setup (info)
- #endif /* USE_LPF_RECEIVE */
-
- #ifdef USE_LPF_SEND
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
-+ struct interface_info *interface;
-+ struct packet *packet;
-+ struct dhcp_packet *raw;
-+ size_t len;
-+ struct in_addr from;
-+ struct sockaddr_in *to;
-+ struct hardware *hto;
-+{
-+ unsigned ibufp = 0;
-+ double ih [1536 / sizeof (double)];
-+ unsigned char *buf = (unsigned char *)ih;
-+ ssize_t result;
-+
-+ union sockunion {
-+ struct sockaddr sa;
-+ struct sockaddr_ll sll;
-+ struct sockaddr_storage ss;
-+ } su;
-+
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
-+ to->sin_addr.s_addr, to->sin_port,
-+ (unsigned char *)raw, len);
-+ memcpy (buf + ibufp, raw, len);
-+
-+ memset(&su, 0, sizeof(su));
-+ su.sll.sll_family = AF_PACKET;
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
-+
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
-+ errno = ENOENT;
-+ log_error ("send_packet_ib: %m - failed to get if index");
-+ return -1;
-+ }
-+
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
-+
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
-+ &su.sa, sizeof(su));
-+
-+ if (result < 0)
-+ log_error ("send_packet_ib: %m");
-+
-+ return result;
-+}
-+
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
-@@ -334,6 +419,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return send_packet_ib(interface, packet, raw, len, from,
-+ to, hto);
-+ }
-+
- if (hto == NULL && interface->anycast_mac_addr.hlen)
- hto = &interface->anycast_mac_addr;
-
-@@ -355,6 +445,42 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- #endif /* USE_LPF_SEND */
-
- #ifdef USE_LPF_RECEIVE
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
-+ struct interface_info *interface;
-+ unsigned char *buf;
-+ size_t len;
-+ struct sockaddr_in *from;
-+ struct hardware *hfrom;
-+{
-+ int length = 0;
-+ int offset = 0;
-+ unsigned char ibuf [1536];
-+ unsigned bufix = 0;
-+ unsigned paylen;
-+
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
-+
-+ if (length <= 0)
-+ return length;
-+
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
-+ (unsigned)length, &paylen, 0);
-+
-+ if (offset < 0)
-+ return 0;
-+
-+ bufix += offset;
-+ length -= offset;
-+
-+ if (length < paylen)
-+ log_fatal("Internal inconsistency at %s:%d.", MDL);
-+
-+ /* Copy out the data in the packet... */
-+ memcpy(buf, &ibuf[bufix], paylen);
-+
-+ return (ssize_t)paylen;
-+}
-+
- ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
-@@ -381,6 +507,10 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
- };
- struct cmsghdr *cmsg;
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return receive_packet_ib(interface, buf, len, from, hfrom);
-+ }
-+
- length = recvmsg (interface -> rfdesc, &msg, 0);
- if (length <= 0)
- return length;
-@@ -461,33 +591,41 @@ void maybe_setup_fallback ()
- }
-
- void
--get_hw_addr(const char *name, struct hardware *hw) {
-- int sock;
-- struct ifreq tmp;
-- struct sockaddr *sa;
-+get_hw_addr(struct interface_info *info)
-+{
-+ struct hardware *hw = &info->hw_address;
-+ char *name = info->name;
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-
-- if (strlen(name) >= sizeof(tmp.ifr_name)) {
-- log_fatal("Device name too long: \"%s\"", name);
-- }
-+ if (getifaddrs(&ifaddrs) == -1)
-+ log_fatal("Failed to get interfaces");
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-
-- sock = socket(AF_INET, SOCK_DGRAM, 0);
-- if (sock < 0) {
-- log_fatal("Can't create socket for \"%s\": %m", name);
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
- }
-
-- memset(&tmp, 0, sizeof(tmp));
-- strcpy(tmp.ifr_name, name);
-- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
-- log_fatal("Error getting hardware address for \"%s\": %m",
-- name);
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ log_fatal("Failed to get HW address for %s\n", name);
- }
-
-- sa = &tmp.ifr_hwaddr;
-- switch (sa->sa_family) {
-+ switch (sll->sll_hatype) {
- case ARPHRD_ETHER:
- hw->hlen = 7;
- hw->hbuf[0] = HTYPE_ETHER;
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
- break;
- case ARPHRD_IEEE802:
- #ifdef ARPHRD_IEEE802_TR
-@@ -495,18 +633,36 @@ get_hw_addr(const char *name, struct hardware *hw) {
- #endif /* ARPHRD_IEEE802_TR */
- hw->hlen = 7;
- hw->hbuf[0] = HTYPE_IEEE802;
-- memcpy(&hw->hbuf[1], sa->sa_data, 6);
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 6);
- break;
- case ARPHRD_FDDI:
- hw->hlen = 17;
- hw->hbuf[0] = HTYPE_FDDI;
-- memcpy(&hw->hbuf[1], sa->sa_data, 16);
-+ memcpy(&hw->hbuf[1], sll->sll_addr, 16);
-+ break;
-+ case ARPHRD_INFINIBAND:
-+ /* For Infiniband, save the broadcast address and store
-+ * the port GUID into the hardware address.
-+ */
-+ if (ifa->ifa_flags & IFF_BROADCAST) {
-+ struct sockaddr_ll *bll;
-+
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
-+ } else {
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
-+ 20);
-+ }
-+
-+ hw->hlen = 1;
-+ hw->hbuf[0] = HTYPE_INFINIBAND;
- break;
- default:
-+ freeifaddrs(ifaddrs);
- log_fatal("Unsupported device type %ld for \"%s\"",
-- (long int)sa->sa_family, name);
-+ (long int)sll->sll_family, name);
- }
-
-- close(sock);
-+ freeifaddrs(ifaddrs);
- }
- #endif
-diff --git a/common/socket.c b/common/socket.c
-index f95665c..8fead01 100644
---- a/common/socket.c
-+++ b/common/socket.c
-@@ -325,7 +325,7 @@ void if_register_send (info)
- info->wfdesc = if_register_socket(info, AF_INET, 0);
- /* If this is a normal IPv4 address, get the hardware address. */
- if (strcmp(info->name, "fallback") != 0)
-- get_hw_addr(info->name, &info->hw_address);
-+ get_hw_addr(info);
- #if defined (USE_SOCKET_FALLBACK)
- /* Fallback only registers for send, but may need to receive as
- well. */
-@@ -388,7 +388,7 @@ void if_register_receive (info)
- #endif /* IP_PKTINFO... */
- /* If this is a normal IPv4 address, get the hardware address. */
- if (strcmp(info->name, "fallback") != 0)
-- get_hw_addr(info->name, &info->hw_address);
-+ get_hw_addr(info);
-
- if (!quiet_interface_discovery)
- log_info ("Listening on Socket/%s%s%s",
-@@ -498,7 +498,7 @@ if_register6(struct interface_info *info, int do_multicast) {
- if (req_multi)
- if_register_multicast(info);
-
-- get_hw_addr(info->name, &info->hw_address);
-+ get_hw_addr(info);
-
- if (!quiet_interface_discovery) {
- if (info->shared_network != NULL) {
-diff --git a/includes/dhcpd.h b/includes/dhcpd.h
-index a4cd01e..4bd695b 100644
---- a/includes/dhcpd.h
-+++ b/includes/dhcpd.h
-@@ -1223,6 +1223,7 @@ struct interface_info {
- struct shared_network *shared_network;
- /* Networks connected to this interface. */
- struct hardware hw_address; /* Its physical address. */
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
- struct in_addr *addresses; /* Addresses associated with this
- * interface.
- */
-@@ -2342,7 +2343,7 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t);
- #endif
- const char *print_time(TIME);
-
--void get_hw_addr(const char *name, struct hardware *hw);
-+void get_hw_addr(struct interface_info *info);
-
- /* socket.c */
- #if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
---
-1.7.12.4
-
+++ /dev/null
-From 7f59e9b0c6a411df9c5a2281d301b305b75a2baf Mon Sep 17 00:00:00 2001
-From: root <root@reg-ovm-036-004.lab.mtl.com>
-Date: Tue, 25 Mar 2014 23:30:18 +0200
-Subject: [PATCH 2/2] dhcp 4.2.4p2 improved xid
-
----
- client/dhclient.c | 70 ++++++++++++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 56 insertions(+), 14 deletions(-)
-
-diff --git a/client/dhclient.c b/client/dhclient.c
-index 09ad2ab..77d56d6 100644
---- a/client/dhclient.c
-+++ b/client/dhclient.c
-@@ -612,6 +612,26 @@ main(int argc, char **argv) {
- }
- }
-
-+ /* We create a backup seed before rediscovering interfaces in order to
-+ have a seed built using all of the available interfaces
-+ It's interesting if required interfaces doesn't let us defined
-+ a really unique seed due to a lack of valid HW addr later
-+ (this is the case with DHCP over IB)
-+ We only use the last device as using a sum could broke the
-+ uniqueness of the seed among multiple nodes
-+ */
-+ unsigned backup_seed = 0;
-+ for (ip = interfaces; ip; ip = ip -> next) {
-+ int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
-+ memcpy (&junk,
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
-+ sizeof seed], sizeof seed);
-+ backup_seed = junk;
-+ }
-+
-+
- /* At this point, all the interfaces that the script thinks
- are relevant should be running, so now we once again call
- discover_interfaces(), and this time ask it to actually set
-@@ -626,14 +646,36 @@ main(int argc, char **argv) {
- Not much entropy, but we're booting, so we're not likely to
- find anything better. */
- seed = 0;
-+ int seed_flag = 0;
- for (ip = interfaces; ip; ip = ip->next) {
- int junk;
-+ if (ip->hw_address.hlen <= sizeof seed)
-+ continue;
- memcpy(&junk,
- &ip->hw_address.hbuf[ip->hw_address.hlen -
- sizeof seed], sizeof seed);
- seed += junk;
-+ seed_flag = 1;
- }
-- srandom(seed + cur_time + (unsigned)getpid());
-+ if ( seed_flag == 0 ) {
-+ if ( backup_seed != 0 ) {
-+ seed = backup_seed;
-+ log_info ("xid: rand init seed (0x%x) built using all"
-+ " available interfaces",seed);
-+ }
-+ else {
-+ seed = cur_time^((unsigned) gethostid()) ;
-+ log_info ("xid: warning: no netdev with useable HWADDR found"
-+ " for seed's uniqueness enforcement");
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",
-+ seed);
-+ }
-+ /* we only use seed and no current time as a broadcast reply */
-+ /* will certainly be used by the hwaddrless interface */
-+ srandom(seed);
-+ }
-+ else
-+ srandom(seed + cur_time + (unsigned)getpid());
-
- /* Setup specific Infiniband options */
- for (ip = interfaces; ip; ip = ip->next) {
-@@ -1133,7 +1175,7 @@ void dhcpack (packet)
- return;
- }
-
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- lease = packet_to_lease (packet, client);
- if (!lease) {
-@@ -1849,7 +1891,7 @@ void dhcpnak (packet)
- return;
- }
-
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- if (!client -> active) {
- #if defined (DEBUG)
-@@ -1975,10 +2017,10 @@ void send_discover (cpp)
- client -> packet.secs = htons (65535);
- client -> secs = client -> packet.secs;
-
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
-- client -> name ? client -> name : client -> interface -> name,
-- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
-+ client -> name ? client -> name : client -> interface -> name,
-+ inet_ntoa (sockaddr_broadcast.sin_addr),
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);
-
- /* Send out a packet. */
- result = send_packet(client->interface, NULL, &client->packet,
-@@ -2245,10 +2287,10 @@ void send_request (cpp)
- client -> packet.secs = htons (65535);
- }
-
-- log_info ("DHCPREQUEST on %s to %s port %d",
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
- fallback_interface) {
-@@ -2288,10 +2330,10 @@ void send_decline (cpp)
-
- int result;
-
-- log_info ("DHCPDECLINE on %s to %s port %d",
-- client->name ? client->name : client->interface->name,
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
-+ client->name ? client->name : client->interface->name,
- inet_ntoa(sockaddr_broadcast.sin_addr),
-- ntohs(sockaddr_broadcast.sin_port));
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);
-
- /* Send out a packet. */
- result = send_packet(client->interface, NULL, &client->packet,
-@@ -2334,10 +2376,10 @@ void send_release (cpp)
- return;
- }
-
-- log_info ("DHCPRELEASE on %s to %s port %d",
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (fallback_interface) {
- result = send_packet(fallback_interface, NULL, &client->packet,
---
-1.7.12.4
-
+++ /dev/null
-DHCP IPoIB support for dhcp-4.2.4.P2-0.16.15.src.rpm
-
-Build Procedure:
-
-1. Have the rpmbuild command use another directory (e.g., /home/your_userid/rpm)
-by putting this line in a file called .rpmmacros in your home directory:
-
-%_topdir /home/your_userid/rpm
-
-2. Create the following subdirectories in that directory:
-
-cd /home/your_userid/rpm
-mkdir SOURCES SPECS BUILD SRPMS
-mkdir -p RPMS/i386 RPMS/i486 RPMS/i586 RPMS/i686 RPMS/x86_64 RPMS/noarch
-
-3. Install the .src.rpm file this way:
-
-rpm -i dhcp-<ver>.src.rpm
-
-This will create files in the SOURCES directory of your RPM building directory tree, and a .spec file in the SPECS directory.
-
-4. Copy the 0001-dhcp-4.2.4p2-lpf-ip-over-ib-support.patch and 0002-dhcp-4.2.4p2-improved-xid.patch to /home/your_userid/rpm/SOURCES
-
-5. apply dhcp.spec.diff to dhcp.spec via patch command (patch -p1 -i dhcp.spec.diff)
-
-6. Go the SPECS directory and give the command to build the RPM:
-
-cd /home/your_userid/rpm/SPECS
-rpmbuild --define '%_topdir /home/your_userid/rpm' -bb dhcp.spec
-
-NOTE: The build should be performed on a machine with the appropriate distro.
-With SLES(11), the build will not succeed without doing this.
-
+++ /dev/null
-diff --git a/dhcp.spec b/dhcp.spec
-index 39e0cfb..44eb248 100644
---- a/dhcp.spec
-+++ b/dhcp.spec
-@@ -98,6 +98,8 @@ Patch49: dhcp-4.2.4-parsing-and-printing-options.patch
- Patch50: dhcp-4.2.4-interface-discovery-using-getifaddrs.patch
- Patch51: dhcp-4.2.4-P2-do-not-die-on-sigpipe.patch
- Patch52: dhcp-4.2.4-P2-obvious-fixes-from-4.2.5rc1.patch
-+Patch53: 0001-dhcp-4.2.4p2-lpf-ip-over-ib-support.patch
-+Patch54: 0002-dhcp-4.2.4p2-improved-xid.patch
- Patch70: dhcp-4.2.4-P2-no-bind-regex-check.CVE-2013-2266.diff
- ##
- PreReq: /bin/touch /sbin/chkconfig sysconfig
-@@ -243,6 +245,8 @@ Authors:
- %patch50 -p1
- %patch51 -p1
- %patch52 -p1
-+%patch53 -p1
-+%patch54 -p1
- ##
- find . -type f -name \*.cat\* -exec rm -f {} \;
- dos2unix contrib/ms2isc/*
+++ /dev/null
-diff -ruN client/dhclient.c.gpxe client/dhclient.c
---- client/dhclient.c.gpxe 2011-01-21 04:48:49.496984000 +0200
-+++ client/dhclient.c 2011-01-21 04:51:10.760597000 +0200
-@@ -47,6 +47,13 @@
- static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
- char *path_dhclient_script = path_dhclient_script_array;
-
-+/* Default Prefix */
-+static unsigned char default_prefix[12] = {
-+ 0xff, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x02, 0x00,
-+ 0x00, 0x02, 0xc9, 0x00
-+};
-+
- int dhcp_max_agent_option_packet_length = 0;
-
- int interfaces_requested = 0;
-@@ -575,6 +582,12 @@
- static void setup_ib_interface(struct interface_info *ip)
- {
- struct group *g;
-+ struct hardware *hw = &ip->hw_address;
-+ char client_id[64];
-+ char *arg_conf = NULL;
-+ int arg_conf_len = 0;
-+ isc_result_t status;
-+ struct parse *cfile = (struct parse *)0;
-
- /* Set the broadcast flag */
- bootp_broadcast_always = 1;
-@@ -591,8 +604,39 @@
- }
- }
-
-- /* No client ID specified */
-- log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+ /*
-+ * No client ID specified, make up one based on a default
-+ * "prefix" and the port GUID.
-+ *
-+ * NOTE: This is compatible with what gpxe does.
-+ */
-+ sprintf(client_id, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
-+ default_prefix[0], default_prefix[1], default_prefix[2],
-+ default_prefix[3], default_prefix[4], default_prefix[5],
-+ default_prefix[6], default_prefix[7], default_prefix[8],
-+ default_prefix[9], default_prefix[10], default_prefix[11],
-+ hw->hbuf[1], hw->hbuf[2], hw->hbuf[3], hw->hbuf[4],
-+ hw->hbuf[5], hw->hbuf[6], hw->hbuf[7], hw->hbuf[8]);
-+
-+ arg_conf_len = asprintf(&arg_conf,
-+ "send dhcp-client-identifier %s;",
-+ client_id);
-+
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))
-+ log_fatal("Unable to send option dhcp-client-identifier");
-+
-+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len,
-+ "Automatic Infiniband client identifier", 0);
-+
-+ if ((status != ISC_R_SUCCESS) || (cfile->warnings_occurred))
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ parse_client_statement(cfile, NULL, ip->client->config);
-+
-+ if (cfile->warnings_occurred)
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ end_parse(&cfile);
- }
-
- static void usage ()
-diff -ruN common/discover.c.gpxe common/discover.c
---- common/discover.c.gpxe 2011-01-21 04:48:49.474985000 +0200
-+++ common/discover.c 2011-01-21 04:51:18.413829000 +0200
-@@ -120,6 +120,34 @@
- trace_outpacket_stop, MDL);
- }
- #endif
-+static unsigned char * get_ib_hw_addr(char * name)
-+{
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+ static unsigned char hw_addr[8];
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ return NULL;
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ return NULL;
-+ }
-+ memcpy(hw_addr, &sll->sll_addr[sll->sll_halen - 8], 8);
-+ freeifaddrs(ifaddrs);
-+ return (unsigned char *)&hw_addr;
-+}
-
- isc_result_t interface_initialize (omapi_object_t *ipo,
- const char *file, int line)
-@@ -156,6 +184,7 @@
- isc_result_t status;
- static int setup_fallback = 0;
- int wifcount = 0;
-+ unsigned char *hw_addr;
-
- /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
- if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-@@ -552,6 +581,10 @@
- setup_ib_bcast_addr ( tmp );
- tmp -> hw_address.hlen = 1;
- tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ hw_addr = get_ib_hw_addr(tmp -> name);
-+ if (!hw_addr)
-+ log_fatal("Failed getting %s hw addr", tmp -> name);
-+ memcpy (&tmp -> hw_address.hbuf [1], hw_addr, 8);
- break;
-
- default:
+++ /dev/null
-diff -ruN client/dhclient.c.xid client/dhclient.c
---- client/dhclient.c.xid 2010-09-27 21:29:02.495805000 +0200
-+++ client/dhclient.c 2010-09-28 13:27:26.629193000 +0200
-@@ -434,6 +434,26 @@
- }
- }
-
-+ /* We create a backup seed before rediscovering interfaces in order to
-+ have a seed built using all of the available interfaces
-+ It's interesting if required interfaces doesn't let us defined
-+ a really unique seed due to a lack of valid HW addr later
-+ (this is the case with DHCP over IB)
-+ We only use the last device as using a sum could broke the
-+ uniqueness of the seed among multiple nodes
-+ */
-+ unsigned backup_seed = 0;
-+ for (ip = interfaces; ip; ip = ip -> next) {
-+ int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
-+ memcpy (&junk,
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
-+ sizeof seed], sizeof seed);
-+ backup_seed = junk;
-+ }
-+
-+
- /* At this point, all the interfaces that the script thinks
- are relevant should be running, so now we once again call
- discover_interfaces(), and this time ask it to actually set
-@@ -448,14 +468,36 @@
- Not much entropy, but we're booting, so we're not likely to
- find anything better. */
- seed = 0;
-+ int seed_flag = 0;
- for (ip = interfaces; ip; ip = ip -> next) {
- int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
- memcpy (&junk,
- &ip -> hw_address.hbuf [ip -> hw_address.hlen -
- sizeof seed], sizeof seed);
- seed += junk;
-+ seed_flag = 1;
-+ }
-+ if ( seed_flag == 0 ) {
-+ if ( backup_seed != 0 ) {
-+ seed = backup_seed;
-+ log_info ("xid: rand init seed (0x%x) built using all"
-+ " available interfaces",seed);
-+ }
-+ else {
-+ seed = cur_time^((unsigned) gethostid()) ;
-+ log_info ("xid: warning: no netdev with useable HWADDR found"
-+ " for seed's uniqueness enforcement");
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",
-+ seed);
-+ }
-+ /* we only use seed and no current time as a broadcast reply */
-+ /* will certainly be used by the hwaddrless interface */
-+ srandom(seed);
- }
-- srandom (seed + cur_time);
-+ else
-+ srandom (seed + cur_time);
-
- /* Setup specific Infiniband options */
- for (ip = interfaces; ip; ip = ip->next) {
-@@ -805,7 +847,7 @@
- return;
- }
-
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- lease = packet_to_lease (packet, client);
- if (!lease) {
-@@ -1445,7 +1487,7 @@
- return;
- }
-
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- if (!client -> active) {
- #if defined (DEBUG)
-@@ -1570,10 +1612,10 @@
- client -> packet.secs = htons (65535);
- client -> secs = client -> packet.secs;
-
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -1823,10 +1865,10 @@
- client -> packet.secs = htons (65535);
- }
-
-- log_info ("DHCPREQUEST on %s to %s port %d",
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
- fallback_interface)
-@@ -1855,10 +1897,10 @@
-
- int result;
-
-- log_info ("DHCPDECLINE on %s to %s port %d",
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port));
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -1898,10 +1940,10 @@
- return;
- }
-
-- log_info ("DHCPRELEASE on %s to %s port %d",
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (fallback_interface)
- result = send_packet (fallback_interface,
+++ /dev/null
-diff -ruN common/lpf.c.ib common/lpf.c
---- common/lpf.c.ib 2008-03-25 00:27:13.000000000 +0200
-+++ common/lpf.c 2010-09-28 14:46:21.927090000 +0200
-@@ -39,6 +39,7 @@
- #include <asm/types.h>
- #include <linux/filter.h>
- #include <linux/if_ether.h>
-+#include <linux/if_packet.h>
- #include <netinet/in_systm.h>
- #include "includes/netinet/ip.h"
- #include "includes/netinet/udp.h"
-@@ -71,11 +72,24 @@
- int sock;
- char filename[50];
- int b;
-- struct sockaddr sa;
-+ union {
-+ struct sockaddr_ll ll;
-+ struct sockaddr common;
-+ } sa;
-+ struct ifreq ifr;
-+ int type;
-+ int protocol;
-
- /* Make an LPF socket. */
-- if ((sock = socket(PF_PACKET, SOCK_PACKET,
-- htons((short)ETH_P_ALL))) < 0) {
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ type = SOCK_DGRAM;
-+ protocol = ETHERTYPE_IP;
-+ } else {
-+ type = SOCK_RAW;
-+ protocol = ETH_P_ALL;
-+ }
-+
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -89,11 +103,17 @@
- log_fatal ("Open a socket for LPF: %m");
- }
-
-+ memset (&ifr, 0, sizeof ifr);
-+ strncpy (ifr.ifr_name, (const char *)info -> ifp, sizeof ifr.ifr_name);
-+ if (ioctl (sock, SIOCGIFINDEX, &ifr))
-+ log_fatal ("Failed to get interface index: %m");
-+
- /* Bind to the interface name */
- memset (&sa, 0, sizeof sa);
-- sa.sa_family = AF_PACKET;
-- strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data);
-- if (bind (sock, &sa, sizeof sa)) {
-+ sa.ll.sll_family = AF_PACKET;
-+ sa.ll.sll_protocol = htons(protocol);
-+ sa.ll.sll_ifindex = ifr.ifr_ifindex;
-+ if (bind (sock, &sa.common, sizeof sa)) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -161,6 +181,8 @@
- in bpf includes... */
- extern struct sock_filter dhcp_bpf_filter [];
- extern int dhcp_bpf_filter_len;
-+extern struct sock_filter dhcp_ib_bpf_filter [];
-+extern int dhcp_ib_bpf_filter_len;
-
- #if defined (HAVE_TR_SUPPORT)
- extern struct sock_filter dhcp_bpf_tr_filter [];
-@@ -219,15 +241,28 @@
-
- memset(&p, 0, sizeof(p));
-
-- /* Set up the bpf filter program structure. This is defined in
-- bpf.c */
-- p.len = dhcp_bpf_filter_len;
-- p.filter = dhcp_bpf_filter;
--
-- /* 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 [8].k = ntohs ((short)local_port);
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ /* Set up the bpf filter program structure. */
-+ p.len = dhcp_ib_bpf_filter_len;
-+ p.filter = dhcp_ib_bpf_filter;
-+
-+ /* 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_ib_bpf_filter[6].k = ntohs ((short)local_port);
-+ } else {
-+ /* Set up the bpf filter program structure.
-+ This is defined in bpf.c */
-+ p.len = dhcp_bpf_filter_len;
-+ p.filter = dhcp_bpf_filter;
-+
-+ /* 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 [8].k = ntohs ((short)local_port);
-+ }
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
-@@ -282,6 +317,54 @@
- #endif /* USE_LPF_RECEIVE */
-
- #ifdef USE_LPF_SEND
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
-+ struct interface_info *interface;
-+ struct packet *packet;
-+ struct dhcp_packet *raw;
-+ size_t len;
-+ struct in_addr from;
-+ struct sockaddr_in *to;
-+ struct hardware *hto;
-+{
-+ unsigned ibufp = 0;
-+ double ih [1536 / sizeof (double)];
-+ unsigned char *buf = (unsigned char *)ih;
-+ ssize_t result;
-+
-+ union sockunion {
-+ struct sockaddr sa;
-+ struct sockaddr_ll sll;
-+ struct sockaddr_storage ss;
-+ } su;
-+
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
-+ to->sin_addr.s_addr, to->sin_port,
-+ (unsigned char *)raw, len);
-+ memcpy (buf + ibufp, raw, len);
-+
-+ memset(&su, 0, sizeof(su));
-+ su.sll.sll_family = AF_PACKET;
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
-+
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
-+ errno = ENOENT;
-+ log_error ("send_packet_ib: %m - failed to get if index");
-+ return -1;
-+ }
-+
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
-+
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
-+ &su.sa, sizeof(su));
-+
-+ if (result < 0)
-+ log_error ("send_packet_ib: %m");
-+
-+ return result;
-+}
-+
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
-@@ -303,6 +386,11 @@
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return send_packet_ib(interface, packet, raw, len, from,
-+ to, hto);
-+ }
-+
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto);
- fudge = hbufp % 4; /* IP header must be word-aligned. */
-@@ -329,6 +417,38 @@
- #endif /* USE_LPF_SEND */
-
- #ifdef USE_LPF_RECEIVE
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
-+ struct interface_info *interface;
-+ unsigned char *buf;
-+ size_t len;
-+ struct sockaddr_in *from;
-+ struct hardware *hfrom;
-+{
-+ int length = 0;
-+ int offset = 0;
-+ unsigned char ibuf [1536];
-+ unsigned bufix = 0;
-+
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
-+
-+ if (length <= 0)
-+ return length;
-+
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
-+ (unsigned)length, 0);
-+
-+ if (offset < 0)
-+ return 0;
-+
-+ bufix += offset;
-+ length -= offset;
-+
-+ /* Copy out the data in the packet... */
-+ memcpy(buf, &ibuf[bufix], length);
-+
-+ return length;
-+}
-+
- ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
-@@ -343,6 +463,10 @@
- unsigned bufix = 0;
- unsigned paylen;
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return receive_packet_ib(interface, buf, len, from, hfrom);
-+ }
-+
- length = read (interface -> rfdesc, ibuf, sizeof ibuf);
- if (length <= 0)
- return length;
-diff -ruN includes/dhcp.h.ib includes/dhcp.h
---- includes/dhcp.h.ib 2008-01-22 21:02:51.000000000 +0200
-+++ includes/dhcp.h 2010-09-28 14:42:35.088656000 +0200
-@@ -76,6 +76,7 @@
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
- #define HTYPE_FDDI 8 /* FDDI... */
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */
-
- /* Magic cookie validating dhcp options field (and bootp vendor
- extensions field). */
-diff -ruN client/dhclient.c.ib client/dhclient.c
---- client/dhclient.c.ib 2010-09-28 14:39:47.928519000 +0200
-+++ client/dhclient.c 2010-09-28 14:42:39.268274000 +0200
-@@ -74,8 +74,10 @@
- int onetry=0;
- int quiet=0;
- int nowait=0;
-+int bootp_broadcast_always = 0;
-
- static void usage PROTO ((void));
-+static void setup_ib_interface(struct interface_info *ip);
-
- int main (argc, argv, envp)
- int argc;
-@@ -456,6 +458,14 @@
- }
- srandom (seed + cur_time);
-
-+ /* Setup specific Infiniband options */
-+ for (ip = interfaces; ip; ip = ip->next) {
-+ if (ip->client &&
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
-+ setup_ib_interface(ip);
-+ }
-+ }
-+
- /* Start a configuration state machine for each interface. */
- for (ip = interfaces; ip; ip = ip -> next) {
- ip -> flags |= INTERFACE_RUNNING;
-@@ -520,6 +530,29 @@
- return 0;
- }
-
-+static void setup_ib_interface(struct interface_info *ip)
-+{
-+ struct group *g;
-+
-+ /* Set the broadcast flag */
-+ bootp_broadcast_always = 1;
-+
-+ /*
-+ * Find out if a dhcp-client-identifier option was specified either
-+ * in the config file or on the command line
-+ */
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
-+ if ((g->statements != NULL) &&
-+ (strcmp(g->statements->data.option->option->name,
-+ "dhcp-client-identifier") == 0)) {
-+ return;
-+ }
-+ }
-+
-+ /* No client ID specified */
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+}
-+
- static void usage ()
- {
- log_info ("%s %s", message, DHCP_VERSION);
-diff -ruN common/bpf.c.ib common/bpf.c
---- common/bpf.c.ib 2007-05-24 02:30:32.000000000 +0300
-+++ common/bpf.c 2010-09-28 14:42:44.402799000 +0200
-@@ -194,11 +194,44 @@
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
-+/* Packet filter program for DHCP over Infiniband.
-+ *
-+ * XXX
-+ * Changes to the filter program may require changes to the constant offsets
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
-+ * XXX
-+ */
-+struct bpf_insn dhcp_ib_bpf_filter [] = {
-+ /* Packet filter for Infiniband */
-+ /* Make sure it's a UDP packet... */
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
-+ 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, 6),
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-+
-+ /* Get the IP header length... */
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
-+
-+ /* Make sure it's to the right port... */
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
-+
-+ /* 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),
-+};
-+
- #if defined (DEC_FDDI)
- struct bpf_insn *bpf_fddi_filter;
- #endif
-
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
-+
- #if defined (HAVE_TR_SUPPORT)
- struct bpf_insn dhcp_bpf_tr_filter [] = {
- /* accept all token ring packets due to variable length header */
-diff -ruN common/discover.c.ib common/discover.c
---- common/discover.c.ib 2006-11-08 01:41:39.000000000 +0200
-+++ common/discover.c 2010-09-28 14:42:48.411418000 +0200
-@@ -39,6 +39,8 @@
-
- #include "dhcpd.h"
- #include <sys/ioctl.h>
-+#include <ifaddrs.h>
-+#include <linux/if_packet.h>
-
- struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
- int interfaces_invalidated;
-@@ -58,6 +60,8 @@
- unsigned int,
- struct iaddr, struct hardware *));
-
-+void setup_ib_bcast_addr(struct interface_info *info);
-+
- omapi_object_type_t *dhcp_type_interface;
- #if defined (TRACING)
- trace_type_t *interface_trace;
-@@ -70,6 +74,15 @@
-
- OMAPI_OBJECT_ALLOC (interface, struct interface_info, dhcp_type_interface)
-
-+/* Default broadcast address for IPoIB */
-+unsigned char default_ib_bcast_addr[20] = {
-+ 0x00, 0xff, 0xff, 0xff,
-+ 0xff, 0x12, 0x40, 0x1b,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0xff, 0xff, 0xff, 0xff
-+};
-+
- isc_result_t interface_setup ()
- {
- isc_result_t status;
-@@ -532,6 +545,15 @@
- break;
- #endif
-
-+#ifndef HAVE_ARPHRD_INFINIBAND
-+# define ARPHRD_INFINIBAND HTYPE_INFINIBAND
-+#endif
-+ case ARPHRD_INFINIBAND:
-+ setup_ib_bcast_addr ( tmp );
-+ tmp -> hw_address.hlen = 1;
-+ tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ break;
-+
- default:
- log_error ("%s: unknown hardware address type %d",
- ifr.ifr_name, sa.sa_family);
-@@ -712,6 +734,57 @@
- #endif
- }
-
-+void setup_ib_bcast_addr (struct interface_info *info)
-+{
-+ char *name = info->name;
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ log_fatal("Failed to get interfaces");
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ log_fatal("Failed to get HW address for %s\n", name);
-+ }
-+
-+ switch (sll->sll_hatype) {
-+ case ARPHRD_INFINIBAND:
-+ /* For Infiniband, save the broadcast address and store
-+ * the port GUID into the hardware address.
-+ */
-+ if (ifa->ifa_flags & IFF_BROADCAST) {
-+ struct sockaddr_ll *bll;
-+
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
-+ } else {
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
-+ 20);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ freeifaddrs(ifaddrs);
-+}
-+
- int if_readsocket (h)
- omapi_object_t *h;
- {
-diff -ruN includes/dhcpd.h.ib includes/dhcpd.h
---- includes/dhcpd.h.ib 2010-09-28 14:39:47.649523000 +0200
-+++ includes/dhcpd.h 2010-09-28 14:42:55.298753000 +0200
-@@ -974,6 +974,7 @@
- struct shared_network *shared_network;
- /* Networks connected to this interface. */
- struct hardware hw_address; /* Its physical address. */
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
- struct in_addr primary_address; /* Primary interface address. */
-
- u_int8_t *circuit_id; /* Circuit ID associated with this
-diff -ruN includes/osdep.h.ib includes/osdep.h
---- includes/osdep.h.ib 2006-02-25 01:16:29.000000000 +0200
-+++ includes/osdep.h 2010-09-28 14:42:59.928281000 +0200
-@@ -307,6 +307,10 @@
- # define HAVE_ARPHRD_METRICOM
- #endif
-
-+#if defined (ARPHRD_INFINIBAND) && !defined (HAVE_ARPHRD_INFINIBAND)
-+# define HAVE_ARPHRD_INFINIBAND
-+#endif
-+
- #if defined (SO_BINDTODEVICE) && !defined (HAVE_SO_BINDTODEVICE)
- # define HAVE_SO_BINDTODEVICE
- #endif
-diff -ruN server/dhcp.c.ib server/dhcp.c
---- server/dhcp.c.ib 2008-01-22 21:02:51.000000000 +0200
-+++ server/dhcp.c 2010-09-28 14:43:04.314900000 +0200
-@@ -2964,7 +2964,10 @@
- unicastp = 0;
- }
-
-- memcpy (&from, state -> from.iabuf, sizeof from);
-+ if (state -> ip -> hw_address.hbuf [0] != HTYPE_INFINIBAND)
-+ memcpy (&from, state -> from.iabuf, sizeof from);
-+ else
-+ from = state ->ip -> primary_address;
-
- result = send_packet (state -> ip,
- (struct packet *)0, &raw, packet_length,
+++ /dev/null
-diff -ruN dhcp.spec.ib dhcp.spec
---- dhcp.spec.ib 2009-02-23 20:46:55.000000000 +0200
-+++ dhcp.spec 2010-09-28 14:17:55.024158000 +0200
-@@ -85,6 +85,10 @@
- Patch43: dhcp-3.1.1-dhclient-no-dereference-twice.dif
- Patch50: dhcp-3.1.1-dhclient-conf.dif
- Patch60: dhcp-3.1.1-dhclient-script.dif
-+Patch70: dhcp-3.1.1-lpf-ib.dif
-+Patch71: dhcp-3.1.1-improved-xid.dif
-+Patch72: dhcp-3.1.1-gpxe-cid.dif
-+
- ##
- Obsoletes: dhcp-base
- Provides: dhcp-base:/usr/bin/omshell
-@@ -218,6 +221,10 @@
- %patch43 -p0
- %patch50 -p0
- %patch60 -p0
-+%patch70 -p0
-+%patch71 -p0
-+%patch72 -p0
-+
- ##
- find . -type f -name \*.cat\* -exec rm -f {} \;
- cp -p %{S:2} %{S:3} %{S:11} %{S:12} %{S:14} %{S:32} %{S:33} .
+++ /dev/null
-diff -ruN dhcp.spec.ib dhcp.spec
---- dhcp.spec.ib 2009-02-23 20:46:55.000000000 +0200
-+++ dhcp.spec 2010-09-28 14:17:55.024158000 +0200
-@@ -85,6 +85,9 @@
- Patch43: dhcp-3.1.1-dhclient-no-dereference-twice.dif
- Patch50: dhcp-3.1.1-dhclient-conf.dif
- Patch60: dhcp-3.1.1-dhclient-script.dif
-+Patch70: dhcp-3.1.1-lpf-ib.dif
-+Patch71: dhcp-3.1.1-improved-xid.dif
-+
- ##
- Obsoletes: dhcp-base
- Provides: dhcp-base:/usr/bin/omshell
-@@ -218,6 +221,9 @@
- %patch43 -p0
- %patch50 -p0
- %patch60 -p0
-+%patch70 -p0
-+%patch71 -p0
-+
- ##
- find . -type f -name \*.cat\* -exec rm -f {} \;
- cp -p %{S:2} %{S:3} %{S:11} %{S:12} %{S:14} %{S:32} %{S:33} .
+++ /dev/null
-diff -ruN client/dhclient.c.gpxe client/dhclient.c
---- client/dhclient.c.gpxe 2011-01-21 04:48:49.496984000 +0200
-+++ client/dhclient.c 2011-01-21 04:51:10.760597000 +0200
-@@ -47,6 +47,13 @@
- static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
- char *path_dhclient_script = path_dhclient_script_array;
-
-+/* Default Prefix */
-+static unsigned char default_prefix[12] = {
-+ 0xff, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x02, 0x00,
-+ 0x00, 0x02, 0xc9, 0x00
-+};
-+
- int dhcp_max_agent_option_packet_length = 0;
-
- int interfaces_requested = 0;
-@@ -575,6 +582,12 @@
- static void setup_ib_interface(struct interface_info *ip)
- {
- struct group *g;
-+ struct hardware *hw = &ip->hw_address;
-+ char client_id[64];
-+ char *arg_conf = NULL;
-+ int arg_conf_len = 0;
-+ isc_result_t status;
-+ struct parse *cfile = (struct parse *)0;
-
- /* Set the broadcast flag */
- bootp_broadcast_always = 1;
-@@ -591,8 +604,39 @@
- }
- }
-
-- /* No client ID specified */
-- log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+ /*
-+ * No client ID specified, make up one based on a default
-+ * "prefix" and the port GUID.
-+ *
-+ * NOTE: This is compatible with what gpxe does.
-+ */
-+ sprintf(client_id, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
-+ default_prefix[0], default_prefix[1], default_prefix[2],
-+ default_prefix[3], default_prefix[4], default_prefix[5],
-+ default_prefix[6], default_prefix[7], default_prefix[8],
-+ default_prefix[9], default_prefix[10], default_prefix[11],
-+ hw->hbuf[1], hw->hbuf[2], hw->hbuf[3], hw->hbuf[4],
-+ hw->hbuf[5], hw->hbuf[6], hw->hbuf[7], hw->hbuf[8]);
-+
-+ arg_conf_len = asprintf(&arg_conf,
-+ "send dhcp-client-identifier %s;",
-+ client_id);
-+
-+ if ((arg_conf == 0) || (arg_conf_len <= 0))
-+ log_fatal("Unable to send option dhcp-client-identifier");
-+
-+ status = new_parse(&cfile, -1, arg_conf, arg_conf_len,
-+ "Automatic Infiniband client identifier", 0);
-+
-+ if ((status != ISC_R_SUCCESS) || (cfile->warnings_occurred))
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ parse_client_statement(cfile, NULL, ip->client->config);
-+
-+ if (cfile->warnings_occurred)
-+ log_fatal("Failed to parse Infiniband client identifier");
-+
-+ end_parse(&cfile);
- }
-
- static void usage ()
-diff -ruN common/discover.c.gpxe common/discover.c
---- common/discover.c.gpxe 2011-01-21 04:48:49.474985000 +0200
-+++ common/discover.c 2011-01-21 04:51:18.413829000 +0200
-@@ -120,6 +120,34 @@
- trace_outpacket_stop, MDL);
- }
- #endif
-+static unsigned char * get_ib_hw_addr(char * name)
-+{
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+ static unsigned char hw_addr[8];
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ return NULL;
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ return NULL;
-+ }
-+ memcpy(hw_addr, &sll->sll_addr[sll->sll_halen - 8], 8);
-+ freeifaddrs(ifaddrs);
-+ return (unsigned char *)&hw_addr;
-+}
-
- isc_result_t interface_initialize (omapi_object_t *ipo,
- const char *file, int line)
-@@ -156,6 +184,7 @@
- isc_result_t status;
- static int setup_fallback = 0;
- int wifcount = 0;
-+ unsigned char *hw_addr;
-
- /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
- if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-@@ -552,6 +581,10 @@
- setup_ib_bcast_addr ( tmp );
- tmp -> hw_address.hlen = 1;
- tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ hw_addr = get_ib_hw_addr(tmp -> name);
-+ if (!hw_addr)
-+ log_fatal("Failed getting %s hw addr", tmp -> name);
-+ memcpy (&tmp -> hw_address.hbuf [1], hw_addr, 8);
- break;
-
- default:
+++ /dev/null
-diff -ruN client/dhclient.c.xid client/dhclient.c
---- client/dhclient.c.xid 2010-09-27 21:29:02.495805000 +0200
-+++ client/dhclient.c 2010-09-28 13:27:26.629193000 +0200
-@@ -434,6 +434,26 @@
- }
- }
-
-+ /* We create a backup seed before rediscovering interfaces in order to
-+ have a seed built using all of the available interfaces
-+ It's interesting if required interfaces doesn't let us defined
-+ a really unique seed due to a lack of valid HW addr later
-+ (this is the case with DHCP over IB)
-+ We only use the last device as using a sum could broke the
-+ uniqueness of the seed among multiple nodes
-+ */
-+ unsigned backup_seed = 0;
-+ for (ip = interfaces; ip; ip = ip -> next) {
-+ int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
-+ memcpy (&junk,
-+ &ip -> hw_address.hbuf [ip -> hw_address.hlen -
-+ sizeof seed], sizeof seed);
-+ backup_seed = junk;
-+ }
-+
-+
- /* At this point, all the interfaces that the script thinks
- are relevant should be running, so now we once again call
- discover_interfaces(), and this time ask it to actually set
-@@ -448,14 +468,36 @@
- Not much entropy, but we're booting, so we're not likely to
- find anything better. */
- seed = 0;
-+ int seed_flag = 0;
- for (ip = interfaces; ip; ip = ip -> next) {
- int junk;
-+ if ( ip -> hw_address.hlen <= sizeof seed )
-+ continue;
- memcpy (&junk,
- &ip -> hw_address.hbuf [ip -> hw_address.hlen -
- sizeof seed], sizeof seed);
- seed += junk;
-+ seed_flag = 1;
-+ }
-+ if ( seed_flag == 0 ) {
-+ if ( backup_seed != 0 ) {
-+ seed = backup_seed;
-+ log_info ("xid: rand init seed (0x%x) built using all"
-+ " available interfaces",seed);
-+ }
-+ else {
-+ seed = cur_time^((unsigned) gethostid()) ;
-+ log_info ("xid: warning: no netdev with useable HWADDR found"
-+ " for seed's uniqueness enforcement");
-+ log_info ("xid: rand init seed (0x%x) built using gethostid",
-+ seed);
-+ }
-+ /* we only use seed and no current time as a broadcast reply */
-+ /* will certainly be used by the hwaddrless interface */
-+ srandom(seed);
- }
-- srandom (seed + cur_time);
-+ else
-+ srandom (seed + cur_time);
-
- /* Setup specific Infiniband options */
- for (ip = interfaces; ip; ip = ip->next) {
-@@ -805,7 +847,7 @@
- return;
- }
-
-- log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPACK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- lease = packet_to_lease (packet, client);
- if (!lease) {
-@@ -1445,7 +1487,7 @@
- return;
- }
-
-- log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
-+ log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), client -> xid);
-
- if (!client -> active) {
- #if defined (DEBUG)
-@@ -1570,10 +1612,10 @@
- client -> packet.secs = htons (65535);
- client -> secs = client -> packet.secs;
-
-- log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
-+ log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
-+ ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -1823,10 +1865,10 @@
- client -> packet.secs = htons (65535);
- }
-
-- log_info ("DHCPREQUEST on %s to %s port %d",
-+ log_info ("DHCPREQUEST on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
- fallback_interface)
-@@ -1855,10 +1897,10 @@
-
- int result;
-
-- log_info ("DHCPDECLINE on %s to %s port %d",
-+ log_info ("DHCPDECLINE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (sockaddr_broadcast.sin_addr),
-- ntohs (sockaddr_broadcast.sin_port));
-+ ntohs (sockaddr_broadcast.sin_port), client -> xid);
-
- /* Send out a packet. */
- result = send_packet (client -> interface, (struct packet *)0,
-@@ -1898,10 +1940,10 @@
- return;
- }
-
-- log_info ("DHCPRELEASE on %s to %s port %d",
-+ log_info ("DHCPRELEASE on %s to %s port %d (xid=0x%x)",
- client -> name ? client -> name : client -> interface -> name,
- inet_ntoa (destination.sin_addr),
-- ntohs (destination.sin_port));
-+ ntohs (destination.sin_port), client -> xid);
-
- if (fallback_interface)
- result = send_packet (fallback_interface,
+++ /dev/null
-diff -ruN common/lpf.c.ib common/lpf.c
---- common/lpf.c.ib 2008-03-25 00:27:13.000000000 +0200
-+++ common/lpf.c 2010-09-28 14:46:21.927090000 +0200
-@@ -39,6 +39,7 @@
- #include <asm/types.h>
- #include <linux/filter.h>
- #include <linux/if_ether.h>
-+#include <linux/if_packet.h>
- #include <netinet/in_systm.h>
- #include "includes/netinet/ip.h"
- #include "includes/netinet/udp.h"
-@@ -71,11 +72,24 @@
- int sock;
- char filename[50];
- int b;
-- struct sockaddr sa;
-+ union {
-+ struct sockaddr_ll ll;
-+ struct sockaddr common;
-+ } sa;
-+ struct ifreq ifr;
-+ int type;
-+ int protocol;
-
- /* Make an LPF socket. */
-- if ((sock = socket(PF_PACKET, SOCK_PACKET,
-- htons((short)ETH_P_ALL))) < 0) {
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ type = SOCK_DGRAM;
-+ protocol = ETHERTYPE_IP;
-+ } else {
-+ type = SOCK_RAW;
-+ protocol = ETH_P_ALL;
-+ }
-+
-+ if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -89,11 +103,17 @@
- log_fatal ("Open a socket for LPF: %m");
- }
-
-+ memset (&ifr, 0, sizeof ifr);
-+ strncpy (ifr.ifr_name, (const char *)info -> ifp, sizeof ifr.ifr_name);
-+ if (ioctl (sock, SIOCGIFINDEX, &ifr))
-+ log_fatal ("Failed to get interface index: %m");
-+
- /* Bind to the interface name */
- memset (&sa, 0, sizeof sa);
-- sa.sa_family = AF_PACKET;
-- strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data);
-- if (bind (sock, &sa, sizeof sa)) {
-+ sa.ll.sll_family = AF_PACKET;
-+ sa.ll.sll_protocol = htons(protocol);
-+ sa.ll.sll_ifindex = ifr.ifr_ifindex;
-+ if (bind (sock, &sa.common, sizeof sa)) {
- if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
- errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
- errno == EAFNOSUPPORT || errno == EINVAL) {
-@@ -161,6 +181,8 @@
- in bpf includes... */
- extern struct sock_filter dhcp_bpf_filter [];
- extern int dhcp_bpf_filter_len;
-+extern struct sock_filter dhcp_ib_bpf_filter [];
-+extern int dhcp_ib_bpf_filter_len;
-
- #if defined (HAVE_TR_SUPPORT)
- extern struct sock_filter dhcp_bpf_tr_filter [];
-@@ -219,15 +241,28 @@
-
- memset(&p, 0, sizeof(p));
-
-- /* Set up the bpf filter program structure. This is defined in
-- bpf.c */
-- p.len = dhcp_bpf_filter_len;
-- p.filter = dhcp_bpf_filter;
--
-- /* 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 [8].k = ntohs ((short)local_port);
-+ if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ /* Set up the bpf filter program structure. */
-+ p.len = dhcp_ib_bpf_filter_len;
-+ p.filter = dhcp_ib_bpf_filter;
-+
-+ /* 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_ib_bpf_filter[6].k = ntohs ((short)local_port);
-+ } else {
-+ /* Set up the bpf filter program structure.
-+ This is defined in bpf.c */
-+ p.len = dhcp_bpf_filter_len;
-+ p.filter = dhcp_bpf_filter;
-+
-+ /* 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 [8].k = ntohs ((short)local_port);
-+ }
-
- if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
- sizeof p) < 0) {
-@@ -282,6 +317,54 @@
- #endif /* USE_LPF_RECEIVE */
-
- #ifdef USE_LPF_SEND
-+ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
-+ struct interface_info *interface;
-+ struct packet *packet;
-+ struct dhcp_packet *raw;
-+ size_t len;
-+ struct in_addr from;
-+ struct sockaddr_in *to;
-+ struct hardware *hto;
-+{
-+ unsigned ibufp = 0;
-+ double ih [1536 / sizeof (double)];
-+ unsigned char *buf = (unsigned char *)ih;
-+ ssize_t result;
-+
-+ union sockunion {
-+ struct sockaddr sa;
-+ struct sockaddr_ll sll;
-+ struct sockaddr_storage ss;
-+ } su;
-+
-+ assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
-+ to->sin_addr.s_addr, to->sin_port,
-+ (unsigned char *)raw, len);
-+ memcpy (buf + ibufp, raw, len);
-+
-+ memset(&su, 0, sizeof(su));
-+ su.sll.sll_family = AF_PACKET;
-+ su.sll.sll_protocol = htons(ETHERTYPE_IP);
-+
-+ if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
-+ errno = ENOENT;
-+ log_error ("send_packet_ib: %m - failed to get if index");
-+ return -1;
-+ }
-+
-+ su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
-+ su.sll.sll_halen = sizeof(interface->bcast_addr);
-+ memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
-+
-+ result = sendto(interface->wfdesc, buf, ibufp + len, 0,
-+ &su.sa, sizeof(su));
-+
-+ if (result < 0)
-+ log_error ("send_packet_ib: %m");
-+
-+ return result;
-+}
-+
- ssize_t send_packet (interface, packet, raw, len, from, to, hto)
- struct interface_info *interface;
- struct packet *packet;
-@@ -303,6 +386,11 @@
- return send_fallback (interface, packet, raw,
- len, from, to, hto);
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return send_packet_ib(interface, packet, raw, len, from,
-+ to, hto);
-+ }
-+
- /* Assemble the headers... */
- assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto);
- fudge = hbufp % 4; /* IP header must be word-aligned. */
-@@ -329,6 +417,38 @@
- #endif /* USE_LPF_SEND */
-
- #ifdef USE_LPF_RECEIVE
-+ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
-+ struct interface_info *interface;
-+ unsigned char *buf;
-+ size_t len;
-+ struct sockaddr_in *from;
-+ struct hardware *hfrom;
-+{
-+ int length = 0;
-+ int offset = 0;
-+ unsigned char ibuf [1536];
-+ unsigned bufix = 0;
-+
-+ length = read(interface->rfdesc, ibuf, sizeof(ibuf));
-+
-+ if (length <= 0)
-+ return length;
-+
-+ offset = decode_udp_ip_header(interface, ibuf, bufix, from,
-+ (unsigned)length, 0);
-+
-+ if (offset < 0)
-+ return 0;
-+
-+ bufix += offset;
-+ length -= offset;
-+
-+ /* Copy out the data in the packet... */
-+ memcpy(buf, &ibuf[bufix], length);
-+
-+ return length;
-+}
-+
- ssize_t receive_packet (interface, buf, len, from, hfrom)
- struct interface_info *interface;
- unsigned char *buf;
-@@ -343,6 +463,10 @@
- unsigned bufix = 0;
- unsigned paylen;
-
-+ if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
-+ return receive_packet_ib(interface, buf, len, from, hfrom);
-+ }
-+
- length = read (interface -> rfdesc, ibuf, sizeof ibuf);
- if (length <= 0)
- return length;
-diff -ruN includes/dhcp.h.ib includes/dhcp.h
---- includes/dhcp.h.ib 2008-01-22 21:02:51.000000000 +0200
-+++ includes/dhcp.h 2010-09-28 14:42:35.088656000 +0200
-@@ -76,6 +76,7 @@
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
- #define HTYPE_FDDI 8 /* FDDI... */
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */
-
- /* Magic cookie validating dhcp options field (and bootp vendor
- extensions field). */
-diff -ruN client/dhclient.c.ib client/dhclient.c
---- client/dhclient.c.ib 2010-09-28 14:39:47.928519000 +0200
-+++ client/dhclient.c 2010-09-28 14:42:39.268274000 +0200
-@@ -74,8 +74,10 @@
- int onetry=0;
- int quiet=0;
- int nowait=0;
-+int bootp_broadcast_always = 0;
-
- static void usage PROTO ((void));
-+static void setup_ib_interface(struct interface_info *ip);
-
- int main (argc, argv, envp)
- int argc;
-@@ -456,6 +458,14 @@
- }
- srandom (seed + cur_time);
-
-+ /* Setup specific Infiniband options */
-+ for (ip = interfaces; ip; ip = ip->next) {
-+ if (ip->client &&
-+ (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
-+ setup_ib_interface(ip);
-+ }
-+ }
-+
- /* Start a configuration state machine for each interface. */
- for (ip = interfaces; ip; ip = ip -> next) {
- ip -> flags |= INTERFACE_RUNNING;
-@@ -520,6 +530,29 @@
- return 0;
- }
-
-+static void setup_ib_interface(struct interface_info *ip)
-+{
-+ struct group *g;
-+
-+ /* Set the broadcast flag */
-+ bootp_broadcast_always = 1;
-+
-+ /*
-+ * Find out if a dhcp-client-identifier option was specified either
-+ * in the config file or on the command line
-+ */
-+ for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
-+ if ((g->statements != NULL) &&
-+ (strcmp(g->statements->data.option->option->name,
-+ "dhcp-client-identifier") == 0)) {
-+ return;
-+ }
-+ }
-+
-+ /* No client ID specified */
-+ log_fatal("dhcp-client-identifier must be specified for InfiniBand");
-+}
-+
- static void usage ()
- {
- log_info ("%s %s", message, DHCP_VERSION);
-diff -ruN common/bpf.c.ib common/bpf.c
---- common/bpf.c.ib 2007-05-24 02:30:32.000000000 +0300
-+++ common/bpf.c 2010-09-28 14:42:44.402799000 +0200
-@@ -194,11 +194,44 @@
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
-+/* Packet filter program for DHCP over Infiniband.
-+ *
-+ * XXX
-+ * Changes to the filter program may require changes to the constant offsets
-+ * used in lpf_gen_filter_setup to patch the port in the BPF program!
-+ * XXX
-+ */
-+struct bpf_insn dhcp_ib_bpf_filter [] = {
-+ /* Packet filter for Infiniband */
-+ /* Make sure it's a UDP packet... */
-+ BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
-+ 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, 6),
-+ BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-+
-+ /* Get the IP header length... */
-+ BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
-+
-+ /* Make sure it's to the right port... */
-+ BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
-+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
-+
-+ /* 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),
-+};
-+
- #if defined (DEC_FDDI)
- struct bpf_insn *bpf_fddi_filter;
- #endif
-
- int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
-+int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
-+
- #if defined (HAVE_TR_SUPPORT)
- struct bpf_insn dhcp_bpf_tr_filter [] = {
- /* accept all token ring packets due to variable length header */
-diff -ruN common/discover.c.ib common/discover.c
---- common/discover.c.ib 2006-11-08 01:41:39.000000000 +0200
-+++ common/discover.c 2010-09-28 14:42:48.411418000 +0200
-@@ -39,6 +39,8 @@
-
- #include "dhcpd.h"
- #include <sys/ioctl.h>
-+#include <ifaddrs.h>
-+#include <linux/if_packet.h>
-
- struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
- int interfaces_invalidated;
-@@ -58,6 +60,8 @@
- unsigned int,
- struct iaddr, struct hardware *));
-
-+void setup_ib_bcast_addr(struct interface_info *info);
-+
- omapi_object_type_t *dhcp_type_interface;
- #if defined (TRACING)
- trace_type_t *interface_trace;
-@@ -70,6 +74,15 @@
-
- OMAPI_OBJECT_ALLOC (interface, struct interface_info, dhcp_type_interface)
-
-+/* Default broadcast address for IPoIB */
-+unsigned char default_ib_bcast_addr[20] = {
-+ 0x00, 0xff, 0xff, 0xff,
-+ 0xff, 0x12, 0x40, 0x1b,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00,
-+ 0xff, 0xff, 0xff, 0xff
-+};
-+
- isc_result_t interface_setup ()
- {
- isc_result_t status;
-@@ -532,6 +545,15 @@
- break;
- #endif
-
-+#ifndef HAVE_ARPHRD_INFINIBAND
-+# define ARPHRD_INFINIBAND HTYPE_INFINIBAND
-+#endif
-+ case ARPHRD_INFINIBAND:
-+ setup_ib_bcast_addr ( tmp );
-+ tmp -> hw_address.hlen = 1;
-+ tmp -> hw_address.hbuf [0] = ARPHRD_INFINIBAND;
-+ break;
-+
- default:
- log_error ("%s: unknown hardware address type %d",
- ifr.ifr_name, sa.sa_family);
-@@ -712,6 +734,57 @@
- #endif
- }
-
-+void setup_ib_bcast_addr (struct interface_info *info)
-+{
-+ char *name = info->name;
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-+
-+ if (getifaddrs(&ifaddrs) == -1)
-+ log_fatal("Failed to get interfaces");
-+
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
-+ continue;
-+
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
-+ continue;
-+
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
-+ }
-+
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ log_fatal("Failed to get HW address for %s\n", name);
-+ }
-+
-+ switch (sll->sll_hatype) {
-+ case ARPHRD_INFINIBAND:
-+ /* For Infiniband, save the broadcast address and store
-+ * the port GUID into the hardware address.
-+ */
-+ if (ifa->ifa_flags & IFF_BROADCAST) {
-+ struct sockaddr_ll *bll;
-+
-+ bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
-+ memcpy(&info->bcast_addr, bll->sll_addr, 20);
-+ } else {
-+ memcpy(&info->bcast_addr, default_ib_bcast_addr,
-+ 20);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ freeifaddrs(ifaddrs);
-+}
-+
- int if_readsocket (h)
- omapi_object_t *h;
- {
-diff -ruN includes/dhcpd.h.ib includes/dhcpd.h
---- includes/dhcpd.h.ib 2010-09-28 14:39:47.649523000 +0200
-+++ includes/dhcpd.h 2010-09-28 14:42:55.298753000 +0200
-@@ -974,6 +974,7 @@
- struct shared_network *shared_network;
- /* Networks connected to this interface. */
- struct hardware hw_address; /* Its physical address. */
-+ u_int8_t bcast_addr[20]; /* Infiniband broadcast address */
- struct in_addr primary_address; /* Primary interface address. */
-
- u_int8_t *circuit_id; /* Circuit ID associated with this
-diff -ruN includes/osdep.h.ib includes/osdep.h
---- includes/osdep.h.ib 2006-02-25 01:16:29.000000000 +0200
-+++ includes/osdep.h 2010-09-28 14:42:59.928281000 +0200
-@@ -307,6 +307,10 @@
- # define HAVE_ARPHRD_METRICOM
- #endif
-
-+#if defined (ARPHRD_INFINIBAND) && !defined (HAVE_ARPHRD_INFINIBAND)
-+# define HAVE_ARPHRD_INFINIBAND
-+#endif
-+
- #if defined (SO_BINDTODEVICE) && !defined (HAVE_SO_BINDTODEVICE)
- # define HAVE_SO_BINDTODEVICE
- #endif
-diff -ruN server/dhcp.c.ib server/dhcp.c
---- server/dhcp.c.ib 2008-01-22 21:02:51.000000000 +0200
-+++ server/dhcp.c 2010-09-28 14:43:04.314900000 +0200
-@@ -2964,7 +2964,10 @@
- unicastp = 0;
- }
-
-- memcpy (&from, state -> from.iabuf, sizeof from);
-+ if (state -> ip -> hw_address.hbuf [0] != HTYPE_INFINIBAND)
-+ memcpy (&from, state -> from.iabuf, sizeof from);
-+ else
-+ from = state ->ip -> primary_address;
-
- result = send_packet (state -> ip,
- (struct packet *)0, &raw, packet_length,
+++ /dev/null
-diff -ruN dhcp.spec.ib dhcp.spec
---- dhcp.spec.ib 2010-05-12 09:42:23.000000000 +0300
-+++ dhcp.spec 2010-09-28 14:54:46.226304000 +0200
-@@ -82,6 +82,9 @@
- Patch60: dhcp-3.1.3-dhclient-script.dif
- Patch61: dhcp-3.1.3-dhclient-script.bnc555095.dif
- Patch62: dhcp-3.1.3-dhclient-script.bnc585380.dif
-+Patch70: dhcp-3.1.1-lpf-ib.dif
-+Patch71: dhcp-3.1.1-improved-xid.dif
-+Patch72: dhcp-3.1.1-gpxe-cid.dif
- ##
- Obsoletes: dhcp-base
- Provides: dhcp-base:/usr/bin/omshell
-@@ -205,6 +207,9 @@
- %patch60 -p0
- %patch61 -p0
- %patch62 -p0
-+%patch70 -p0
-+%patch71 -p0
-+%patch72 -p0
- ##
- find . -type f -name \*.cat\* -exec rm -f {} \;
- cp -p %{S:2} %{S:3} %{S:11} %{S:12} %{S:14} %{S:32} %{S:33} .
+++ /dev/null
-diff -ruN dhcp.spec.ib dhcp.spec
---- dhcp.spec.ib 2010-05-12 09:42:23.000000000 +0300
-+++ dhcp.spec 2010-09-28 14:54:46.226304000 +0200
-@@ -82,6 +82,8 @@
- Patch60: dhcp-3.1.3-dhclient-script.dif
- Patch61: dhcp-3.1.3-dhclient-script.bnc555095.dif
- Patch62: dhcp-3.1.3-dhclient-script.bnc585380.dif
-+Patch70: dhcp-3.1.1-lpf-ib.dif
-+Patch71: dhcp-3.1.1-improved-xid.dif
- ##
- Obsoletes: dhcp-base
- Provides: dhcp-base:/usr/bin/omshell
-@@ -205,6 +207,8 @@
- %patch60 -p0
- %patch61 -p0
- %patch62 -p0
-+%patch70 -p0
-+%patch71 -p0
- ##
- find . -type f -name \*.cat\* -exec rm -f {} \;
- cp -p %{S:2} %{S:3} %{S:11} %{S:12} %{S:14} %{S:32} %{S:33} .