diff --git a/dhcp-duid_uuid.patch b/dhcp-duid_uuid.patch new file mode 100644 index 0000000..7fe5cb6 --- /dev/null +++ b/dhcp-duid_uuid.patch @@ -0,0 +1,123 @@ +diff -up dhcp-4.3.3/client/dhclient.c.duid_uuid dhcp-4.3.3/client/dhclient.c +--- dhcp-4.3.3/client/dhclient.c.duid_uuid 2015-12-14 12:10:54.694082625 +0100 ++++ dhcp-4.3.3/client/dhclient.c 2015-12-14 12:13:19.538018362 +0100 +@@ -3328,6 +3328,59 @@ write_options(struct client_state *clien + } + } + ++int unhexchar(char c) { ++ ++ if (c >= '0' && c <= '9') ++ return c - '0'; ++ ++ if (c >= 'a' && c <= 'f') ++ return c - 'a' + 10; ++ ++ if (c >= 'A' && c <= 'F') ++ return c - 'A' + 10; ++ ++ return -1; ++} ++ ++isc_result_t ++read_uuid(u_int8_t* uuid) { ++ const char *id_fname = "/etc/machine-id"; ++ char id[32]; ++ size_t nread; ++ FILE * file = fopen( id_fname , "r"); ++ if (!file) { ++ log_debug("Cannot open %s", id_fname); ++ return ISC_R_IOERROR; ++ } ++ nread = fread(id, 1, sizeof id, file); ++ fclose(file); ++ ++ if (nread < 32) { ++ log_debug("Not enough data in %s", id_fname); ++ return ISC_R_IOERROR; ++ } ++ ++ for (int j = 0; j < 16; j++) { ++ int a, b; ++ ++ a = unhexchar(id[j*2]); ++ b = unhexchar(id[j*2+1]); ++ ++ if (a < 0 || b < 0) { ++ log_debug("Wrong data in %s", id_fname); ++ return ISC_R_IOERROR; ++ } ++ uuid[j] = a << 4 | b; ++ } ++ ++ /* Set UUID version to 4 --- truly random generation */ ++ uuid[6] = (uuid[6] & 0x0F) | 0x40; ++ /* Set the UUID variant to DCE */ ++ uuid[8] = (uuid[8] & 0x3F) | 0x80; ++ ++ return ISC_R_SUCCESS; ++} ++ + /* + * The "best" default DUID, since we cannot predict any information + * about the system (such as whether or not the hardware addresses are +@@ -3348,6 +3401,7 @@ form_duid(struct data_string *duid, cons + struct interface_info *ip; + int len; + char *str; ++ u_int8_t uuid[16]; + + /* For now, just use the first interface on the list. */ + ip = interfaces; +@@ -3368,9 +3422,16 @@ form_duid(struct data_string *duid, cons + (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf))) + log_fatal("Impossible hardware address length at %s:%d.", MDL); + +- if (duid_type == 0) +- duid_type = stateless ? DUID_LL : DUID_LLT; +- ++ if (duid_type == 0) { ++ if (read_uuid(uuid) == ISC_R_SUCCESS) ++ duid_type = DUID_UUID; ++ else ++ duid_type = stateless ? DUID_LL : DUID_LLT; ++ } ++ ++ if (duid_type == DUID_UUID) ++ len = 2 + sizeof (uuid); ++ else { + /* + * 2 bytes for the 'duid type' field. + * 2 bytes for the 'htype' field. +@@ -3381,13 +3442,18 @@ form_duid(struct data_string *duid, cons + len = 4 + (ip->hw_address.hlen - 1); + if (duid_type == DUID_LLT) + len += 4; ++ } + if (!buffer_allocate(&duid->buffer, len, MDL)) + log_fatal("no memory for default DUID!"); + duid->data = duid->buffer->data; + duid->len = len; + ++ if (duid_type == DUID_UUID) { ++ putUShort(duid->buffer->data, DUID_UUID); ++ memcpy(duid->buffer->data + 2, uuid, sizeof(uuid)); ++ } + /* Basic Link Local Address type of DUID. */ +- if (duid_type == DUID_LLT) { ++ else if (duid_type == DUID_LLT) { + putUShort(duid->buffer->data, DUID_LLT); + putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]); + putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH); +diff -up dhcp-4.3.3/includes/dhcp6.h.duid_uuid dhcp-4.3.3/includes/dhcp6.h +--- dhcp-4.3.3/includes/dhcp6.h.duid_uuid 2015-08-26 21:13:14.000000000 +0200 ++++ dhcp-4.3.3/includes/dhcp6.h 2015-12-14 12:12:33.258038895 +0100 +@@ -119,6 +119,8 @@ extern const int dhcpv6_type_name_max; + #define DUID_LLT 1 + #define DUID_EN 2 + #define DUID_LL 3 ++/* RFC6355 */ ++#define DUID_UUID 4 + + /* Offsets into IA_*'s where Option spaces commence. */ + #define IA_NA_OFFSET 12 /* IAID, T1, T2, all 4 octets each */ diff --git a/dhcp.spec b/dhcp.spec index 4a8149d..34e79ba 100644 --- a/dhcp.spec +++ b/dhcp.spec @@ -18,7 +18,7 @@ Summary: Dynamic host configuration protocol software Name: dhcp Version: 4.3.3 -Release: 8%{?dist} +Release: 9%{?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. @@ -62,8 +62,9 @@ Patch21: dhcp-PPP.patch Patch23: dhcp-lpf-ib.patch Patch24: dhcp-IPoIB-log-id.patch Patch25: dhcp-improved-xid.patch -Patch26: dhcp-gpxe-cid.patch -Patch27: dhcp-duidv4.patch +#Patch26: dhcp-gpxe-cid.patch +Patch26: dhcp-duidv4.patch +Patch27: dhcp-duid_uuid.patch Patch28: dhcp-systemtap.patch Patch29: dhcp-getifaddrs.patch Patch30: dhcp-omapi-leak.patch @@ -295,10 +296,13 @@ rm bind/bind.tar.gz # add GUID/DUID to dhcpd logs (#1064416) %patch24 -p1 -b .IPoIB-log-id %patch25 -p1 -b .improved-xid + # create client identifier per rfc4390 #%%patch26 -p1 -b .gpxe-cid (not needed as we use DUIDs - see next patch) # Turn on creating/sending of DUID as client identifier with DHCPv4 clients (#560361c#40, rfc4361) -%patch27 -p1 -b .duidv4 +%patch26 -p1 -b .duidv4 +# Implement DUID-UUID (RFC 6355) and make it default DUID type (#560361#60) +%patch27 -p1 -b .duid_uuid # http://sourceware.org/systemtap/wiki/SystemTap %patch28 -p1 -b .systemtap @@ -663,6 +667,9 @@ done %doc doc/html/ %changelog +* Mon Dec 14 2015 Jiri Popelka - 12:4.3.3-9 +- implement DUID-UUID (RFC 6355) and make it default DUID type (#560361#60) + * Tue Nov 24 2015 Jiri Popelka - 12:4.3.3-8 - dispatcher.d/12-dhcpd: use reset-failed command