diff --git a/.gitignore b/.gitignore index d6061ec..b16a929 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /dhcp-4.2.3.tar.gz /dhcp-4.2.3-P1.tar.gz /dhcp-4.2.3-P2.tar.gz +/dhcp-4.2.4b1.tar.gz diff --git a/dhcp-4.2.0-PPP.patch b/dhcp-4.2.0-PPP.patch deleted file mode 100644 index bef2be7..0000000 --- a/dhcp-4.2.0-PPP.patch +++ /dev/null @@ -1,150 +0,0 @@ -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/dhcp-4.2.0-UseMulticast.patch b/dhcp-4.2.0-UseMulticast.patch deleted file mode 100644 index 319344a..0000000 --- a/dhcp-4.2.0-UseMulticast.patch +++ /dev/null @@ -1,229 +0,0 @@ -diff -up dhcp-4.2.0/server/dhcpv6.c.UseMulticast dhcp-4.2.0/server/dhcpv6.c ---- dhcp-4.2.0/server/dhcpv6.c.UseMulticast 2010-06-01 19:30:00.000000000 +0200 -+++ dhcp-4.2.0/server/dhcpv6.c 2010-07-21 16:17:30.000000000 +0200 -@@ -346,6 +346,48 @@ generate_new_server_duid(void) { - } - - /* -+ * Is the D6O_UNICAST option defined in dhcpd.conf ? -+ */ -+static isc_boolean_t unicast_option_defined; -+ -+/* -+ * Did we already search dhcpd.conf for D6O_UNICAST option ? -+ * We need to store it here to not parse dhcpd.conf repeatedly. -+ */ -+static isc_boolean_t unicast_option_parsed = ISC_FALSE; -+ -+ -+/* -+ * Is the D6O_UNICAST option defined in dhcpd.conf ? -+ */ -+isc_boolean_t -+is_unicast_option_defined(void) { -+ struct option_state *opt_state; -+ struct option_cache *oc; -+ -+ /* -+ * If we are looking for the unicast option for the first time -+ */ -+ if (unicast_option_parsed == ISC_FALSE) { -+ unicast_option_parsed = ISC_TRUE; -+ opt_state = NULL; -+ if (!option_state_allocate(&opt_state, MDL)) { -+ log_fatal("No memory for option state."); -+ } -+ -+ execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL, -+ opt_state, &global_scope, root_group, NULL); -+ -+ oc = lookup_option(&dhcpv6_universe, opt_state, D6O_UNICAST); -+ unicast_option_defined = (oc != NULL); -+ -+ option_state_dereference(&opt_state, MDL); -+ } -+ -+ return (unicast_option_defined); -+} -+ -+/* - * Get the client identifier from the packet. - */ - isc_result_t -@@ -1405,6 +1447,56 @@ lease_to_client(struct data_string *repl - reply.shared->group); - } - -+ /* reject unicast message, unless we set unicast option */ -+ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined()) -+ /* -+ * RFC3315 section 18.2.1 (Request): -+ * -+ * When the server receives a Request message via unicast from a client -+ * to which the server has not sent a unicast option, the server -+ * discards the Request message and responds with a Reply message -+ * containing a Status Code option with the value UseMulticast, a Server -+ * Identifier option containing the server's DUID, the Client Identifier -+ * option from the client message, and no other options. -+ * -+ * Section 18.2.3 (Renew): -+ * -+ * When the server receives a Renew message via unicast from a client to -+ * which the server has not sent a unicast option, the server discards -+ * the Renew message and responds with a Reply message containing a -+ * Status Code option with the value UseMulticast, a Server Identifier -+ * option containing the server's DUID, the Client Identifier option -+ * from the client message, and no other options. -+ */ -+ { -+ /* Set the UseMulticast status code. */ -+ if (!set_status_code(STATUS_UseMulticast, -+ "Unicast not allowed by server.", -+ reply.opt_state)) { -+ log_error("lease_to_client: Unable to set " -+ "UseMulticast status code."); -+ goto exit; -+ } -+ -+ /* Rewind the cursor to the start. */ -+ reply.cursor = REPLY_OPTIONS_INDEX; -+ -+ /* -+ * Produce an reply that includes only: -+ * -+ * Status code. -+ * Server DUID. -+ * Client DUID. -+ */ -+ reply.cursor += store_options6((char *)reply.buf.data + -+ reply.cursor, -+ sizeof(reply.buf) - -+ reply.cursor, -+ reply.opt_state, reply.packet, -+ required_opts_NAA, -+ NULL); -+ } else if (no_resources_avail && (reply.ia_count != 0) && -+ (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) - /* - * RFC3315 section 17.2.2 (Solicit): - * -@@ -1429,8 +1521,6 @@ lease_to_client(struct data_string *repl - * the server. - * Sends a Renew/Rebind if the IA is not in the Reply message. - */ -- if (no_resources_avail && (reply.ia_count != 0) && -- (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) - { - /* Set the NoAddrsAvail status code. */ - if (!set_status_code(STATUS_NoAddrsAvail, -@@ -4128,7 +4218,6 @@ dhcpv6_solicit(struct data_string *reply - * Very similar to Solicit handling, except the server DUID is required. - */ - --/* TODO: reject unicast messages, unless we set unicast option */ - static void - dhcpv6_request(struct data_string *reply_ret, struct packet *packet) { - struct data_string client_id; -@@ -4443,7 +4532,6 @@ exit: - * except for the error code of when addresses don't match. - */ - --/* TODO: reject unicast messages, unless we set unicast option */ - static void - dhcpv6_renew(struct data_string *reply, struct packet *packet) { - struct data_string client_id; -@@ -4688,18 +4776,60 @@ iterate_over_ia_na(struct data_string *r - goto exit; - } - -- snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type); -- if (!set_status_code(STATUS_Success, status_msg, opt_state)) { -- goto exit; -- } -+ /* reject unicast message, unless we set unicast option */ -+ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined()) { -+ /* -+ * RFC3315 section 18.2.6 (Release): -+ * -+ * When the server receives a Release message via unicast from a client -+ * to which the server has not sent a unicast option, the server -+ * discards the Release message and responds with a Reply message -+ * containing a Status Code option with value UseMulticast, a Server -+ * Identifier option containing the server's DUID, the Client Identifier -+ * option from the client message, and no other options. -+ * -+ * Section 18.2.7 (Decline): -+ * -+ * When the server receives a Decline message via unicast from a client -+ * to which the server has not sent a unicast option, the server -+ * discards the Decline message and responds with a Reply message -+ * containing a Status Code option with the value UseMulticast, a Server -+ * Identifier option containing the server's DUID, the Client Identifier -+ * option from the client message, and no other options. -+ */ -+ snprintf(status_msg, sizeof(status_msg), -+ "%s received unicast.", packet_type); -+ if (!set_status_code(STATUS_UseMulticast, status_msg, opt_state)) { -+ goto exit; -+ } - -- /* -- * Add our options that are not associated with any IA_NA or IA_TA. -- */ -- reply_ofs += store_options6(reply_data+reply_ofs, -- sizeof(reply_data)-reply_ofs, -+ /* -+ * Produce an reply that includes only: -+ * -+ * Status code. -+ * Server DUID. -+ * Client DUID. -+ */ -+ reply_ofs += store_options6(reply_data+reply_ofs, -+ sizeof(reply_data)-reply_ofs, - opt_state, packet, -- required_opts, NULL); -+ required_opts_NAA, NULL); -+ -+ goto return_reply; -+ } else { -+ snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type); -+ if (!set_status_code(STATUS_Success, status_msg, opt_state)) { -+ goto exit; -+ } -+ -+ /* -+ * Add our options that are not associated with any IA_NA or IA_TA. -+ */ -+ reply_ofs += store_options6(reply_data+reply_ofs, -+ sizeof(reply_data)-reply_ofs, -+ opt_state, packet, -+ required_opts, NULL); -+ } - - /* - * Loop through the IA_NA reported by the client, and deal with -@@ -4838,6 +4968,7 @@ iterate_over_ia_na(struct data_string *r - /* - * Return our reply to the caller. - */ -+return_reply: - reply_ret->len = reply_ofs; - reply_ret->buffer = NULL; - if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) { -@@ -4883,7 +5014,6 @@ exit: - * we still need to be aware of this possibility. - */ - --/* TODO: reject unicast messages, unless we set unicast option */ - /* TODO: IA_TA */ - static void - dhcpv6_decline(struct data_string *reply, struct packet *packet) { -@@ -5355,7 +5485,6 @@ exit: - * Release means a client is done with the leases. - */ - --/* TODO: reject unicast messages, unless we set unicast option */ - static void - dhcpv6_release(struct data_string *reply, struct packet *packet) { - struct data_string client_id; diff --git a/dhcp-4.2.0-noprefixavail.patch b/dhcp-4.2.0-noprefixavail.patch deleted file mode 100644 index 729a172..0000000 --- a/dhcp-4.2.0-noprefixavail.patch +++ /dev/null @@ -1,140 +0,0 @@ -diff -up dhcp-4.2.0/server/dhcpv6.c.noprefixavail dhcp-4.2.0/server/dhcpv6.c ---- dhcp-4.2.0/server/dhcpv6.c.noprefixavail 2010-10-07 13:48:45.000000000 +0200 -+++ dhcp-4.2.0/server/dhcpv6.c 2010-10-13 11:00:25.000000000 +0200 -@@ -1134,7 +1134,7 @@ try_client_v6_prefix(struct iasubopt **p - return DHCP_R_INVALIDARG; - } - tmp_plen = (int) requested_pref->data[0]; -- if ((tmp_plen < 3) || (tmp_plen > 128)) { -+ if ((tmp_plen < 3) || (tmp_plen > 128) ||((int)tmp_plen != pool->units)) { - return ISC_R_FAILURE; - } - memcpy(&tmp_pref, requested_pref->data + 1, sizeof(tmp_pref)); -@@ -1147,9 +1147,8 @@ try_client_v6_prefix(struct iasubopt **p - return ISC_R_FAILURE; - } - -- if (((int)tmp_plen != pool->units) || -- !ipv6_in_pool(&tmp_pref, pool)) { -- return ISC_R_FAILURE; -+ if (!ipv6_in_pool(&tmp_pref, pool)) { -+ return ISC_R_ADDRNOTAVAIL; - } - - if (prefix6_exists(pool, &tmp_pref, tmp_plen)) { -@@ -1409,13 +1408,6 @@ lease_to_client(struct data_string *repl - if ((status != ISC_R_SUCCESS) && - (status != ISC_R_NORESOURCES)) - goto exit; -- -- /* -- * If any prefix cannot be given to any IA_PD, then -- * set the NoPrefixAvail status code. -- */ -- if (reply.client_resources == 0) -- no_resources_avail = ISC_TRUE; - } - - /* -@@ -1549,36 +1541,6 @@ lease_to_client(struct data_string *repl - reply.opt_state, reply.packet, - required_opts_NAA, - NULL); -- } else if (no_resources_avail && (reply.ia_count == 0) && -- (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) -- { -- /* Set the NoPrefixAvail status code. */ -- if (!set_status_code(STATUS_NoPrefixAvail, -- "No prefixes available for this " -- "interface.", reply.opt_state)) { -- log_error("lease_to_client: Unable to set " -- "NoPrefixAvail status code."); -- goto exit; -- } -- -- /* Rewind the cursor to the start. */ -- reply.cursor = REPLY_OPTIONS_INDEX; -- -- /* -- * Produce an advertise that includes only: -- * -- * Status code. -- * Server DUID. -- * Client DUID. -- */ -- reply.buf.reply.msg_type = DHCPV6_ADVERTISE; -- reply.cursor += store_options6((char *)reply.buf.data + -- reply.cursor, -- sizeof(reply.buf) - -- reply.cursor, -- reply.opt_state, reply.packet, -- required_opts_NAA, -- NULL); - } else { - /* - * Having stored the client's IA's, store any options that -@@ -2793,16 +2755,18 @@ find_client_temporaries(struct reply_sta - */ - static isc_result_t - reply_process_try_addr(struct reply_state *reply, struct iaddr *addr) { -- isc_result_t status = ISC_R_NORESOURCES; -+ isc_result_t status = ISC_R_ADDRNOTAVAIL; - struct ipv6_pool *pool; - int i; - struct data_string data_addr; - - if ((reply == NULL) || (reply->shared == NULL) || -- (reply->shared->ipv6_pools == NULL) || (addr == NULL) || -- (reply->lease != NULL)) -+ (addr == NULL) || (reply->lease != NULL)) - return DHCP_R_INVALIDARG; - -+ if (reply->shared->ipv6_pools == NULL) -+ return ISC_R_ADDRNOTAVAIL; -+ - memset(&data_addr, 0, sizeof(data_addr)); - data_addr.len = addr->len; - data_addr.data = addr->iabuf; -@@ -3314,7 +3278,9 @@ reply_process_ia_pd(struct reply_state * - if (status == ISC_R_CANCELED) - break; - -- if ((status != ISC_R_SUCCESS) && (status != ISC_R_ADDRINUSE)) -+ if ((status != ISC_R_SUCCESS) && -+ (status != ISC_R_ADDRINUSE) && -+ (status != ISC_R_ADDRNOTAVAIL)) - goto cleanup; - } - -@@ -3594,7 +3560,8 @@ reply_process_prefix(struct reply_state - - /* Either error out or skip this prefix. */ - if ((status != ISC_R_SUCCESS) && -- (status != ISC_R_ADDRINUSE)) -+ (status != ISC_R_ADDRINUSE) && -+ (status != ISC_R_ADDRNOTAVAIL)) - goto cleanup; - - if (reply->lease == NULL) { -@@ -3773,16 +3740,18 @@ prefix_is_owned(struct reply_state *repl - static isc_result_t - reply_process_try_prefix(struct reply_state *reply, - struct iaddrcidrnet *pref) { -- isc_result_t status = ISC_R_NORESOURCES; -+ isc_result_t status = ISC_R_ADDRNOTAVAIL; - struct ipv6_pool *pool; - int i; - struct data_string data_pref; - - if ((reply == NULL) || (reply->shared == NULL) || -- (reply->shared->ipv6_pools == NULL) || (pref == NULL) || -- (reply->lease != NULL)) -+ (pref == NULL) || (reply->lease != NULL)) - return DHCP_R_INVALIDARG; - -+ if (reply->shared->ipv6_pools == NULL) -+ return ISC_R_ADDRNOTAVAIL; -+ - memset(&data_pref, 0, sizeof(data_pref)); - data_pref.len = 17; - if (!buffer_allocate(&data_pref.buffer, data_pref.len, MDL)) { diff --git a/dhcp-4.2.0-unicast-bootp.patch b/dhcp-4.2.0-unicast-bootp.patch deleted file mode 100644 index 78bc078..0000000 --- a/dhcp-4.2.0-unicast-bootp.patch +++ /dev/null @@ -1,99 +0,0 @@ -diff -up dhcp-4.2.0/server/bootp.c.unicast dhcp-4.2.0/server/bootp.c ---- dhcp-4.2.0/server/bootp.c.unicast 2009-11-20 02:49:03.000000000 +0100 -+++ dhcp-4.2.0/server/bootp.c 2010-07-21 13:40:25.000000000 +0200 -@@ -58,6 +58,7 @@ void bootp (packet) - char msgbuf [1024]; - int ignorep; - int peer_has_leases = 0; -+ int norelay = 0; - - if (packet -> raw -> op != BOOTREQUEST) - return; -@@ -73,7 +74,7 @@ void bootp (packet) - ? inet_ntoa (packet -> raw -> giaddr) - : packet -> interface -> name); - -- if (!locate_network (packet)) { -+ if ((norelay = locate_network (packet)) == 0) { - log_info ("%s: network unknown", msgbuf); - return; - } -@@ -390,6 +391,13 @@ void bootp (packet) - from, &to, &hto); - goto out; - } -+ } else if (norelay == 2) { -+ to.sin_addr = raw.ciaddr; -+ to.sin_port = remote_port; -+ if (fallback_interface) { -+ result = send_packet (fallback_interface, (struct packet *)0, &raw, outgoing.packet_length, from, &to, &hto); -+ goto out; -+ } - - /* If it comes from a client that already knows its address - and is not requesting a broadcast response, and we can -diff -up dhcp-4.2.0/server/dhcp.c.unicast dhcp-4.2.0/server/dhcp.c ---- dhcp-4.2.0/server/dhcp.c.unicast 2010-06-01 19:29:59.000000000 +0200 -+++ dhcp-4.2.0/server/dhcp.c 2010-07-21 13:40:25.000000000 +0200 -@@ -4185,6 +4185,7 @@ int locate_network (packet) - struct data_string data; - struct subnet *subnet = (struct subnet *)0; - struct option_cache *oc; -+ int norelay = 0; - - /* See if there's a Relay Agent Link Selection Option, or a - * Subnet Selection Option. The Link-Select and Subnet-Select -@@ -4200,12 +4201,24 @@ int locate_network (packet) - from the interface, if there is one. If not, fail. */ - if (!oc && !packet -> raw -> giaddr.s_addr) { - if (packet -> interface -> shared_network) { -- shared_network_reference -- (&packet -> shared_network, -- packet -> interface -> shared_network, MDL); -- return 1; -+ struct in_addr any_addr; -+ any_addr.s_addr = INADDR_ANY; -+ -+ if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) { -+ struct iaddr cip; -+ memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4); -+ cip.len = 4; -+ if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL)) -+ norelay = 2; -+ } -+ -+ if (!norelay) { -+ shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL); -+ return 1; -+ } -+ } else { -+ return 0; - } -- return 0; - } - - /* If there's an option indicating link connection, and it's valid, -@@ -4228,7 +4241,10 @@ int locate_network (packet) - data_string_forget (&data, MDL); - } else { - ia.len = 4; -- memcpy (ia.iabuf, &packet -> raw -> giaddr, 4); -+ if (norelay) -+ memcpy (ia.iabuf, &packet->raw->ciaddr, 4); -+ else -+ memcpy (ia.iabuf, &packet->raw->giaddr, 4); - } - - /* If we know the subnet on which the IP address lives, use it. */ -@@ -4236,7 +4252,10 @@ int locate_network (packet) - shared_network_reference (&packet -> shared_network, - subnet -> shared_network, MDL); - subnet_dereference (&subnet, MDL); -- return 1; -+ if (norelay) -+ return norelay; -+ else -+ return 1; - } - - /* Otherwise, fail. */ diff --git a/dhcp-4.2.1-64_bit_lease_parse.patch b/dhcp-4.2.1-64_bit_lease_parse.patch deleted file mode 100644 index a540bc1..0000000 --- a/dhcp-4.2.1-64_bit_lease_parse.patch +++ /dev/null @@ -1,94 +0,0 @@ -diff -up dhcp-4.2.1b1/common/dispatch.c.64-bit_lease_parse dhcp-4.2.1b1/common/dispatch.c -diff -up dhcp-4.2.1b1/common/parse.c.64-bit_lease_parse dhcp-4.2.1b1/common/parse.c ---- dhcp-4.2.1b1/common/parse.c.64-bit_lease_parse 2010-12-30 00:01:42.000000000 +0100 -+++ dhcp-4.2.1b1/common/parse.c 2011-01-28 08:01:10.000000000 +0100 -@@ -909,8 +909,8 @@ TIME - parse_date_core(cfile) - struct parse *cfile; - { -- int guess; -- int tzoff, wday, year, mon, mday, hour, min, sec; -+ TIME guess; -+ long int tzoff, wday, year, mon, mday, hour, min, sec; - const char *val; - enum dhcp_token token; - static int months[11] = { 31, 59, 90, 120, 151, 181, -@@ -936,7 +936,7 @@ parse_date_core(cfile) - } - - token = next_token(&val, NULL, cfile); /* consume number */ -- guess = atoi(val); -+ guess = atol(val); - - return((TIME)guess); - } -@@ -948,7 +948,7 @@ parse_date_core(cfile) - return((TIME)0); - } - token = next_token(&val, NULL, cfile); /* consume day of week */ -- wday = atoi(val); -+ wday = atol(val); - - /* Year... */ - token = peek_token(&val, NULL, cfile); -@@ -964,7 +964,7 @@ parse_date_core(cfile) - somebody invents a time machine, I think we can safely disregard - it. This actually works around a stupid Y2K bug that was present - in a very early beta release of dhcpd. */ -- year = atoi(val); -+ year = atol(val); - if (year > 1900) - year -= 1900; - -@@ -988,7 +988,7 @@ parse_date_core(cfile) - return((TIME)0); - } - token = next_token(&val, NULL, cfile); /* consume month */ -- mon = atoi(val) - 1; -+ mon = atol(val) - 1; - - /* Slash separating month from day... */ - token = peek_token(&val, NULL, cfile); -@@ -1010,7 +1010,7 @@ parse_date_core(cfile) - return((TIME)0); - } - token = next_token(&val, NULL, cfile); /* consume day of month */ -- mday = atoi(val); -+ mday = atol(val); - - /* Hour... */ - token = peek_token(&val, NULL, cfile); -@@ -1021,7 +1021,7 @@ parse_date_core(cfile) - return((TIME)0); - } - token = next_token(&val, NULL, cfile); /* consume hour */ -- hour = atoi(val); -+ hour = atol(val); - - /* Colon separating hour from minute... */ - token = peek_token(&val, NULL, cfile); -@@ -1043,7 +1043,7 @@ parse_date_core(cfile) - return((TIME)0); - } - token = next_token(&val, NULL, cfile); /* consume minute */ -- min = atoi(val); -+ min = atol(val); - - /* Colon separating minute from second... */ - token = peek_token(&val, NULL, cfile); -@@ -1065,13 +1065,13 @@ parse_date_core(cfile) - return((TIME)0); - } - token = next_token(&val, NULL, cfile); /* consume second */ -- sec = atoi(val); -+ sec = atol(val); - - tzoff = 0; - token = peek_token(&val, NULL, cfile); - if (token == NUMBER) { - token = next_token(&val, NULL, cfile); /* consume tzoff */ -- tzoff = atoi(val); -+ tzoff = atol(val); - } else if (token != SEMI) { - token = next_token(&val, NULL, cfile); - parse_warn(cfile, diff --git a/dhcp-4.2.2-improved-xid.patch b/dhcp-4.2.2-improved-xid.patch deleted file mode 100644 index f49fc78..0000000 --- a/dhcp-4.2.2-improved-xid.patch +++ /dev/null @@ -1,138 +0,0 @@ -diff -up dhcp-4.2.2/client/dhclient.c.improved-xid dhcp-4.2.2/client/dhclient.c ---- dhcp-4.2.2/client/dhclient.c.improved-xid 2011-09-16 18:18:00.649730661 +0200 -+++ dhcp-4.2.2/client/dhclient.c 2011-09-16 18:22:36.815035513 +0200 -@@ -898,6 +898,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 -@@ -912,14 +932,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) { -@@ -1457,7 +1499,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) { -@@ -2174,7 +2216,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) -@@ -2300,10 +2342,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, -@@ -2584,10 +2626,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) -@@ -2618,10 +2660,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, -@@ -2661,10 +2703,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, diff --git a/dhcp-4.2.2-lpf-ib.patch b/dhcp-4.2.2-lpf-ib.patch deleted file mode 100644 index 4034028..0000000 --- a/dhcp-4.2.2-lpf-ib.patch +++ /dev/null @@ -1,538 +0,0 @@ -diff -up dhcp-4.2.2/client/dhclient.c.lpf-ib dhcp-4.2.2/client/dhclient.c ---- dhcp-4.2.2/client/dhclient.c.lpf-ib 2011-09-19 11:24:08.693775799 +0200 -+++ dhcp-4.2.2/client/dhclient.c 2011-09-19 11:24:08.703775541 +0200 -@@ -113,6 +113,8 @@ static int check_domain_name_list(const - 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); -+ - int - main(int argc, char **argv) { - int fd; -@@ -919,6 +921,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) { -@@ -1195,6 +1205,29 @@ int find_subnet (struct subnet **sp, - return 0; - } - -+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"); -+} -+ - /* Individual States: - * - * Each routine is called from the dhclient_state_machine() in one of -diff -up dhcp-4.2.2/common/bpf.c.lpf-ib dhcp-4.2.2/common/bpf.c ---- dhcp-4.2.2/common/bpf.c.lpf-ib 2011-09-19 11:24:08.694775773 +0200 -+++ dhcp-4.2.2/common/bpf.c 2011-09-19 11:24:08.704775516 +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.2.2/common/lpf.c.lpf-ib dhcp-4.2.2/common/lpf.c ---- dhcp-4.2.2/common/lpf.c.lpf-ib 2011-09-19 11:24:08.694775773 +0200 -+++ dhcp-4.2.2/common/lpf.c 2011-09-19 11:26:15.107109935 +0200 -@@ -42,6 +42,7 @@ - #include "includes/netinet/udp.h" - #include "includes/netinet/if_ether.h" - #include -+#include - - #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) { -@@ -112,6 +133,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 || -@@ -127,8 +149,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 */ -@@ -183,6 +203,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 +222,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) -@@ -250,15 +274,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) { -@@ -315,6 +352,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; -@@ -335,6 +420,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; - -@@ -356,6 +446,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; -@@ -382,6 +508,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; -@@ -462,33 +592,44 @@ 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"); - -- sock = socket(AF_INET, SOCK_DGRAM, 0); -- if (sock < 0) { -- log_fatal("Can't create socket for \"%s\": %m", name); -+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { -+ -+ if (ifa->ifa_addr == NULL) -+ continue; -+ -+ 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 -@@ -496,18 +637,35 @@ 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; - #if defined(ARPHRD_PPP) - case ARPHRD_PPP: - if (local_family != AF_INET6) -- log_fatal("Unsupported device type %d for \"%s\"", -- sa->sa_family, name); -+ log_fatal("Unsupported device type %ld for \"%s\"", -+ (long int)sll->sll_family, name); - hw->hlen = 0; - hw->hbuf[0] = HTYPE_RESERVED; - /* 0xdeadbeef should never occur on the wire, -@@ -520,10 +678,11 @@ get_hw_addr(const char *name, struct har - break; - #endif - 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.2.2/common/socket.c.lpf-ib dhcp-4.2.2/common/socket.c ---- dhcp-4.2.2/common/socket.c.lpf-ib 2011-06-27 18:18:20.000000000 +0200 -+++ dhcp-4.2.2/common/socket.c 2011-09-19 11:24:08.705775490 +0200 -@@ -324,7 +324,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. */ -@@ -387,7 +387,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", -@@ -497,7 +497,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.2.2/includes/dhcpd.h.lpf-ib dhcp-4.2.2/includes/dhcpd.h ---- dhcp-4.2.2/includes/dhcpd.h.lpf-ib 2011-09-19 11:24:08.696775721 +0200 -+++ dhcp-4.2.2/includes/dhcpd.h 2011-09-19 11:24:08.707775438 +0200 -@@ -1243,6 +1243,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. - */ -@@ -2356,7 +2357,7 @@ void print_dns_status (int, struct dhcp_ - #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) \ -diff -up dhcp-4.2.2/includes/dhcp.h.lpf-ib dhcp-4.2.2/includes/dhcp.h ---- dhcp-4.2.2/includes/dhcp.h.lpf-ib 2011-09-19 11:24:08.696775721 +0200 -+++ dhcp-4.2.2/includes/dhcp.h 2011-09-19 11:24:08.707775438 +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 */ - - #define HTYPE_RESERVED 0 /* RFC 5494 */ - diff --git a/dhcp-4.2.2-systemtap.patch b/dhcp-4.2.2-systemtap.patch deleted file mode 100644 index 327c573..0000000 --- a/dhcp-4.2.2-systemtap.patch +++ /dev/null @@ -1,809 +0,0 @@ -diff -up dhcp-4.2.2/configure.ac.systemtap dhcp-4.2.2/configure.ac ---- dhcp-4.2.2/configure.ac.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/configure.ac 2011-10-09 20:22:23.000000000 +0200 -@@ -485,6 +485,35 @@ else - AC_MSG_RESULT(no) - fi - -+AC_MSG_CHECKING([whether to include systemtap tracing support]) -+AC_ARG_ENABLE([systemtap], -+ [AS_HELP_STRING([--enable-systemtap], -+ [Enable inclusion of systemtap trace support])], -+ [ENABLE_SYSTEMTAP="${enableval}"], [ENABLE_SYSTEMTAP='no']) -+AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test x$ENABLE_SYSTEMTAP = xyes]) -+AC_MSG_RESULT(${ENABLE_SYSTEMTAP}) -+ -+if test "x${ENABLE_SYSTEMTAP}" = xyes; then -+ # Additional configuration for --enable-systemtap is HERE -+ AC_CHECK_PROGS(DTRACE, dtrace) -+ if test -z "$DTRACE"; then -+ AC_MSG_ERROR([dtrace not found]) -+ fi -+ AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND='yes'], -+ [SDT_H_FOUND='no'; -+ AC_MSG_ERROR([systemtap support needs sys/sdt.h header])]) -+ AC_DEFINE([HAVE_SYSTEMTAP], [1], [Define to 1 if using SystemTap probes.]) -+ AC_ARG_WITH([tapset-install-dir], -+ [AS_HELP_STRING([--with-tapset-install-dir], -+ [The absolute path where the tapset dir will be installed])], -+ [if test "x${withval}" = x; then -+ ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset" -+ else -+ ABS_TAPSET_DIR="${withval}" -+ fi], [ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"]) -+ AC_SUBST(ABS_TAPSET_DIR) -+fi -+ - # Solaris needs some libraries for functions - AC_SEARCH_LIBS(socket, [socket]) - AC_SEARCH_LIBS(inet_ntoa, [nsl]) -@@ -631,6 +660,7 @@ AC_OUTPUT([ - relay/Makefile - server/Makefile - tests/Makefile -+ tapset/Makefile - ]) - - sh util/bindvar.sh -diff -up dhcp-4.2.2/Makefile.am.systemtap dhcp-4.2.2/Makefile.am ---- dhcp-4.2.2/Makefile.am.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/Makefile.am 2011-10-09 20:22:23.000000000 +0200 -@@ -29,5 +29,8 @@ endif - - SUBDIRS += includes tests common dst omapip client dhcpctl relay server - -+SUBDIRS += tapset -+#DIST_SUBDIRS = $(SUBDIRS) -+ - nobase_include_HEADERS = dhcpctl/dhcpctl.h - -diff -up dhcp-4.2.2/server/dhcp.c.systemtap dhcp-4.2.2/server/dhcp.c ---- dhcp-4.2.2/server/dhcp.c.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/server/dhcp.c 2011-10-09 20:22:23.000000000 +0200 -@@ -36,7 +36,7 @@ - #include - #include - #include -- -+#include "trace.h" - static void commit_leases_ackout(void *foo); - static void maybe_return_agent_options(struct packet *packet, - struct option_state *options); -@@ -275,6 +275,8 @@ void dhcpdiscover (packet, ms_nulltp) - dhcp_failover_state_t *peer; - #endif - -+ TRACE(DHCPD_DISCOVER_START()); -+ - find_lease (&lease, packet, packet -> shared_network, - 0, &peer_has_leases, (struct lease *)0, MDL); - -@@ -399,6 +401,8 @@ void dhcpdiscover (packet, ms_nulltp) - out: - if (lease) - lease_dereference (&lease, MDL); -+ -+ TRACE(DHCPD_DISCOVER_DONE()); - } - - void dhcprequest (packet, ms_nulltp, ip_lease) -@@ -422,6 +426,8 @@ void dhcprequest (packet, ms_nulltp, ip_ - int have_server_identifier = 0; - int have_requested_addr = 0; - -+ TRACE(DHCPD_REQUEST_START()); -+ - oc = lookup_option (&dhcp_universe, packet -> options, - DHO_DHCP_REQUESTED_ADDRESS); - memset (&data, 0, sizeof data); -@@ -679,6 +685,9 @@ void dhcprequest (packet, ms_nulltp, ip_ - log_info ("%s: unknown lease %s.", msgbuf, piaddr (cip)); - - out: -+ -+ TRACE(DHCPD_REQUEST_DONE()); -+ - if (subnet) - subnet_dereference (&subnet, MDL); - if (lease) -@@ -697,6 +706,7 @@ void dhcprelease (packet, ms_nulltp) - const char *s; - char msgbuf [1024], cstr[16]; /* XXX */ - -+ TRACE(DHCPD_RELEASE_START()); - - /* DHCPRELEASE must not specify address in requested-address - option, but old protocol specs weren't explicit about this, -@@ -821,6 +831,8 @@ void dhcprelease (packet, ms_nulltp) - #endif - if (lease) - lease_dereference (&lease, MDL); -+ -+ TRACE(DHCPD_RELEASE_DONE()); - } - - void dhcpdecline (packet, ms_nulltp) -@@ -838,6 +850,8 @@ void dhcpdecline (packet, ms_nulltp) - struct option_cache *oc; - struct data_string data; - -+ TRACE(DHCPD_DECLINE_START()); -+ - /* DHCPDECLINE must specify address. */ - if (!(oc = lookup_option (&dhcp_universe, packet -> options, - DHO_DHCP_REQUESTED_ADDRESS))) -@@ -949,6 +963,8 @@ void dhcpdecline (packet, ms_nulltp) - option_state_dereference (&options, MDL); - if (lease) - lease_dereference (&lease, MDL); -+ -+ TRACE(DHCPD_DECLINE_DONE()); - } - - void dhcpinform (packet, ms_nulltp) -@@ -970,6 +986,8 @@ void dhcpinform (packet, ms_nulltp) - struct in_addr from; - isc_boolean_t zeroed_ciaddr; - -+ TRACE(DHCPD_INFORM_START()); -+ - /* The client should set ciaddr to its IP address, but apparently - it's common for clients not to do this, so we'll use their IP - source address if they didn't set ciaddr. */ -@@ -1320,6 +1338,8 @@ void dhcpinform (packet, ms_nulltp) - from, &to, (struct hardware *)0); - if (subnet) - subnet_dereference (&subnet, MDL); -+ -+ TRACE(DHCPD_INFORM_DONE()); - } - - void nak_lease (packet, cip) -@@ -1336,6 +1356,8 @@ void nak_lease (packet, cip) - struct option_state *options = (struct option_state *)0; - struct option_cache *oc = (struct option_cache *)0; - -+ TRACE(DHCPD_NAK_LEASE_START()); -+ - option_state_allocate (&options, MDL); - memset (&outgoing, 0, sizeof outgoing); - memset (&raw, 0, sizeof raw); -@@ -1474,6 +1496,8 @@ void nak_lease (packet, cip) - errno = 0; - result = send_packet(packet->interface, packet, &raw, - outgoing.packet_length, from, &to, NULL); -+ -+ TRACE(DHCPD_NAK_LEASE_DONE()); - } - - void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp) -@@ -1515,6 +1539,8 @@ void ack_lease (packet, lease, offer, wh - if (lease -> state) - return; - -+ TRACE(DHCPD_ACK_LEASE_START()); -+ - /* Save original cltt for comparison later. */ - lease_cltt = lease->cltt; - -@@ -2877,6 +2903,8 @@ void ack_lease (packet, lease, offer, wh - #endif - dhcp_reply(lease); - } -+ -+ TRACE(DHCPD_ACK_LEASE_DONE()); - } - - /* -@@ -3029,6 +3057,8 @@ void dhcp_reply (lease) - if (!state) - log_fatal ("dhcp_reply was supplied lease with no state!"); - -+ TRACE(DHCPD_REPLY_START()); -+ - /* Compose a response for the client... */ - memset (&raw, 0, sizeof raw); - memset (&d1, 0, sizeof d1); -@@ -3236,6 +3266,8 @@ void dhcp_reply (lease) - - free_lease_state (state, MDL); - lease -> state = (struct lease_state *)0; -+ -+ TRACE(DHCPD_REPLY_DONE()); - } - - int find_lease (struct lease **lp, -@@ -3258,6 +3290,8 @@ int find_lease (struct lease **lp, - struct data_string client_identifier; - struct hardware h; - -+ TRACE(DHCPD_FIND_LEASE_START()); -+ - #if defined(FAILOVER_PROTOCOL) - /* Quick check to see if the peer has leases. */ - if (peer_has_leases) { -@@ -3985,6 +4019,9 @@ int find_lease (struct lease **lp, - #if defined (DEBUG_FIND_LEASE) - log_info ("Not returning a lease."); - #endif -+ -+ TRACE(DHCPD_FIND_LEASE_DONE()); -+ - return 0; - } - -diff -up dhcp-4.2.2/server/dhcpd.c.systemtap dhcp-4.2.2/server/dhcpd.c ---- dhcp-4.2.2/server/dhcpd.c.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/server/dhcpd.c 2011-10-09 20:24:24.000000000 +0200 -@@ -58,6 +58,8 @@ static const char url [] = - # undef group - #endif /* PARANOIA */ - -+#include "trace.h" -+ - static void usage(void); - - struct iaddr server_identifier; -@@ -859,6 +861,7 @@ main(int argc, char **argv) { - omapi_set_int_value ((omapi_object_t *)dhcp_control_object, - (omapi_object_t *)0, "state", server_running); - -+ TRACE(DHCPD_MAIN()); - /* Receive packets and dispatch them... */ - dispatch (); - -diff -up dhcp-4.2.2/server/dhcpv6.c.systemtap dhcp-4.2.2/server/dhcpv6.c ---- dhcp-4.2.2/server/dhcpv6.c.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/server/dhcpv6.c 2011-10-09 20:22:23.000000000 +0200 -@@ -15,6 +15,7 @@ - */ - - #include "dhcpd.h" -+#include "trace.h" - - #ifdef DHCPv6 - -@@ -4171,6 +4172,8 @@ static void - dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) { - struct data_string client_id; - -+ TRACE(DHCPD_6_SOLICIT_START()); -+ - /* - * Validate our input. - */ -@@ -4184,6 +4187,8 @@ dhcpv6_solicit(struct data_string *reply - * Clean up. - */ - data_string_forget(&client_id, MDL); -+ -+ TRACE(DHCPD_6_SOLICIT_DONE()); - } - - /* -@@ -4197,6 +4202,8 @@ dhcpv6_request(struct data_string *reply - struct data_string client_id; - struct data_string server_id; - -+ TRACE(DHCPD_6_REQUEST_START()); -+ - /* - * Validate our input. - */ -@@ -4214,6 +4221,8 @@ dhcpv6_request(struct data_string *reply - */ - data_string_forget(&client_id, MDL); - data_string_forget(&server_id, MDL); -+ -+ TRACE(DHCPD_6_REQUEST_DONE()); - } - - /* Find a DHCPv6 packet's shared network from hints in the packet. -@@ -4326,6 +4335,8 @@ dhcpv6_confirm(struct data_string *reply - struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data; - int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options)); - -+ TRACE(DHCPD_6_CONFIRM_START()); -+ - /* - * Basic client message validation. - */ -@@ -4512,6 +4523,8 @@ exit: - option_state_dereference(&cli_enc_opt_state, MDL); - if (opt_state != NULL) - option_state_dereference(&opt_state, MDL); -+ -+ TRACE(DHCPD_6_CONFIRM_DONE()); - } - - /* -@@ -4526,6 +4539,8 @@ dhcpv6_renew(struct data_string *reply, - struct data_string client_id; - struct data_string server_id; - -+ TRACE(DHCPD_6_RENEW_START()); -+ - /* - * Validate the request. - */ -@@ -4543,6 +4558,8 @@ dhcpv6_renew(struct data_string *reply, - */ - data_string_forget(&server_id, MDL); - data_string_forget(&client_id, MDL); -+ -+ TRACE(DHCPD_6_RENEW_DONE()); - } - - /* -@@ -4556,6 +4573,8 @@ static void - dhcpv6_rebind(struct data_string *reply, struct packet *packet) { - struct data_string client_id; - -+ TRACE(DHCPD_6_REBIND_START()); -+ - if (!valid_client_msg(packet, &client_id)) { - return; - } -@@ -4563,6 +4582,8 @@ dhcpv6_rebind(struct data_string *reply, - lease_to_client(reply, packet, &client_id, NULL); - - data_string_forget(&client_id, MDL); -+ -+ TRACE(DHCPD_6_REBIND_DONE()); - } - - static void -@@ -5009,6 +5030,8 @@ dhcpv6_decline(struct data_string *reply - struct data_string client_id; - struct data_string server_id; - -+ TRACE(DHCPD_6_DECLINE_START()); -+ - /* - * Validate our input. - */ -@@ -5029,6 +5052,8 @@ dhcpv6_decline(struct data_string *reply - - data_string_forget(&server_id, MDL); - data_string_forget(&client_id, MDL); -+ -+ TRACE(DHCPD_6_DECLINE_DONE()); - } - - static void -@@ -5479,6 +5504,8 @@ dhcpv6_release(struct data_string *reply - struct data_string client_id; - struct data_string server_id; - -+ TRACE(DHCPD_6_RELEASE_START()); -+ - /* - * Validate our input. - */ -@@ -5500,6 +5527,8 @@ dhcpv6_release(struct data_string *reply - - data_string_forget(&server_id, MDL); - data_string_forget(&client_id, MDL); -+ -+ TRACE(DHCPD_6_RELEASE_DONE()); - } - - /* -@@ -5512,6 +5541,8 @@ dhcpv6_information_request(struct data_s - struct data_string client_id; - struct data_string server_id; - -+ TRACE(DHCPD_6_INFORMATION_REQUEST_START()); -+ - /* - * Validate our input. - */ -@@ -5543,6 +5574,8 @@ dhcpv6_information_request(struct data_s - data_string_forget(&client_id, MDL); - } - data_string_forget(&server_id, MDL); -+ -+ TRACE(DHCPD_6_INFORMATION_REQUEST_DONE()); - } - - /* -@@ -5571,6 +5604,8 @@ dhcpv6_relay_forw(struct data_string *re - struct dhcpv6_relay_packet *reply; - int reply_ofs; - -+ TRACE(DHCPD_6_RELAY_FORW_START()); -+ - /* - * Initialize variables for early exit. - */ -@@ -5828,6 +5863,8 @@ exit: - if (enc_packet != NULL) { - packet_dereference(&enc_packet, MDL); - } -+ -+ TRACE(DHCPD_6_RELAY_FORW_DONE()); - } - - static void -diff -up dhcp-4.2.2/server/failover.c.systemtap dhcp-4.2.2/server/failover.c ---- dhcp-4.2.2/server/failover.c.systemtap 2011-05-11 16:21:00.000000000 +0200 -+++ dhcp-4.2.2/server/failover.c 2011-10-09 20:22:23.000000000 +0200 -@@ -35,6 +35,8 @@ - #include "dhcpd.h" - #include - -+#include "trace.h" -+ - #if defined (FAILOVER_PROTOCOL) - dhcp_failover_state_t *failover_states; - static isc_result_t do_a_failover_option (omapi_object_t *, -@@ -1711,6 +1713,8 @@ isc_result_t dhcp_failover_set_state (dh - struct lease *l; - struct timeval tv; - -+ TRACE(DHCPD_FAILOVER_SET_STATE_START(state->me.state, new_state)); -+ - /* If we're in certain states where we're sending updates, and the peer - * state changes, we need to re-schedule any pending updates just to - * be on the safe side. This results in retransmission. -@@ -1938,6 +1942,8 @@ isc_result_t dhcp_failover_set_state (dh - break; - } - -+ TRACE(DHCPD_FAILOVER_SET_STATE_DONE()); -+ - return ISC_R_SUCCESS; - } - -@@ -2420,6 +2426,8 @@ dhcp_failover_pool_dobalance(dhcp_failov - if (state -> me.state != normal) - return 0; - -+ TRACE(DHCPD_FAILOVER_POOL_DOBALANCE_START()); -+ - state->last_balance = cur_time; - - for (s = shared_networks ; s ; s = s->next) { -@@ -2580,6 +2588,8 @@ dhcp_failover_pool_dobalance(dhcp_failov - if (leases_queued) - commit_leases(); - -+ TRACE(DHCPD_FAILOVER_POOL_DOBALANCE_DONE()); -+ - return leases_queued; - } - -diff -up dhcp-4.2.2/server/Makefile.am.systemtap dhcp-4.2.2/server/Makefile.am ---- dhcp-4.2.2/server/Makefile.am.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/server/Makefile.am 2011-10-09 20:22:23.000000000 +0200 -@@ -4,7 +4,7 @@ dist_sysconf_DATA = dhcpd.conf - sbin_PROGRAMS = dhcpd - dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \ - omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c \ -- dhcpv6.c mdb6.c ldap.c ldap_casa.c -+ dhcpv6.c mdb6.c ldap.c ldap_casa.c probes.d trace.h - - dhcpd_CFLAGS = $(LDAP_CFLAGS) - dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \ -@@ -13,3 +13,13 @@ dhcpd_LDADD = ../common/libdhcp.a ../oma - man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5 - EXTRA_DIST = $(man_MANS) - -+if ENABLE_SYSTEMTAP -+BUILT_SOURCES = probes.h -+probes.h: probes.d -+ $(DTRACE) -C -h -s $< -o $@ -+ -+probes.o: probes.d -+ $(DTRACE) -C -G -s $< -o $@ -+ -+dhcpd_LDADD += probes.o -+endif -diff -up dhcp-4.2.2/server/probes.d.systemtap dhcp-4.2.2/server/probes.d ---- dhcp-4.2.2/server/probes.d.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/server/probes.d 2011-10-09 20:22:23.000000000 +0200 -@@ -0,0 +1,43 @@ -+provider dhcpd { -+ probe main(); -+ probe discover_start() -+ probe discover_done() -+ probe request_start() -+ probe request_done() -+ probe release_start() -+ probe release_done() -+ probe decline_start() -+ probe decline_done() -+ probe inform_start() -+ probe inform_done() -+ probe nak_lease_start() -+ probe nak_lease_done() -+ probe ack_lease_start() -+ probe ack_lease_done() -+ probe reply_start() -+ probe reply_done() -+ probe find_lease_start() -+ probe find_lease_done() -+ probe 6_solicit_start() -+ probe 6_solicit_done() -+ probe 6_request_start() -+ probe 6_request_done() -+ probe 6_confirm_start() -+ probe 6_confirm_done() -+ probe 6_renew_start() -+ probe 6_renew_done() -+ probe 6_rebind_start() -+ probe 6_rebind_done() -+ probe 6_decline_start() -+ probe 6_decline_done() -+ probe 6_release_start() -+ probe 6_release_done() -+ probe 6_information_request_start() -+ probe 6_information_request_done() -+ probe 6_relay_forw_start() -+ probe 6_relay_forw_done() -+ probe failover_pool_dobalance_start() -+ probe failover_pool_dobalance_done() -+ probe failover_set_state_start(int, int) /* state, new_state */ -+ probe failover_set_state_done() -+}; -diff -up dhcp-4.2.2/server/trace.h.systemtap dhcp-4.2.2/server/trace.h ---- dhcp-4.2.2/server/trace.h.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/server/trace.h 2011-10-09 20:22:23.000000000 +0200 -@@ -0,0 +1,11 @@ -+// trace.h -+ -+#include "config.h" -+#ifdef HAVE_SYSTEMTAP -+// include the generated probes header and put markers in code -+#include "probes.h" -+#define TRACE(probe) probe -+#else -+// Wrap the probe to allow it to be removed when no systemtap available -+#define TRACE(probe) -+#endif -diff -up dhcp-4.2.2/tapset/dhcpd.stp.systemtap dhcp-4.2.2/tapset/dhcpd.stp ---- dhcp-4.2.2/tapset/dhcpd.stp.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/tapset/dhcpd.stp 2011-10-09 20:22:23.000000000 +0200 -@@ -0,0 +1,212 @@ -+/* dhcpd tapset -+ Copyright (C) 2011, Red Hat Inc. -+ */ -+ -+probe dhcpd_main = process("dhcpd").mark("main") -+{ -+ probestr = sprintf("%s(locals: %s)", $$name, $$locals); -+ -+} -+ -+probe dhcpd_discover_start = process("dhcpd").mark("discover_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_discover_done = process("dhcpd").mark("discover_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_request_start = process("dhcpd").mark("request_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_request_done = process("dhcpd").mark("request_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_release_start = process("dhcpd").mark("release_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_release_done = process("dhcpd").mark("release_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_decline_start = process("dhcpd").mark("decline_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_decline_done = process("dhcpd").mark("decline_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_inform_start = process("dhcpd").mark("inform_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_inform_done = process("dhcpd").mark("inform_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_nak_lease_start = process("dhcpd").mark("nak_lease_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_nak_lease_done = process("dhcpd").mark("nak_lease_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_ack_lease_start = process("dhcpd").mark("ack_lease_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_ack_lease_done = process("dhcpd").mark("ack_lease_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_reply_start = process("dhcpd").mark("reply_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_reply_done = process("dhcpd").mark("reply_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_find_lease_start = process("dhcpd").mark("find_lease_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_find_lease_done = process("dhcpd").mark("find_lease_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_solicit_start = process("dhcpd").mark("6_solicit_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_solicit_done = process("dhcpd").mark("6_solicit_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_request_start = process("dhcpd").mark("6_request_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_request_done = process("dhcpd").mark("6_request_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_confirm_start = process("dhcpd").mark("6_confirm_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_confirm_done = process("dhcpd").mark("6_confirm_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_renew_start = process("dhcpd").mark("6_renew_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_renew_done = process("dhcpd").mark("6_renew_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_rebind_start = process("dhcpd").mark("6_rebind_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_rebind_done = process("dhcpd").mark("6_rebind_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_decline_start = process("dhcpd").mark("6_decline_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_decline_done = process("dhcpd").mark("6_decline_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_release_start = process("dhcpd").mark("6_release_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_release_done = process("dhcpd").mark("6_release_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_information_request_start = process("dhcpd").mark("6_information_request_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_information_request_done = process("dhcpd").mark("6_information_request_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_relay_forw_start = process("dhcpd").mark("6_relay_forw_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_6_relay_forw_done = process("dhcpd").mark("6_relay_forw_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_failover_pool_dobalance_start = process("dhcpd").mark("failover_pool_dobalance_start") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+probe dhcpd_failover_pool_dobalance_done = process("dhcpd").mark("failover_pool_dobalance_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -+ -+ -+probe dhcpd_failover_set_state_start = process("dhcpd").mark("failover_set_state_start") -+{ -+ state = $arg1; -+ new_state = $arg2; -+ probestr = sprintf("%s(state=%d, new_state=%d)", $$name, state, new_state); -+} -+ -+probe dhcpd_failover_set_state_done = process("dhcpd").mark("failover_set_state_done") -+{ -+ probestr = sprintf("%s", $$name); -+} -diff -up dhcp-4.2.2/tapset/Makefile.am.systemtap dhcp-4.2.2/tapset/Makefile.am ---- dhcp-4.2.2/tapset/Makefile.am.systemtap 2011-10-09 20:22:23.000000000 +0200 -+++ dhcp-4.2.2/tapset/Makefile.am 2011-10-09 20:22:23.000000000 +0200 -@@ -0,0 +1,26 @@ -+# Makefile.am for dhcp/tapset -+# Jiri Popelka -+ -+.PHONY: clean-local install-data-hook uninstall-local -+ -+# -+EXTRA_DIST = dhcpd.stp -+TAPSET_FILES = $(EXTRA_DIST) -+TAPSET_INSTALL_DIR = $(DESTDIR)@ABS_TAPSET_DIR@ -+ -+if ENABLE_SYSTEMTAP -+all-local: $(TAPSET_FILES) -+ -+clean-local: -+ -+install-data-hook: -+ $(MKDIR_P) $(TAPSET_INSTALL_DIR) -+ $(INSTALL_DATA) $(TAPSET_FILES) $(TAPSET_INSTALL_DIR) -+ -+uninstall-local: -+ @list='$(TAPSET_FILES)'; for p in $$list; do \ -+ echo " rm -f '$(TAPSET_INSTALL_DIR)/$$p'"; \ -+ rm -f "$(TAPSET_INSTALL_DIR)/$$p"; \ -+ done -+endif -+ diff --git a/dhcp-4.2.3-P2-send_release.patch b/dhcp-4.2.3-P2-send_release.patch deleted file mode 100644 index 2aa18f1..0000000 --- a/dhcp-4.2.3-P2-send_release.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff -up dhcp-4.2.3-P2/client/dhclient.c.send_release dhcp-4.2.3-P2/client/dhclient.c ---- dhcp-4.2.3-P2/client/dhclient.c.send_release 2012-03-21 19:16:16.000000000 +0100 -+++ dhcp-4.2.3-P2/client/dhclient.c 2012-03-21 19:21:39.920599903 +0100 -@@ -2749,8 +2749,8 @@ void send_release (cpp) - inet_ntoa (destination.sin_addr), - ntohs (destination.sin_port), client -> xid); - -- if (fallback_interface) -- result = send_packet (fallback_interface, -+ if (client -> interface) -+ result = send_packet (client -> interface, - (struct packet *)0, - &client -> packet, - client -> packet_length, -@@ -2758,7 +2758,7 @@ void send_release (cpp) - (struct hardware *)0); - else - /* Send out a packet. */ -- result = send_packet (client -> interface, (struct packet *)0, -+ result = send_packet (fallback_interface, (struct packet *)0, - &client -> packet, - client -> packet_length, - from, &destination, diff --git a/dhcp-4.2.3-options.patch b/dhcp-4.2.3-options.patch deleted file mode 100644 index c902e62..0000000 --- a/dhcp-4.2.3-options.patch +++ /dev/null @@ -1,391 +0,0 @@ -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 - #include - -+/* -+ * 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 and -F 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 argument can be specified"); -+ exit(1); -+ } -+ -+ if (dhcp_host_name_arg != NULL) { -+ log_error("The -F and -H 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 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 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 && \ diff --git a/dhcp-4.2.3-rfc3442-classless-static-routes.patch b/dhcp-4.2.3-rfc3442-classless-static-routes.patch deleted file mode 100644 index 5897c21..0000000 --- a/dhcp-4.2.3-rfc3442-classless-static-routes.patch +++ /dev/null @@ -1,405 +0,0 @@ -diff -up dhcp-4.2.3rc1/client/clparse.c.rfc3442 dhcp-4.2.3rc1/client/clparse.c ---- dhcp-4.2.3rc1/client/clparse.c.rfc3442 2011-10-18 18:50:11.564621939 +0200 -+++ dhcp-4.2.3rc1/client/clparse.c 2011-10-18 18:50:11.661620727 +0200 -@@ -37,7 +37,7 @@ - - struct client_config top_level_config; - --#define NUM_DEFAULT_REQUESTED_OPTS 14 -+#define NUM_DEFAULT_REQUESTED_OPTS 15 - struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1]; - - static void parse_client_default_duid(struct parse *cfile); -@@ -82,7 +82,11 @@ isc_result_t read_client_conf () - dhcp_universe.code_hash, &code, 0, MDL); - - /* 4 */ -- code = DHO_ROUTERS; -+ /* The Classless Static Routes option code MUST appear in the parameter -+ * request list prior to both the Router option code and the Static -+ * Routes option code, if present. (RFC3442) -+ */ -+ code = DHO_CLASSLESS_STATIC_ROUTES; - option_code_hash_lookup(&default_requested_options[3], - dhcp_universe.code_hash, &code, 0, MDL); - -@@ -136,6 +140,11 @@ isc_result_t read_client_conf () - option_code_hash_lookup(&default_requested_options[13], - dhcp_universe.code_hash, &code, 0, MDL); - -+ /* 15 */ -+ code = DHO_ROUTERS; -+ option_code_hash_lookup(&default_requested_options[14], -+ dhcp_universe.code_hash, &code, 0, MDL); -+ - for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) { - if (default_requested_options[code] == NULL) - log_fatal("Unable to find option definition for " -diff -up dhcp-4.2.3rc1/common/dhcp-options.5.rfc3442 dhcp-4.2.3rc1/common/dhcp-options.5 ---- dhcp-4.2.3rc1/common/dhcp-options.5.rfc3442 2011-10-18 18:50:11.550622114 +0200 -+++ dhcp-4.2.3rc1/common/dhcp-options.5 2011-10-18 18:50:11.662620715 +0200 -@@ -115,6 +115,26 @@ hexadecimal, separated by colons. For - or - option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f; - .fi -+.PP -+The -+.B destination-descriptor -+describe the IP subnet number and subnet mask -+of a particular destination using a compact encoding. This encoding -+consists of one octet describing the width of the subnet mask, -+followed by all the significant octets of the subnet number. -+The following table contains some examples of how various subnet -+number/mask combinations can be encoded: -+.nf -+.sp 1 -+Subnet number Subnet mask Destination descriptor -+0 0 0 -+10.0.0.0 255.0.0.0 8.10 -+10.0.0.0 255.255.255.0 24.10.0.0 -+10.17.0.0 255.255.0.0 16.10.17 -+10.27.129.0 255.255.255.0 24.10.27.129 -+10.229.0.128 255.255.255.128 25.10.229.0.128 -+10.198.122.47 255.255.255.255 32.10.198.122.47 -+.fi - .SH SETTING OPTION VALUES USING EXPRESSIONS - Sometimes it's helpful to be able to set the value of a DHCP option - based on some value that the client has sent. To do this, you can -@@ -931,6 +951,29 @@ dhclient-script will create routes: - .RE - .PP - .nf -+.B option \fBclassless-static-routes\fR \fIdestination-descriptor ip-address\fR -+ [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR -+.fi -+.RS 0.25i -+.PP -+This option (see RFC3442) specifies a list of classless static routes -+that the client should install in its routing cache. -+.PP -+This option can contain one or more static routes, each of which -+consists of a destination descriptor and the IP address of the router -+that should be used to reach that destination. -+.PP -+Many clients may not implement the Classless Static Routes option. -+DHCP server administrators should therefore configure their DHCP -+servers to send both a Router option and a Classless Static Routes -+option, and should specify the default router(s) both in the Router -+option and in the Classless Static Routes option. -+.PP -+If the DHCP server returns both a Classless Static Routes option and -+a Router option, the DHCP client ignores the Router option. -+.RE -+.PP -+.nf - .B option \fBstreettalk-directory-assistance-server\fR \fIip-address\fR - [\fB,\fR \fIip-address\fR...]\fB;\fR - .fi -diff -up dhcp-4.2.3rc1/common/inet.c.rfc3442 dhcp-4.2.3rc1/common/inet.c ---- dhcp-4.2.3rc1/common/inet.c.rfc3442 2011-05-11 02:47:22.000000000 +0200 -+++ dhcp-4.2.3rc1/common/inet.c 2011-10-18 18:50:11.665620676 +0200 -@@ -528,6 +528,60 @@ free_iaddrcidrnetlist(struct iaddrcidrne - return ISC_R_SUCCESS; - } - -+static const char * -+inet_ntopdd(const unsigned char *src, unsigned srclen, char *dst, size_t size) -+{ -+ char tmp[sizeof("32.255.255.255.255")]; -+ int len; -+ -+ switch (srclen) { -+ case 2: -+ len = sprintf (tmp, "%u.%u", src[0], src[1]); -+ break; -+ case 3: -+ len = sprintf (tmp, "%u.%u.%u", src[0], src[1], src[2]); -+ break; -+ case 4: -+ len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]); -+ break; -+ case 5: -+ len = sprintf (tmp, "%u.%u.%u.%u.%u", src[0], src[1], src[2], src[3], src[4]); -+ break; -+ default: -+ return NULL; -+ } -+ if (len < 0) -+ return NULL; -+ -+ if (len > size) { -+ errno = ENOSPC; -+ return NULL; -+ } -+ -+ return strcpy (dst, tmp); -+} -+ -+/* pdestdesc() turns an iaddr structure into a printable dest. descriptor */ -+const char * -+pdestdesc(const struct iaddr addr) { -+ static char pbuf[sizeof("255.255.255.255.255")]; -+ -+ if (addr.len == 0) { -+ return ""; -+ } -+ if (addr.len == 1) { -+ return "0"; -+ } -+ if ((addr.len >= 2) && (addr.len <= 5)) { -+ return inet_ntopdd(addr.iabuf, addr.len, pbuf, sizeof(pbuf)); -+ } -+ -+ log_fatal("pdestdesc():%s:%d: Invalid destination descriptor length %d.", -+ MDL, addr.len); -+ /* quell compiler warnings */ -+ return NULL; -+} -+ - /* piaddr() turns an iaddr structure into a printable address. */ - /* XXX: should use a const pointer rather than passing the structure */ - const char * -diff -up dhcp-4.2.3rc1/common/options.c.rfc3442 dhcp-4.2.3rc1/common/options.c ---- dhcp-4.2.3rc1/common/options.c.rfc3442 2011-07-20 00:22:48.000000000 +0200 -+++ dhcp-4.2.3rc1/common/options.c 2011-10-18 18:50:11.725619925 +0200 -@@ -706,7 +706,11 @@ cons_options(struct packet *inpacket, st - * packet. - */ - priority_list[priority_len++] = DHO_SUBNET_MASK; -- priority_list[priority_len++] = DHO_ROUTERS; -+ if (lookup_option(&dhcp_universe, cfg_options, -+ DHO_CLASSLESS_STATIC_ROUTES)) -+ priority_list[priority_len++] = DHO_CLASSLESS_STATIC_ROUTES; -+ else -+ priority_list[priority_len++] = DHO_ROUTERS; - priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS; - priority_list[priority_len++] = DHO_HOST_NAME; - priority_list[priority_len++] = DHO_FQDN; -@@ -1683,6 +1687,7 @@ const char *pretty_print_option (option, - const unsigned char *dp = data; - char comma; - unsigned long tval; -+ unsigned int octets = 0; - - if (emit_commas) - comma = ','; -@@ -1691,6 +1696,7 @@ const char *pretty_print_option (option, - - memset (enumbuf, 0, sizeof enumbuf); - -+ if (option->format[0] != 'R') { /* see explanation lower */ - /* Figure out the size of the data. */ - for (l = i = 0; option -> format [i]; i++, l++) { - if (l >= sizeof(fmtbuf) - 1) -@@ -1840,6 +1846,33 @@ const char *pretty_print_option (option, - if (numhunk < 0) - numhunk = 1; - -+ } else { /* option->format[i] == 'R') */ -+ /* R (destination descriptor) has variable length. -+ * We can find it only in classless static route option, -+ * so we are for sure parsing classless static route option now. -+ * We go through whole the option to check whether there are no -+ * missing/extra bytes. -+ * I didn't find out how to improve the existing code and that's the -+ * reason for this separate 'else' where I do my own checkings. -+ * I know it's little bit unsystematic, but it works. -+ */ -+ numhunk = 0; -+ numelem = 2; /* RI */ -+ fmtbuf[0]='R'; fmtbuf[1]='I'; fmtbuf[2]=0; -+ for (i =0; i < len; i = i + octets + 5) { -+ if (data[i] > 32) { /* subnet mask width */ -+ log_error ("wrong subnet mask width in destination descriptor"); -+ break; -+ } -+ numhunk++; -+ octets = ((data[i]+7) / 8); -+ } -+ if (i != len) { -+ log_error ("classless static routes option has wrong size or " -+ "there's some garbage in format"); -+ } -+ } -+ - /* Cycle through the array (or hunk) printing the data. */ - for (i = 0; i < numhunk; i++) { - for (j = 0; j < numelem; j++) { -@@ -1978,6 +2011,20 @@ const char *pretty_print_option (option, - strcpy(op, piaddr(iaddr)); - dp += 4; - break; -+ -+ case 'R': -+ if (dp[0] <= 32) -+ iaddr.len = (((dp[0]+7)/8)+1); -+ else { -+ log_error ("wrong subnet mask width in destination descriptor"); -+ return ""; -+ } -+ -+ memcpy(iaddr.iabuf, dp, iaddr.len); -+ strcpy(op, pdestdesc(iaddr)); -+ dp += iaddr.len; -+ break; -+ - case '6': - iaddr.len = 16; - memcpy(iaddr.iabuf, dp, 16); -diff -up dhcp-4.2.3rc1/common/parse.c.rfc3442 dhcp-4.2.3rc1/common/parse.c ---- dhcp-4.2.3rc1/common/parse.c.rfc3442 2011-10-18 18:50:11.609621377 +0200 -+++ dhcp-4.2.3rc1/common/parse.c 2011-10-18 18:50:11.731619852 +0200 -@@ -341,6 +341,39 @@ int parse_ip_addr (cfile, addr) - } - - /* -+ * destination-descriptor :== NUMBER DOT NUMBER | -+ * NUMBER DOT NUMBER DOT NUMBER | -+ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER | -+ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER DOT NUMBER -+ */ -+ -+int parse_destination_descriptor (cfile, addr) -+ struct parse *cfile; -+ struct iaddr *addr; -+{ -+ unsigned int mask_width, dest_dest_len; -+ addr -> len = 0; -+ if (parse_numeric_aggregate (cfile, addr -> iabuf, -+ &addr -> len, DOT, 10, 8)) { -+ mask_width = (unsigned int)addr->iabuf[0]; -+ dest_dest_len = (((mask_width+7)/8)+1); -+ if (mask_width > 32) { -+ parse_warn (cfile, -+ "subnet mask width (%u) greater than 32.", mask_width); -+ } -+ else if (dest_dest_len != addr->len) { -+ parse_warn (cfile, -+ "destination descriptor with subnet mask width %u " -+ "should have %u octets, but has %u octets.", -+ mask_width, dest_dest_len, addr->len); -+ } -+ -+ return 1; -+ } -+ return 0; -+} -+ -+/* - * Return true if every character in the string is hexadecimal. - */ - static int -@@ -700,8 +733,10 @@ unsigned char *parse_numeric_aggregate ( - if (count) { - token = peek_token (&val, (unsigned *)0, cfile); - if (token != separator) { -- if (!*max) -+ if (!*max) { -+ *max = count; - break; -+ } - if (token != RBRACE && token != LBRACE) - token = next_token (&val, - (unsigned *)0, -@@ -1624,6 +1659,9 @@ int parse_option_code_definition (cfile, - case IP_ADDRESS: - type = 'I'; - break; -+ case DESTINATION_DESCRIPTOR: -+ type = 'R'; -+ break; - case IP6_ADDRESS: - type = '6'; - break; -@@ -5372,6 +5410,15 @@ int parse_option_token (rv, cfile, fmt, - } - break; - -+ case 'R': /* destination descriptor */ -+ if (!parse_destination_descriptor (cfile, &addr)) { -+ return 0; -+ } -+ if (!make_const_data (&t, addr.iabuf, addr.len, 0, 1, MDL)) { -+ return 0; -+ } -+ break; -+ - case '6': /* IPv6 address. */ - if (!parse_ip6_addr(cfile, &addr)) { - return 0; -@@ -5632,6 +5679,13 @@ int parse_option_decl (oc, cfile) - goto exit; - len = ip_addr.len; - dp = ip_addr.iabuf; -+ goto alloc; -+ -+ case 'R': /* destination descriptor */ -+ if (!parse_destination_descriptor (cfile, &ip_addr)) -+ goto exit; -+ len = ip_addr.len; -+ dp = ip_addr.iabuf; - - alloc: - if (hunkix + len > sizeof hunkbuf) { -diff -up dhcp-4.2.3rc1/common/tables.c.rfc3442 dhcp-4.2.3rc1/common/tables.c ---- dhcp-4.2.3rc1/common/tables.c.rfc3442 2011-10-18 18:50:11.600621489 +0200 -+++ dhcp-4.2.3rc1/common/tables.c 2011-10-18 18:50:11.736619789 +0200 -@@ -51,6 +51,7 @@ HASH_FUNCTIONS (option_code, const unsig - Format codes: - - I - IPv4 address -+ R - destination descriptor (RFC3442) - 6 - IPv6 address - l - 32-bit signed integer - L - 32-bit unsigned integer -@@ -208,6 +209,7 @@ static struct option dhcp_options[] = { - { "default-url", "t", &dhcp_universe, 114, 1 }, - { "subnet-selection", "I", &dhcp_universe, 118, 1 }, - { "domain-search", "D", &dhcp_universe, 119, 1 }, -+ { "classless-static-routes", "RIA", &dhcp_universe, 121, 1 }, - { "vivco", "Evendor-class.", &dhcp_universe, 124, 1 }, - { "vivso", "Evendor.", &dhcp_universe, 125, 1 }, - #if 0 -diff -up dhcp-4.2.3rc1/includes/dhcpd.h.rfc3442 dhcp-4.2.3rc1/includes/dhcpd.h ---- dhcp-4.2.3rc1/includes/dhcpd.h.rfc3442 2011-10-18 18:50:11.561621977 +0200 -+++ dhcp-4.2.3rc1/includes/dhcpd.h 2011-10-18 18:50:11.767619401 +0200 -@@ -2665,6 +2665,7 @@ isc_result_t range2cidr(struct iaddrcidr - const struct iaddr *lo, const struct iaddr *hi); - isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result); - const char *piaddr (struct iaddr); -+const char *pdestdesc (struct iaddr); - char *piaddrmask(struct iaddr *, struct iaddr *); - char *piaddrcidr(const struct iaddr *, unsigned int); - u_int16_t validate_port(char *); -@@ -2872,6 +2873,7 @@ void parse_client_lease_declaration (str - int parse_option_decl (struct option_cache **, struct parse *); - void parse_string_list (struct parse *, struct string_list **, int); - int parse_ip_addr (struct parse *, struct iaddr *); -+int parse_destination_descriptor (struct parse *, struct iaddr *); - int parse_ip_addr_with_subnet(struct parse *, struct iaddrmatch *); - void parse_reject_statement (struct parse *, struct client_config *); - -diff -up dhcp-4.2.3rc1/includes/dhcp.h.rfc3442 dhcp-4.2.3rc1/includes/dhcp.h ---- dhcp-4.2.3rc1/includes/dhcp.h.rfc3442 2009-11-20 02:49:01.000000000 +0100 -+++ dhcp-4.2.3rc1/includes/dhcp.h 2011-10-18 18:50:11.772619339 +0200 -@@ -158,6 +158,7 @@ struct dhcp_packet { - #define DHO_ASSOCIATED_IP 92 - #define DHO_SUBNET_SELECTION 118 /* RFC3011! */ - #define DHO_DOMAIN_SEARCH 119 /* RFC3397 */ -+#define DHO_CLASSLESS_STATIC_ROUTES 121 /* RFC3442 */ - #define DHO_VIVCO_SUBOPTIONS 124 - #define DHO_VIVSO_SUBOPTIONS 125 - -diff -up dhcp-4.2.3rc1/includes/dhctoken.h.rfc3442 dhcp-4.2.3rc1/includes/dhctoken.h ---- dhcp-4.2.3rc1/includes/dhctoken.h.rfc3442 2011-10-18 18:50:11.000000000 +0200 -+++ dhcp-4.2.3rc1/includes/dhctoken.h 2011-10-18 18:50:55.753069508 +0200 -@@ -364,7 +364,8 @@ enum dhcp_token { - GETHOSTBYNAME = 665, - PRIMARY6 = 666, - SECONDARY6 = 667, -- BOOTP_BROADCAST_ALWAYS = 668 -+ BOOTP_BROADCAST_ALWAYS = 668, -+ DESTINATION_DESCRIPTOR = 669 - }; - - #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/dhcp-4.2.4-64_bit_lease_parse.patch b/dhcp-4.2.4-64_bit_lease_parse.patch new file mode 100644 index 0000000..c1b978b --- /dev/null +++ b/dhcp-4.2.4-64_bit_lease_parse.patch @@ -0,0 +1,84 @@ +diff -up dhcp-4.2.4b1/common/parse.c.64-bit_lease_parse dhcp-4.2.4b1/common/parse.c +--- dhcp-4.2.4b1/common/parse.c.64-bit_lease_parse 2012-03-09 12:28:10.000000000 +0100 ++++ dhcp-4.2.4b1/common/parse.c 2012-04-16 17:30:55.867045149 +0200 +@@ -906,8 +906,8 @@ TIME + parse_date_core(cfile) + struct parse *cfile; + { +- int guess; +- int tzoff, year, mon, mday, hour, min, sec; ++ TIME guess; ++ long int tzoff, year, mon, mday, hour, min, sec; + const char *val; + enum dhcp_token token; + static int months[11] = { 31, 59, 90, 120, 151, 181, +@@ -933,7 +933,7 @@ parse_date_core(cfile) + } + + token = next_token(&val, NULL, cfile); /* consume number */ +- guess = atoi(val); ++ guess = atol(val); + + return((TIME)guess); + } +@@ -961,7 +961,7 @@ parse_date_core(cfile) + somebody invents a time machine, I think we can safely disregard + it. This actually works around a stupid Y2K bug that was present + in a very early beta release of dhcpd. */ +- year = atoi(val); ++ year = atol(val); + if (year > 1900) + year -= 1900; + +@@ -985,7 +985,7 @@ parse_date_core(cfile) + return((TIME)0); + } + token = next_token(&val, NULL, cfile); /* consume month */ +- mon = atoi(val) - 1; ++ mon = atol(val) - 1; + + /* Slash separating month from day... */ + token = peek_token(&val, NULL, cfile); +@@ -1007,7 +1007,7 @@ parse_date_core(cfile) + return((TIME)0); + } + token = next_token(&val, NULL, cfile); /* consume day of month */ +- mday = atoi(val); ++ mday = atol(val); + + /* Hour... */ + token = peek_token(&val, NULL, cfile); +@@ -1018,7 +1018,7 @@ parse_date_core(cfile) + return((TIME)0); + } + token = next_token(&val, NULL, cfile); /* consume hour */ +- hour = atoi(val); ++ hour = atol(val); + + /* Colon separating hour from minute... */ + token = peek_token(&val, NULL, cfile); +@@ -1040,7 +1040,7 @@ parse_date_core(cfile) + return((TIME)0); + } + token = next_token(&val, NULL, cfile); /* consume minute */ +- min = atoi(val); ++ min = atol(val); + + /* Colon separating minute from second... */ + token = peek_token(&val, NULL, cfile); +@@ -1062,13 +1062,13 @@ parse_date_core(cfile) + return((TIME)0); + } + token = next_token(&val, NULL, cfile); /* consume second */ +- sec = atoi(val); ++ sec = atol(val); + + tzoff = 0; + token = peek_token(&val, NULL, cfile); + if (token == NUMBER) { + token = next_token(&val, NULL, cfile); /* consume tzoff */ +- tzoff = atoi(val); ++ tzoff = atol(val); + } else if (token != SEMI) { + token = next_token(&val, NULL, cfile); + parse_warn(cfile, diff --git a/dhcp-4.2.4-PPP.patch b/dhcp-4.2.4-PPP.patch new file mode 100644 index 0000000..edb11bf --- /dev/null +++ b/dhcp-4.2.4-PPP.patch @@ -0,0 +1,150 @@ +diff -up dhcp-4.2.4b1/client/dhc6.c.PPP dhcp-4.2.4b1/client/dhc6.c +--- dhcp-4.2.4b1/client/dhc6.c.PPP 2012-04-16 17:37:23.243618764 +0200 ++++ dhcp-4.2.4b1/client/dhc6.c 2012-04-16 17:37:23.252618638 +0200 +@@ -133,7 +133,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; +@@ -145,6 +145,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); +@@ -180,6 +189,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; + } + + /* +@@ -5130,7 +5141,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.4b1/client/dhclient.c.PPP dhcp-4.2.4b1/client/dhclient.c +--- dhcp-4.2.4b1/client/dhclient.c.PPP 2012-04-16 17:37:23.214619170 +0200 ++++ dhcp-4.2.4b1/client/dhclient.c 2012-04-16 17:37:23.254618610 +0200 +@@ -919,8 +919,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.4b1/common/bpf.c.PPP dhcp-4.2.4b1/common/bpf.c +--- dhcp-4.2.4b1/common/bpf.c.PPP 2012-04-16 17:37:23.175619716 +0200 ++++ dhcp-4.2.4b1/common/bpf.c 2012-04-16 17:37:23.255618596 +0200 +@@ -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.4b1/common/lpf.c.PPP dhcp-4.2.4b1/common/lpf.c +--- dhcp-4.2.4b1/common/lpf.c.PPP 2012-04-16 17:37:23.155619996 +0200 ++++ dhcp-4.2.4b1/common/lpf.c 2012-04-16 17:37:23.256618582 +0200 +@@ -503,6 +503,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.4b1/includes/dhcpd.h.PPP dhcp-4.2.4b1/includes/dhcpd.h +--- dhcp-4.2.4b1/includes/dhcpd.h.PPP 2012-04-16 17:37:23.239618820 +0200 ++++ dhcp-4.2.4b1/includes/dhcpd.h 2012-04-16 17:37:23.257618568 +0200 +@@ -2760,7 +2760,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.4b1/includes/dhcp.h.PPP dhcp-4.2.4b1/includes/dhcp.h +--- dhcp-4.2.4b1/includes/dhcp.h.PPP 2012-04-16 17:37:23.000000000 +0200 ++++ dhcp-4.2.4b1/includes/dhcp.h 2012-04-16 17:38:34.675618138 +0200 +@@ -85,6 +85,8 @@ struct dhcp_packet { + * is no standard for this so we + * just steal a type */ + ++#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.4b1/server/dhcpv6.c.PPP dhcp-4.2.4b1/server/dhcpv6.c +--- dhcp-4.2.4b1/server/dhcpv6.c.PPP 2012-04-16 17:37:23.218619114 +0200 ++++ dhcp-4.2.4b1/server/dhcpv6.c 2012-04-16 17:37:23.260618526 +0200 +@@ -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/dhcp-4.2.4-UseMulticast.patch b/dhcp-4.2.4-UseMulticast.patch new file mode 100644 index 0000000..d0c5dfe --- /dev/null +++ b/dhcp-4.2.4-UseMulticast.patch @@ -0,0 +1,239 @@ +diff -up dhcp-4.2.4b1/server/dhcpv6.c.UseMulticast dhcp-4.2.4b1/server/dhcpv6.c +--- dhcp-4.2.4b1/server/dhcpv6.c.UseMulticast 2012-04-11 00:14:04.000000000 +0200 ++++ dhcp-4.2.4b1/server/dhcpv6.c 2012-04-16 19:21:43.575923732 +0200 +@@ -346,6 +346,48 @@ generate_new_server_duid(void) { + } + + /* ++ * Is the D6O_UNICAST option defined in dhcpd.conf ? ++ */ ++static isc_boolean_t unicast_option_defined; ++ ++/* ++ * Did we already search dhcpd.conf for D6O_UNICAST option ? ++ * We need to store it here to not parse dhcpd.conf repeatedly. ++ */ ++static isc_boolean_t unicast_option_parsed = ISC_FALSE; ++ ++ ++/* ++ * Is the D6O_UNICAST option defined in dhcpd.conf ? ++ */ ++isc_boolean_t ++is_unicast_option_defined(void) { ++ struct option_state *opt_state; ++ struct option_cache *oc; ++ ++ /* ++ * If we are looking for the unicast option for the first time ++ */ ++ if (unicast_option_parsed == ISC_FALSE) { ++ unicast_option_parsed = ISC_TRUE; ++ opt_state = NULL; ++ if (!option_state_allocate(&opt_state, MDL)) { ++ log_fatal("No memory for option state."); ++ } ++ ++ execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL, ++ opt_state, &global_scope, root_group, NULL); ++ ++ oc = lookup_option(&dhcpv6_universe, opt_state, D6O_UNICAST); ++ unicast_option_defined = (oc != NULL); ++ ++ option_state_dereference(&opt_state, MDL); ++ } ++ ++ return (unicast_option_defined); ++} ++ ++/* + * Get the client identifier from the packet. + */ + isc_result_t +@@ -1404,6 +1446,56 @@ lease_to_client(struct data_string *repl + reply.shared->group); + } + ++ /* reject unicast message, unless we set unicast option */ ++ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined()) ++ /* ++ * RFC3315 section 18.2.1 (Request): ++ * ++ * When the server receives a Request message via unicast from a client ++ * to which the server has not sent a unicast option, the server ++ * discards the Request message and responds with a Reply message ++ * containing a Status Code option with the value UseMulticast, a Server ++ * Identifier option containing the server's DUID, the Client Identifier ++ * option from the client message, and no other options. ++ * ++ * Section 18.2.3 (Renew): ++ * ++ * When the server receives a Renew message via unicast from a client to ++ * which the server has not sent a unicast option, the server discards ++ * the Renew message and responds with a Reply message containing a ++ * Status Code option with the value UseMulticast, a Server Identifier ++ * option containing the server's DUID, the Client Identifier option ++ * from the client message, and no other options. ++ */ ++ { ++ /* Set the UseMulticast status code. */ ++ if (!set_status_code(STATUS_UseMulticast, ++ "Unicast not allowed by server.", ++ reply.opt_state)) { ++ log_error("lease_to_client: Unable to set " ++ "UseMulticast status code."); ++ goto exit; ++ } ++ ++ /* Rewind the cursor to the start. */ ++ reply.cursor = REPLY_OPTIONS_INDEX; ++ ++ /* ++ * Produce an reply that includes only: ++ * ++ * Status code. ++ * Server DUID. ++ * Client DUID. ++ */ ++ reply.cursor += store_options6((char *)reply.buf.data + ++ reply.cursor, ++ sizeof(reply.buf) - ++ reply.cursor, ++ reply.opt_state, reply.packet, ++ required_opts_NAA, ++ NULL); ++ } ++ + /* + * RFC3315 section 17.2.2 (Solicit): + * +@@ -1429,8 +1521,8 @@ lease_to_client(struct data_string *repl + * Sends a Renew/Rebind if the IA is not in the Reply message. + */ + #if defined (RFC3315_PRE_ERRATA_2010_08) +- if (no_resources_avail && (reply.ia_count != 0) && +- (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) ++ else if (no_resources_avail && (reply.ia_count != 0) && ++ (reply.packet->dhcpv6_msg_type == DHCPV6_SOLICIT)) + { + /* Set the NoAddrsAvail status code. */ + if (!set_status_code(STATUS_NoAddrsAvail, +@@ -1477,6 +1569,7 @@ lease_to_client(struct data_string *repl + * Having stored the client's IA's, store any options that + * will fit in the remaining space. + */ ++ else + reply.cursor += store_options6((char *)reply.buf.data + reply.cursor, + sizeof(reply.buf) - reply.cursor, + reply.opt_state, reply.packet, +@@ -4126,7 +4219,6 @@ dhcpv6_solicit(struct data_string *reply + * Very similar to Solicit handling, except the server DUID is required. + */ + +-/* TODO: reject unicast messages, unless we set unicast option */ + static void + dhcpv6_request(struct data_string *reply_ret, struct packet *packet) { + struct data_string client_id; +@@ -4456,7 +4548,6 @@ exit: + * except for the error code of when addresses don't match. + */ + +-/* TODO: reject unicast messages, unless we set unicast option */ + static void + dhcpv6_renew(struct data_string *reply, struct packet *packet) { + struct data_string client_id; +@@ -4700,18 +4791,60 @@ iterate_over_ia_na(struct data_string *r + goto exit; + } + +- snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type); +- if (!set_status_code(STATUS_Success, status_msg, opt_state)) { +- goto exit; +- } ++ /* reject unicast message, unless we set unicast option */ ++ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined()) { ++ /* ++ * RFC3315 section 18.2.6 (Release): ++ * ++ * When the server receives a Release message via unicast from a client ++ * to which the server has not sent a unicast option, the server ++ * discards the Release message and responds with a Reply message ++ * containing a Status Code option with value UseMulticast, a Server ++ * Identifier option containing the server's DUID, the Client Identifier ++ * option from the client message, and no other options. ++ * ++ * Section 18.2.7 (Decline): ++ * ++ * When the server receives a Decline message via unicast from a client ++ * to which the server has not sent a unicast option, the server ++ * discards the Decline message and responds with a Reply message ++ * containing a Status Code option with the value UseMulticast, a Server ++ * Identifier option containing the server's DUID, the Client Identifier ++ * option from the client message, and no other options. ++ */ ++ snprintf(status_msg, sizeof(status_msg), ++ "%s received unicast.", packet_type); ++ if (!set_status_code(STATUS_UseMulticast, status_msg, opt_state)) { ++ goto exit; ++ } + +- /* +- * Add our options that are not associated with any IA_NA or IA_TA. +- */ +- reply_ofs += store_options6(reply_data+reply_ofs, +- sizeof(reply_data)-reply_ofs, ++ /* ++ * Produce an reply that includes only: ++ * ++ * Status code. ++ * Server DUID. ++ * Client DUID. ++ */ ++ reply_ofs += store_options6(reply_data+reply_ofs, ++ sizeof(reply_data)-reply_ofs, + opt_state, packet, +- required_opts, NULL); ++ required_opts_NAA, NULL); ++ ++ goto return_reply; ++ } else { ++ snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type); ++ if (!set_status_code(STATUS_Success, status_msg, opt_state)) { ++ goto exit; ++ } ++ ++ /* ++ * Add our options that are not associated with any IA_NA or IA_TA. ++ */ ++ reply_ofs += store_options6(reply_data+reply_ofs, ++ sizeof(reply_data)-reply_ofs, ++ opt_state, packet, ++ required_opts, NULL); ++ } + + /* + * Loop through the IA_NA reported by the client, and deal with +@@ -4849,6 +4982,7 @@ iterate_over_ia_na(struct data_string *r + /* + * Return our reply to the caller. + */ ++return_reply: + reply_ret->len = reply_ofs; + reply_ret->buffer = NULL; + if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) { +@@ -4894,7 +5028,6 @@ exit: + * we still need to be aware of this possibility. + */ + +-/* TODO: reject unicast messages, unless we set unicast option */ + /* TODO: IA_TA */ + static void + dhcpv6_decline(struct data_string *reply, struct packet *packet) { +@@ -5364,7 +5497,6 @@ exit: + * Release means a client is done with the leases. + */ + +-/* TODO: reject unicast messages, unless we set unicast option */ + static void + dhcpv6_release(struct data_string *reply, struct packet *packet) { + struct data_string client_id; diff --git a/dhcp-4.2.4-improved-xid.patch b/dhcp-4.2.4-improved-xid.patch new file mode 100644 index 0000000..f353fb0 --- /dev/null +++ b/dhcp-4.2.4-improved-xid.patch @@ -0,0 +1,138 @@ +diff -up dhcp-4.2.4b1/client/dhclient.c.improved-xid dhcp-4.2.4b1/client/dhclient.c +--- dhcp-4.2.4b1/client/dhclient.c.improved-xid 2012-04-16 17:42:37.444217424 +0200 ++++ dhcp-4.2.4b1/client/dhclient.c 2012-04-16 17:45:32.105770755 +0200 +@@ -888,6 +888,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 +@@ -902,14 +922,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) { +@@ -1447,7 +1489,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) { +@@ -2164,7 +2206,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) +@@ -2290,10 +2332,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, NULL, &client->packet, +@@ -2577,10 +2619,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) { +@@ -2620,10 +2662,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, NULL, &client->packet, +@@ -2666,10 +2708,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, diff --git a/dhcp-4.2.4-lpf-ib.patch b/dhcp-4.2.4-lpf-ib.patch new file mode 100644 index 0000000..7511691 --- /dev/null +++ b/dhcp-4.2.4-lpf-ib.patch @@ -0,0 +1,527 @@ +diff -up dhcp-4.2.4b1/client/dhclient.c.lpf-ib dhcp-4.2.4b1/client/dhclient.c +--- dhcp-4.2.4b1/client/dhclient.c.lpf-ib 2012-04-16 17:41:56.866785839 +0200 ++++ dhcp-4.2.4b1/client/dhclient.c 2012-04-16 17:41:56.879785657 +0200 +@@ -113,6 +113,8 @@ static int check_domain_name_list(const + 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); ++ + int + main(int argc, char **argv) { + int fd; +@@ -909,6 +911,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) { +@@ -1185,6 +1195,29 @@ int find_subnet (struct subnet **sp, + return 0; + } + ++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"); ++} ++ + /* Individual States: + * + * Each routine is called from the dhclient_state_machine() in one of +diff -up dhcp-4.2.4b1/common/bpf.c.lpf-ib dhcp-4.2.4b1/common/bpf.c +--- dhcp-4.2.4b1/common/bpf.c.lpf-ib 2012-04-16 17:41:56.867785825 +0200 ++++ dhcp-4.2.4b1/common/bpf.c 2012-04-16 17:41:56.879785657 +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.2.4b1/common/lpf.c.lpf-ib dhcp-4.2.4b1/common/lpf.c +--- dhcp-4.2.4b1/common/lpf.c.lpf-ib 2012-04-16 17:41:56.867785825 +0200 ++++ dhcp-4.2.4b1/common/lpf.c 2012-04-16 17:41:56.880785643 +0200 +@@ -42,6 +42,7 @@ + #include "includes/netinet/udp.h" + #include "includes/netinet/if_ether.h" + #include ++#include + + #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) { +@@ -112,6 +133,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 || +@@ -127,8 +149,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 */ +@@ -183,6 +203,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 +222,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) +@@ -250,15 +274,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) { +@@ -315,6 +352,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; +@@ -335,6 +420,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; + +@@ -356,6 +446,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; +@@ -382,6 +508,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; +@@ -462,33 +592,44 @@ 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"); + +- sock = socket(AF_INET, SOCK_DGRAM, 0); +- if (sock < 0) { +- log_fatal("Can't create socket for \"%s\": %m", name); ++ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) { ++ ++ if (ifa->ifa_addr == NULL) ++ continue; ++ ++ 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 +@@ -496,18 +637,35 @@ 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; + #if defined(ARPHRD_PPP) + case ARPHRD_PPP: + if (local_family != AF_INET6) +- log_fatal("Unsupported device type %d for \"%s\"", +- sa->sa_family, name); ++ log_fatal("Unsupported device type %ld for \"%s\"", ++ (long int)sll->sll_family, name); + hw->hlen = 0; + hw->hbuf[0] = HTYPE_RESERVED; + /* 0xdeadbeef should never occur on the wire, +@@ -520,10 +678,11 @@ get_hw_addr(const char *name, struct har + break; + #endif + 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.2.4b1/common/socket.c.lpf-ib dhcp-4.2.4b1/common/socket.c +--- dhcp-4.2.4b1/common/socket.c.lpf-ib 2012-03-09 12:28:11.000000000 +0100 ++++ dhcp-4.2.4b1/common/socket.c 2012-04-16 17:41:56.880785643 +0200 +@@ -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 + 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.2.4b1/includes/dhcpd.h.lpf-ib dhcp-4.2.4b1/includes/dhcpd.h +--- dhcp-4.2.4b1/includes/dhcpd.h.lpf-ib 2012-04-16 17:41:56.869785797 +0200 ++++ dhcp-4.2.4b1/includes/dhcpd.h 2012-04-16 17:41:56.882785615 +0200 +@@ -1243,6 +1243,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. + */ +@@ -2360,7 +2361,7 @@ void print_dns_status (int, struct dhcp_ + #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) \ diff --git a/dhcp-4.2.4-options.patch b/dhcp-4.2.4-options.patch new file mode 100644 index 0000000..b0080e1 --- /dev/null +++ b/dhcp-4.2.4-options.patch @@ -0,0 +1,391 @@ +diff -up dhcp-4.2.4b1/client/clparse.c.options dhcp-4.2.4b1/client/clparse.c +--- dhcp-4.2.4b1/client/clparse.c.options 2012-03-09 12:28:10.000000000 +0100 ++++ dhcp-4.2.4b1/client/clparse.c 2012-04-16 17:24:58.794047046 +0200 +@@ -154,6 +154,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) +@@ -320,7 +321,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; +@@ -739,6 +741,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.4b1/client/dhclient.c.options dhcp-4.2.4b1/client/dhclient.c +--- dhcp-4.2.4b1/client/dhclient.c.options 2012-04-11 22:43:24.000000000 +0200 ++++ dhcp-4.2.4b1/client/dhclient.c 2012-04-16 17:24:58.795047032 +0200 +@@ -39,6 +39,12 @@ + #include + #include + ++/* ++ * 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 and -F 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 argument can be specified"); ++ exit(1); ++ } ++ ++ if (dhcp_host_name_arg != NULL) { ++ log_error("The -F and -H 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 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 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(); + +@@ -2421,7 +2671,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); +@@ -2505,7 +2756,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); +@@ -2567,7 +2820,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.4b1/common/conflex.c.options dhcp-4.2.4b1/common/conflex.c +--- dhcp-4.2.4b1/common/conflex.c.options 2012-02-16 22:09:14.000000000 +0100 ++++ dhcp-4.2.4b1/common/conflex.c 2012-04-16 17:24:58.796047018 +0200 +@@ -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.4b1/includes/dhcpd.h.options dhcp-4.2.4b1/includes/dhcpd.h +--- dhcp-4.2.4b1/includes/dhcpd.h.options 2012-04-10 02:55:06.000000000 +0200 ++++ dhcp-4.2.4b1/includes/dhcpd.h 2012-04-16 17:24:58.797047004 +0200 +@@ -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.4b1/includes/dhctoken.h.options dhcp-4.2.4b1/includes/dhctoken.h +--- dhcp-4.2.4b1/includes/dhctoken.h.options 2012-02-16 22:09:15.000000000 +0100 ++++ dhcp-4.2.4b1/includes/dhctoken.h 2012-04-16 17:25:53.819276248 +0200 +@@ -364,7 +364,8 @@ enum dhcp_token { + GETHOSTBYNAME = 665, + PRIMARY6 = 666, + SECONDARY6 = 667, +- TOKEN_INFINIBAND = 668 ++ TOKEN_INFINIBAND = 668, ++ BOOTP_BROADCAST_ALWAYS = 669 + }; + + #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/dhcp-4.2.4-rfc3442-classless-static-routes.patch b/dhcp-4.2.4-rfc3442-classless-static-routes.patch new file mode 100644 index 0000000..a2fe219 --- /dev/null +++ b/dhcp-4.2.4-rfc3442-classless-static-routes.patch @@ -0,0 +1,405 @@ +diff -up dhcp-4.2.4b1/client/clparse.c.rfc3442 dhcp-4.2.4b1/client/clparse.c +--- dhcp-4.2.4b1/client/clparse.c.rfc3442 2012-04-16 17:34:27.546079944 +0200 ++++ dhcp-4.2.4b1/client/clparse.c 2012-04-16 17:34:27.605079118 +0200 +@@ -37,7 +37,7 @@ + + struct client_config top_level_config; + +-#define NUM_DEFAULT_REQUESTED_OPTS 14 ++#define NUM_DEFAULT_REQUESTED_OPTS 15 + struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 1]; + + static void parse_client_default_duid(struct parse *cfile); +@@ -90,7 +90,11 @@ isc_result_t read_client_conf () + dhcp_universe.code_hash, &code, 0, MDL); + + /* 4 */ +- code = DHO_ROUTERS; ++ /* The Classless Static Routes option code MUST appear in the parameter ++ * request list prior to both the Router option code and the Static ++ * Routes option code, if present. (RFC3442) ++ */ ++ code = DHO_CLASSLESS_STATIC_ROUTES; + option_code_hash_lookup(&default_requested_options[3], + dhcp_universe.code_hash, &code, 0, MDL); + +@@ -144,6 +148,11 @@ isc_result_t read_client_conf () + option_code_hash_lookup(&default_requested_options[13], + dhcp_universe.code_hash, &code, 0, MDL); + ++ /* 15 */ ++ code = DHO_ROUTERS; ++ option_code_hash_lookup(&default_requested_options[14], ++ dhcp_universe.code_hash, &code, 0, MDL); ++ + for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) { + if (default_requested_options[code] == NULL) + log_fatal("Unable to find option definition for " +diff -up dhcp-4.2.4b1/common/dhcp-options.5.rfc3442 dhcp-4.2.4b1/common/dhcp-options.5 +--- dhcp-4.2.4b1/common/dhcp-options.5.rfc3442 2012-04-16 17:34:27.537080070 +0200 ++++ dhcp-4.2.4b1/common/dhcp-options.5 2012-04-16 17:34:27.606079104 +0200 +@@ -115,6 +115,26 @@ hexadecimal, separated by colons. For + or + option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f; + .fi ++.PP ++The ++.B destination-descriptor ++describe the IP subnet number and subnet mask ++of a particular destination using a compact encoding. This encoding ++consists of one octet describing the width of the subnet mask, ++followed by all the significant octets of the subnet number. ++The following table contains some examples of how various subnet ++number/mask combinations can be encoded: ++.nf ++.sp 1 ++Subnet number Subnet mask Destination descriptor ++0 0 0 ++10.0.0.0 255.0.0.0 8.10 ++10.0.0.0 255.255.255.0 24.10.0.0 ++10.17.0.0 255.255.0.0 16.10.17 ++10.27.129.0 255.255.255.0 24.10.27.129 ++10.229.0.128 255.255.255.128 25.10.229.0.128 ++10.198.122.47 255.255.255.255 32.10.198.122.47 ++.fi + .SH SETTING OPTION VALUES USING EXPRESSIONS + Sometimes it's helpful to be able to set the value of a DHCP option + based on some value that the client has sent. To do this, you can +@@ -931,6 +951,29 @@ dhclient-script will create routes: + .RE + .PP + .nf ++.B option \fBclassless-static-routes\fR \fIdestination-descriptor ip-address\fR ++ [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR ++.fi ++.RS 0.25i ++.PP ++This option (see RFC3442) specifies a list of classless static routes ++that the client should install in its routing cache. ++.PP ++This option can contain one or more static routes, each of which ++consists of a destination descriptor and the IP address of the router ++that should be used to reach that destination. ++.PP ++Many clients may not implement the Classless Static Routes option. ++DHCP server administrators should therefore configure their DHCP ++servers to send both a Router option and a Classless Static Routes ++option, and should specify the default router(s) both in the Router ++option and in the Classless Static Routes option. ++.PP ++If the DHCP server returns both a Classless Static Routes option and ++a Router option, the DHCP client ignores the Router option. ++.RE ++.PP ++.nf + .B option \fBstreettalk-directory-assistance-server\fR \fIip-address\fR + [\fB,\fR \fIip-address\fR...]\fB;\fR + .fi +diff -up dhcp-4.2.4b1/common/inet.c.rfc3442 dhcp-4.2.4b1/common/inet.c +--- dhcp-4.2.4b1/common/inet.c.rfc3442 2011-05-11 02:47:22.000000000 +0200 ++++ dhcp-4.2.4b1/common/inet.c 2012-04-16 17:34:27.607079090 +0200 +@@ -528,6 +528,60 @@ free_iaddrcidrnetlist(struct iaddrcidrne + return ISC_R_SUCCESS; + } + ++static const char * ++inet_ntopdd(const unsigned char *src, unsigned srclen, char *dst, size_t size) ++{ ++ char tmp[sizeof("32.255.255.255.255")]; ++ int len; ++ ++ switch (srclen) { ++ case 2: ++ len = sprintf (tmp, "%u.%u", src[0], src[1]); ++ break; ++ case 3: ++ len = sprintf (tmp, "%u.%u.%u", src[0], src[1], src[2]); ++ break; ++ case 4: ++ len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]); ++ break; ++ case 5: ++ len = sprintf (tmp, "%u.%u.%u.%u.%u", src[0], src[1], src[2], src[3], src[4]); ++ break; ++ default: ++ return NULL; ++ } ++ if (len < 0) ++ return NULL; ++ ++ if (len > size) { ++ errno = ENOSPC; ++ return NULL; ++ } ++ ++ return strcpy (dst, tmp); ++} ++ ++/* pdestdesc() turns an iaddr structure into a printable dest. descriptor */ ++const char * ++pdestdesc(const struct iaddr addr) { ++ static char pbuf[sizeof("255.255.255.255.255")]; ++ ++ if (addr.len == 0) { ++ return ""; ++ } ++ if (addr.len == 1) { ++ return "0"; ++ } ++ if ((addr.len >= 2) && (addr.len <= 5)) { ++ return inet_ntopdd(addr.iabuf, addr.len, pbuf, sizeof(pbuf)); ++ } ++ ++ log_fatal("pdestdesc():%s:%d: Invalid destination descriptor length %d.", ++ MDL, addr.len); ++ /* quell compiler warnings */ ++ return NULL; ++} ++ + /* piaddr() turns an iaddr structure into a printable address. */ + /* XXX: should use a const pointer rather than passing the structure */ + const char * +diff -up dhcp-4.2.4b1/common/options.c.rfc3442 dhcp-4.2.4b1/common/options.c +--- dhcp-4.2.4b1/common/options.c.rfc3442 2012-03-20 01:31:53.000000000 +0100 ++++ dhcp-4.2.4b1/common/options.c 2012-04-16 17:34:27.608079076 +0200 +@@ -706,7 +706,11 @@ cons_options(struct packet *inpacket, st + * packet. + */ + priority_list[priority_len++] = DHO_SUBNET_MASK; +- priority_list[priority_len++] = DHO_ROUTERS; ++ if (lookup_option(&dhcp_universe, cfg_options, ++ DHO_CLASSLESS_STATIC_ROUTES)) ++ priority_list[priority_len++] = DHO_CLASSLESS_STATIC_ROUTES; ++ else ++ priority_list[priority_len++] = DHO_ROUTERS; + priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS; + priority_list[priority_len++] = DHO_HOST_NAME; + priority_list[priority_len++] = DHO_FQDN; +@@ -1683,6 +1687,7 @@ const char *pretty_print_option (option, + const unsigned char *dp = data; + char comma; + unsigned long tval; ++ unsigned int octets = 0; + + if (emit_commas) + comma = ','; +@@ -1691,6 +1696,7 @@ const char *pretty_print_option (option, + + memset (enumbuf, 0, sizeof enumbuf); + ++ if (option->format[0] != 'R') { /* see explanation lower */ + /* Figure out the size of the data. */ + for (l = i = 0; option -> format [i]; i++, l++) { + if (l >= sizeof(fmtbuf) - 1) +@@ -1840,6 +1846,33 @@ const char *pretty_print_option (option, + if (numhunk < 0) + numhunk = 1; + ++ } else { /* option->format[i] == 'R') */ ++ /* R (destination descriptor) has variable length. ++ * We can find it only in classless static route option, ++ * so we are for sure parsing classless static route option now. ++ * We go through whole the option to check whether there are no ++ * missing/extra bytes. ++ * I didn't find out how to improve the existing code and that's the ++ * reason for this separate 'else' where I do my own checkings. ++ * I know it's little bit unsystematic, but it works. ++ */ ++ numhunk = 0; ++ numelem = 2; /* RI */ ++ fmtbuf[0]='R'; fmtbuf[1]='I'; fmtbuf[2]=0; ++ for (i =0; i < len; i = i + octets + 5) { ++ if (data[i] > 32) { /* subnet mask width */ ++ log_error ("wrong subnet mask width in destination descriptor"); ++ break; ++ } ++ numhunk++; ++ octets = ((data[i]+7) / 8); ++ } ++ if (i != len) { ++ log_error ("classless static routes option has wrong size or " ++ "there's some garbage in format"); ++ } ++ } ++ + /* Cycle through the array (or hunk) printing the data. */ + for (i = 0; i < numhunk; i++) { + for (j = 0; j < numelem; j++) { +@@ -1978,6 +2011,20 @@ const char *pretty_print_option (option, + strcpy(op, piaddr(iaddr)); + dp += 4; + break; ++ ++ case 'R': ++ if (dp[0] <= 32) ++ iaddr.len = (((dp[0]+7)/8)+1); ++ else { ++ log_error ("wrong subnet mask width in destination descriptor"); ++ return ""; ++ } ++ ++ memcpy(iaddr.iabuf, dp, iaddr.len); ++ strcpy(op, pdestdesc(iaddr)); ++ dp += iaddr.len; ++ break; ++ + case '6': + iaddr.len = 16; + memcpy(iaddr.iabuf, dp, 16); +diff -up dhcp-4.2.4b1/common/parse.c.rfc3442 dhcp-4.2.4b1/common/parse.c +--- dhcp-4.2.4b1/common/parse.c.rfc3442 2012-04-16 17:34:27.577079510 +0200 ++++ dhcp-4.2.4b1/common/parse.c 2012-04-16 17:34:27.610079048 +0200 +@@ -341,6 +341,39 @@ int parse_ip_addr (cfile, addr) + } + + /* ++ * destination-descriptor :== NUMBER DOT NUMBER | ++ * NUMBER DOT NUMBER DOT NUMBER | ++ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER | ++ * NUMBER DOT NUMBER DOT NUMBER DOT NUMBER DOT NUMBER ++ */ ++ ++int parse_destination_descriptor (cfile, addr) ++ struct parse *cfile; ++ struct iaddr *addr; ++{ ++ unsigned int mask_width, dest_dest_len; ++ addr -> len = 0; ++ if (parse_numeric_aggregate (cfile, addr -> iabuf, ++ &addr -> len, DOT, 10, 8)) { ++ mask_width = (unsigned int)addr->iabuf[0]; ++ dest_dest_len = (((mask_width+7)/8)+1); ++ if (mask_width > 32) { ++ parse_warn (cfile, ++ "subnet mask width (%u) greater than 32.", mask_width); ++ } ++ else if (dest_dest_len != addr->len) { ++ parse_warn (cfile, ++ "destination descriptor with subnet mask width %u " ++ "should have %u octets, but has %u octets.", ++ mask_width, dest_dest_len, addr->len); ++ } ++ ++ return 1; ++ } ++ return 0; ++} ++ ++/* + * Return true if every character in the string is hexadecimal. + */ + static int +@@ -704,8 +737,10 @@ unsigned char *parse_numeric_aggregate ( + if (count) { + token = peek_token (&val, (unsigned *)0, cfile); + if (token != separator) { +- if (!*max) ++ if (!*max) { ++ *max = count; + break; ++ } + if (token != RBRACE && token != LBRACE) + token = next_token (&val, + (unsigned *)0, +@@ -1628,6 +1663,9 @@ int parse_option_code_definition (cfile, + case IP_ADDRESS: + type = 'I'; + break; ++ case DESTINATION_DESCRIPTOR: ++ type = 'R'; ++ break; + case IP6_ADDRESS: + type = '6'; + break; +@@ -5375,6 +5413,15 @@ int parse_option_token (rv, cfile, fmt, + } + break; + ++ case 'R': /* destination descriptor */ ++ if (!parse_destination_descriptor (cfile, &addr)) { ++ return 0; ++ } ++ if (!make_const_data (&t, addr.iabuf, addr.len, 0, 1, MDL)) { ++ return 0; ++ } ++ break; ++ + case '6': /* IPv6 address. */ + if (!parse_ip6_addr(cfile, &addr)) { + return 0; +@@ -5635,6 +5682,13 @@ int parse_option_decl (oc, cfile) + goto exit; + len = ip_addr.len; + dp = ip_addr.iabuf; ++ goto alloc; ++ ++ case 'R': /* destination descriptor */ ++ if (!parse_destination_descriptor (cfile, &ip_addr)) ++ goto exit; ++ len = ip_addr.len; ++ dp = ip_addr.iabuf; + + alloc: + if (hunkix + len > sizeof hunkbuf) { +diff -up dhcp-4.2.4b1/common/tables.c.rfc3442 dhcp-4.2.4b1/common/tables.c +--- dhcp-4.2.4b1/common/tables.c.rfc3442 2012-04-16 17:34:27.566079664 +0200 ++++ dhcp-4.2.4b1/common/tables.c 2012-04-16 17:34:27.611079034 +0200 +@@ -52,6 +52,7 @@ HASH_FUNCTIONS (option_code, const unsig + Format codes: + + I - IPv4 address ++ R - destination descriptor (RFC3442) + 6 - IPv6 address + l - 32-bit signed integer + L - 32-bit unsigned integer +@@ -209,6 +210,7 @@ static struct option dhcp_options[] = { + { "default-url", "t", &dhcp_universe, 114, 1 }, + { "subnet-selection", "I", &dhcp_universe, 118, 1 }, + { "domain-search", "D", &dhcp_universe, 119, 1 }, ++ { "classless-static-routes", "RIA", &dhcp_universe, 121, 1 }, + { "vivco", "Evendor-class.", &dhcp_universe, 124, 1 }, + { "vivso", "Evendor.", &dhcp_universe, 125, 1 }, + #if 0 +diff -up dhcp-4.2.4b1/includes/dhcpd.h.rfc3442 dhcp-4.2.4b1/includes/dhcpd.h +--- dhcp-4.2.4b1/includes/dhcpd.h.rfc3442 2012-04-16 17:34:27.543079986 +0200 ++++ dhcp-4.2.4b1/includes/dhcpd.h 2012-04-16 17:34:27.613079006 +0200 +@@ -2666,6 +2666,7 @@ isc_result_t range2cidr(struct iaddrcidr + const struct iaddr *lo, const struct iaddr *hi); + isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result); + const char *piaddr (struct iaddr); ++const char *pdestdesc (struct iaddr); + char *piaddrmask(struct iaddr *, struct iaddr *); + char *piaddrcidr(const struct iaddr *, unsigned int); + u_int16_t validate_port(char *); +@@ -2873,6 +2874,7 @@ void parse_client_lease_declaration (str + int parse_option_decl (struct option_cache **, struct parse *); + void parse_string_list (struct parse *, struct string_list **, int); + int parse_ip_addr (struct parse *, struct iaddr *); ++int parse_destination_descriptor (struct parse *, struct iaddr *); + int parse_ip_addr_with_subnet(struct parse *, struct iaddrmatch *); + void parse_reject_statement (struct parse *, struct client_config *); + +diff -up dhcp-4.2.4b1/includes/dhcp.h.rfc3442 dhcp-4.2.4b1/includes/dhcp.h +--- dhcp-4.2.4b1/includes/dhcp.h.rfc3442 2012-02-16 22:09:14.000000000 +0100 ++++ dhcp-4.2.4b1/includes/dhcp.h 2012-04-16 17:34:27.613079006 +0200 +@@ -163,6 +163,7 @@ struct dhcp_packet { + #define DHO_ASSOCIATED_IP 92 + #define DHO_SUBNET_SELECTION 118 /* RFC3011! */ + #define DHO_DOMAIN_SEARCH 119 /* RFC3397 */ ++#define DHO_CLASSLESS_STATIC_ROUTES 121 /* RFC3442 */ + #define DHO_VIVCO_SUBOPTIONS 124 + #define DHO_VIVSO_SUBOPTIONS 125 + +diff -up dhcp-4.2.4b1/includes/dhctoken.h.rfc3442 dhcp-4.2.4b1/includes/dhctoken.h +--- dhcp-4.2.4b1/includes/dhctoken.h.rfc3442 2012-04-16 17:34:27.000000000 +0200 ++++ dhcp-4.2.4b1/includes/dhctoken.h 2012-04-16 17:35:15.028414805 +0200 +@@ -365,7 +365,8 @@ enum dhcp_token { + PRIMARY6 = 666, + SECONDARY6 = 667, + TOKEN_INFINIBAND = 668, +- BOOTP_BROADCAST_ALWAYS = 669 ++ BOOTP_BROADCAST_ALWAYS = 669, ++ DESTINATION_DESCRIPTOR = 670 + }; + + #define is_identifier(x) ((x) >= FIRST_TOKEN && \ diff --git a/dhcp-4.2.4-send_release.patch b/dhcp-4.2.4-send_release.patch new file mode 100644 index 0000000..3e0a618 --- /dev/null +++ b/dhcp-4.2.4-send_release.patch @@ -0,0 +1,23 @@ +diff -up dhcp-4.2.4b1/client/dhclient.c.send_release dhcp-4.2.4b1/client/dhclient.c +--- dhcp-4.2.4b1/client/dhclient.c.send_release 2012-04-16 17:48:52.000000000 +0200 ++++ dhcp-4.2.4b1/client/dhclient.c 2012-04-16 17:50:44.357396720 +0200 +@@ -2764,8 +2764,8 @@ void send_release (cpp) + inet_ntoa (destination.sin_addr), + ntohs (destination.sin_port), client -> xid); + +- if (fallback_interface) { +- result = send_packet(fallback_interface, NULL, &client->packet, ++ if (client -> interface) { ++ result = send_packet(client -> interface, NULL, &client->packet, + client->packet_length, from, &destination, + NULL); + if (result < 0) { +@@ -2776,7 +2776,7 @@ void send_release (cpp) + } + } else { + /* Send out a packet. */ +- result = send_packet(client->interface, NULL, &client->packet, ++ result = send_packet(fallback_interface, NULL, &client->packet, + client->packet_length, from, &destination, + NULL); + if (result < 0) { diff --git a/dhcp-4.2.4-systemtap.patch b/dhcp-4.2.4-systemtap.patch new file mode 100644 index 0000000..bba60b1 --- /dev/null +++ b/dhcp-4.2.4-systemtap.patch @@ -0,0 +1,808 @@ +diff -up dhcp-4.2.4b1/configure.ac.systemtap dhcp-4.2.4b1/configure.ac +--- dhcp-4.2.4b1/configure.ac.systemtap 2012-04-16 17:46:10.913227143 +0200 ++++ dhcp-4.2.4b1/configure.ac 2012-04-16 17:46:10.947226667 +0200 +@@ -504,6 +504,35 @@ else + AC_MSG_RESULT(no) + fi + ++AC_MSG_CHECKING([whether to include systemtap tracing support]) ++AC_ARG_ENABLE([systemtap], ++ [AS_HELP_STRING([--enable-systemtap], ++ [Enable inclusion of systemtap trace support])], ++ [ENABLE_SYSTEMTAP="${enableval}"], [ENABLE_SYSTEMTAP='no']) ++AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test x$ENABLE_SYSTEMTAP = xyes]) ++AC_MSG_RESULT(${ENABLE_SYSTEMTAP}) ++ ++if test "x${ENABLE_SYSTEMTAP}" = xyes; then ++ # Additional configuration for --enable-systemtap is HERE ++ AC_CHECK_PROGS(DTRACE, dtrace) ++ if test -z "$DTRACE"; then ++ AC_MSG_ERROR([dtrace not found]) ++ fi ++ AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND='yes'], ++ [SDT_H_FOUND='no'; ++ AC_MSG_ERROR([systemtap support needs sys/sdt.h header])]) ++ AC_DEFINE([HAVE_SYSTEMTAP], [1], [Define to 1 if using SystemTap probes.]) ++ AC_ARG_WITH([tapset-install-dir], ++ [AS_HELP_STRING([--with-tapset-install-dir], ++ [The absolute path where the tapset dir will be installed])], ++ [if test "x${withval}" = x; then ++ ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset" ++ else ++ ABS_TAPSET_DIR="${withval}" ++ fi], [ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"]) ++ AC_SUBST(ABS_TAPSET_DIR) ++fi ++ + # Solaris needs some libraries for functions + AC_SEARCH_LIBS(socket, [socket]) + AC_SEARCH_LIBS(inet_ntoa, [nsl]) +@@ -650,6 +679,7 @@ AC_OUTPUT([ + relay/Makefile + server/Makefile + tests/Makefile ++ tapset/Makefile + ]) + + sh util/bindvar.sh +diff -up dhcp-4.2.4b1/Makefile.am.systemtap dhcp-4.2.4b1/Makefile.am +--- dhcp-4.2.4b1/Makefile.am.systemtap 2012-04-16 17:46:10.791228851 +0200 ++++ dhcp-4.2.4b1/Makefile.am 2012-04-16 17:46:10.947226667 +0200 +@@ -29,5 +29,8 @@ endif + + SUBDIRS += includes tests common dst omapip client dhcpctl relay server + ++SUBDIRS += tapset ++#DIST_SUBDIRS = $(SUBDIRS) ++ + nobase_include_HEADERS = dhcpctl/dhcpctl.h + +diff -up dhcp-4.2.4b1/server/dhcp.c.systemtap dhcp-4.2.4b1/server/dhcp.c +--- dhcp-4.2.4b1/server/dhcp.c.systemtap 2012-04-16 17:46:10.816228501 +0200 ++++ dhcp-4.2.4b1/server/dhcp.c 2012-04-16 17:48:11.528537555 +0200 +@@ -36,7 +36,7 @@ + #include + #include + #include +- ++#include "trace.h" + static void commit_leases_ackout(void *foo); + static void maybe_return_agent_options(struct packet *packet, + struct option_state *options); +@@ -275,6 +275,8 @@ void dhcpdiscover (packet, ms_nulltp) + dhcp_failover_state_t *peer; + #endif + ++ TRACE(DHCPD_DISCOVER_START()); ++ + find_lease (&lease, packet, packet -> shared_network, + 0, &peer_has_leases, (struct lease *)0, MDL); + +@@ -399,6 +401,8 @@ void dhcpdiscover (packet, ms_nulltp) + out: + if (lease) + lease_dereference (&lease, MDL); ++ ++ TRACE(DHCPD_DISCOVER_DONE()); + } + + void dhcprequest (packet, ms_nulltp, ip_lease) +@@ -421,6 +425,8 @@ void dhcprequest (packet, ms_nulltp, ip_ + #endif + int have_requested_addr = 0; + ++ TRACE(DHCPD_REQUEST_START()); ++ + oc = lookup_option (&dhcp_universe, packet -> options, + DHO_DHCP_REQUESTED_ADDRESS); + memset (&data, 0, sizeof data); +@@ -677,6 +683,9 @@ void dhcprequest (packet, ms_nulltp, ip_ + log_info ("%s: unknown lease %s.", msgbuf, piaddr (cip)); + + out: ++ ++ TRACE(DHCPD_REQUEST_DONE()); ++ + if (subnet) + subnet_dereference (&subnet, MDL); + if (lease) +@@ -695,6 +704,7 @@ void dhcprelease (packet, ms_nulltp) + const char *s; + char msgbuf [1024], cstr[16]; /* XXX */ + ++ TRACE(DHCPD_RELEASE_START()); + + /* DHCPRELEASE must not specify address in requested-address + option, but old protocol specs weren't explicit about this, +@@ -819,6 +829,8 @@ void dhcprelease (packet, ms_nulltp) + #endif + if (lease) + lease_dereference (&lease, MDL); ++ ++ TRACE(DHCPD_RELEASE_DONE()); + } + + void dhcpdecline (packet, ms_nulltp) +@@ -836,6 +848,8 @@ void dhcpdecline (packet, ms_nulltp) + struct option_cache *oc; + struct data_string data; + ++ TRACE(DHCPD_DECLINE_START()); ++ + /* DHCPDECLINE must specify address. */ + if (!(oc = lookup_option (&dhcp_universe, packet -> options, + DHO_DHCP_REQUESTED_ADDRESS))) +@@ -947,6 +961,8 @@ void dhcpdecline (packet, ms_nulltp) + option_state_dereference (&options, MDL); + if (lease) + lease_dereference (&lease, MDL); ++ ++ TRACE(DHCPD_DECLINE_DONE()); + } + + void dhcpinform (packet, ms_nulltp) +@@ -970,6 +986,8 @@ void dhcpinform (packet, ms_nulltp) + struct interface_info *interface; + int result; + ++ TRACE(DHCPD_INFORM_START()); ++ + /* The client should set ciaddr to its IP address, but apparently + it's common for clients not to do this, so we'll use their IP + source address if they didn't set ciaddr. */ +@@ -1327,6 +1345,8 @@ void dhcpinform (packet, ms_nulltp) + + if (subnet) + subnet_dereference (&subnet, MDL); ++ ++ TRACE(DHCPD_INFORM_DONE()); + } + + void nak_lease (packet, cip) +@@ -1343,6 +1363,8 @@ void nak_lease (packet, cip) + struct option_state *options = (struct option_state *)0; + struct option_cache *oc = (struct option_cache *)0; + ++ TRACE(DHCPD_NAK_LEASE_START()); ++ + option_state_allocate (&options, MDL); + memset (&outgoing, 0, sizeof outgoing); + memset (&raw, 0, sizeof raw); +@@ -1494,6 +1516,7 @@ void nak_lease (packet, cip) + packet->interface->name); + } + ++ TRACE(DHCPD_NAK_LEASE_DONE()); + } + + void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp) +@@ -1535,6 +1558,8 @@ void ack_lease (packet, lease, offer, wh + if (lease -> state) + return; + ++ TRACE(DHCPD_ACK_LEASE_START()); ++ + /* Save original cltt for comparison later. */ + lease_cltt = lease->cltt; + +@@ -2897,6 +2922,8 @@ void ack_lease (packet, lease, offer, wh + #endif + dhcp_reply(lease); + } ++ ++ TRACE(DHCPD_ACK_LEASE_DONE()); + } + + /* +@@ -3049,6 +3076,8 @@ void dhcp_reply (lease) + if (!state) + log_fatal ("dhcp_reply was supplied lease with no state!"); + ++ TRACE(DHCPD_REPLY_START()); ++ + /* Compose a response for the client... */ + memset (&raw, 0, sizeof raw); + memset (&d1, 0, sizeof d1); +@@ -3270,6 +3299,8 @@ void dhcp_reply (lease) + + free_lease_state (state, MDL); + lease -> state = (struct lease_state *)0; ++ ++ TRACE(DHCPD_REPLY_DONE()); + } + + int find_lease (struct lease **lp, +@@ -3292,6 +3323,8 @@ int find_lease (struct lease **lp, + struct data_string client_identifier; + struct hardware h; + ++ TRACE(DHCPD_FIND_LEASE_START()); ++ + #if defined(FAILOVER_PROTOCOL) + /* Quick check to see if the peer has leases. */ + if (peer_has_leases) { +@@ -4019,6 +4052,9 @@ int find_lease (struct lease **lp, + #if defined (DEBUG_FIND_LEASE) + log_info ("Not returning a lease."); + #endif ++ ++ TRACE(DHCPD_FIND_LEASE_DONE()); ++ + return 0; + } + +diff -up dhcp-4.2.4b1/server/dhcpd.c.systemtap dhcp-4.2.4b1/server/dhcpd.c +--- dhcp-4.2.4b1/server/dhcpd.c.systemtap 2012-04-16 17:46:10.928226933 +0200 ++++ dhcp-4.2.4b1/server/dhcpd.c 2012-04-16 17:46:10.951226611 +0200 +@@ -58,6 +58,8 @@ static const char url [] = + # undef group + #endif /* PARANOIA */ + ++#include "trace.h" ++ + static void usage(void); + + struct iaddr server_identifier; +@@ -859,6 +861,7 @@ main(int argc, char **argv) { + omapi_set_int_value ((omapi_object_t *)dhcp_control_object, + (omapi_object_t *)0, "state", server_running); + ++ TRACE(DHCPD_MAIN()); + /* Receive packets and dispatch them... */ + dispatch (); + +diff -up dhcp-4.2.4b1/server/dhcpv6.c.systemtap dhcp-4.2.4b1/server/dhcpv6.c +--- dhcp-4.2.4b1/server/dhcpv6.c.systemtap 2012-04-16 17:46:10.925226975 +0200 ++++ dhcp-4.2.4b1/server/dhcpv6.c 2012-04-16 17:46:10.953226583 +0200 +@@ -15,6 +15,7 @@ + */ + + #include "dhcpd.h" ++#include "trace.h" + + #ifdef DHCPv6 + +@@ -4198,6 +4199,8 @@ static void + dhcpv6_solicit(struct data_string *reply_ret, struct packet *packet) { + struct data_string client_id; + ++ TRACE(DHCPD_6_SOLICIT_START()); ++ + /* + * Validate our input. + */ +@@ -4211,6 +4214,8 @@ dhcpv6_solicit(struct data_string *reply + * Clean up. + */ + data_string_forget(&client_id, MDL); ++ ++ TRACE(DHCPD_6_SOLICIT_DONE()); + } + + /* +@@ -4224,6 +4229,8 @@ dhcpv6_request(struct data_string *reply + struct data_string client_id; + struct data_string server_id; + ++ TRACE(DHCPD_6_REQUEST_START()); ++ + /* + * Validate our input. + */ +@@ -4241,6 +4248,8 @@ dhcpv6_request(struct data_string *reply + */ + data_string_forget(&client_id, MDL); + data_string_forget(&server_id, MDL); ++ ++ TRACE(DHCPD_6_REQUEST_DONE()); + } + + /* Find a DHCPv6 packet's shared network from hints in the packet. +@@ -4353,6 +4362,8 @@ dhcpv6_confirm(struct data_string *reply + struct dhcpv6_packet *reply = (struct dhcpv6_packet *)reply_data; + int reply_ofs = (int)(offsetof(struct dhcpv6_packet, options)); + ++ TRACE(DHCPD_6_CONFIRM_START()); ++ + /* + * Basic client message validation. + */ +@@ -4539,6 +4550,8 @@ exit: + option_state_dereference(&cli_enc_opt_state, MDL); + if (opt_state != NULL) + option_state_dereference(&opt_state, MDL); ++ ++ TRACE(DHCPD_6_CONFIRM_DONE()); + } + + /* +@@ -4553,6 +4566,8 @@ dhcpv6_renew(struct data_string *reply, + struct data_string client_id; + struct data_string server_id; + ++ TRACE(DHCPD_6_RENEW_START()); ++ + /* + * Validate the request. + */ +@@ -4570,6 +4585,8 @@ dhcpv6_renew(struct data_string *reply, + */ + data_string_forget(&server_id, MDL); + data_string_forget(&client_id, MDL); ++ ++ TRACE(DHCPD_6_RENEW_DONE()); + } + + /* +@@ -4583,6 +4600,8 @@ static void + dhcpv6_rebind(struct data_string *reply, struct packet *packet) { + struct data_string client_id; + ++ TRACE(DHCPD_6_REBIND_START()); ++ + if (!valid_client_msg(packet, &client_id)) { + return; + } +@@ -4590,6 +4609,8 @@ dhcpv6_rebind(struct data_string *reply, + lease_to_client(reply, packet, &client_id, NULL); + + data_string_forget(&client_id, MDL); ++ ++ TRACE(DHCPD_6_REBIND_DONE()); + } + + static void +@@ -5034,6 +5055,8 @@ dhcpv6_decline(struct data_string *reply + struct data_string client_id; + struct data_string server_id; + ++ TRACE(DHCPD_6_DECLINE_START()); ++ + /* + * Validate our input. + */ +@@ -5054,6 +5077,8 @@ dhcpv6_decline(struct data_string *reply + + data_string_forget(&server_id, MDL); + data_string_forget(&client_id, MDL); ++ ++ TRACE(DHCPD_6_DECLINE_DONE()); + } + + static void +@@ -5502,6 +5527,8 @@ dhcpv6_release(struct data_string *reply + struct data_string client_id; + struct data_string server_id; + ++ TRACE(DHCPD_6_RELEASE_START()); ++ + /* + * Validate our input. + */ +@@ -5523,6 +5550,8 @@ dhcpv6_release(struct data_string *reply + + data_string_forget(&server_id, MDL); + data_string_forget(&client_id, MDL); ++ ++ TRACE(DHCPD_6_RELEASE_DONE()); + } + + /* +@@ -5535,6 +5564,8 @@ dhcpv6_information_request(struct data_s + struct data_string client_id; + struct data_string server_id; + ++ TRACE(DHCPD_6_INFORMATION_REQUEST_START()); ++ + /* + * Validate our input. + */ +@@ -5566,6 +5597,8 @@ dhcpv6_information_request(struct data_s + data_string_forget(&client_id, MDL); + } + data_string_forget(&server_id, MDL); ++ ++ TRACE(DHCPD_6_INFORMATION_REQUEST_DONE()); + } + + /* +@@ -5594,6 +5627,8 @@ dhcpv6_relay_forw(struct data_string *re + struct dhcpv6_relay_packet *reply; + int reply_ofs; + ++ TRACE(DHCPD_6_RELAY_FORW_START()); ++ + /* + * Initialize variables for early exit. + */ +@@ -5853,6 +5888,8 @@ exit: + if (enc_packet != NULL) { + packet_dereference(&enc_packet, MDL); + } ++ ++ TRACE(DHCPD_6_RELAY_FORW_DONE()); + } + + static void +diff -up dhcp-4.2.4b1/server/failover.c.systemtap dhcp-4.2.4b1/server/failover.c +--- dhcp-4.2.4b1/server/failover.c.systemtap 2012-03-19 23:29:49.000000000 +0100 ++++ dhcp-4.2.4b1/server/failover.c 2012-04-16 17:46:10.955226555 +0200 +@@ -36,6 +36,8 @@ + #include "dhcpd.h" + #include + ++#include "trace.h" ++ + #if defined (FAILOVER_PROTOCOL) + dhcp_failover_state_t *failover_states; + static isc_result_t do_a_failover_option (omapi_object_t *, +@@ -1712,6 +1714,8 @@ isc_result_t dhcp_failover_set_state (dh + struct lease *l; + struct timeval tv; + ++ TRACE(DHCPD_FAILOVER_SET_STATE_START(state->me.state, new_state)); ++ + /* If we're in certain states where we're sending updates, and the peer + * state changes, we need to re-schedule any pending updates just to + * be on the safe side. This results in retransmission. +@@ -1939,6 +1943,8 @@ isc_result_t dhcp_failover_set_state (dh + break; + } + ++ TRACE(DHCPD_FAILOVER_SET_STATE_DONE()); ++ + return ISC_R_SUCCESS; + } + +@@ -2422,6 +2428,8 @@ dhcp_failover_pool_dobalance(dhcp_failov + if (state -> me.state != normal) + return 0; + ++ TRACE(DHCPD_FAILOVER_POOL_DOBALANCE_START()); ++ + state->last_balance = cur_time; + + for (s = shared_networks ; s ; s = s->next) { +@@ -2582,6 +2590,8 @@ dhcp_failover_pool_dobalance(dhcp_failov + if (leases_queued) + commit_leases(); + ++ TRACE(DHCPD_FAILOVER_POOL_DOBALANCE_DONE()); ++ + return leases_queued; + } + +diff -up dhcp-4.2.4b1/server/Makefile.am.systemtap dhcp-4.2.4b1/server/Makefile.am +--- dhcp-4.2.4b1/server/Makefile.am.systemtap 2012-04-16 17:46:10.914227129 +0200 ++++ dhcp-4.2.4b1/server/Makefile.am 2012-04-16 17:46:10.956226541 +0200 +@@ -4,7 +4,7 @@ dist_sysconf_DATA = dhcpd.conf + sbin_PROGRAMS = dhcpd + dhcpd_SOURCES = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \ + omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c \ +- dhcpv6.c mdb6.c ldap.c ldap_casa.c ++ dhcpv6.c mdb6.c ldap.c ldap_casa.c probes.d trace.h + + dhcpd_CFLAGS = $(LDAP_CFLAGS) + dhcpd_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \ +@@ -13,3 +13,13 @@ dhcpd_LDADD = ../common/libdhcp.a ../oma + man_MANS = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5 + EXTRA_DIST = $(man_MANS) + ++if ENABLE_SYSTEMTAP ++BUILT_SOURCES = probes.h ++probes.h: probes.d ++ $(DTRACE) -C -h -s $< -o $@ ++ ++probes.o: probes.d ++ $(DTRACE) -C -G -s $< -o $@ ++ ++dhcpd_LDADD += probes.o ++endif +diff -up dhcp-4.2.4b1/server/probes.d.systemtap dhcp-4.2.4b1/server/probes.d +--- dhcp-4.2.4b1/server/probes.d.systemtap 2012-04-16 17:46:10.956226541 +0200 ++++ dhcp-4.2.4b1/server/probes.d 2012-04-16 17:46:10.956226541 +0200 +@@ -0,0 +1,43 @@ ++provider dhcpd { ++ probe main(); ++ probe discover_start() ++ probe discover_done() ++ probe request_start() ++ probe request_done() ++ probe release_start() ++ probe release_done() ++ probe decline_start() ++ probe decline_done() ++ probe inform_start() ++ probe inform_done() ++ probe nak_lease_start() ++ probe nak_lease_done() ++ probe ack_lease_start() ++ probe ack_lease_done() ++ probe reply_start() ++ probe reply_done() ++ probe find_lease_start() ++ probe find_lease_done() ++ probe 6_solicit_start() ++ probe 6_solicit_done() ++ probe 6_request_start() ++ probe 6_request_done() ++ probe 6_confirm_start() ++ probe 6_confirm_done() ++ probe 6_renew_start() ++ probe 6_renew_done() ++ probe 6_rebind_start() ++ probe 6_rebind_done() ++ probe 6_decline_start() ++ probe 6_decline_done() ++ probe 6_release_start() ++ probe 6_release_done() ++ probe 6_information_request_start() ++ probe 6_information_request_done() ++ probe 6_relay_forw_start() ++ probe 6_relay_forw_done() ++ probe failover_pool_dobalance_start() ++ probe failover_pool_dobalance_done() ++ probe failover_set_state_start(int, int) /* state, new_state */ ++ probe failover_set_state_done() ++}; +diff -up dhcp-4.2.4b1/server/trace.h.systemtap dhcp-4.2.4b1/server/trace.h +--- dhcp-4.2.4b1/server/trace.h.systemtap 2012-04-16 17:46:10.956226541 +0200 ++++ dhcp-4.2.4b1/server/trace.h 2012-04-16 17:46:10.956226541 +0200 +@@ -0,0 +1,11 @@ ++// trace.h ++ ++#include "config.h" ++#ifdef HAVE_SYSTEMTAP ++// include the generated probes header and put markers in code ++#include "probes.h" ++#define TRACE(probe) probe ++#else ++// Wrap the probe to allow it to be removed when no systemtap available ++#define TRACE(probe) ++#endif +diff -up dhcp-4.2.4b1/tapset/dhcpd.stp.systemtap dhcp-4.2.4b1/tapset/dhcpd.stp +--- dhcp-4.2.4b1/tapset/dhcpd.stp.systemtap 2012-04-16 17:46:10.957226527 +0200 ++++ dhcp-4.2.4b1/tapset/dhcpd.stp 2012-04-16 17:46:10.957226527 +0200 +@@ -0,0 +1,212 @@ ++/* dhcpd tapset ++ Copyright (C) 2011, Red Hat Inc. ++ */ ++ ++probe dhcpd_main = process("dhcpd").mark("main") ++{ ++ probestr = sprintf("%s(locals: %s)", $$name, $$locals); ++ ++} ++ ++probe dhcpd_discover_start = process("dhcpd").mark("discover_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_discover_done = process("dhcpd").mark("discover_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_request_start = process("dhcpd").mark("request_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_request_done = process("dhcpd").mark("request_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_release_start = process("dhcpd").mark("release_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_release_done = process("dhcpd").mark("release_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_decline_start = process("dhcpd").mark("decline_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_decline_done = process("dhcpd").mark("decline_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_inform_start = process("dhcpd").mark("inform_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_inform_done = process("dhcpd").mark("inform_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_nak_lease_start = process("dhcpd").mark("nak_lease_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_nak_lease_done = process("dhcpd").mark("nak_lease_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_ack_lease_start = process("dhcpd").mark("ack_lease_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_ack_lease_done = process("dhcpd").mark("ack_lease_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_reply_start = process("dhcpd").mark("reply_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_reply_done = process("dhcpd").mark("reply_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_find_lease_start = process("dhcpd").mark("find_lease_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_find_lease_done = process("dhcpd").mark("find_lease_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_solicit_start = process("dhcpd").mark("6_solicit_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_solicit_done = process("dhcpd").mark("6_solicit_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_request_start = process("dhcpd").mark("6_request_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_request_done = process("dhcpd").mark("6_request_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_confirm_start = process("dhcpd").mark("6_confirm_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_confirm_done = process("dhcpd").mark("6_confirm_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_renew_start = process("dhcpd").mark("6_renew_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_renew_done = process("dhcpd").mark("6_renew_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_rebind_start = process("dhcpd").mark("6_rebind_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_rebind_done = process("dhcpd").mark("6_rebind_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_decline_start = process("dhcpd").mark("6_decline_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_decline_done = process("dhcpd").mark("6_decline_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_release_start = process("dhcpd").mark("6_release_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_release_done = process("dhcpd").mark("6_release_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_information_request_start = process("dhcpd").mark("6_information_request_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_information_request_done = process("dhcpd").mark("6_information_request_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_relay_forw_start = process("dhcpd").mark("6_relay_forw_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_6_relay_forw_done = process("dhcpd").mark("6_relay_forw_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_failover_pool_dobalance_start = process("dhcpd").mark("failover_pool_dobalance_start") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++probe dhcpd_failover_pool_dobalance_done = process("dhcpd").mark("failover_pool_dobalance_done") ++{ ++ probestr = sprintf("%s", $$name); ++} ++ ++ ++probe dhcpd_failover_set_state_start = process("dhcpd").mark("failover_set_state_start") ++{ ++ state = $arg1; ++ new_state = $arg2; ++ probestr = sprintf("%s(state=%d, new_state=%d)", $$name, state, new_state); ++} ++ ++probe dhcpd_failover_set_state_done = process("dhcpd").mark("failover_set_state_done") ++{ ++ probestr = sprintf("%s", $$name); ++} +diff -up dhcp-4.2.4b1/tapset/Makefile.am.systemtap dhcp-4.2.4b1/tapset/Makefile.am +--- dhcp-4.2.4b1/tapset/Makefile.am.systemtap 2012-04-16 17:46:10.957226527 +0200 ++++ dhcp-4.2.4b1/tapset/Makefile.am 2012-04-16 17:46:10.957226527 +0200 +@@ -0,0 +1,26 @@ ++# Makefile.am for dhcp/tapset ++# Jiri Popelka ++ ++.PHONY: clean-local install-data-hook uninstall-local ++ ++# ++EXTRA_DIST = dhcpd.stp ++TAPSET_FILES = $(EXTRA_DIST) ++TAPSET_INSTALL_DIR = $(DESTDIR)@ABS_TAPSET_DIR@ ++ ++if ENABLE_SYSTEMTAP ++all-local: $(TAPSET_FILES) ++ ++clean-local: ++ ++install-data-hook: ++ $(MKDIR_P) $(TAPSET_INSTALL_DIR) ++ $(INSTALL_DATA) $(TAPSET_FILES) $(TAPSET_INSTALL_DIR) ++ ++uninstall-local: ++ @list='$(TAPSET_FILES)'; for p in $$list; do \ ++ echo " rm -f '$(TAPSET_INSTALL_DIR)/$$p'"; \ ++ rm -f "$(TAPSET_INSTALL_DIR)/$$p"; \ ++ done ++endif ++ diff --git a/dhcp-4.2.4-unicast-bootp.patch b/dhcp-4.2.4-unicast-bootp.patch new file mode 100644 index 0000000..69ab4c8 --- /dev/null +++ b/dhcp-4.2.4-unicast-bootp.patch @@ -0,0 +1,101 @@ +diff -up dhcp-4.2.4b1/server/bootp.c.unicast dhcp-4.2.4b1/server/bootp.c +--- dhcp-4.2.4b1/server/bootp.c.unicast 2012-04-10 23:27:06.000000000 +0200 ++++ dhcp-4.2.4b1/server/bootp.c 2012-04-16 17:28:42.095919022 +0200 +@@ -59,6 +59,7 @@ void bootp (packet) + char msgbuf [1024]; + int ignorep; + int peer_has_leases = 0; ++ int norelay = 0; + + if (packet -> raw -> op != BOOTREQUEST) + return; +@@ -74,7 +75,7 @@ void bootp (packet) + ? inet_ntoa (packet -> raw -> giaddr) + : packet -> interface -> name); + +- if (!locate_network (packet)) { ++ if ((norelay = locate_network (packet)) == 0) { + log_info ("%s: network unknown", msgbuf); + return; + } +@@ -399,6 +400,15 @@ void bootp (packet) + + goto out; + } ++ } else if (norelay == 2) { ++ to.sin_addr = raw.ciaddr; ++ to.sin_port = remote_port; ++ if (fallback_interface) { ++ result = send_packet (fallback_interface, NULL, &raw, ++ outgoing.packet_length, from, ++ &to, &hto); ++ goto out; ++ } + + /* If it comes from a client that already knows its address + and is not requesting a broadcast response, and we can +diff -up dhcp-4.2.4b1/server/dhcp.c.unicast dhcp-4.2.4b1/server/dhcp.c +--- dhcp-4.2.4b1/server/dhcp.c.unicast 2012-03-09 12:28:12.000000000 +0100 ++++ dhcp-4.2.4b1/server/dhcp.c 2012-04-16 17:26:55.067418285 +0200 +@@ -4299,6 +4299,7 @@ int locate_network (packet) + struct data_string data; + struct subnet *subnet = (struct subnet *)0; + struct option_cache *oc; ++ int norelay = 0; + + /* See if there's a Relay Agent Link Selection Option, or a + * Subnet Selection Option. The Link-Select and Subnet-Select +@@ -4314,12 +4315,24 @@ int locate_network (packet) + from the interface, if there is one. If not, fail. */ + if (!oc && !packet -> raw -> giaddr.s_addr) { + if (packet -> interface -> shared_network) { +- shared_network_reference +- (&packet -> shared_network, +- packet -> interface -> shared_network, MDL); +- return 1; ++ struct in_addr any_addr; ++ any_addr.s_addr = INADDR_ANY; ++ ++ if (!packet -> packet_type && memcmp(&packet -> raw -> ciaddr, &any_addr, 4)) { ++ struct iaddr cip; ++ memcpy(cip.iabuf, &packet -> raw -> ciaddr, 4); ++ cip.len = 4; ++ if (!find_grouped_subnet(&subnet, packet->interface->shared_network, cip, MDL)) ++ norelay = 2; ++ } ++ ++ if (!norelay) { ++ shared_network_reference(&packet -> shared_network, packet -> interface -> shared_network, MDL); ++ return 1; ++ } ++ } else { ++ return 0; + } +- return 0; + } + + /* If there's an option indicating link connection, and it's valid, +@@ -4342,7 +4355,10 @@ int locate_network (packet) + data_string_forget (&data, MDL); + } else { + ia.len = 4; +- memcpy (ia.iabuf, &packet -> raw -> giaddr, 4); ++ if (norelay) ++ memcpy (ia.iabuf, &packet->raw->ciaddr, 4); ++ else ++ memcpy (ia.iabuf, &packet->raw->giaddr, 4); + } + + /* If we know the subnet on which the IP address lives, use it. */ +@@ -4350,7 +4366,10 @@ int locate_network (packet) + shared_network_reference (&packet -> shared_network, + subnet -> shared_network, MDL); + subnet_dereference (&subnet, MDL); +- return 1; ++ if (norelay) ++ return norelay; ++ else ++ return 1; + } + + /* Otherwise, fail. */ diff --git a/dhcp.spec b/dhcp.spec index 79b4c73..6b196ac 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -7,19 +7,19 @@ # Where dhcp configuration files are stored %global dhcpconfdir %{_sysconfdir}/dhcp -# Patch version -%global patchver P2 -# Pre-Release version -#%%global prever rc1 -#%%global VERSION %{version}%{prever} +#%%global patchver P2 +%global prever b1 + + #%%global VERSION %{version} -%global VERSION %{version}-%{patchver} +#%%global VERSION %{version}-%{patchver} +%global VERSION %{version}%{prever} Summary: Dynamic host configuration protocol software Name: dhcp -Version: 4.2.3 -Release: 25.%{patchver}%{?dist} +Version: 4.2.4 +Release: 0.1.%{prever}%{?dist} # NEVER CHANGE THE EPOCH on this package. The previous maintainer (prior to # dcantrell maintaining the package) made incorrect use of the epoch and # that's why it is at 12 now. It should have never been used, but it was. @@ -38,10 +38,10 @@ Source6: dhcpd6.service Source7: dhcrelay.service Patch0: dhcp-4.2.0-errwarn-message.patch -Patch1: dhcp-4.2.3-options.patch +Patch1: dhcp-4.2.4-options.patch Patch2: dhcp-4.2.0-release-by-ifup.patch Patch3: dhcp-4.2.0-dhclient-decline-backoff.patch -Patch4: dhcp-4.2.0-unicast-bootp.patch +Patch4: dhcp-4.2.4-unicast-bootp.patch Patch6: dhcp-4.2.2-dhclient-usage.patch Patch7: dhcp-4.2.0-default-requested-options.patch Patch8: dhcp-4.2.2-xen-checksum.patch @@ -52,27 +52,26 @@ Patch13: dhcp-4.2.0-inherit-leases.patch Patch14: dhcp-4.2.0-garbage-chars.patch Patch15: dhcp-4.2.0-missing-ipv6-not-fatal.patch Patch17: dhcp-4.2.0-add_timeout_when_NULL.patch -Patch18: dhcp-4.2.1-64_bit_lease_parse.patch +Patch18: dhcp-4.2.4-64_bit_lease_parse.patch Patch19: dhcp-4.2.2-capability.patch Patch20: dhcp-4.2.0-logpid.patch -Patch21: dhcp-4.2.0-UseMulticast.patch +Patch21: dhcp-4.2.4-UseMulticast.patch Patch22: dhcp-4.2.1-sendDecline.patch Patch23: dhcp-4.2.1-retransmission.patch -Patch25: dhcp-4.2.3-rfc3442-classless-static-routes.patch +Patch25: dhcp-4.2.4-rfc3442-classless-static-routes.patch Patch27: dhcp-4.2.0-honor-expired.patch -Patch28: dhcp-4.2.0-noprefixavail.patch Patch29: dhcp-4.2.2-remove-bind.patch Patch30: dhcp-4.2.2-sharedlib.patch -Patch31: dhcp-4.2.0-PPP.patch +Patch31: dhcp-4.2.4-PPP.patch Patch32: dhcp-4.2.3-paranoia.patch -Patch33: dhcp-4.2.2-lpf-ib.patch -Patch34: dhcp-4.2.2-improved-xid.patch +Patch33: dhcp-4.2.4-lpf-ib.patch +Patch34: dhcp-4.2.4-improved-xid.patch Patch35: dhcp-4.2.2-gpxe-cid.patch -Patch36: dhcp-4.2.2-systemtap.patch +Patch36: dhcp-4.2.4-systemtap.patch Patch37: dhcp-4.2.3-dhclient-decline-onetry.patch Patch38: dhcp-4.2.3-P2-log_perror.patch Patch39: dhcp-4.2.3-P2-getifaddrs.patch -Patch40: dhcp-4.2.3-P2-send_release.patch +Patch40: dhcp-4.2.4-send_release.patch Patch41: dhcp-4.2.3-P2-rfc5970-dhcpv6-options-for-network-boot.patch BuildRequires: autoconf @@ -266,17 +265,6 @@ rm bind/bind.tar.gz # (Submitted to dhcp-suggest@isc.org - [ISC-Bugs #22675]) %patch27 -p1 -b .honor-expired -# 1) When server has empty pool of addresses/prefixes it must send Advertise with -# NoAddrsAvail/NoPrefixAvail status in response to clients Solicit. -# Without this patch server having empty pool of addresses/prefixes was ignoring -# client's' Solicit when client was also sending address in IA_NA or prefix in IA_PD as a preference. -# 2) When client sends prefix in IA_PD as a preference and server doesn't have -# this prefix in any pool the server should offer other free prefix. -# Without this patch server ignored client's Solicit in which the client was sending -# prefix in IA_PD (as a preference) and this prefix was not in any of server's pools. -# (Submitted to dhcp-bugs@isc.org - [ISC-Bugs #22676]) -%patch28 -p1 -b .noprefixavail - #Build dhcp's libraries as shared libs instead of static libs. %patch30 -p1 -b .sharedlib @@ -616,6 +604,9 @@ fi %changelog +* Mon Apr 16 2012 Jiri Popelka - 12:4.2.4-0.1.b1 +- 4.2.4b1: noprefixavail.patch merged upstream + * Fri Mar 30 2012 Jiri Popelka - 12:4.2.3-25.P2 - move dhclient & dhclient-script from /sbin to /usr/sbin diff --git a/sources b/sources index ad71aa8..64fb9ad 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ 14f57fd580d01633d0fad4809007a801 dhcp-4.2.3-P2.tar.gz +50f45d0436417e777d5b6040d7a38c48 dhcp-4.2.4b1.tar.gz