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