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