aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Shvetsov <alexxy@gentoo.org>2012-03-16 01:41:19 +0400
committerAlexey Shvetsov <alexxy@gentoo.org>2012-03-16 01:41:51 +0400
commit725d9c01fda0f3598aabcadd272c13fdf6770cd2 (patch)
treea80c8a2624e4fa325297ad2ce70b67dc12bca1fa /net-misc
parentMerge branch 'master' of git+ssh://git.overlays.gentoo.org/proj/sci (diff)
downloadsci-725d9c01fda0f3598aabcadd272c13fdf6770cd2.tar.gz
sci-725d9c01fda0f3598aabcadd272c13fdf6770cd2.tar.bz2
sci-725d9c01fda0f3598aabcadd272c13fdf6770cd2.zip
[net-misc/dhcp] Import more patches to make also client work
(Portage version: 2.2.0_alpha90/git/Linux x86_64, unsigned Manifest commit)
Diffstat (limited to 'net-misc')
-rw-r--r--net-misc/dhcp/ChangeLog7
-rw-r--r--net-misc/dhcp/Manifest2
-rw-r--r--net-misc/dhcp/dhcp-4.2.3_p2-r1.ebuild (renamed from net-misc/dhcp/dhcp-4.2.3_p1-r1.ebuild)4
-rw-r--r--net-misc/dhcp/files/dhcp-4.2.0-PPP.patch150
-rw-r--r--net-misc/dhcp/files/dhcp-4.2.2-xen-checksum.patch249
-rw-r--r--net-misc/dhcp/files/dhcp-4.2.3-options.patch391
6 files changed, 802 insertions, 1 deletions
diff --git a/net-misc/dhcp/ChangeLog b/net-misc/dhcp/ChangeLog
index 0b47c0a32..0b811b859 100644
--- a/net-misc/dhcp/ChangeLog
+++ b/net-misc/dhcp/ChangeLog
@@ -2,6 +2,13 @@
# Copyright 1999-2012 Gentoo Foundation; Distributed under the GPL v2
# $Header: $
+*dhcp-4.2.3_p2-r1 (15 Mar 2012)
+
+ 15 Mar 2012; Alexey Shvetsov <alexxy@gentoo.org> +dhcp-4.2.3_p2-r1.ebuild,
+ +files/dhcp-4.2.0-PPP.patch, +files/dhcp-4.2.2-xen-checksum.patch,
+ +files/dhcp-4.2.3-options.patch, -dhcp-4.2.3_p1-r1.ebuild:
+ [net-misc/dhcp] Import more patches to make also client work
+
15 Mar 2012; Alexey Shvetsov <alexxy@gentoo.org>
+files/dhcp-4.2.2-gpxe-cid.patch, +files/dhcp-4.2.2-improved-xid.patch,
+files/dhcp-4.2.2-lpf-ib.patch, -files/dhcp-4.2.0-ib-options.patch,
diff --git a/net-misc/dhcp/Manifest b/net-misc/dhcp/Manifest
index e20ee98a4..5e3658ed5 100644
--- a/net-misc/dhcp/Manifest
+++ b/net-misc/dhcp/Manifest
@@ -1 +1 @@
-DIST dhcp-4.2.3-P1.tar.gz 9525670 SHA256 4860625e07c290768d513b9a2260e655ae4bad4cc5c4c8f5eaaeb4f9cbfa96af SHA512 3036775e49e2843992122fb4fdd90be1544c93634a0b8582581d4740e14f8a8afa5fa627e5f5f7ec0908bd4aa7112cc97d53ca065c27a04a28699fcd374739c8 WHIRLPOOL f52de3d74c9fec5d1ac1ef0e6fa9c8886e30ce9e8df006212d84995d42118651443399ff23b1a93884ef25a2f0d089ec9db2b358f00eba30bbddf06170b2739c
+DIST dhcp-4.2.3-P2.tar.gz 9527546 SHA256 5cf7ae2cad9c4ca0103748b2476ec8ea78484e408f8fe597e4e0a4afb051b469 SHA512 539000628cdd2bc3b092aac545434dadbc74908a67b73adafcd4800ef65d69a004ea2f6a9964a11be00020b683febd071baaa0d371ca08491321bf3264334e2a WHIRLPOOL a824aa30121bfa6d4f41148d18028ad4c459a803cfccf8ce62f4704be0e6ec4d96736dd1a5b7a789a7c9ddb6afcbb97cc4bb02c8a325a0657ced7e03438c01b4
diff --git a/net-misc/dhcp/dhcp-4.2.3_p1-r1.ebuild b/net-misc/dhcp/dhcp-4.2.3_p2-r1.ebuild
index 22d75872d..35069f79f 100644
--- a/net-misc/dhcp/dhcp-4.2.3_p1-r1.ebuild
+++ b/net-misc/dhcp/dhcp-4.2.3_p2-r1.ebuild
@@ -62,11 +62,15 @@ src_prepare() {
# infiniband patches
if use infiniband; then
+ epatch "${FILESDIR}"/${PN}-4.2.3-options.patch
+ epatch "${FILESDIR}"/${PN}-4.2.2-xen-checksum.patch
+ epatch "${FILESDIR}"/${PN}-4.2.0-PPP.patch
epatch "${FILESDIR}"/${PN}-4.2.2-lpf-ib.patch
epatch "${FILESDIR}"/${PN}-4.2.2-improved-xid.patch
epatch "${FILESDIR}"/${PN}-4.2.2-gpxe-cid.patch
fi
+
# Brand the version with Gentoo
sed -i \
-e "/VERSION=/s:'$: Gentoo-${PR}':" \
diff --git a/net-misc/dhcp/files/dhcp-4.2.0-PPP.patch b/net-misc/dhcp/files/dhcp-4.2.0-PPP.patch
new file mode 100644
index 000000000..bef2be7f0
--- /dev/null
+++ b/net-misc/dhcp/files/dhcp-4.2.0-PPP.patch
@@ -0,0 +1,150 @@
+diff -up dhcp-4.2.0-P1/client/dhc6.c.PPP dhcp-4.2.0-P1/client/dhc6.c
+--- dhcp-4.2.0-P1/client/dhc6.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/client/dhc6.c 2010-11-09 15:54:12.000000000 +0100
+@@ -129,7 +129,7 @@ extern int stateless;
+ * is not how it is intended. Upcoming rearchitecting the client should
+ * address this "one daemon model."
+ */
+-void
++isc_result_t
+ form_duid(struct data_string *duid, const char *file, int line)
+ {
+ struct interface_info *ip;
+@@ -141,6 +141,15 @@ form_duid(struct data_string *duid, cons
+ if (ip == NULL)
+ log_fatal("Impossible condition at %s:%d.", MDL);
+
++ while (ip && ip->hw_address.hbuf[0] == HTYPE_RESERVED) {
++ /* Try the other interfaces */
++ log_debug("Cannot form default DUID from interface %s.", ip->name);
++ ip = ip->next;
++ }
++ if (ip == NULL) {
++ return ISC_R_UNEXPECTED;
++ }
++
+ if ((ip->hw_address.hlen == 0) ||
+ (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
+ log_fatal("Impossible hardware address length at %s:%d.", MDL);
+@@ -176,6 +185,8 @@ form_duid(struct data_string *duid, cons
+ memcpy(duid->buffer->data + 4, ip->hw_address.hbuf + 1,
+ ip->hw_address.hlen - 1);
+ }
++
++ return ISC_R_SUCCESS;
+ }
+
+ /*
+@@ -5289,7 +5300,8 @@ make_client6_options(struct client_state
+ */
+ if ((oc = lookup_option(&dhcpv6_universe, *op,
+ D6O_CLIENTID)) == NULL) {
+- if (!option_cache(&oc, &default_duid, NULL, clientid_option,
++ if (default_duid.len == 0 ||
++ !option_cache(&oc, &default_duid, NULL, clientid_option,
+ MDL))
+ log_fatal("Failure assembling a DUID.");
+
+diff -up dhcp-4.2.0-P1/client/dhclient.c.PPP dhcp-4.2.0-P1/client/dhclient.c
+--- dhcp-4.2.0-P1/client/dhclient.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/client/dhclient.c 2010-11-09 15:37:26.000000000 +0100
+@@ -911,8 +911,8 @@ main(int argc, char **argv) {
+ if (default_duid.buffer != NULL)
+ data_string_forget(&default_duid, MDL);
+
+- form_duid(&default_duid, MDL);
+- write_duid(&default_duid);
++ if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
++ write_duid(&default_duid);
+ }
+
+ for (ip = interfaces ; ip != NULL ; ip = ip->next) {
+diff -up dhcp-4.2.0-P1/common/bpf.c.PPP dhcp-4.2.0-P1/common/bpf.c
+--- dhcp-4.2.0-P1/common/bpf.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/common/bpf.c 2010-11-09 15:42:42.000000000 +0100
+@@ -599,6 +599,22 @@ get_hw_addr(const char *name, struct har
+ memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
+ break;
+ #endif /* IFT_FDDI */
++#if defined(IFT_PPP)
++ case IFT_PPP:
++ if (local_family != AF_INET6)
++ log_fatal("Unsupported device type %d for \"%s\"",
++ sa->sdl_type, name);
++ hw->hlen = 0;
++ hw->hbuf[0] = HTYPE_RESERVED;
++ /* 0xdeadbeef should never occur on the wire,
++ * and is a signature that something went wrong.
++ */
++ hw->hbuf[1] = 0xde;
++ hw->hbuf[2] = 0xad;
++ hw->hbuf[3] = 0xbe;
++ hw->hbuf[4] = 0xef;
++ break;
++#endif
+ default:
+ log_fatal("Unsupported device type %d for \"%s\"",
+ sa->sdl_type, name);
+diff -up dhcp-4.2.0-P1/common/lpf.c.PPP dhcp-4.2.0-P1/common/lpf.c
+--- dhcp-4.2.0-P1/common/lpf.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/common/lpf.c 2010-11-09 15:45:40.000000000 +0100
+@@ -502,6 +502,22 @@ get_hw_addr(const char *name, struct har
+ hw->hbuf[0] = HTYPE_FDDI;
+ memcpy(&hw->hbuf[1], sa->sa_data, 16);
+ break;
++#if defined(ARPHRD_PPP)
++ case ARPHRD_PPP:
++ if (local_family != AF_INET6)
++ log_fatal("Unsupported device type %d for \"%s\"",
++ sa->sa_family, name);
++ hw->hlen = 0;
++ hw->hbuf[0] = HTYPE_RESERVED;
++ /* 0xdeadbeef should never occur on the wire,
++ * and is a signature that something went wrong.
++ */
++ hw->hbuf[1] = 0xde;
++ hw->hbuf[2] = 0xad;
++ hw->hbuf[3] = 0xbe;
++ hw->hbuf[4] = 0xef;
++ break;
++#endif
+ default:
+ log_fatal("Unsupported device type %ld for \"%s\"",
+ (long int)sa->sa_family, name);
+diff -up dhcp-4.2.0-P1/includes/dhcpd.h.PPP dhcp-4.2.0-P1/includes/dhcpd.h
+--- dhcp-4.2.0-P1/includes/dhcpd.h.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/includes/dhcpd.h 2010-11-09 15:46:58.000000000 +0100
+@@ -2733,7 +2733,7 @@ void dhcpv4_client_assignments(void);
+ void dhcpv6_client_assignments(void);
+
+ /* dhc6.c */
+-void form_duid(struct data_string *duid, const char *file, int line);
++isc_result_t form_duid(struct data_string *duid, const char *file, int line);
+ void dhc6_lease_destroy(struct dhc6_lease **src, const char *file, int line);
+ void start_init6(struct client_state *client);
+ void start_info_request6(struct client_state *client);
+diff -up dhcp-4.2.0-P1/includes/dhcp.h.PPP dhcp-4.2.0-P1/includes/dhcp.h
+--- dhcp-4.2.0-P1/includes/dhcp.h.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/includes/dhcp.h 2010-11-09 15:48:53.000000000 +0100
+@@ -80,6 +80,8 @@ struct dhcp_packet {
+ #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
+ #define HTYPE_FDDI 8 /* FDDI... */
+
++#define HTYPE_RESERVED 0 /* RFC 5494 */
++
+ /* Magic cookie validating dhcp options field (and bootp vendor
+ extensions field). */
+ #define DHCP_OPTIONS_COOKIE "\143\202\123\143"
+diff -up dhcp-4.2.0-P1/server/dhcpv6.c.PPP dhcp-4.2.0-P1/server/dhcpv6.c
+--- dhcp-4.2.0-P1/server/dhcpv6.c.PPP 2010-11-05 10:47:37.000000000 +0100
++++ dhcp-4.2.0-P1/server/dhcpv6.c 2010-11-09 15:50:17.000000000 +0100
+@@ -300,6 +300,9 @@ generate_new_server_duid(void) {
+ if (p->hw_address.hlen > 0) {
+ break;
+ }
++ if (p->next == NULL && p->hw_address.hbuf[0] == HTYPE_RESERVED) {
++ log_error("Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
++ }
+ }
+ if (p == NULL) {
+ return ISC_R_UNEXPECTED;
diff --git a/net-misc/dhcp/files/dhcp-4.2.2-xen-checksum.patch b/net-misc/dhcp/files/dhcp-4.2.2-xen-checksum.patch
new file mode 100644
index 000000000..038d346d7
--- /dev/null
+++ b/net-misc/dhcp/files/dhcp-4.2.2-xen-checksum.patch
@@ -0,0 +1,249 @@
+diff -up dhcp-4.2.2b1/common/bpf.c.xen dhcp-4.2.2b1/common/bpf.c
+--- dhcp-4.2.2b1/common/bpf.c.xen 2009-11-20 02:48:59.000000000 +0100
++++ dhcp-4.2.2b1/common/bpf.c 2011-07-01 14:00:16.936959001 +0200
+@@ -485,7 +485,7 @@ ssize_t receive_packet (interface, buf,
+ offset = decode_udp_ip_header (interface,
+ interface -> rbuf,
+ interface -> rbuf_offset,
+- from, hdr.bh_caplen, &paylen);
++ from, hdr.bh_caplen, &paylen, 0);
+
+ /* If the IP or UDP checksum was bad, skip the packet... */
+ if (offset < 0) {
+diff -up dhcp-4.2.2b1/common/dlpi.c.xen dhcp-4.2.2b1/common/dlpi.c
+--- dhcp-4.2.2b1/common/dlpi.c.xen 2011-05-11 16:20:59.000000000 +0200
++++ dhcp-4.2.2b1/common/dlpi.c 2011-07-01 14:00:16.937958997 +0200
+@@ -693,7 +693,7 @@ ssize_t receive_packet (interface, buf,
+ length -= offset;
+ #endif
+ offset = decode_udp_ip_header (interface, dbuf, bufix,
+- from, length, &paylen);
++ from, length, &paylen, 0);
+
+ /*
+ * If the IP or UDP checksum was bad, skip the packet...
+diff -up dhcp-4.2.2b1/common/lpf.c.xen dhcp-4.2.2b1/common/lpf.c
+--- dhcp-4.2.2b1/common/lpf.c.xen 2011-05-10 16:38:58.000000000 +0200
++++ dhcp-4.2.2b1/common/lpf.c 2011-07-01 14:11:24.725748028 +0200
+@@ -29,19 +29,33 @@
+ #include "dhcpd.h"
+ #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
+ #include <sys/ioctl.h>
++#include <sys/socket.h>
+ #include <sys/uio.h>
+ #include <errno.h>
+
+ #include <asm/types.h>
+ #include <linux/filter.h>
+ #include <linux/if_ether.h>
++#include <linux/if_packet.h>
+ #include <netinet/in_systm.h>
+-#include <net/if_packet.h>
+ #include "includes/netinet/ip.h"
+ #include "includes/netinet/udp.h"
+ #include "includes/netinet/if_ether.h"
+ #include <net/if.h>
+
++#ifndef PACKET_AUXDATA
++#define PACKET_AUXDATA 8
++
++struct tpacket_auxdata
++{
++ __u32 tp_status;
++ __u32 tp_len;
++ __u32 tp_snaplen;
++ __u16 tp_mac;
++ __u16 tp_net;
++};
++#endif
++
+ /* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+@@ -67,10 +81,14 @@ int if_register_lpf (info)
+ struct interface_info *info;
+ {
+ int sock;
+- struct sockaddr sa;
++ union {
++ struct sockaddr_ll ll;
++ struct sockaddr common;
++ } sa;
++ struct ifreq ifr;
+
+ /* Make an LPF socket. */
+- if ((sock = socket(PF_PACKET, SOCK_PACKET,
++ if ((sock = socket(PF_PACKET, SOCK_RAW,
+ htons((short)ETH_P_ALL))) < 0) {
+ if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+ errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
+@@ -85,11 +103,17 @@ int if_register_lpf (info)
+ 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);
++ ifr.ifr_name[IFNAMSIZ-1] = '\0';
++ 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_ifindex = ifr.ifr_ifindex;
++ if (bind (sock, &sa.common, sizeof sa)) {
+ if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+ errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
+ errno == EAFNOSUPPORT || errno == EINVAL) {
+@@ -171,9 +195,18 @@ static void lpf_gen_filter_setup (struct
+ void if_register_receive (info)
+ struct interface_info *info;
+ {
++ int val;
++
+ /* 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 defined (HAVE_TR_SUPPORT)
+ if (info -> hw_address.hbuf [0] == HTYPE_IEEE802)
+ lpf_tr_filter_setup (info);
+@@ -295,7 +328,6 @@ ssize_t send_packet (interface, packet,
+ double hh [16];
+ double ih [1536 / sizeof (double)];
+ unsigned char *buf = (unsigned char *)ih;
+- struct sockaddr_pkt sa;
+ int result;
+ int fudge;
+
+@@ -316,17 +348,7 @@ ssize_t send_packet (interface, packet,
+ (unsigned char *)raw, len);
+ memcpy (buf + ibufp, raw, len);
+
+- /* For some reason, SOCK_PACKET sockets can't be connected,
+- so we have to do a sentdo every time. */
+- memset (&sa, 0, sizeof sa);
+- sa.spkt_family = AF_PACKET;
+- strncpy ((char *)sa.spkt_device,
+- (const char *)interface -> ifp, sizeof sa.spkt_device);
+- sa.spkt_protocol = htons(ETH_P_IP);
+-
+- result = sendto (interface -> wfdesc,
+- buf + fudge, ibufp + len - fudge, 0,
+- (const struct sockaddr *)&sa, sizeof sa);
++ result = write (interface -> wfdesc, buf + fudge, ibufp + len - fudge);
+ if (result < 0)
+ log_error ("send_packet: %m");
+ return result;
+@@ -343,14 +365,35 @@ ssize_t receive_packet (interface, buf,
+ {
+ int length = 0;
+ int offset = 0;
++ int nocsum = 0;
+ unsigned char ibuf [1536];
+ unsigned bufix = 0;
+ unsigned paylen;
++ unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
++ struct iovec iov = {
++ .iov_base = ibuf,
++ .iov_len = sizeof ibuf,
++ };
++ struct msghdr msg = {
++ .msg_iov = &iov,
++ .msg_iovlen = 1,
++ .msg_control = cmsgbuf,
++ .msg_controllen = sizeof(cmsgbuf),
++ };
++ struct cmsghdr *cmsg;
+
+- length = read (interface -> rfdesc, ibuf, sizeof ibuf);
++ length = recvmsg (interface -> rfdesc, &msg, 0);
+ if (length <= 0)
+ return length;
+
++ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
++ if (cmsg->cmsg_level == SOL_PACKET &&
++ cmsg->cmsg_type == PACKET_AUXDATA) {
++ struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg);
++ nocsum = aux->tp_status & TP_STATUS_CSUMNOTREADY;
++ }
++ }
++
+ bufix = 0;
+ /* Decode the physical header... */
+ offset = decode_hw_header (interface, ibuf, bufix, hfrom);
+@@ -367,7 +410,7 @@ ssize_t receive_packet (interface, buf,
+
+ /* Decode the IP and UDP headers... */
+ offset = decode_udp_ip_header (interface, ibuf, bufix, from,
+- (unsigned)length, &paylen);
++ (unsigned)length, &paylen, nocsum);
+
+ /* If the IP or UDP checksum was bad, skip the packet... */
+ if (offset < 0)
+diff -up dhcp-4.2.2b1/common/nit.c.xen dhcp-4.2.2b1/common/nit.c
+--- dhcp-4.2.2b1/common/nit.c.xen 2009-11-20 02:49:01.000000000 +0100
++++ dhcp-4.2.2b1/common/nit.c 2011-07-01 14:00:16.939958989 +0200
+@@ -369,7 +369,7 @@ ssize_t receive_packet (interface, buf,
+
+ /* Decode the IP and UDP headers... */
+ offset = decode_udp_ip_header (interface, ibuf, bufix,
+- from, length, &paylen);
++ from, length, &paylen, 0);
+
+ /* If the IP or UDP checksum was bad, skip the packet... */
+ if (offset < 0)
+diff -up dhcp-4.2.2b1/common/packet.c.xen dhcp-4.2.2b1/common/packet.c
+--- dhcp-4.2.2b1/common/packet.c.xen 2009-07-23 20:52:20.000000000 +0200
++++ dhcp-4.2.2b1/common/packet.c 2011-07-01 14:00:16.939958989 +0200
+@@ -211,7 +211,7 @@ ssize_t
+ decode_udp_ip_header(struct interface_info *interface,
+ unsigned char *buf, unsigned bufix,
+ struct sockaddr_in *from, unsigned buflen,
+- unsigned *rbuflen)
++ unsigned *rbuflen, int nocsum)
+ {
+ unsigned char *data;
+ struct ip ip;
+@@ -322,7 +322,7 @@ decode_udp_ip_header(struct interface_in
+ 8, IPPROTO_UDP + ulen))));
+
+ udp_packets_seen++;
+- if (usum && usum != sum) {
++ if (!nocsum && usum && usum != sum) {
+ udp_packets_bad_checksum++;
+ if (udp_packets_seen > 4 &&
+ (udp_packets_seen / udp_packets_bad_checksum) < 2) {
+diff -up dhcp-4.2.2b1/common/upf.c.xen dhcp-4.2.2b1/common/upf.c
+--- dhcp-4.2.2b1/common/upf.c.xen 2009-11-20 02:49:01.000000000 +0100
++++ dhcp-4.2.2b1/common/upf.c 2011-07-01 14:00:16.940958986 +0200
+@@ -320,7 +320,7 @@ ssize_t receive_packet (interface, buf,
+
+ /* Decode the IP and UDP headers... */
+ offset = decode_udp_ip_header (interface, ibuf, bufix,
+- from, length, &paylen);
++ from, length, &paylen, 0);
+
+ /* If the IP or UDP checksum was bad, skip the packet... */
+ if (offset < 0)
+diff -up dhcp-4.2.2b1/includes/dhcpd.h.xen dhcp-4.2.2b1/includes/dhcpd.h
+--- dhcp-4.2.2b1/includes/dhcpd.h.xen 2011-07-01 14:00:16.000000000 +0200
++++ dhcp-4.2.2b1/includes/dhcpd.h 2011-07-01 14:12:18.069642470 +0200
+@@ -2796,7 +2796,7 @@ ssize_t decode_hw_header (struct interfa
+ unsigned, struct hardware *);
+ ssize_t decode_udp_ip_header (struct interface_info *, unsigned char *,
+ unsigned, struct sockaddr_in *,
+- unsigned, unsigned *);
++ unsigned, unsigned *, int);
+
+ /* ethernet.c */
+ void assemble_ethernet_header (struct interface_info *, unsigned char *,
diff --git a/net-misc/dhcp/files/dhcp-4.2.3-options.patch b/net-misc/dhcp/files/dhcp-4.2.3-options.patch
new file mode 100644
index 000000000..c902e62a3
--- /dev/null
+++ b/net-misc/dhcp/files/dhcp-4.2.3-options.patch
@@ -0,0 +1,391 @@
+diff -up dhcp-4.2.3-P2/client/clparse.c.options dhcp-4.2.3-P2/client/clparse.c
+--- dhcp-4.2.3-P2/client/clparse.c.options 2011-04-21 16:08:14.000000000 +0200
++++ dhcp-4.2.3-P2/client/clparse.c 2012-02-13 18:21:32.233471518 +0100
+@@ -146,6 +146,7 @@ isc_result_t read_client_conf ()
+ /* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)
+ */
+ top_level_config.requested_lease = 7200;
++ top_level_config.bootp_broadcast_always = 0;
+
+ group_allocate (&top_level_config.on_receipt, MDL);
+ if (!top_level_config.on_receipt)
+@@ -313,7 +314,8 @@ void read_client_leases ()
+ interface-declaration |
+ LEASE client-lease-statement |
+ ALIAS client-lease-statement |
+- KEY key-definition */
++ KEY key-definition |
++ BOOTP_BROADCAST_ALWAYS */
+
+ void parse_client_statement (cfile, ip, config)
+ struct parse *cfile;
+@@ -732,6 +734,12 @@ void parse_client_statement (cfile, ip,
+ parse_reject_statement (cfile, config);
+ return;
+
++ case BOOTP_BROADCAST_ALWAYS:
++ token = next_token(&val, (unsigned*)0, cfile);
++ config -> bootp_broadcast_always = 1;
++ parse_semi (cfile);
++ return;
++
+ default:
+ lose = 0;
+ stmt = (struct executable_statement *)0;
+diff -up dhcp-4.2.3-P2/client/dhclient.c.options dhcp-4.2.3-P2/client/dhclient.c
+--- dhcp-4.2.3-P2/client/dhclient.c.options 2011-12-31 01:55:21.000000000 +0100
++++ dhcp-4.2.3-P2/client/dhclient.c 2012-02-13 18:22:11.554979930 +0100
+@@ -39,6 +39,12 @@
+ #include <limits.h>
+ #include <dns/result.h>
+
++/*
++ * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
++ * that when building ISC code.
++ */
++extern int asprintf(char **strp, const char *fmt, ...);
++
+ TIME default_lease_time = 43200; /* 12 hours... */
+ TIME max_lease_time = 86400; /* 24 hours... */
+
+@@ -87,6 +93,9 @@ int wanted_ia_na = -1; /* the absolute
+ int wanted_ia_ta = 0;
+ int wanted_ia_pd = 0;
+ char *mockup_relay = NULL;
++int bootp_broadcast_always = 0;
++
++extern u_int32_t default_requested_options[];
+
+ void run_stateless(int exit_mode);
+
+@@ -123,6 +132,15 @@ main(int argc, char **argv) {
+ int local_family_set = 0;
+ #endif /* DHCPv6 */
+ char *s;
++ char *dhcp_client_identifier_arg = NULL;
++ char *dhcp_host_name_arg = NULL;
++ char *dhcp_fqdn_arg = NULL;
++ char *dhcp_vendor_class_identifier_arg = NULL;
++ char *dhclient_request_options = NULL;
++
++ int timeout_arg = 0;
++ char *arg_conf = NULL;
++ int arg_conf_len = 0;
+
+ /* Initialize client globals. */
+ memset(&default_duid, 0, sizeof(default_duid));
+@@ -310,6 +328,88 @@ main(int argc, char **argv) {
+ } else if (!strcmp(argv[i], "--version")) {
+ log_info("isc-dhclient-%s", PACKAGE_VERSION);
+ exit(0);
++ } else if (!strcmp(argv[i], "-I")) {
++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++ usage();
++ exit(1);
++ }
++
++ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++ log_error("-I option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++ exit(1);
++ }
++
++ dhcp_client_identifier_arg = argv[i];
++ } else if (!strcmp(argv[i], "-B")) {
++ bootp_broadcast_always = 1;
++ } else if (!strcmp(argv[i], "-H")) {
++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++ usage();
++ exit(1);
++ }
++
++ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++ log_error("-H option host-name string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++ exit(1);
++ }
++
++ if (dhcp_host_name_arg != NULL) {
++ log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
++ exit(1);
++ }
++
++ dhcp_host_name_arg = argv[i];
++ } else if (!strcmp(argv[i], "-F")) {
++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++ usage();
++ exit(1);
++ }
++
++ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++ log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++ exit(1);
++ }
++
++ if (dhcp_fqdn_arg != NULL) {
++ log_error("Only one -F <fqdn> argument can be specified");
++ exit(1);
++ }
++
++ if (dhcp_host_name_arg != NULL) {
++ log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
++ exit(1);
++ }
++
++ dhcp_fqdn_arg = argv[i];
++ } else if (!strcmp(argv[i], "-timeout")) {
++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++ usage();
++ exit(1);
++ }
++
++ if ((timeout_arg = atoi(argv[i])) <= 0) {
++ log_error("timeout option must be > 0 - bad value: %s",argv[i]);
++ exit(1);
++ }
++ } else if (!strcmp(argv[i], "-V")) {
++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++ usage();
++ exit(1);
++ }
++
++ if (strlen(argv[i]) >= DHCP_MAX_OPTION_LEN) {
++ log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d", argv[i], DHCP_MAX_OPTION_LEN-1);
++ exit(1);
++ }
++
++ dhcp_vendor_class_identifier_arg = argv[i];
++ } else if (!strcmp(argv[i], "-R")) {
++ if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++ usage();
++ exit(1);
++ }
++
++ dhclient_request_options = argv[i];
+ } else if (argv[i][0] == '-') {
+ usage();
+ } else if (interfaces_requested < 0) {
+@@ -484,6 +584,156 @@ main(int argc, char **argv) {
+ /* Parse the dhclient.conf file. */
+ read_client_conf();
+
++ /* Parse any extra command line configuration arguments: */
++ if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
++ arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to send -I option dhcp-client-identifier");
++ }
++
++ if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {
++ if (arg_conf == 0) {
++ arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to send -H option host-name");
++ } else {
++ char *last_arg_conf = arg_conf;
++ arg_conf = NULL;
++ arg_conf_len = asprintf(&arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to send -H option host-name");
++
++ free(last_arg_conf);
++ }
++ }
++
++ if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {
++ if (arg_conf == 0) {
++ arg_conf_len = asprintf(&arg_conf, "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to send -F option fqdn.fqdn");
++ } else {
++ char *last_arg_conf = arg_conf;
++ arg_conf = NULL;
++ arg_conf_len = asprintf(&arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to send -F option fqdn.fqdn");
++
++ free(last_arg_conf);
++ }
++ }
++
++ if (timeout_arg) {
++ if (arg_conf == 0) {
++ arg_conf_len = asprintf(&arg_conf, "timeout %d;", timeout_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to process -timeout timeout argument");
++ } else {
++ char *last_arg_conf = arg_conf;
++ arg_conf = NULL;
++ arg_conf_len = asprintf(&arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len == 0))
++ log_fatal("Unable to process -timeout timeout argument");
++
++ free(last_arg_conf);
++ }
++ }
++
++ if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {
++ if (arg_conf == 0) {
++ arg_conf_len = asprintf(&arg_conf, "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to send -V option vendor-class-identifier");
++ } else {
++ char *last_arg_conf = arg_conf;
++ arg_conf = NULL;
++ arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to send -V option vendor-class-identifier");
++
++ free(last_arg_conf);
++ }
++ }
++
++ if (dhclient_request_options != NULL) {
++ if (arg_conf == 0) {
++ arg_conf_len = asprintf(&arg_conf, "request %s;", dhclient_request_options);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to parse -R <request options list> argument");
++ } else {
++ char *last_arg_conf = arg_conf;
++ arg_conf = NULL;
++ arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);
++
++ if ((arg_conf == 0) || (arg_conf_len <= 0))
++ log_fatal("Unable to parse -R <request options list> argument");
++
++ free(last_arg_conf);
++ }
++ }
++
++ if (arg_conf) {
++ if (arg_conf_len == 0)
++ if ((arg_conf_len = strlen(arg_conf)) == 0)
++ /* huh ? cannot happen ! */
++ log_fatal("Unable to process -I/-H/-F/-timeout/-V/-R configuration arguments");
++
++ /* parse the extra dhclient.conf configuration arguments
++ * into top level config: */
++ struct parse *cfile = (struct parse *)0;
++ const char *val = NULL;
++ int token;
++
++ status = new_parse(&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -I/-H/-F/-timeout/-V/-R configuration arguments", 0);
++
++ if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))
++ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R configuration arguments !");
++ /* more detailed parse failures will be logged */
++
++ do {
++ token = peek_token(&val, (unsigned *)0, cfile);
++ if (token == END_OF_FILE)
++ break;
++
++ parse_client_statement(cfile, (struct interface_info *)0, &top_level_config);
++ } while (1);
++
++ if (cfile -> warnings_occurred)
++ log_fatal("Cannot parse -I/-H/-F/-timeout/-V/-R configuration arguments !");
++ end_parse(&cfile);
++
++ if (timeout_arg) {
++ /* we just set the toplevel timeout, but per-client
++ * timeouts may still be at defaults.
++ */
++ for (ip=interfaces; ip; ip = ip->next) {
++ if (ip->client->config->timeout == 60)
++ ip->client->config->timeout = timeout_arg;
++ }
++ }
++
++ if ((dhclient_request_options != 0) && (top_level_config.requested_options != default_requested_options)) {
++ for (ip=interfaces; ip; ip = ip->next) {
++ if (ip->client->config->requested_options == default_requested_options)
++ ip->client->config->requested_options = top_level_config.requested_options;
++ }
++ }
++
++ free(arg_conf);
++ arg_conf = NULL;
++ arg_conf_len = 0;
++ }
++
+ /* Parse the lease database. */
+ read_client_leases();
+
+@@ -2397,7 +2647,8 @@ void make_discover (client, lease)
+ client -> packet.xid = random ();
+ client -> packet.secs = 0; /* filled in by send_discover. */
+
+- if (can_receive_unicast_unconfigured (client -> interface))
++ if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always))
++ && can_receive_unicast_unconfigured(client->interface))
+ client -> packet.flags = 0;
+ else
+ client -> packet.flags = htons (BOOTP_BROADCAST);
+@@ -2481,7 +2732,9 @@ void make_request (client, lease)
+ } else {
+ memset (&client -> packet.ciaddr, 0,
+ sizeof client -> packet.ciaddr);
+- if (can_receive_unicast_unconfigured (client -> interface))
++ if ((!(bootp_broadcast_always ||
++ client ->config->bootp_broadcast_always)) &&
++ can_receive_unicast_unconfigured (client -> interface))
+ client -> packet.flags = 0;
+ else
+ client -> packet.flags = htons (BOOTP_BROADCAST);
+@@ -2543,7 +2796,8 @@ void make_decline (client, lease)
+ client -> packet.hops = 0;
+ client -> packet.xid = client -> xid;
+ client -> packet.secs = 0; /* Filled in by send_request. */
+- if (can_receive_unicast_unconfigured (client -> interface))
++ if ((!(bootp_broadcast_always || client->config-> bootp_broadcast_always))
++ && can_receive_unicast_unconfigured (client->interface))
+ client -> packet.flags = 0;
+ else
+ client -> packet.flags = htons (BOOTP_BROADCAST);
+diff -up dhcp-4.2.3-P2/common/conflex.c.options dhcp-4.2.3-P2/common/conflex.c
+--- dhcp-4.2.3-P2/common/conflex.c.options 2011-09-21 22:43:10.000000000 +0200
++++ dhcp-4.2.3-P2/common/conflex.c 2012-02-13 18:21:32.335470243 +0100
+@@ -808,6 +808,8 @@ intern(char *atom, enum dhcp_token dfv)
+ return BALANCE;
+ if (!strcasecmp (atom + 1, "ound"))
+ return BOUND;
++ if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
++ return BOOTP_BROADCAST_ALWAYS;
+ break;
+ case 'c':
+ if (!strcasecmp(atom + 1, "ase"))
+diff -up dhcp-4.2.3-P2/includes/dhcpd.h.options dhcp-4.2.3-P2/includes/dhcpd.h
+--- dhcp-4.2.3-P2/includes/dhcpd.h.options 2011-12-31 00:17:04.000000000 +0100
++++ dhcp-4.2.3-P2/includes/dhcpd.h 2012-02-13 18:21:32.542467656 +0100
+@@ -1147,6 +1147,9 @@ struct client_config {
+ int do_forward_update; /* If nonzero, and if we have the
+ information we need, update the
+ A record for the address we get. */
++
++ int bootp_broadcast_always; /* If nonzero, always set the BOOTP_BROADCAST
++ flag in requests */
+ };
+
+ /* Per-interface state used in the dhcp client... */
+diff -up dhcp-4.2.3-P2/includes/dhctoken.h.options dhcp-4.2.3-P2/includes/dhctoken.h
+--- dhcp-4.2.3-P2/includes/dhctoken.h.options 2011-09-21 22:43:10.000000000 +0200
++++ dhcp-4.2.3-P2/includes/dhctoken.h 2012-02-13 18:21:32.644466377 +0100
+@@ -363,7 +363,8 @@ enum dhcp_token {
+ INITIAL_DELAY = 664,
+ GETHOSTBYNAME = 665,
+ PRIMARY6 = 666,
+- SECONDARY6 = 667
++ SECONDARY6 = 667,
++ BOOTP_BROADCAST_ALWAYS = 668
+ };
+
+ #define is_identifier(x) ((x) >= FIRST_TOKEN && \