]> git.ipfire.org Git - ipfire-3.x.git/blame - dhcp/patches/0024-dhcp-duid_uuid.patch
dhcp: Update to 4.3.5b1
[ipfire-3.x.git] / dhcp / patches / 0024-dhcp-duid_uuid.patch
CommitLineData
d8feb2d7
SS
1diff -up dhcp-4.3.4/client/dhclient.c.duid_uuid dhcp-4.3.4/client/dhclient.c
2--- dhcp-4.3.4/client/dhclient.c.duid_uuid 2016-04-29 12:58:14.846150838 +0200
3+++ dhcp-4.3.4/client/dhclient.c 2016-04-29 12:58:14.851150839 +0200
4@@ -3868,6 +3868,59 @@ write_options(struct client_state *clien
5 }
6 }
7
8+int unhexchar(char c) {
9+
10+ if (c >= '0' && c <= '9')
11+ return c - '0';
12+
13+ if (c >= 'a' && c <= 'f')
14+ return c - 'a' + 10;
15+
16+ if (c >= 'A' && c <= 'F')
17+ return c - 'A' + 10;
18+
19+ return -1;
20+}
21+
22+isc_result_t
23+read_uuid(u_int8_t* uuid) {
24+ const char *id_fname = "/etc/machine-id";
25+ char id[32];
26+ size_t nread;
27+ FILE * file = fopen( id_fname , "r");
28+ if (!file) {
29+ log_debug("Cannot open %s", id_fname);
30+ return ISC_R_IOERROR;
31+ }
32+ nread = fread(id, 1, sizeof id, file);
33+ fclose(file);
34+
35+ if (nread < 32) {
36+ log_debug("Not enough data in %s", id_fname);
37+ return ISC_R_IOERROR;
38+ }
39+
40+ for (int j = 0; j < 16; j++) {
41+ int a, b;
42+
43+ a = unhexchar(id[j*2]);
44+ b = unhexchar(id[j*2+1]);
45+
46+ if (a < 0 || b < 0) {
47+ log_debug("Wrong data in %s", id_fname);
48+ return ISC_R_IOERROR;
49+ }
50+ uuid[j] = a << 4 | b;
51+ }
52+
53+ /* Set UUID version to 4 --- truly random generation */
54+ uuid[6] = (uuid[6] & 0x0F) | 0x40;
55+ /* Set the UUID variant to DCE */
56+ uuid[8] = (uuid[8] & 0x3F) | 0x80;
57+
58+ return ISC_R_SUCCESS;
59+}
60+
61 /*
62 * The "best" default DUID, since we cannot predict any information
63 * about the system (such as whether or not the hardware addresses are
64@@ -3888,6 +3941,7 @@ form_duid(struct data_string *duid, cons
65 struct interface_info *ip;
66 int len;
67 char *str;
68+ u_int8_t uuid[16];
69
70 /* For now, just use the first interface on the list. */
71 ip = interfaces;
72@@ -3908,9 +3962,16 @@ form_duid(struct data_string *duid, cons
73 (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
74 log_fatal("Impossible hardware address length at %s:%d.", MDL);
75
76- if (duid_type == 0)
77- duid_type = stateless ? DUID_LL : DUID_LLT;
78-
79+ if (duid_type == 0) {
80+ if (read_uuid(uuid) == ISC_R_SUCCESS)
81+ duid_type = DUID_UUID;
82+ else
83+ duid_type = stateless ? DUID_LL : DUID_LLT;
84+ }
85+
86+ if (duid_type == DUID_UUID)
87+ len = 2 + sizeof (uuid);
88+ else {
89 /*
90 * 2 bytes for the 'duid type' field.
91 * 2 bytes for the 'htype' field.
92@@ -3921,13 +3982,18 @@ form_duid(struct data_string *duid, cons
93 len = 4 + (ip->hw_address.hlen - 1);
94 if (duid_type == DUID_LLT)
95 len += 4;
96+ }
97 if (!buffer_allocate(&duid->buffer, len, MDL))
98 log_fatal("no memory for default DUID!");
99 duid->data = duid->buffer->data;
100 duid->len = len;
101
102+ if (duid_type == DUID_UUID) {
103+ putUShort(duid->buffer->data, DUID_UUID);
104+ memcpy(duid->buffer->data + 2, uuid, sizeof(uuid));
105+ }
106 /* Basic Link Local Address type of DUID. */
107- if (duid_type == DUID_LLT) {
108+ else if (duid_type == DUID_LLT) {
109 putUShort(duid->buffer->data, DUID_LLT);
110 putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
111 putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);