]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp-client.c
dhcp: fix comparison with previous lease
[thirdparty/systemd.git] / src / libsystemd-network / sd-dhcp-client.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright © 2013 Intel Corporation. All rights reserved.
4 ***/
5
6 #include <errno.h>
7 #include <net/ethernet.h>
8 #include <net/if_arp.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/ioctl.h>
13 #include <linux/if_infiniband.h>
14
15 #include "sd-dhcp-client.h"
16
17 #include "alloc-util.h"
18 #include "async.h"
19 #include "dhcp-identifier.h"
20 #include "dhcp-internal.h"
21 #include "dhcp-lease-internal.h"
22 #include "dhcp-protocol.h"
23 #include "dns-domain.h"
24 #include "event-util.h"
25 #include "hostname-util.h"
26 #include "io-util.h"
27 #include "memory-util.h"
28 #include "random-util.h"
29 #include "string-util.h"
30 #include "strv.h"
31
32 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
33 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
34
35 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
36 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
37
38 struct sd_dhcp_client {
39 unsigned n_ref;
40
41 DHCPState state;
42 sd_event *event;
43 int event_priority;
44 sd_event_source *timeout_resend;
45 int ifindex;
46 int fd;
47 uint16_t port;
48 union sockaddr_union link;
49 sd_event_source *receive_message;
50 bool request_broadcast;
51 uint8_t *req_opts;
52 size_t req_opts_allocated;
53 size_t req_opts_size;
54 bool anonymize;
55 be32_t last_addr;
56 uint8_t mac_addr[MAX_MAC_ADDR_LEN];
57 size_t mac_addr_len;
58 uint16_t arp_type;
59 struct {
60 uint8_t type;
61 union {
62 struct {
63 /* 0: Generic (non-LL) (RFC 2132) */
64 uint8_t data[MAX_CLIENT_ID_LEN];
65 } _packed_ gen;
66 struct {
67 /* 1: Ethernet Link-Layer (RFC 2132) */
68 uint8_t haddr[ETH_ALEN];
69 } _packed_ eth;
70 struct {
71 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
72 uint8_t haddr[0];
73 } _packed_ ll;
74 struct {
75 /* 255: Node-specific (RFC 4361) */
76 be32_t iaid;
77 struct duid duid;
78 } _packed_ ns;
79 struct {
80 uint8_t data[MAX_CLIENT_ID_LEN];
81 } _packed_ raw;
82 };
83 } _packed_ client_id;
84 size_t client_id_len;
85 char *hostname;
86 char *vendor_class_identifier;
87 char **user_class;
88 uint32_t mtu;
89 uint32_t xid;
90 usec_t start_time;
91 uint64_t attempt;
92 uint64_t max_attempts;
93 usec_t request_sent;
94 sd_event_source *timeout_t1;
95 sd_event_source *timeout_t2;
96 sd_event_source *timeout_expire;
97 sd_dhcp_client_callback_t callback;
98 void *userdata;
99 sd_dhcp_lease *lease;
100 usec_t start_delay;
101 };
102
103 static const uint8_t default_req_opts[] = {
104 SD_DHCP_OPTION_SUBNET_MASK,
105 SD_DHCP_OPTION_ROUTER,
106 SD_DHCP_OPTION_HOST_NAME,
107 SD_DHCP_OPTION_DOMAIN_NAME,
108 SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
109 };
110
111 /* RFC7844 section 3:
112 MAY contain the Parameter Request List option.
113 RFC7844 section 3.6:
114 The client intending to protect its privacy SHOULD only request a
115 minimal number of options in the PRL and SHOULD also randomly shuffle
116 the ordering of option codes in the PRL. If this random ordering
117 cannot be implemented, the client MAY order the option codes in the
118 PRL by option code number (lowest to highest).
119 */
120 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
121 static const uint8_t default_req_opts_anonymize[] = {
122 SD_DHCP_OPTION_SUBNET_MASK, /* 1 */
123 SD_DHCP_OPTION_ROUTER, /* 3 */
124 SD_DHCP_OPTION_DOMAIN_NAME_SERVER, /* 6 */
125 SD_DHCP_OPTION_DOMAIN_NAME, /* 15 */
126 SD_DHCP_OPTION_ROUTER_DISCOVER, /* 31 */
127 SD_DHCP_OPTION_STATIC_ROUTE, /* 33 */
128 SD_DHCP_OPTION_VENDOR_SPECIFIC, /* 43 */
129 SD_DHCP_OPTION_NETBIOS_NAMESERVER, /* 44 */
130 SD_DHCP_OPTION_NETBIOS_NODETYPE, /* 46 */
131 SD_DHCP_OPTION_NETBIOS_SCOPE, /* 47 */
132 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, /* 121 */
133 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, /* 249 */
134 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY, /* 252 */
135 };
136
137 static int client_receive_message_raw(
138 sd_event_source *s,
139 int fd,
140 uint32_t revents,
141 void *userdata);
142 static int client_receive_message_udp(
143 sd_event_source *s,
144 int fd,
145 uint32_t revents,
146 void *userdata);
147 static void client_stop(sd_dhcp_client *client, int error);
148
149 int sd_dhcp_client_set_callback(
150 sd_dhcp_client *client,
151 sd_dhcp_client_callback_t cb,
152 void *userdata) {
153
154 assert_return(client, -EINVAL);
155
156 client->callback = cb;
157 client->userdata = userdata;
158
159 return 0;
160 }
161
162 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
163 assert_return(client, -EINVAL);
164
165 client->request_broadcast = !!broadcast;
166
167 return 0;
168 }
169
170 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
171 size_t i;
172
173 assert_return(client, -EINVAL);
174 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
175
176 switch(option) {
177
178 case SD_DHCP_OPTION_PAD:
179 case SD_DHCP_OPTION_OVERLOAD:
180 case SD_DHCP_OPTION_MESSAGE_TYPE:
181 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST:
182 case SD_DHCP_OPTION_END:
183 return -EINVAL;
184
185 default:
186 break;
187 }
188
189 for (i = 0; i < client->req_opts_size; i++)
190 if (client->req_opts[i] == option)
191 return -EEXIST;
192
193 if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
194 client->req_opts_size + 1))
195 return -ENOMEM;
196
197 client->req_opts[client->req_opts_size++] = option;
198
199 return 0;
200 }
201
202 int sd_dhcp_client_set_request_address(
203 sd_dhcp_client *client,
204 const struct in_addr *last_addr) {
205
206 assert_return(client, -EINVAL);
207 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
208
209 if (last_addr)
210 client->last_addr = last_addr->s_addr;
211 else
212 client->last_addr = INADDR_ANY;
213
214 return 0;
215 }
216
217 int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) {
218
219 assert_return(client, -EINVAL);
220 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
221 assert_return(ifindex > 0, -EINVAL);
222
223 client->ifindex = ifindex;
224 return 0;
225 }
226
227 int sd_dhcp_client_set_mac(
228 sd_dhcp_client *client,
229 const uint8_t *addr,
230 size_t addr_len,
231 uint16_t arp_type) {
232
233 DHCP_CLIENT_DONT_DESTROY(client);
234 bool need_restart = false;
235
236 assert_return(client, -EINVAL);
237 assert_return(addr, -EINVAL);
238 assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
239 assert_return(arp_type > 0, -EINVAL);
240
241 if (arp_type == ARPHRD_ETHER)
242 assert_return(addr_len == ETH_ALEN, -EINVAL);
243 else if (arp_type == ARPHRD_INFINIBAND)
244 assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
245 else
246 return -EINVAL;
247
248 if (client->mac_addr_len == addr_len &&
249 memcmp(&client->mac_addr, addr, addr_len) == 0)
250 return 0;
251
252 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
253 log_dhcp_client(client, "Changing MAC address on running DHCP client, restarting");
254 need_restart = true;
255 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
256 }
257
258 memcpy(&client->mac_addr, addr, addr_len);
259 client->mac_addr_len = addr_len;
260 client->arp_type = arp_type;
261
262 if (need_restart && client->state != DHCP_STATE_STOPPED)
263 sd_dhcp_client_start(client);
264
265 return 0;
266 }
267
268 int sd_dhcp_client_get_client_id(
269 sd_dhcp_client *client,
270 uint8_t *type,
271 const uint8_t **data,
272 size_t *data_len) {
273
274 assert_return(client, -EINVAL);
275 assert_return(type, -EINVAL);
276 assert_return(data, -EINVAL);
277 assert_return(data_len, -EINVAL);
278
279 *type = 0;
280 *data = NULL;
281 *data_len = 0;
282 if (client->client_id_len) {
283 *type = client->client_id.type;
284 *data = client->client_id.raw.data;
285 *data_len = client->client_id_len - sizeof(client->client_id.type);
286 }
287
288 return 0;
289 }
290
291 int sd_dhcp_client_set_client_id(
292 sd_dhcp_client *client,
293 uint8_t type,
294 const uint8_t *data,
295 size_t data_len) {
296
297 DHCP_CLIENT_DONT_DESTROY(client);
298 bool need_restart = false;
299
300 assert_return(client, -EINVAL);
301 assert_return(data, -EINVAL);
302 assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL);
303
304 if (client->client_id_len == data_len + sizeof(client->client_id.type) &&
305 client->client_id.type == type &&
306 memcmp(&client->client_id.raw.data, data, data_len) == 0)
307 return 0;
308
309 /* For hardware types, log debug message about unexpected data length.
310 *
311 * Note that infiniband's INFINIBAND_ALEN is 20 bytes long, but only
312 * last last 8 bytes of the address are stable and suitable to put into
313 * the client-id. The caller is advised to account for that. */
314 if ((type == ARPHRD_ETHER && data_len != ETH_ALEN) ||
315 (type == ARPHRD_INFINIBAND && data_len != 8))
316 log_dhcp_client(client, "Changing client ID to hardware type %u with "
317 "unexpected address length %zu",
318 type, data_len);
319
320 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
321 log_dhcp_client(client, "Changing client ID on running DHCP "
322 "client, restarting");
323 need_restart = true;
324 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
325 }
326
327 client->client_id.type = type;
328 memcpy(&client->client_id.raw.data, data, data_len);
329 client->client_id_len = data_len + sizeof (client->client_id.type);
330
331 if (need_restart && client->state != DHCP_STATE_STOPPED)
332 sd_dhcp_client_start(client);
333
334 return 0;
335 }
336
337 /**
338 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
339 * without further modification. Otherwise, if duid_type is supported, DUID
340 * is set based on that type. Otherwise, an error is returned.
341 */
342 static int dhcp_client_set_iaid_duid_internal(
343 sd_dhcp_client *client,
344 bool iaid_append,
345 bool iaid_set,
346 uint32_t iaid,
347 uint16_t duid_type,
348 const void *duid,
349 size_t duid_len,
350 usec_t llt_time) {
351
352 DHCP_CLIENT_DONT_DESTROY(client);
353 int r;
354 size_t len;
355
356 assert_return(client, -EINVAL);
357 assert_return(duid_len == 0 || duid, -EINVAL);
358
359 if (duid) {
360 r = dhcp_validate_duid_len(duid_type, duid_len, true);
361 if (r < 0)
362 return r;
363 }
364
365 zero(client->client_id);
366 client->client_id.type = 255;
367
368 if (iaid_append) {
369 if (iaid_set)
370 client->client_id.ns.iaid = htobe32(iaid);
371 else {
372 r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr,
373 client->mac_addr_len,
374 true,
375 &client->client_id.ns.iaid);
376 if (r < 0)
377 return r;
378 }
379 }
380
381 if (duid) {
382 client->client_id.ns.duid.type = htobe16(duid_type);
383 memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
384 len = sizeof(client->client_id.ns.duid.type) + duid_len;
385 } else
386 switch (duid_type) {
387 case DUID_TYPE_LLT:
388 if (client->mac_addr_len == 0)
389 return -EOPNOTSUPP;
390
391 r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
392 if (r < 0)
393 return r;
394 break;
395 case DUID_TYPE_EN:
396 r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
397 if (r < 0)
398 return r;
399 break;
400 case DUID_TYPE_LL:
401 if (client->mac_addr_len == 0)
402 return -EOPNOTSUPP;
403
404 r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
405 if (r < 0)
406 return r;
407 break;
408 case DUID_TYPE_UUID:
409 r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len);
410 if (r < 0)
411 return r;
412 break;
413 default:
414 return -EINVAL;
415 }
416
417 client->client_id_len = sizeof(client->client_id.type) + len +
418 (iaid_append ? sizeof(client->client_id.ns.iaid) : 0);
419
420 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
421 log_dhcp_client(client, "Configured %sDUID, restarting.", iaid_append ? "IAID+" : "");
422 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
423 sd_dhcp_client_start(client);
424 }
425
426 return 0;
427 }
428
429 int sd_dhcp_client_set_iaid_duid(
430 sd_dhcp_client *client,
431 bool iaid_set,
432 uint32_t iaid,
433 uint16_t duid_type,
434 const void *duid,
435 size_t duid_len) {
436 return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, duid_type, duid, duid_len, 0);
437 }
438
439 int sd_dhcp_client_set_iaid_duid_llt(
440 sd_dhcp_client *client,
441 bool iaid_set,
442 uint32_t iaid,
443 usec_t llt_time) {
444 return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, DUID_TYPE_LLT, NULL, 0, llt_time);
445 }
446
447 int sd_dhcp_client_set_duid(
448 sd_dhcp_client *client,
449 uint16_t duid_type,
450 const void *duid,
451 size_t duid_len) {
452 return dhcp_client_set_iaid_duid_internal(client, false, false, 0, duid_type, duid, duid_len, 0);
453 }
454
455 int sd_dhcp_client_set_duid_llt(
456 sd_dhcp_client *client,
457 usec_t llt_time) {
458 return dhcp_client_set_iaid_duid_internal(client, false, false, 0, DUID_TYPE_LLT, NULL, 0, llt_time);
459 }
460
461 int sd_dhcp_client_set_hostname(
462 sd_dhcp_client *client,
463 const char *hostname) {
464
465 assert_return(client, -EINVAL);
466
467 /* Make sure hostnames qualify as DNS and as Linux hostnames */
468 if (hostname &&
469 !(hostname_is_valid(hostname, false) && dns_name_is_valid(hostname) > 0))
470 return -EINVAL;
471
472 return free_and_strdup(&client->hostname, hostname);
473 }
474
475 int sd_dhcp_client_set_vendor_class_identifier(
476 sd_dhcp_client *client,
477 const char *vci) {
478
479 assert_return(client, -EINVAL);
480
481 return free_and_strdup(&client->vendor_class_identifier, vci);
482 }
483
484 int sd_dhcp_client_set_user_class(
485 sd_dhcp_client *client,
486 const char* const* user_class) {
487
488 _cleanup_strv_free_ char **s = NULL;
489 char **p;
490
491 STRV_FOREACH(p, (char **) user_class)
492 if (strlen(*p) > 255)
493 return -ENAMETOOLONG;
494
495 s = strv_copy((char **) user_class);
496 if (!s)
497 return -ENOMEM;
498
499 client->user_class = TAKE_PTR(s);
500
501 return 0;
502 }
503
504 int sd_dhcp_client_set_client_port(
505 sd_dhcp_client *client,
506 uint16_t port) {
507
508 assert_return(client, -EINVAL);
509
510 client->port = port;
511
512 return 0;
513 }
514
515 int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
516 assert_return(client, -EINVAL);
517 assert_return(mtu >= DHCP_DEFAULT_MIN_SIZE, -ERANGE);
518
519 client->mtu = mtu;
520
521 return 0;
522 }
523
524 int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempts) {
525 assert_return(client, -EINVAL);
526
527 client->max_attempts = max_attempts;
528
529 return 0;
530 }
531
532 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
533 assert_return(client, -EINVAL);
534
535 if (!IN_SET(client->state, DHCP_STATE_SELECTING, DHCP_STATE_BOUND, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING))
536 return -EADDRNOTAVAIL;
537
538 if (ret)
539 *ret = client->lease;
540
541 return 0;
542 }
543
544 static int client_notify(sd_dhcp_client *client, int event) {
545 assert(client);
546
547 if (client->callback)
548 return client->callback(client, event, client->userdata);
549
550 return 0;
551 }
552
553 static int client_initialize(sd_dhcp_client *client) {
554 assert_return(client, -EINVAL);
555
556 client->receive_message = sd_event_source_unref(client->receive_message);
557
558 client->fd = asynchronous_close(client->fd);
559
560 (void) event_source_disable(client->timeout_resend);
561 (void) event_source_disable(client->timeout_t1);
562 (void) event_source_disable(client->timeout_t2);
563 (void) event_source_disable(client->timeout_expire);
564
565 client->attempt = 0;
566
567 client->state = DHCP_STATE_INIT;
568 client->xid = 0;
569
570 client->lease = sd_dhcp_lease_unref(client->lease);
571
572 return 0;
573 }
574
575 static void client_stop(sd_dhcp_client *client, int error) {
576 assert(client);
577
578 if (error < 0)
579 log_dhcp_client(client, "STOPPED: %s", strerror(-error));
580 else if (error == SD_DHCP_CLIENT_EVENT_STOP)
581 log_dhcp_client(client, "STOPPED");
582 else
583 log_dhcp_client(client, "STOPPED: Unknown event");
584
585 client_notify(client, error);
586
587 client_initialize(client);
588 }
589
590 static int client_message_init(
591 sd_dhcp_client *client,
592 DHCPPacket **ret,
593 uint8_t type,
594 size_t *_optlen,
595 size_t *_optoffset) {
596
597 _cleanup_free_ DHCPPacket *packet = NULL;
598 size_t optlen, optoffset, size;
599 be16_t max_size;
600 usec_t time_now;
601 uint16_t secs;
602 int r;
603
604 assert(client);
605 assert(client->start_time);
606 assert(ret);
607 assert(_optlen);
608 assert(_optoffset);
609 assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST, DHCP_RELEASE));
610
611 optlen = DHCP_MIN_OPTIONS_SIZE;
612 size = sizeof(DHCPPacket) + optlen;
613
614 packet = malloc0(size);
615 if (!packet)
616 return -ENOMEM;
617
618 r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
619 client->arp_type, optlen, &optoffset);
620 if (r < 0)
621 return r;
622
623 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
624 refuse to issue an DHCP lease if 'secs' is set to zero */
625 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
626 if (r < 0)
627 return r;
628 assert(time_now >= client->start_time);
629
630 /* seconds between sending first and last DISCOVER
631 * must always be strictly positive to deal with broken servers */
632 secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
633 packet->dhcp.secs = htobe16(secs);
634
635 /* RFC2132 section 4.1
636 A client that cannot receive unicast IP datagrams until its protocol
637 software has been configured with an IP address SHOULD set the
638 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
639 DHCPREQUEST messages that client sends. The BROADCAST bit will
640 provide a hint to the DHCP server and BOOTP relay agent to broadcast
641 any messages to the client on the client's subnet.
642
643 Note: some interfaces needs this to be enabled, but some networks
644 needs this to be disabled as broadcasts are filteretd, so this
645 needs to be configurable */
646 if (client->request_broadcast || client->arp_type != ARPHRD_ETHER)
647 packet->dhcp.flags = htobe16(0x8000);
648
649 /* RFC2132 section 4.1.1:
650 The client MUST include its hardware address in the ’chaddr’ field, if
651 necessary for delivery of DHCP reply messages. Non-Ethernet
652 interfaces will leave 'chaddr' empty and use the client identifier
653 instead (eg, RFC 4390 section 2.1).
654 */
655 if (client->arp_type == ARPHRD_ETHER)
656 memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
657
658 /* If no client identifier exists, construct an RFC 4361-compliant one */
659 if (client->client_id_len == 0) {
660 size_t duid_len;
661
662 client->client_id.type = 255;
663
664 r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len,
665 true, &client->client_id.ns.iaid);
666 if (r < 0)
667 return r;
668
669 r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &duid_len);
670 if (r < 0)
671 return r;
672
673 client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid_len;
674 }
675
676 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
677 Identifier option is not set */
678 if (client->client_id_len) {
679 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
680 SD_DHCP_OPTION_CLIENT_IDENTIFIER,
681 client->client_id_len,
682 &client->client_id);
683 if (r < 0)
684 return r;
685 }
686
687 /* RFC2131 section 3.5:
688 in its initial DHCPDISCOVER or DHCPREQUEST message, a
689 client may provide the server with a list of specific
690 parameters the client is interested in. If the client
691 includes a list of parameters in a DHCPDISCOVER message,
692 it MUST include that list in any subsequent DHCPREQUEST
693 messages.
694 */
695
696 /* RFC7844 section 3:
697 MAY contain the Parameter Request List option. */
698 /* NOTE: in case that there would be an option to do not send
699 * any PRL at all, the size should be checked before sending */
700 if (client->req_opts_size > 0 && type != DHCP_RELEASE) {
701 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
702 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
703 client->req_opts_size, client->req_opts);
704 if (r < 0)
705 return r;
706 }
707
708 /* RFC2131 section 3.5:
709 The client SHOULD include the ’maximum DHCP message size’ option to
710 let the server know how large the server may make its DHCP messages.
711
712 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
713 than the defined default size unless the Maximum Message Size option
714 is explicitly set
715
716 RFC3442 "Requirements to Avoid Sizing Constraints":
717 Because a full routing table can be quite large, the standard 576
718 octet maximum size for a DHCP message may be too short to contain
719 some legitimate Classless Static Route options. Because of this,
720 clients implementing the Classless Static Route option SHOULD send a
721 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
722 stack is capable of receiving larger IP datagrams. In this case, the
723 client SHOULD set the value of this option to at least the MTU of the
724 interface that the client is configuring. The client MAY set the
725 value of this option higher, up to the size of the largest UDP packet
726 it is prepared to accept. (Note that the value specified in the
727 Maximum DHCP Message Size option is the total maximum packet size,
728 including IP and UDP headers.)
729 */
730 /* RFC7844 section 3:
731 SHOULD NOT contain any other option. */
732 if (!client->anonymize && type != DHCP_RELEASE) {
733 max_size = htobe16(size);
734 r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
735 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
736 2, &max_size);
737 if (r < 0)
738 return r;
739 }
740
741 *_optlen = optlen;
742 *_optoffset = optoffset;
743 *ret = TAKE_PTR(packet);
744
745 return 0;
746 }
747
748 static int client_append_fqdn_option(
749 DHCPMessage *message,
750 size_t optlen,
751 size_t *optoffset,
752 const char *fqdn) {
753
754 uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH];
755 int r;
756
757 buffer[0] = DHCP_FQDN_FLAG_S | /* Request server to perform A RR DNS updates */
758 DHCP_FQDN_FLAG_E; /* Canonical wire format */
759 buffer[1] = 0; /* RCODE1 (deprecated) */
760 buffer[2] = 0; /* RCODE2 (deprecated) */
761
762 r = dns_name_to_wire_format(fqdn, buffer + 3, sizeof(buffer) - 3, false);
763 if (r > 0)
764 r = dhcp_option_append(message, optlen, optoffset, 0,
765 SD_DHCP_OPTION_FQDN, 3 + r, buffer);
766
767 return r;
768 }
769
770 static int dhcp_client_send_raw(
771 sd_dhcp_client *client,
772 DHCPPacket *packet,
773 size_t len) {
774
775 dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
776 INADDR_BROADCAST, DHCP_PORT_SERVER, len);
777
778 return dhcp_network_send_raw_socket(client->fd, &client->link,
779 packet, len);
780 }
781
782 static int client_send_discover(sd_dhcp_client *client) {
783 _cleanup_free_ DHCPPacket *discover = NULL;
784 size_t optoffset, optlen;
785 int r;
786
787 assert(client);
788 assert(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_SELECTING));
789
790 r = client_message_init(client, &discover, DHCP_DISCOVER,
791 &optlen, &optoffset);
792 if (r < 0)
793 return r;
794
795 /* the client may suggest values for the network address
796 and lease time in the DHCPDISCOVER message. The client may include
797 the ’requested IP address’ option to suggest that a particular IP
798 address be assigned, and may include the ’IP address lease time’
799 option to suggest the lease time it would like.
800 */
801 if (client->last_addr != INADDR_ANY) {
802 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
803 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
804 4, &client->last_addr);
805 if (r < 0)
806 return r;
807 }
808
809 if (client->hostname) {
810 /* According to RFC 4702 "clients that send the Client FQDN option in
811 their messages MUST NOT also send the Host Name option". Just send
812 one of the two depending on the hostname type.
813 */
814 if (dns_name_is_single_label(client->hostname)) {
815 /* it is unclear from RFC 2131 if client should send hostname in
816 DHCPDISCOVER but dhclient does and so we do as well
817 */
818 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
819 SD_DHCP_OPTION_HOST_NAME,
820 strlen(client->hostname), client->hostname);
821 } else
822 r = client_append_fqdn_option(&discover->dhcp, optlen, &optoffset,
823 client->hostname);
824 if (r < 0)
825 return r;
826 }
827
828 if (client->vendor_class_identifier) {
829 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
830 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
831 strlen(client->vendor_class_identifier),
832 client->vendor_class_identifier);
833 if (r < 0)
834 return r;
835 }
836
837 if (client->user_class) {
838 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
839 SD_DHCP_OPTION_USER_CLASS,
840 strv_length(client->user_class),
841 client->user_class);
842 if (r < 0)
843 return r;
844 }
845
846 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
847 SD_DHCP_OPTION_END, 0, NULL);
848 if (r < 0)
849 return r;
850
851 /* We currently ignore:
852 The client SHOULD wait a random time between one and ten seconds to
853 desynchronize the use of DHCP at startup.
854 */
855 r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
856 if (r < 0)
857 return r;
858
859 log_dhcp_client(client, "DISCOVER");
860
861 return 0;
862 }
863
864 static int client_send_release(sd_dhcp_client *client) {
865 _cleanup_free_ DHCPPacket *release = NULL;
866 size_t optoffset, optlen;
867 int r;
868
869 assert(client);
870 assert(!IN_SET(client->state, DHCP_STATE_STOPPED));
871
872 r = client_message_init(client, &release, DHCP_RELEASE,
873 &optlen, &optoffset);
874 if (r < 0)
875 return r;
876
877 /* Fill up release IP and MAC */
878 release->dhcp.ciaddr = client->lease->address;
879 memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
880
881 r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
882 SD_DHCP_OPTION_END, 0, NULL);
883 if (r < 0)
884 return r;
885
886 r = dhcp_network_send_udp_socket(client->fd,
887 client->lease->server_address,
888 DHCP_PORT_SERVER,
889 &release->dhcp,
890 sizeof(DHCPMessage) + optoffset);
891 if (r < 0)
892 return r;
893
894 log_dhcp_client(client, "RELEASE");
895
896 return 0;
897 }
898
899 static int client_send_request(sd_dhcp_client *client) {
900 _cleanup_free_ DHCPPacket *request = NULL;
901 size_t optoffset, optlen;
902 int r;
903
904 assert(client);
905
906 r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset);
907 if (r < 0)
908 return r;
909
910 switch (client->state) {
911 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
912 SELECTING should be REQUESTING)
913 */
914
915 case DHCP_STATE_REQUESTING:
916 /* Client inserts the address of the selected server in ’server
917 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
918 filled in with the yiaddr value from the chosen DHCPOFFER.
919 */
920
921 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
922 SD_DHCP_OPTION_SERVER_IDENTIFIER,
923 4, &client->lease->server_address);
924 if (r < 0)
925 return r;
926
927 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
928 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
929 4, &client->lease->address);
930 if (r < 0)
931 return r;
932
933 break;
934
935 case DHCP_STATE_INIT_REBOOT:
936 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
937 option MUST be filled in with client’s notion of its previously
938 assigned address. ’ciaddr’ MUST be zero.
939 */
940 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
941 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
942 4, &client->last_addr);
943 if (r < 0)
944 return r;
945 break;
946
947 case DHCP_STATE_RENEWING:
948 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
949 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
950 client’s IP address.
951 */
952
953 case DHCP_STATE_REBINDING:
954 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
955 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
956 client’s IP address.
957
958 This message MUST be broadcast to the 0xffffffff IP broadcast address.
959 */
960 request->dhcp.ciaddr = client->lease->address;
961
962 break;
963
964 case DHCP_STATE_INIT:
965 case DHCP_STATE_SELECTING:
966 case DHCP_STATE_REBOOTING:
967 case DHCP_STATE_BOUND:
968 case DHCP_STATE_STOPPED:
969 return -EINVAL;
970 }
971
972 if (client->hostname) {
973 if (dns_name_is_single_label(client->hostname))
974 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
975 SD_DHCP_OPTION_HOST_NAME,
976 strlen(client->hostname), client->hostname);
977 else
978 r = client_append_fqdn_option(&request->dhcp, optlen, &optoffset,
979 client->hostname);
980 if (r < 0)
981 return r;
982 }
983
984 if (client->vendor_class_identifier) {
985 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
986 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
987 strlen(client->vendor_class_identifier),
988 client->vendor_class_identifier);
989 if (r < 0)
990 return r;
991 }
992
993 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
994 SD_DHCP_OPTION_END, 0, NULL);
995 if (r < 0)
996 return r;
997
998 if (client->state == DHCP_STATE_RENEWING) {
999 r = dhcp_network_send_udp_socket(client->fd,
1000 client->lease->server_address,
1001 DHCP_PORT_SERVER,
1002 &request->dhcp,
1003 sizeof(DHCPMessage) + optoffset);
1004 } else {
1005 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
1006 }
1007 if (r < 0)
1008 return r;
1009
1010 switch (client->state) {
1011
1012 case DHCP_STATE_REQUESTING:
1013 log_dhcp_client(client, "REQUEST (requesting)");
1014 break;
1015
1016 case DHCP_STATE_INIT_REBOOT:
1017 log_dhcp_client(client, "REQUEST (init-reboot)");
1018 break;
1019
1020 case DHCP_STATE_RENEWING:
1021 log_dhcp_client(client, "REQUEST (renewing)");
1022 break;
1023
1024 case DHCP_STATE_REBINDING:
1025 log_dhcp_client(client, "REQUEST (rebinding)");
1026 break;
1027
1028 default:
1029 log_dhcp_client(client, "REQUEST (invalid)");
1030 break;
1031 }
1032
1033 return 0;
1034 }
1035
1036 static int client_start(sd_dhcp_client *client);
1037
1038 static int client_timeout_resend(
1039 sd_event_source *s,
1040 uint64_t usec,
1041 void *userdata) {
1042
1043 sd_dhcp_client *client = userdata;
1044 DHCP_CLIENT_DONT_DESTROY(client);
1045 usec_t next_timeout = 0;
1046 uint64_t time_now;
1047 uint32_t time_left;
1048 int r;
1049
1050 assert(s);
1051 assert(client);
1052 assert(client->event);
1053
1054 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1055 if (r < 0)
1056 goto error;
1057
1058 switch (client->state) {
1059
1060 case DHCP_STATE_RENEWING:
1061
1062 time_left = (client->lease->t2 - client->lease->t1) / 2;
1063 if (time_left < 60)
1064 time_left = 60;
1065
1066 next_timeout = time_now + time_left * USEC_PER_SEC;
1067
1068 break;
1069
1070 case DHCP_STATE_REBINDING:
1071
1072 time_left = (client->lease->lifetime - client->lease->t2) / 2;
1073 if (time_left < 60)
1074 time_left = 60;
1075
1076 next_timeout = time_now + time_left * USEC_PER_SEC;
1077 break;
1078
1079 case DHCP_STATE_REBOOTING:
1080 /* start over as we did not receive a timely ack or nak */
1081 r = client_initialize(client);
1082 if (r < 0)
1083 goto error;
1084
1085 r = client_start(client);
1086 if (r < 0)
1087 goto error;
1088 else {
1089 log_dhcp_client(client, "REBOOTED");
1090 return 0;
1091 }
1092
1093 case DHCP_STATE_INIT:
1094 case DHCP_STATE_INIT_REBOOT:
1095 case DHCP_STATE_SELECTING:
1096 case DHCP_STATE_REQUESTING:
1097 case DHCP_STATE_BOUND:
1098
1099 if (client->attempt < client->max_attempts)
1100 client->attempt++;
1101 else
1102 goto error;
1103
1104 next_timeout = time_now + ((UINT64_C(1) << MIN(client->attempt, (uint64_t) 6)) - 1) * USEC_PER_SEC;
1105
1106 break;
1107
1108 case DHCP_STATE_STOPPED:
1109 r = -EINVAL;
1110 goto error;
1111 }
1112
1113 next_timeout += (random_u32() & 0x1fffff);
1114
1115 r = event_reset_time(client->event, &client->timeout_resend,
1116 clock_boottime_or_monotonic(),
1117 next_timeout, 10 * USEC_PER_MSEC,
1118 client_timeout_resend, client,
1119 client->event_priority, "dhcp4-resend-timer", true);
1120 if (r < 0)
1121 goto error;
1122
1123 switch (client->state) {
1124 case DHCP_STATE_INIT:
1125 r = client_send_discover(client);
1126 if (r >= 0) {
1127 client->state = DHCP_STATE_SELECTING;
1128 client->attempt = 0;
1129 } else if (client->attempt >= client->max_attempts)
1130 goto error;
1131
1132 break;
1133
1134 case DHCP_STATE_SELECTING:
1135 r = client_send_discover(client);
1136 if (r < 0 && client->attempt >= client->max_attempts)
1137 goto error;
1138
1139 break;
1140
1141 case DHCP_STATE_INIT_REBOOT:
1142 case DHCP_STATE_REQUESTING:
1143 case DHCP_STATE_RENEWING:
1144 case DHCP_STATE_REBINDING:
1145 r = client_send_request(client);
1146 if (r < 0 && client->attempt >= client->max_attempts)
1147 goto error;
1148
1149 if (client->state == DHCP_STATE_INIT_REBOOT)
1150 client->state = DHCP_STATE_REBOOTING;
1151
1152 client->request_sent = time_now;
1153
1154 break;
1155
1156 case DHCP_STATE_REBOOTING:
1157 case DHCP_STATE_BOUND:
1158
1159 break;
1160
1161 case DHCP_STATE_STOPPED:
1162 r = -EINVAL;
1163 goto error;
1164 }
1165
1166 return 0;
1167
1168 error:
1169 client_stop(client, r);
1170
1171 /* Errors were dealt with when stopping the client, don't spill
1172 errors into the event loop handler */
1173 return 0;
1174 }
1175
1176 static int client_initialize_io_events(
1177 sd_dhcp_client *client,
1178 sd_event_io_handler_t io_callback) {
1179
1180 int r;
1181
1182 assert(client);
1183 assert(client->event);
1184
1185 r = sd_event_add_io(client->event, &client->receive_message,
1186 client->fd, EPOLLIN, io_callback,
1187 client);
1188 if (r < 0)
1189 goto error;
1190
1191 r = sd_event_source_set_priority(client->receive_message,
1192 client->event_priority);
1193 if (r < 0)
1194 goto error;
1195
1196 r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
1197 if (r < 0)
1198 goto error;
1199
1200 error:
1201 if (r < 0)
1202 client_stop(client, r);
1203
1204 return 0;
1205 }
1206
1207 static int client_initialize_time_events(sd_dhcp_client *client) {
1208 uint64_t usec = 0;
1209 int r;
1210
1211 assert(client);
1212 assert(client->event);
1213
1214 if (client->start_delay) {
1215 assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
1216 usec += client->start_delay;
1217 }
1218
1219 r = event_reset_time(client->event, &client->timeout_resend,
1220 clock_boottime_or_monotonic(),
1221 usec, 0,
1222 client_timeout_resend, client,
1223 client->event_priority, "dhcp4-resend-timer", true);
1224 if (r < 0)
1225 client_stop(client, r);
1226
1227 return 0;
1228
1229 }
1230
1231 static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
1232 client_initialize_io_events(client, io_callback);
1233 client_initialize_time_events(client);
1234
1235 return 0;
1236 }
1237
1238 static int client_start_delayed(sd_dhcp_client *client) {
1239 int r;
1240
1241 assert_return(client, -EINVAL);
1242 assert_return(client->event, -EINVAL);
1243 assert_return(client->ifindex > 0, -EINVAL);
1244 assert_return(client->fd < 0, -EBUSY);
1245 assert_return(client->xid == 0, -EINVAL);
1246 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY);
1247
1248 client->xid = random_u32();
1249
1250 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1251 client->xid, client->mac_addr,
1252 client->mac_addr_len, client->arp_type, client->port);
1253 if (r < 0) {
1254 client_stop(client, r);
1255 return r;
1256 }
1257 client->fd = r;
1258
1259 if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT))
1260 client->start_time = now(clock_boottime_or_monotonic());
1261
1262 return client_initialize_events(client, client_receive_message_raw);
1263 }
1264
1265 static int client_start(sd_dhcp_client *client) {
1266 client->start_delay = 0;
1267 return client_start_delayed(client);
1268 }
1269
1270 static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
1271 sd_dhcp_client *client = userdata;
1272 DHCP_CLIENT_DONT_DESTROY(client);
1273
1274 log_dhcp_client(client, "EXPIRED");
1275
1276 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1277
1278 /* lease was lost, start over if not freed or stopped in callback */
1279 if (client->state != DHCP_STATE_STOPPED) {
1280 client_initialize(client);
1281 client_start(client);
1282 }
1283
1284 return 0;
1285 }
1286
1287 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
1288 sd_dhcp_client *client = userdata;
1289 DHCP_CLIENT_DONT_DESTROY(client);
1290 int r;
1291
1292 assert(client);
1293
1294 client->receive_message = sd_event_source_unref(client->receive_message);
1295 client->fd = asynchronous_close(client->fd);
1296
1297 client->state = DHCP_STATE_REBINDING;
1298 client->attempt = 0;
1299
1300 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1301 client->xid, client->mac_addr,
1302 client->mac_addr_len, client->arp_type,
1303 client->port);
1304 if (r < 0) {
1305 client_stop(client, r);
1306 return 0;
1307 }
1308 client->fd = r;
1309
1310 return client_initialize_events(client, client_receive_message_raw);
1311 }
1312
1313 static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
1314 sd_dhcp_client *client = userdata;
1315 DHCP_CLIENT_DONT_DESTROY(client);
1316
1317 client->state = DHCP_STATE_RENEWING;
1318 client->attempt = 0;
1319
1320 return client_initialize_time_events(client);
1321 }
1322
1323 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
1324 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1325 int r;
1326
1327 r = dhcp_lease_new(&lease);
1328 if (r < 0)
1329 return r;
1330
1331 if (client->client_id_len) {
1332 r = dhcp_lease_set_client_id(lease,
1333 (uint8_t *) &client->client_id,
1334 client->client_id_len);
1335 if (r < 0)
1336 return r;
1337 }
1338
1339 r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease, NULL);
1340 if (r != DHCP_OFFER) {
1341 log_dhcp_client(client, "received message was not an OFFER, ignoring");
1342 return -ENOMSG;
1343 }
1344
1345 lease->next_server = offer->siaddr;
1346 lease->address = offer->yiaddr;
1347
1348 if (lease->address == 0 ||
1349 lease->server_address == 0 ||
1350 lease->lifetime == 0) {
1351 log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
1352 return -ENOMSG;
1353 }
1354
1355 if (!lease->have_subnet_mask) {
1356 r = dhcp_lease_set_default_subnet_mask(lease);
1357 if (r < 0) {
1358 log_dhcp_client(client,
1359 "received lease lacks subnet mask, "
1360 "and a fallback one cannot be generated, ignoring");
1361 return -ENOMSG;
1362 }
1363 }
1364
1365 sd_dhcp_lease_unref(client->lease);
1366 client->lease = TAKE_PTR(lease);
1367
1368 if (client_notify(client, SD_DHCP_CLIENT_EVENT_SELECTING) < 0)
1369 return -ENOMSG;
1370
1371 log_dhcp_client(client, "OFFER");
1372
1373 return 0;
1374 }
1375
1376 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
1377 int r;
1378
1379 r = dhcp_option_parse(force, len, NULL, NULL, NULL);
1380 if (r != DHCP_FORCERENEW)
1381 return -ENOMSG;
1382
1383 log_dhcp_client(client, "FORCERENEW");
1384
1385 return 0;
1386 }
1387
1388 static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {
1389 if (a->address != b->address)
1390 return false;
1391
1392 if (a->subnet_mask != b->subnet_mask)
1393 return false;
1394
1395 if (a->router_size != b->router_size)
1396 return false;
1397
1398 for (size_t i = 0; i < a->router_size; i++)
1399 if (a->router[i].s_addr != b->router[i].s_addr)
1400 return false;
1401
1402 return true;
1403 }
1404
1405 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
1406 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1407 _cleanup_free_ char *error_message = NULL;
1408 int r;
1409
1410 r = dhcp_lease_new(&lease);
1411 if (r < 0)
1412 return r;
1413
1414 if (client->client_id_len) {
1415 r = dhcp_lease_set_client_id(lease,
1416 (uint8_t *) &client->client_id,
1417 client->client_id_len);
1418 if (r < 0)
1419 return r;
1420 }
1421
1422 r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease, &error_message);
1423 if (r == DHCP_NAK) {
1424 log_dhcp_client(client, "NAK: %s", strna(error_message));
1425 return -EADDRNOTAVAIL;
1426 }
1427
1428 if (r != DHCP_ACK) {
1429 log_dhcp_client(client, "received message was not an ACK, ignoring");
1430 return -ENOMSG;
1431 }
1432
1433 lease->next_server = ack->siaddr;
1434
1435 lease->address = ack->yiaddr;
1436
1437 if (lease->address == INADDR_ANY ||
1438 lease->server_address == INADDR_ANY ||
1439 lease->lifetime == 0) {
1440 log_dhcp_client(client, "received lease lacks address, server "
1441 "address or lease lifetime, ignoring");
1442 return -ENOMSG;
1443 }
1444
1445 if (lease->subnet_mask == INADDR_ANY) {
1446 r = dhcp_lease_set_default_subnet_mask(lease);
1447 if (r < 0) {
1448 log_dhcp_client(client,
1449 "received lease lacks subnet mask, "
1450 "and a fallback one cannot be generated, ignoring");
1451 return -ENOMSG;
1452 }
1453 }
1454
1455 r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1456 if (client->lease) {
1457 if (lease_equal(client->lease, lease))
1458 r = SD_DHCP_CLIENT_EVENT_RENEW;
1459 else
1460 r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
1461
1462 client->lease = sd_dhcp_lease_unref(client->lease);
1463 }
1464
1465 client->lease = TAKE_PTR(lease);
1466
1467 log_dhcp_client(client, "ACK");
1468
1469 return r;
1470 }
1471
1472 static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) {
1473 assert(client);
1474 assert(client->request_sent);
1475 assert(lifetime > 0);
1476
1477 if (lifetime > 3)
1478 lifetime -= 3;
1479 else
1480 lifetime = 0;
1481
1482 return client->request_sent + (lifetime * USEC_PER_SEC * factor) +
1483 + (random_u32() & 0x1fffff);
1484 }
1485
1486 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1487 usec_t time_now;
1488 uint64_t lifetime_timeout;
1489 uint64_t t2_timeout;
1490 uint64_t t1_timeout;
1491 char time_string[FORMAT_TIMESPAN_MAX];
1492 int r;
1493
1494 assert(client);
1495 assert(client->event);
1496 assert(client->lease);
1497 assert(client->lease->lifetime);
1498
1499 /* don't set timers for infinite leases */
1500 if (client->lease->lifetime == 0xffffffff) {
1501 (void) event_source_disable(client->timeout_t1);
1502 (void) event_source_disable(client->timeout_t2);
1503 (void) event_source_disable(client->timeout_expire);
1504
1505 return 0;
1506 }
1507
1508 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1509 if (r < 0)
1510 return r;
1511 assert(client->request_sent <= time_now);
1512
1513 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1514 lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1515 if (client->lease->t1 > 0 && client->lease->t2 > 0) {
1516 /* both T1 and T2 are given */
1517 if (client->lease->t1 < client->lease->t2 &&
1518 client->lease->t2 < client->lease->lifetime) {
1519 /* they are both valid */
1520 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1521 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1522 } else {
1523 /* discard both */
1524 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1525 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1526 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1527 client->lease->t1 = client->lease->lifetime / 2;
1528 }
1529 } else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) {
1530 /* only T2 is given, and it is valid */
1531 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1532 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1533 client->lease->t1 = client->lease->lifetime / 2;
1534 if (t2_timeout <= t1_timeout) {
1535 /* the computed T1 would be invalid, so discard T2 */
1536 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1537 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1538 }
1539 } else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) {
1540 /* only T1 is given, and it is valid */
1541 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1542 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1543 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1544 if (t2_timeout <= t1_timeout) {
1545 /* the computed T2 would be invalid, so discard T1 */
1546 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1547 client->lease->t2 = client->lease->lifetime / 2;
1548 }
1549 } else {
1550 /* fall back to the default timeouts */
1551 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1552 client->lease->t1 = client->lease->lifetime / 2;
1553 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1554 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1555 }
1556
1557 /* arm lifetime timeout */
1558 r = event_reset_time(client->event, &client->timeout_expire,
1559 clock_boottime_or_monotonic(),
1560 lifetime_timeout, 10 * USEC_PER_MSEC,
1561 client_timeout_expire, client,
1562 client->event_priority, "dhcp4-lifetime", true);
1563 if (r < 0)
1564 return r;
1565
1566 log_dhcp_client(client, "lease expires in %s",
1567 format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime_timeout - time_now, USEC_PER_SEC));
1568
1569 /* don't arm earlier timeouts if this has already expired */
1570 if (lifetime_timeout <= time_now)
1571 return 0;
1572
1573 /* arm T2 timeout */
1574 r = event_reset_time(client->event, &client->timeout_t2,
1575 clock_boottime_or_monotonic(),
1576 t2_timeout, 10 * USEC_PER_MSEC,
1577 client_timeout_t2, client,
1578 client->event_priority, "dhcp4-t2-timeout", true);
1579 if (r < 0)
1580 return r;
1581
1582 log_dhcp_client(client, "T2 expires in %s",
1583 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t2_timeout - time_now, USEC_PER_SEC));
1584
1585 /* don't arm earlier timeout if this has already expired */
1586 if (t2_timeout <= time_now)
1587 return 0;
1588
1589 /* arm T1 timeout */
1590 r = event_reset_time(client->event, &client->timeout_t1,
1591 clock_boottime_or_monotonic(),
1592 t1_timeout, 10 * USEC_PER_MSEC,
1593 client_timeout_t1, client,
1594 client->event_priority, "dhcp4-t1-timer", true);
1595 if (r < 0)
1596 return r;
1597
1598 log_dhcp_client(client, "T1 expires in %s",
1599 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t1_timeout - time_now, USEC_PER_SEC));
1600
1601 return 0;
1602 }
1603
1604 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
1605 DHCP_CLIENT_DONT_DESTROY(client);
1606 char time_string[FORMAT_TIMESPAN_MAX];
1607 int r = 0, notify_event = 0;
1608
1609 assert(client);
1610 assert(client->event);
1611 assert(message);
1612
1613 switch (client->state) {
1614 case DHCP_STATE_SELECTING:
1615
1616 r = client_handle_offer(client, message, len);
1617 if (r >= 0) {
1618
1619 client->state = DHCP_STATE_REQUESTING;
1620 client->attempt = 0;
1621
1622 r = event_reset_time(client->event, &client->timeout_resend,
1623 clock_boottime_or_monotonic(),
1624 0, 0,
1625 client_timeout_resend, client,
1626 client->event_priority, "dhcp4-resend-timer", true);
1627 if (r < 0)
1628 goto error;
1629 } else if (r == -ENOMSG)
1630 /* invalid message, let's ignore it */
1631 return 0;
1632
1633 break;
1634
1635 case DHCP_STATE_REBOOTING:
1636 case DHCP_STATE_REQUESTING:
1637 case DHCP_STATE_RENEWING:
1638 case DHCP_STATE_REBINDING:
1639
1640 r = client_handle_ack(client, message, len);
1641 if (r >= 0) {
1642 client->start_delay = 0;
1643 (void) event_source_disable(client->timeout_resend);
1644 client->receive_message =
1645 sd_event_source_unref(client->receive_message);
1646 client->fd = asynchronous_close(client->fd);
1647
1648 if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1649 DHCP_STATE_REBOOTING))
1650 notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1651 else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
1652 notify_event = r;
1653
1654 client->state = DHCP_STATE_BOUND;
1655 client->attempt = 0;
1656
1657 client->last_addr = client->lease->address;
1658
1659 r = client_set_lease_timeouts(client);
1660 if (r < 0) {
1661 log_dhcp_client(client, "could not set lease timeouts");
1662 goto error;
1663 }
1664
1665 r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
1666 if (r < 0) {
1667 log_dhcp_client(client, "could not bind UDP socket");
1668 goto error;
1669 }
1670
1671 client->fd = r;
1672
1673 client_initialize_io_events(client, client_receive_message_udp);
1674
1675 if (notify_event) {
1676 client_notify(client, notify_event);
1677 if (client->state == DHCP_STATE_STOPPED)
1678 return 0;
1679 }
1680
1681 } else if (r == -EADDRNOTAVAIL) {
1682 /* got a NAK, let's restart the client */
1683 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1684
1685 r = client_initialize(client);
1686 if (r < 0)
1687 goto error;
1688
1689 r = client_start_delayed(client);
1690 if (r < 0)
1691 goto error;
1692
1693 log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1694 client->start_delay, USEC_PER_SEC));
1695
1696 client->start_delay = CLAMP(client->start_delay * 2,
1697 RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
1698
1699 return 0;
1700 } else if (r == -ENOMSG)
1701 /* invalid message, let's ignore it */
1702 return 0;
1703
1704 break;
1705
1706 case DHCP_STATE_BOUND:
1707 r = client_handle_forcerenew(client, message, len);
1708 if (r >= 0) {
1709 r = client_timeout_t1(NULL, 0, client);
1710 if (r < 0)
1711 goto error;
1712 } else if (r == -ENOMSG)
1713 /* invalid message, let's ignore it */
1714 return 0;
1715
1716 break;
1717
1718 case DHCP_STATE_INIT:
1719 case DHCP_STATE_INIT_REBOOT:
1720
1721 break;
1722
1723 case DHCP_STATE_STOPPED:
1724 r = -EINVAL;
1725 goto error;
1726 }
1727
1728 error:
1729 if (r < 0)
1730 client_stop(client, r);
1731
1732 return r;
1733 }
1734
1735 static int client_receive_message_udp(
1736 sd_event_source *s,
1737 int fd,
1738 uint32_t revents,
1739 void *userdata) {
1740
1741 sd_dhcp_client *client = userdata;
1742 _cleanup_free_ DHCPMessage *message = NULL;
1743 const uint8_t *expected_chaddr = NULL;
1744 uint8_t expected_hlen = 0;
1745 ssize_t len, buflen;
1746
1747 assert(s);
1748 assert(client);
1749
1750 buflen = next_datagram_size_fd(fd);
1751 if (buflen == -ENETDOWN) {
1752 /* the link is down. Don't return an error or the I/O event
1753 source will be disconnected and we won't be able to receive
1754 packets again when the link comes back. */
1755 return 0;
1756 }
1757 if (buflen < 0)
1758 return buflen;
1759
1760 message = malloc0(buflen);
1761 if (!message)
1762 return -ENOMEM;
1763
1764 len = recv(fd, message, buflen, 0);
1765 if (len < 0) {
1766 /* see comment above for why we shouldn't error out on ENETDOWN. */
1767 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1768 return 0;
1769
1770 return log_dhcp_client_errno(client, errno,
1771 "Could not receive message from UDP socket: %m");
1772 }
1773 if ((size_t) len < sizeof(DHCPMessage)) {
1774 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
1775 return 0;
1776 }
1777
1778 if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1779 log_dhcp_client(client, "Not a DHCP message: ignoring");
1780 return 0;
1781 }
1782
1783 if (message->op != BOOTREPLY) {
1784 log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
1785 return 0;
1786 }
1787
1788 if (message->htype != client->arp_type) {
1789 log_dhcp_client(client, "Packet type does not match client type");
1790 return 0;
1791 }
1792
1793 if (client->arp_type == ARPHRD_ETHER) {
1794 expected_hlen = ETH_ALEN;
1795 expected_chaddr = &client->mac_addr[0];
1796 }
1797
1798 if (message->hlen != expected_hlen) {
1799 log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
1800 return 0;
1801 }
1802
1803 if (expected_hlen > 0 && memcmp(&message->chaddr[0], expected_chaddr, expected_hlen)) {
1804 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
1805 return 0;
1806 }
1807
1808 if (client->state != DHCP_STATE_BOUND &&
1809 be32toh(message->xid) != client->xid) {
1810 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1811 so ignore the xid in this case */
1812 log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
1813 be32toh(message->xid), client->xid);
1814 return 0;
1815 }
1816
1817 return client_handle_message(client, message, len);
1818 }
1819
1820 static int client_receive_message_raw(
1821 sd_event_source *s,
1822 int fd,
1823 uint32_t revents,
1824 void *userdata) {
1825
1826 sd_dhcp_client *client = userdata;
1827 _cleanup_free_ DHCPPacket *packet = NULL;
1828 uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1829 struct iovec iov = {};
1830 struct msghdr msg = {
1831 .msg_iov = &iov,
1832 .msg_iovlen = 1,
1833 .msg_control = cmsgbuf,
1834 .msg_controllen = sizeof(cmsgbuf),
1835 };
1836 struct cmsghdr *cmsg;
1837 bool checksum = true;
1838 ssize_t buflen, len;
1839 int r;
1840
1841 assert(s);
1842 assert(client);
1843
1844 buflen = next_datagram_size_fd(fd);
1845 if (buflen == -ENETDOWN)
1846 return 0;
1847 if (buflen < 0)
1848 return buflen;
1849
1850 packet = malloc0(buflen);
1851 if (!packet)
1852 return -ENOMEM;
1853
1854 iov = IOVEC_MAKE(packet, buflen);
1855
1856 len = recvmsg(fd, &msg, 0);
1857 if (len < 0) {
1858 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1859 return 0;
1860
1861 return log_dhcp_client_errno(client, errno,
1862 "Could not receive message from raw socket: %m");
1863 } else if ((size_t)len < sizeof(DHCPPacket))
1864 return 0;
1865
1866 CMSG_FOREACH(cmsg, &msg)
1867 if (cmsg->cmsg_level == SOL_PACKET &&
1868 cmsg->cmsg_type == PACKET_AUXDATA &&
1869 cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1870 struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1871
1872 checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1873 break;
1874 }
1875
1876 r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
1877 if (r < 0)
1878 return 0;
1879
1880 len -= DHCP_IP_UDP_SIZE;
1881
1882 return client_handle_message(client, &packet->dhcp, len);
1883 }
1884
1885 int sd_dhcp_client_start(sd_dhcp_client *client) {
1886 int r;
1887
1888 assert_return(client, -EINVAL);
1889
1890 r = client_initialize(client);
1891 if (r < 0)
1892 return r;
1893
1894 /* RFC7844 section 3.3:
1895 SHOULD perform a complete four-way handshake, starting with a
1896 DHCPDISCOVER, to obtain a new address lease. If the client can
1897 ascertain that this is exactly the same network to which it was
1898 previously connected, and if the link-layer address did not change,
1899 the client MAY issue a DHCPREQUEST to try to reclaim the current
1900 address. */
1901 if (client->last_addr && !client->anonymize)
1902 client->state = DHCP_STATE_INIT_REBOOT;
1903
1904 r = client_start(client);
1905 if (r >= 0)
1906 log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
1907
1908 return r;
1909 }
1910
1911 int sd_dhcp_client_send_release(sd_dhcp_client *client) {
1912 assert_return(client, -EINVAL);
1913
1914 client_send_release(client);
1915
1916 return 0;
1917 }
1918
1919 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1920 DHCP_CLIENT_DONT_DESTROY(client);
1921
1922 assert_return(client, -EINVAL);
1923
1924 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
1925 client->state = DHCP_STATE_STOPPED;
1926
1927 return 0;
1928 }
1929
1930 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
1931 int r;
1932
1933 assert_return(client, -EINVAL);
1934 assert_return(!client->event, -EBUSY);
1935
1936 if (event)
1937 client->event = sd_event_ref(event);
1938 else {
1939 r = sd_event_default(&client->event);
1940 if (r < 0)
1941 return 0;
1942 }
1943
1944 client->event_priority = priority;
1945
1946 return 0;
1947 }
1948
1949 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1950 assert_return(client, -EINVAL);
1951
1952 client->event = sd_event_unref(client->event);
1953
1954 return 0;
1955 }
1956
1957 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1958 assert_return(client, NULL);
1959
1960 return client->event;
1961 }
1962
1963 static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
1964 assert(client);
1965
1966 log_dhcp_client(client, "FREE");
1967
1968 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
1969 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
1970 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
1971 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
1972
1973 client_initialize(client);
1974
1975 sd_dhcp_client_detach_event(client);
1976
1977 sd_dhcp_lease_unref(client->lease);
1978
1979 free(client->req_opts);
1980 free(client->hostname);
1981 free(client->vendor_class_identifier);
1982 client->user_class = strv_free(client->user_class);
1983 return mfree(client);
1984 }
1985
1986 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
1987
1988 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
1989 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
1990
1991 assert_return(ret, -EINVAL);
1992
1993 client = new(sd_dhcp_client, 1);
1994 if (!client)
1995 return -ENOMEM;
1996
1997 *client = (sd_dhcp_client) {
1998 .n_ref = 1,
1999 .state = DHCP_STATE_INIT,
2000 .ifindex = -1,
2001 .fd = -1,
2002 .mtu = DHCP_DEFAULT_MIN_SIZE,
2003 .port = DHCP_PORT_CLIENT,
2004 .anonymize = !!anonymize,
2005 .max_attempts = (uint64_t) -1,
2006 };
2007 /* NOTE: this could be moved to a function. */
2008 if (anonymize) {
2009 client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
2010 client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
2011 } else {
2012 client->req_opts_size = ELEMENTSOF(default_req_opts);
2013 client->req_opts = memdup(default_req_opts, client->req_opts_size);
2014 }
2015 if (!client->req_opts)
2016 return -ENOMEM;
2017
2018 *ret = TAKE_PTR(client);
2019
2020 return 0;
2021 }