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