]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp-client.c
Merge pull request #10614 from thom311/dhcp-identifier-set-iaid
[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 "hostname-util.h"
25 #include "random-util.h"
26 #include "string-util.h"
27 #include "util.h"
28 #include "strv.h"
29
30 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
31 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
32
33 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
34 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
35
36 struct sd_dhcp_client {
37 unsigned n_ref;
38
39 DHCPState state;
40 sd_event *event;
41 int event_priority;
42 sd_event_source *timeout_resend;
43 int ifindex;
44 int fd;
45 uint16_t port;
46 union sockaddr_union link;
47 sd_event_source *receive_message;
48 bool request_broadcast;
49 uint8_t *req_opts;
50 size_t req_opts_allocated;
51 size_t req_opts_size;
52 bool anonymize;
53 be32_t last_addr;
54 uint8_t mac_addr[MAX_MAC_ADDR_LEN];
55 size_t mac_addr_len;
56 uint16_t arp_type;
57 struct {
58 uint8_t type;
59 union {
60 struct {
61 /* 0: Generic (non-LL) (RFC 2132) */
62 uint8_t data[MAX_CLIENT_ID_LEN];
63 } _packed_ gen;
64 struct {
65 /* 1: Ethernet Link-Layer (RFC 2132) */
66 uint8_t haddr[ETH_ALEN];
67 } _packed_ eth;
68 struct {
69 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
70 uint8_t haddr[0];
71 } _packed_ ll;
72 struct {
73 /* 255: Node-specific (RFC 4361) */
74 be32_t iaid;
75 struct duid duid;
76 } _packed_ ns;
77 struct {
78 uint8_t data[MAX_CLIENT_ID_LEN];
79 } _packed_ raw;
80 };
81 } _packed_ client_id;
82 size_t client_id_len;
83 char *hostname;
84 char *vendor_class_identifier;
85 char **user_class;
86 uint32_t mtu;
87 uint32_t xid;
88 usec_t start_time;
89 unsigned attempt;
90 usec_t request_sent;
91 sd_event_source *timeout_t1;
92 sd_event_source *timeout_t2;
93 sd_event_source *timeout_expire;
94 sd_dhcp_client_callback_t callback;
95 void *userdata;
96 sd_dhcp_lease *lease;
97 usec_t start_delay;
98 };
99
100 static const uint8_t default_req_opts[] = {
101 SD_DHCP_OPTION_SUBNET_MASK,
102 SD_DHCP_OPTION_ROUTER,
103 SD_DHCP_OPTION_HOST_NAME,
104 SD_DHCP_OPTION_DOMAIN_NAME,
105 SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
106 };
107
108 /* RFC7844 section 3:
109 MAY contain the Parameter Request List option.
110 RFC7844 section 3.6:
111 The client intending to protect its privacy SHOULD only request a
112 minimal number of options in the PRL and SHOULD also randomly shuffle
113 the ordering of option codes in the PRL. If this random ordering
114 cannot be implemented, the client MAY order the option codes in the
115 PRL by option code number (lowest to highest).
116 */
117 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
118 static const uint8_t default_req_opts_anonymize[] = {
119 SD_DHCP_OPTION_SUBNET_MASK, /* 1 */
120 SD_DHCP_OPTION_ROUTER, /* 3 */
121 SD_DHCP_OPTION_DOMAIN_NAME_SERVER, /* 6 */
122 SD_DHCP_OPTION_DOMAIN_NAME, /* 15 */
123 SD_DHCP_OPTION_ROUTER_DISCOVER, /* 31 */
124 SD_DHCP_OPTION_STATIC_ROUTE, /* 33 */
125 SD_DHCP_OPTION_VENDOR_SPECIFIC, /* 43 */
126 SD_DHCP_OPTION_NETBIOS_NAMESERVER, /* 44 */
127 SD_DHCP_OPTION_NETBIOS_NODETYPE, /* 46 */
128 SD_DHCP_OPTION_NETBIOS_SCOPE, /* 47 */
129 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, /* 121 */
130 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, /* 249 */
131 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY, /* 252 */
132 };
133
134 static int client_receive_message_raw(
135 sd_event_source *s,
136 int fd,
137 uint32_t revents,
138 void *userdata);
139 static int client_receive_message_udp(
140 sd_event_source *s,
141 int fd,
142 uint32_t revents,
143 void *userdata);
144 static void client_stop(sd_dhcp_client *client, int error);
145
146 int sd_dhcp_client_set_callback(
147 sd_dhcp_client *client,
148 sd_dhcp_client_callback_t cb,
149 void *userdata) {
150
151 assert_return(client, -EINVAL);
152
153 client->callback = cb;
154 client->userdata = userdata;
155
156 return 0;
157 }
158
159 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
160 assert_return(client, -EINVAL);
161
162 client->request_broadcast = !!broadcast;
163
164 return 0;
165 }
166
167 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
168 size_t i;
169
170 assert_return(client, -EINVAL);
171 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
172
173 switch(option) {
174
175 case SD_DHCP_OPTION_PAD:
176 case SD_DHCP_OPTION_OVERLOAD:
177 case SD_DHCP_OPTION_MESSAGE_TYPE:
178 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST:
179 case SD_DHCP_OPTION_END:
180 return -EINVAL;
181
182 default:
183 break;
184 }
185
186 for (i = 0; i < client->req_opts_size; i++)
187 if (client->req_opts[i] == option)
188 return -EEXIST;
189
190 if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
191 client->req_opts_size + 1))
192 return -ENOMEM;
193
194 client->req_opts[client->req_opts_size++] = option;
195
196 return 0;
197 }
198
199 int sd_dhcp_client_set_request_address(
200 sd_dhcp_client *client,
201 const struct in_addr *last_addr) {
202
203 assert_return(client, -EINVAL);
204 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
205
206 if (last_addr)
207 client->last_addr = last_addr->s_addr;
208 else
209 client->last_addr = INADDR_ANY;
210
211 return 0;
212 }
213
214 int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) {
215
216 assert_return(client, -EINVAL);
217 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
218 assert_return(ifindex > 0, -EINVAL);
219
220 client->ifindex = ifindex;
221 return 0;
222 }
223
224 int sd_dhcp_client_set_mac(
225 sd_dhcp_client *client,
226 const uint8_t *addr,
227 size_t addr_len,
228 uint16_t arp_type) {
229
230 DHCP_CLIENT_DONT_DESTROY(client);
231 bool need_restart = false;
232
233 assert_return(client, -EINVAL);
234 assert_return(addr, -EINVAL);
235 assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
236 assert_return(arp_type > 0, -EINVAL);
237
238 if (arp_type == ARPHRD_ETHER)
239 assert_return(addr_len == ETH_ALEN, -EINVAL);
240 else if (arp_type == ARPHRD_INFINIBAND)
241 assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
242 else
243 return -EINVAL;
244
245 if (client->mac_addr_len == addr_len &&
246 memcmp(&client->mac_addr, addr, addr_len) == 0)
247 return 0;
248
249 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
250 log_dhcp_client(client, "Changing MAC address on running DHCP client, restarting");
251 need_restart = true;
252 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
253 }
254
255 memcpy(&client->mac_addr, addr, addr_len);
256 client->mac_addr_len = addr_len;
257 client->arp_type = arp_type;
258
259 if (need_restart && client->state != DHCP_STATE_STOPPED)
260 sd_dhcp_client_start(client);
261
262 return 0;
263 }
264
265 int sd_dhcp_client_get_client_id(
266 sd_dhcp_client *client,
267 uint8_t *type,
268 const uint8_t **data,
269 size_t *data_len) {
270
271 assert_return(client, -EINVAL);
272 assert_return(type, -EINVAL);
273 assert_return(data, -EINVAL);
274 assert_return(data_len, -EINVAL);
275
276 *type = 0;
277 *data = NULL;
278 *data_len = 0;
279 if (client->client_id_len) {
280 *type = client->client_id.type;
281 *data = client->client_id.raw.data;
282 *data_len = client->client_id_len - sizeof(client->client_id.type);
283 }
284
285 return 0;
286 }
287
288 int sd_dhcp_client_set_client_id(
289 sd_dhcp_client *client,
290 uint8_t type,
291 const uint8_t *data,
292 size_t data_len) {
293
294 DHCP_CLIENT_DONT_DESTROY(client);
295 bool need_restart = false;
296
297 assert_return(client, -EINVAL);
298 assert_return(data, -EINVAL);
299 assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL);
300
301 switch (type) {
302
303 case ARPHRD_ETHER:
304 if (data_len != ETH_ALEN)
305 return -EINVAL;
306 break;
307
308 case ARPHRD_INFINIBAND:
309 if (data_len != INFINIBAND_ALEN)
310 return -EINVAL;
311 break;
312
313 default:
314 break;
315 }
316
317 if (client->client_id_len == data_len + sizeof(client->client_id.type) &&
318 client->client_id.type == type &&
319 memcmp(&client->client_id.raw.data, data, data_len) == 0)
320 return 0;
321
322 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
323 log_dhcp_client(client, "Changing client ID on running DHCP "
324 "client, restarting");
325 need_restart = true;
326 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
327 }
328
329 client->client_id.type = type;
330 memcpy(&client->client_id.raw.data, data, data_len);
331 client->client_id_len = data_len + sizeof (client->client_id.type);
332
333 if (need_restart && client->state != DHCP_STATE_STOPPED)
334 sd_dhcp_client_start(client);
335
336 return 0;
337 }
338
339 /**
340 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
341 * without further modification. Otherwise, if duid_type is supported, DUID
342 * is set based on that type. Otherwise, an error is returned.
343 */
344 static int dhcp_client_set_iaid_duid_internal(
345 sd_dhcp_client *client,
346 uint32_t iaid,
347 bool append_iaid,
348 uint16_t duid_type,
349 const void *duid,
350 size_t duid_len,
351 usec_t llt_time) {
352
353 DHCP_CLIENT_DONT_DESTROY(client);
354 int r;
355 size_t len;
356
357 assert_return(client, -EINVAL);
358 assert_return(duid_len == 0 || duid != NULL, -EINVAL);
359
360 if (duid != NULL) {
361 r = dhcp_validate_duid_len(duid_type, duid_len);
362 if (r < 0)
363 return r;
364 }
365
366 zero(client->client_id);
367 client->client_id.type = 255;
368
369 if (append_iaid) {
370 /* If IAID is not configured, generate it. */
371 if (iaid == 0) {
372 r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr,
373 client->mac_addr_len,
374 true,
375 &client->client_id.ns.iaid);
376 if (r < 0)
377 return r;
378 } else
379 client->client_id.ns.iaid = htobe32(iaid);
380 }
381
382 if (duid != NULL) {
383 client->client_id.ns.duid.type = htobe16(duid_type);
384 memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
385 len = sizeof(client->client_id.ns.duid.type) + duid_len;
386 } else
387 switch (duid_type) {
388 case DUID_TYPE_LLT:
389 if (client->mac_addr_len == 0)
390 return -EOPNOTSUPP;
391
392 r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
393 if (r < 0)
394 return r;
395 break;
396 case DUID_TYPE_EN:
397 r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
398 if (r < 0)
399 return r;
400 break;
401 case DUID_TYPE_LL:
402 if (client->mac_addr_len == 0)
403 return -EOPNOTSUPP;
404
405 r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
406 if (r < 0)
407 return r;
408 break;
409 case DUID_TYPE_UUID:
410 r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len);
411 if (r < 0)
412 return r;
413 break;
414 default:
415 return -EINVAL;
416 }
417
418 client->client_id_len = sizeof(client->client_id.type) + len +
419 (append_iaid ? sizeof(client->client_id.ns.iaid) : 0);
420
421 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
422 log_dhcp_client(client, "Configured %sDUID, restarting.", append_iaid ? "IAID+" : "");
423 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
424 sd_dhcp_client_start(client);
425 }
426
427 return 0;
428 }
429
430 int sd_dhcp_client_set_iaid_duid(
431 sd_dhcp_client *client,
432 uint32_t iaid,
433 uint16_t duid_type,
434 const void *duid,
435 size_t duid_len) {
436 return dhcp_client_set_iaid_duid_internal(client, iaid, true, duid_type, duid, duid_len, 0);
437 }
438
439 int sd_dhcp_client_set_iaid_duid_llt(
440 sd_dhcp_client *client,
441 uint32_t iaid,
442 usec_t llt_time) {
443 return dhcp_client_set_iaid_duid_internal(client, iaid, true, DUID_TYPE_LLT, NULL, 0, llt_time);
444 }
445
446 int sd_dhcp_client_set_duid(
447 sd_dhcp_client *client,
448 uint16_t duid_type,
449 const void *duid,
450 size_t duid_len) {
451 return dhcp_client_set_iaid_duid_internal(client, 0, false, duid_type, duid, duid_len, 0);
452 }
453
454 int sd_dhcp_client_set_duid_llt(
455 sd_dhcp_client *client,
456 usec_t llt_time) {
457 return dhcp_client_set_iaid_duid_internal(client, 0, false, DUID_TYPE_LLT, NULL, 0, llt_time);
458 }
459
460 int sd_dhcp_client_set_hostname(
461 sd_dhcp_client *client,
462 const char *hostname) {
463
464 assert_return(client, -EINVAL);
465
466 /* Make sure hostnames qualify as DNS and as Linux hostnames */
467 if (hostname &&
468 !(hostname_is_valid(hostname, false) && dns_name_is_valid(hostname) > 0))
469 return -EINVAL;
470
471 return free_and_strdup(&client->hostname, hostname);
472 }
473
474 int sd_dhcp_client_set_vendor_class_identifier(
475 sd_dhcp_client *client,
476 const char *vci) {
477
478 assert_return(client, -EINVAL);
479
480 return free_and_strdup(&client->vendor_class_identifier, vci);
481 }
482
483 int sd_dhcp_client_set_user_class(
484 sd_dhcp_client *client,
485 const char* const* user_class) {
486
487 _cleanup_strv_free_ char **s = NULL;
488 char **p;
489
490 STRV_FOREACH(p, (char **) user_class)
491 if (strlen(*p) > 255)
492 return -ENAMETOOLONG;
493
494 s = strv_copy((char **) user_class);
495 if (!s)
496 return -ENOMEM;
497
498 client->user_class = TAKE_PTR(s);
499
500 return 0;
501 }
502
503 int sd_dhcp_client_set_client_port(
504 sd_dhcp_client *client,
505 uint16_t port) {
506
507 assert_return(client, -EINVAL);
508
509 client->port = port;
510
511 return 0;
512 }
513
514 int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
515 assert_return(client, -EINVAL);
516 assert_return(mtu >= DHCP_DEFAULT_MIN_SIZE, -ERANGE);
517
518 client->mtu = mtu;
519
520 return 0;
521 }
522
523 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
524 assert_return(client, -EINVAL);
525
526 if (!IN_SET(client->state, DHCP_STATE_BOUND, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING))
527 return -EADDRNOTAVAIL;
528
529 if (ret)
530 *ret = client->lease;
531
532 return 0;
533 }
534
535 static void client_notify(sd_dhcp_client *client, int event) {
536 assert(client);
537
538 if (client->callback)
539 client->callback(client, event, client->userdata);
540 }
541
542 static int client_initialize(sd_dhcp_client *client) {
543 assert_return(client, -EINVAL);
544
545 client->receive_message = sd_event_source_unref(client->receive_message);
546
547 client->fd = asynchronous_close(client->fd);
548
549 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
550
551 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
552 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
553 client->timeout_expire = sd_event_source_unref(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 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
1069
1070 r = sd_event_add_time(client->event,
1071 &client->timeout_resend,
1072 clock_boottime_or_monotonic(),
1073 next_timeout, 10 * USEC_PER_MSEC,
1074 client_timeout_resend, client);
1075 if (r < 0)
1076 goto error;
1077
1078 r = sd_event_source_set_priority(client->timeout_resend,
1079 client->event_priority);
1080 if (r < 0)
1081 goto error;
1082
1083 r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
1084 if (r < 0)
1085 goto error;
1086
1087 switch (client->state) {
1088 case DHCP_STATE_INIT:
1089 r = client_send_discover(client);
1090 if (r >= 0) {
1091 client->state = DHCP_STATE_SELECTING;
1092 client->attempt = 1;
1093 } else {
1094 if (client->attempt >= 64)
1095 goto error;
1096 }
1097
1098 break;
1099
1100 case DHCP_STATE_SELECTING:
1101 r = client_send_discover(client);
1102 if (r < 0 && client->attempt >= 64)
1103 goto error;
1104
1105 break;
1106
1107 case DHCP_STATE_INIT_REBOOT:
1108 case DHCP_STATE_REQUESTING:
1109 case DHCP_STATE_RENEWING:
1110 case DHCP_STATE_REBINDING:
1111 r = client_send_request(client);
1112 if (r < 0 && client->attempt >= 64)
1113 goto error;
1114
1115 if (client->state == DHCP_STATE_INIT_REBOOT)
1116 client->state = DHCP_STATE_REBOOTING;
1117
1118 client->request_sent = time_now;
1119
1120 break;
1121
1122 case DHCP_STATE_REBOOTING:
1123 case DHCP_STATE_BOUND:
1124
1125 break;
1126
1127 case DHCP_STATE_STOPPED:
1128 r = -EINVAL;
1129 goto error;
1130 }
1131
1132 return 0;
1133
1134 error:
1135 client_stop(client, r);
1136
1137 /* Errors were dealt with when stopping the client, don't spill
1138 errors into the event loop handler */
1139 return 0;
1140 }
1141
1142 static int client_initialize_io_events(
1143 sd_dhcp_client *client,
1144 sd_event_io_handler_t io_callback) {
1145
1146 int r;
1147
1148 assert(client);
1149 assert(client->event);
1150
1151 r = sd_event_add_io(client->event, &client->receive_message,
1152 client->fd, EPOLLIN, io_callback,
1153 client);
1154 if (r < 0)
1155 goto error;
1156
1157 r = sd_event_source_set_priority(client->receive_message,
1158 client->event_priority);
1159 if (r < 0)
1160 goto error;
1161
1162 r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
1163 if (r < 0)
1164 goto error;
1165
1166 error:
1167 if (r < 0)
1168 client_stop(client, r);
1169
1170 return 0;
1171 }
1172
1173 static int client_initialize_time_events(sd_dhcp_client *client) {
1174 uint64_t usec = 0;
1175 int r;
1176
1177 assert(client);
1178 assert(client->event);
1179
1180 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
1181
1182 if (client->start_delay) {
1183 assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
1184 usec += client->start_delay;
1185 }
1186
1187 r = sd_event_add_time(client->event,
1188 &client->timeout_resend,
1189 clock_boottime_or_monotonic(),
1190 usec, 0,
1191 client_timeout_resend, client);
1192 if (r < 0)
1193 goto error;
1194
1195 r = sd_event_source_set_priority(client->timeout_resend,
1196 client->event_priority);
1197 if (r < 0)
1198 goto error;
1199
1200 r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
1201 if (r < 0)
1202 goto error;
1203
1204 error:
1205 if (r < 0)
1206 client_stop(client, r);
1207
1208 return 0;
1209
1210 }
1211
1212 static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
1213 client_initialize_io_events(client, io_callback);
1214 client_initialize_time_events(client);
1215
1216 return 0;
1217 }
1218
1219 static int client_start_delayed(sd_dhcp_client *client) {
1220 int r;
1221
1222 assert_return(client, -EINVAL);
1223 assert_return(client->event, -EINVAL);
1224 assert_return(client->ifindex > 0, -EINVAL);
1225 assert_return(client->fd < 0, -EBUSY);
1226 assert_return(client->xid == 0, -EINVAL);
1227 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY);
1228
1229 client->xid = random_u32();
1230
1231 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1232 client->xid, client->mac_addr,
1233 client->mac_addr_len, client->arp_type, client->port);
1234 if (r < 0) {
1235 client_stop(client, r);
1236 return r;
1237 }
1238 client->fd = r;
1239
1240 if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT))
1241 client->start_time = now(clock_boottime_or_monotonic());
1242
1243 return client_initialize_events(client, client_receive_message_raw);
1244 }
1245
1246 static int client_start(sd_dhcp_client *client) {
1247 client->start_delay = 0;
1248 return client_start_delayed(client);
1249 }
1250
1251 static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
1252 sd_dhcp_client *client = userdata;
1253 DHCP_CLIENT_DONT_DESTROY(client);
1254
1255 log_dhcp_client(client, "EXPIRED");
1256
1257 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1258
1259 /* lease was lost, start over if not freed or stopped in callback */
1260 if (client->state != DHCP_STATE_STOPPED) {
1261 client_initialize(client);
1262 client_start(client);
1263 }
1264
1265 return 0;
1266 }
1267
1268 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
1269 sd_dhcp_client *client = userdata;
1270 DHCP_CLIENT_DONT_DESTROY(client);
1271 int r;
1272
1273 assert(client);
1274
1275 client->receive_message = sd_event_source_unref(client->receive_message);
1276 client->fd = asynchronous_close(client->fd);
1277
1278 client->state = DHCP_STATE_REBINDING;
1279 client->attempt = 1;
1280
1281 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1282 client->xid, client->mac_addr,
1283 client->mac_addr_len, client->arp_type,
1284 client->port);
1285 if (r < 0) {
1286 client_stop(client, r);
1287 return 0;
1288 }
1289 client->fd = r;
1290
1291 return client_initialize_events(client, client_receive_message_raw);
1292 }
1293
1294 static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
1295 sd_dhcp_client *client = userdata;
1296 DHCP_CLIENT_DONT_DESTROY(client);
1297
1298 client->state = DHCP_STATE_RENEWING;
1299 client->attempt = 1;
1300
1301 return client_initialize_time_events(client);
1302 }
1303
1304 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
1305 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1306 int r;
1307
1308 r = dhcp_lease_new(&lease);
1309 if (r < 0)
1310 return r;
1311
1312 if (client->client_id_len) {
1313 r = dhcp_lease_set_client_id(lease,
1314 (uint8_t *) &client->client_id,
1315 client->client_id_len);
1316 if (r < 0)
1317 return r;
1318 }
1319
1320 r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease, NULL);
1321 if (r != DHCP_OFFER) {
1322 log_dhcp_client(client, "received message was not an OFFER, ignoring");
1323 return -ENOMSG;
1324 }
1325
1326 lease->next_server = offer->siaddr;
1327 lease->address = offer->yiaddr;
1328
1329 if (lease->address == 0 ||
1330 lease->server_address == 0 ||
1331 lease->lifetime == 0) {
1332 log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
1333 return -ENOMSG;
1334 }
1335
1336 if (!lease->have_subnet_mask) {
1337 r = dhcp_lease_set_default_subnet_mask(lease);
1338 if (r < 0) {
1339 log_dhcp_client(client,
1340 "received lease lacks subnet mask, "
1341 "and a fallback one cannot be generated, ignoring");
1342 return -ENOMSG;
1343 }
1344 }
1345
1346 sd_dhcp_lease_unref(client->lease);
1347 client->lease = TAKE_PTR(lease);
1348
1349 log_dhcp_client(client, "OFFER");
1350
1351 return 0;
1352 }
1353
1354 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
1355 int r;
1356
1357 r = dhcp_option_parse(force, len, NULL, NULL, NULL);
1358 if (r != DHCP_FORCERENEW)
1359 return -ENOMSG;
1360
1361 log_dhcp_client(client, "FORCERENEW");
1362
1363 return 0;
1364 }
1365
1366 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
1367 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1368 _cleanup_free_ char *error_message = NULL;
1369 int r;
1370
1371 r = dhcp_lease_new(&lease);
1372 if (r < 0)
1373 return r;
1374
1375 if (client->client_id_len) {
1376 r = dhcp_lease_set_client_id(lease,
1377 (uint8_t *) &client->client_id,
1378 client->client_id_len);
1379 if (r < 0)
1380 return r;
1381 }
1382
1383 r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease, &error_message);
1384 if (r == DHCP_NAK) {
1385 log_dhcp_client(client, "NAK: %s", strna(error_message));
1386 return -EADDRNOTAVAIL;
1387 }
1388
1389 if (r != DHCP_ACK) {
1390 log_dhcp_client(client, "received message was not an ACK, ignoring");
1391 return -ENOMSG;
1392 }
1393
1394 lease->next_server = ack->siaddr;
1395
1396 lease->address = ack->yiaddr;
1397
1398 if (lease->address == INADDR_ANY ||
1399 lease->server_address == INADDR_ANY ||
1400 lease->lifetime == 0) {
1401 log_dhcp_client(client, "received lease lacks address, server "
1402 "address or lease lifetime, ignoring");
1403 return -ENOMSG;
1404 }
1405
1406 if (lease->subnet_mask == INADDR_ANY) {
1407 r = dhcp_lease_set_default_subnet_mask(lease);
1408 if (r < 0) {
1409 log_dhcp_client(client,
1410 "received lease lacks subnet mask, "
1411 "and a fallback one cannot be generated, ignoring");
1412 return -ENOMSG;
1413 }
1414 }
1415
1416 r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1417 if (client->lease) {
1418 if (client->lease->address != lease->address ||
1419 client->lease->subnet_mask != lease->subnet_mask ||
1420 client->lease->router != lease->router) {
1421 r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
1422 } else
1423 r = SD_DHCP_CLIENT_EVENT_RENEW;
1424
1425 client->lease = sd_dhcp_lease_unref(client->lease);
1426 }
1427
1428 client->lease = TAKE_PTR(lease);
1429
1430 log_dhcp_client(client, "ACK");
1431
1432 return r;
1433 }
1434
1435 static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) {
1436 assert(client);
1437 assert(client->request_sent);
1438 assert(lifetime > 0);
1439
1440 if (lifetime > 3)
1441 lifetime -= 3;
1442 else
1443 lifetime = 0;
1444
1445 return client->request_sent + (lifetime * USEC_PER_SEC * factor) +
1446 + (random_u32() & 0x1fffff);
1447 }
1448
1449 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1450 usec_t time_now;
1451 uint64_t lifetime_timeout;
1452 uint64_t t2_timeout;
1453 uint64_t t1_timeout;
1454 char time_string[FORMAT_TIMESPAN_MAX];
1455 int r;
1456
1457 assert(client);
1458 assert(client->event);
1459 assert(client->lease);
1460 assert(client->lease->lifetime);
1461
1462 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
1463 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
1464 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
1465
1466 /* don't set timers for infinite leases */
1467 if (client->lease->lifetime == 0xffffffff)
1468 return 0;
1469
1470 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1471 if (r < 0)
1472 return r;
1473 assert(client->request_sent <= time_now);
1474
1475 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1476 lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1477 if (client->lease->t1 > 0 && client->lease->t2 > 0) {
1478 /* both T1 and T2 are given */
1479 if (client->lease->t1 < client->lease->t2 &&
1480 client->lease->t2 < client->lease->lifetime) {
1481 /* they are both valid */
1482 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1483 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1484 } else {
1485 /* discard both */
1486 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1487 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1488 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1489 client->lease->t1 = client->lease->lifetime / 2;
1490 }
1491 } else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) {
1492 /* only T2 is given, and it is valid */
1493 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1494 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1495 client->lease->t1 = client->lease->lifetime / 2;
1496 if (t2_timeout <= t1_timeout) {
1497 /* the computed T1 would be invalid, so discard T2 */
1498 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1499 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1500 }
1501 } else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) {
1502 /* only T1 is given, and it is valid */
1503 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1504 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1505 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1506 if (t2_timeout <= t1_timeout) {
1507 /* the computed T2 would be invalid, so discard T1 */
1508 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1509 client->lease->t2 = client->lease->lifetime / 2;
1510 }
1511 } else {
1512 /* fall back to the default timeouts */
1513 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1514 client->lease->t1 = client->lease->lifetime / 2;
1515 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1516 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1517 }
1518
1519 /* arm lifetime timeout */
1520 r = sd_event_add_time(client->event, &client->timeout_expire,
1521 clock_boottime_or_monotonic(),
1522 lifetime_timeout, 10 * USEC_PER_MSEC,
1523 client_timeout_expire, client);
1524 if (r < 0)
1525 return r;
1526
1527 r = sd_event_source_set_priority(client->timeout_expire,
1528 client->event_priority);
1529 if (r < 0)
1530 return r;
1531
1532 r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime");
1533 if (r < 0)
1534 return r;
1535
1536 log_dhcp_client(client, "lease expires in %s",
1537 format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime_timeout - time_now, USEC_PER_SEC));
1538
1539 /* don't arm earlier timeouts if this has already expired */
1540 if (lifetime_timeout <= time_now)
1541 return 0;
1542
1543 /* arm T2 timeout */
1544 r = sd_event_add_time(client->event,
1545 &client->timeout_t2,
1546 clock_boottime_or_monotonic(),
1547 t2_timeout,
1548 10 * USEC_PER_MSEC,
1549 client_timeout_t2, client);
1550 if (r < 0)
1551 return r;
1552
1553 r = sd_event_source_set_priority(client->timeout_t2,
1554 client->event_priority);
1555 if (r < 0)
1556 return r;
1557
1558 r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout");
1559 if (r < 0)
1560 return r;
1561
1562 log_dhcp_client(client, "T2 expires in %s",
1563 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t2_timeout - time_now, USEC_PER_SEC));
1564
1565 /* don't arm earlier timeout if this has already expired */
1566 if (t2_timeout <= time_now)
1567 return 0;
1568
1569 /* arm T1 timeout */
1570 r = sd_event_add_time(client->event,
1571 &client->timeout_t1,
1572 clock_boottime_or_monotonic(),
1573 t1_timeout, 10 * USEC_PER_MSEC,
1574 client_timeout_t1, client);
1575 if (r < 0)
1576 return r;
1577
1578 r = sd_event_source_set_priority(client->timeout_t1,
1579 client->event_priority);
1580 if (r < 0)
1581 return r;
1582
1583 r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer");
1584 if (r < 0)
1585 return r;
1586
1587 log_dhcp_client(client, "T1 expires in %s",
1588 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t1_timeout - time_now, USEC_PER_SEC));
1589
1590 return 0;
1591 }
1592
1593 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
1594 DHCP_CLIENT_DONT_DESTROY(client);
1595 char time_string[FORMAT_TIMESPAN_MAX];
1596 int r = 0, notify_event = 0;
1597
1598 assert(client);
1599 assert(client->event);
1600 assert(message);
1601
1602 switch (client->state) {
1603 case DHCP_STATE_SELECTING:
1604
1605 r = client_handle_offer(client, message, len);
1606 if (r >= 0) {
1607
1608 client->timeout_resend =
1609 sd_event_source_unref(client->timeout_resend);
1610
1611 client->state = DHCP_STATE_REQUESTING;
1612 client->attempt = 1;
1613
1614 r = sd_event_add_time(client->event,
1615 &client->timeout_resend,
1616 clock_boottime_or_monotonic(),
1617 0, 0,
1618 client_timeout_resend, client);
1619 if (r < 0)
1620 goto error;
1621
1622 r = sd_event_source_set_priority(client->timeout_resend,
1623 client->event_priority);
1624 if (r < 0)
1625 goto error;
1626
1627 r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
1628 if (r < 0)
1629 goto error;
1630 } else if (r == -ENOMSG)
1631 /* invalid message, let's ignore it */
1632 return 0;
1633
1634 break;
1635
1636 case DHCP_STATE_REBOOTING:
1637 case DHCP_STATE_REQUESTING:
1638 case DHCP_STATE_RENEWING:
1639 case DHCP_STATE_REBINDING:
1640
1641 r = client_handle_ack(client, message, len);
1642 if (r >= 0) {
1643 client->start_delay = 0;
1644 client->timeout_resend =
1645 sd_event_source_unref(client->timeout_resend);
1646 client->receive_message =
1647 sd_event_source_unref(client->receive_message);
1648 client->fd = asynchronous_close(client->fd);
1649
1650 if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1651 DHCP_STATE_REBOOTING))
1652 notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1653 else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
1654 notify_event = r;
1655
1656 client->state = DHCP_STATE_BOUND;
1657 client->attempt = 1;
1658
1659 client->last_addr = client->lease->address;
1660
1661 r = client_set_lease_timeouts(client);
1662 if (r < 0) {
1663 log_dhcp_client(client, "could not set lease timeouts");
1664 goto error;
1665 }
1666
1667 r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
1668 if (r < 0) {
1669 log_dhcp_client(client, "could not bind UDP socket");
1670 goto error;
1671 }
1672
1673 client->fd = r;
1674
1675 client_initialize_io_events(client, client_receive_message_udp);
1676
1677 if (notify_event) {
1678 client_notify(client, notify_event);
1679 if (client->state == DHCP_STATE_STOPPED)
1680 return 0;
1681 }
1682
1683 } else if (r == -EADDRNOTAVAIL) {
1684 /* got a NAK, let's restart the client */
1685 client->timeout_resend =
1686 sd_event_source_unref(client->timeout_resend);
1687
1688 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1689
1690 r = client_initialize(client);
1691 if (r < 0)
1692 goto error;
1693
1694 r = client_start_delayed(client);
1695 if (r < 0)
1696 goto error;
1697
1698 log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1699 client->start_delay, USEC_PER_SEC));
1700
1701 client->start_delay = CLAMP(client->start_delay * 2,
1702 RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
1703
1704 return 0;
1705 } else if (r == -ENOMSG)
1706 /* invalid message, let's ignore it */
1707 return 0;
1708
1709 break;
1710
1711 case DHCP_STATE_BOUND:
1712 r = client_handle_forcerenew(client, message, len);
1713 if (r >= 0) {
1714 r = client_timeout_t1(NULL, 0, client);
1715 if (r < 0)
1716 goto error;
1717 } else if (r == -ENOMSG)
1718 /* invalid message, let's ignore it */
1719 return 0;
1720
1721 break;
1722
1723 case DHCP_STATE_INIT:
1724 case DHCP_STATE_INIT_REBOOT:
1725
1726 break;
1727
1728 case DHCP_STATE_STOPPED:
1729 r = -EINVAL;
1730 goto error;
1731 }
1732
1733 error:
1734 if (r < 0)
1735 client_stop(client, r);
1736
1737 return r;
1738 }
1739
1740 static int client_receive_message_udp(
1741 sd_event_source *s,
1742 int fd,
1743 uint32_t revents,
1744 void *userdata) {
1745
1746 sd_dhcp_client *client = userdata;
1747 _cleanup_free_ DHCPMessage *message = NULL;
1748 const struct ether_addr zero_mac = {};
1749 const struct ether_addr *expected_chaddr = NULL;
1750 uint8_t expected_hlen = 0;
1751 ssize_t len, buflen;
1752
1753 assert(s);
1754 assert(client);
1755
1756 buflen = next_datagram_size_fd(fd);
1757 if (buflen < 0)
1758 return buflen;
1759
1760 message = malloc0(buflen);
1761 if (!message)
1762 return -ENOMEM;
1763
1764 len = recv(fd, message, buflen, 0);
1765 if (len < 0) {
1766 if (IN_SET(errno, EAGAIN, EINTR))
1767 return 0;
1768
1769 return log_dhcp_client_errno(client, errno,
1770 "Could not receive message from UDP socket: %m");
1771 }
1772 if ((size_t) len < sizeof(DHCPMessage)) {
1773 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
1774 return 0;
1775 }
1776
1777 if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1778 log_dhcp_client(client, "Not a DHCP message: ignoring");
1779 return 0;
1780 }
1781
1782 if (message->op != BOOTREPLY) {
1783 log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
1784 return 0;
1785 }
1786
1787 if (message->htype != client->arp_type) {
1788 log_dhcp_client(client, "Packet type does not match client type");
1789 return 0;
1790 }
1791
1792 if (client->arp_type == ARPHRD_ETHER) {
1793 expected_hlen = ETH_ALEN;
1794 expected_chaddr = (const struct ether_addr *) &client->mac_addr;
1795 } else {
1796 /* Non-Ethernet links expect zero chaddr */
1797 expected_hlen = 0;
1798 expected_chaddr = &zero_mac;
1799 }
1800
1801 if (message->hlen != expected_hlen) {
1802 log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
1803 return 0;
1804 }
1805
1806 if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
1807 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
1808 return 0;
1809 }
1810
1811 if (client->state != DHCP_STATE_BOUND &&
1812 be32toh(message->xid) != client->xid) {
1813 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1814 so ignore the xid in this case */
1815 log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
1816 be32toh(message->xid), client->xid);
1817 return 0;
1818 }
1819
1820 return client_handle_message(client, message, len);
1821 }
1822
1823 static int client_receive_message_raw(
1824 sd_event_source *s,
1825 int fd,
1826 uint32_t revents,
1827 void *userdata) {
1828
1829 sd_dhcp_client *client = userdata;
1830 _cleanup_free_ DHCPPacket *packet = NULL;
1831 uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1832 struct iovec iov = {};
1833 struct msghdr msg = {
1834 .msg_iov = &iov,
1835 .msg_iovlen = 1,
1836 .msg_control = cmsgbuf,
1837 .msg_controllen = sizeof(cmsgbuf),
1838 };
1839 struct cmsghdr *cmsg;
1840 bool checksum = true;
1841 ssize_t buflen, len;
1842 int r;
1843
1844 assert(s);
1845 assert(client);
1846
1847 buflen = next_datagram_size_fd(fd);
1848 if (buflen < 0)
1849 return buflen;
1850
1851 packet = malloc0(buflen);
1852 if (!packet)
1853 return -ENOMEM;
1854
1855 iov.iov_base = packet;
1856 iov.iov_len = buflen;
1857
1858 len = recvmsg(fd, &msg, 0);
1859 if (len < 0) {
1860 if (IN_SET(errno, EAGAIN, EINTR))
1861 return 0;
1862
1863 return log_dhcp_client_errno(client, errno,
1864 "Could not receive message from raw socket: %m");
1865 } else if ((size_t)len < sizeof(DHCPPacket))
1866 return 0;
1867
1868 CMSG_FOREACH(cmsg, &msg) {
1869 if (cmsg->cmsg_level == SOL_PACKET &&
1870 cmsg->cmsg_type == PACKET_AUXDATA &&
1871 cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1872 struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1873
1874 checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1875 break;
1876 }
1877 }
1878
1879 r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
1880 if (r < 0)
1881 return 0;
1882
1883 len -= DHCP_IP_UDP_SIZE;
1884
1885 return client_handle_message(client, &packet->dhcp, len);
1886 }
1887
1888 int sd_dhcp_client_start(sd_dhcp_client *client) {
1889 int r;
1890
1891 assert_return(client, -EINVAL);
1892
1893 r = client_initialize(client);
1894 if (r < 0)
1895 return r;
1896
1897 /* RFC7844 section 3.3:
1898 SHOULD perform a complete four-way handshake, starting with a
1899 DHCPDISCOVER, to obtain a new address lease. If the client can
1900 ascertain that this is exactly the same network to which it was
1901 previously connected, and if the link-layer address did not change,
1902 the client MAY issue a DHCPREQUEST to try to reclaim the current
1903 address. */
1904 if (client->last_addr && !client->anonymize)
1905 client->state = DHCP_STATE_INIT_REBOOT;
1906
1907 r = client_start(client);
1908 if (r >= 0)
1909 log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
1910
1911 return r;
1912 }
1913
1914 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1915 DHCP_CLIENT_DONT_DESTROY(client);
1916
1917 assert_return(client, -EINVAL);
1918
1919 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
1920 client->state = DHCP_STATE_STOPPED;
1921
1922 return 0;
1923 }
1924
1925 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
1926 int r;
1927
1928 assert_return(client, -EINVAL);
1929 assert_return(!client->event, -EBUSY);
1930
1931 if (event)
1932 client->event = sd_event_ref(event);
1933 else {
1934 r = sd_event_default(&client->event);
1935 if (r < 0)
1936 return 0;
1937 }
1938
1939 client->event_priority = priority;
1940
1941 return 0;
1942 }
1943
1944 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1945 assert_return(client, -EINVAL);
1946
1947 client->event = sd_event_unref(client->event);
1948
1949 return 0;
1950 }
1951
1952 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1953 assert_return(client, NULL);
1954
1955 return client->event;
1956 }
1957
1958 static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
1959 assert(client);
1960
1961 log_dhcp_client(client, "FREE");
1962
1963 client_initialize(client);
1964
1965 client->receive_message = sd_event_source_unref(client->receive_message);
1966
1967 sd_dhcp_client_detach_event(client);
1968
1969 sd_dhcp_lease_unref(client->lease);
1970
1971 free(client->req_opts);
1972 free(client->hostname);
1973 free(client->vendor_class_identifier);
1974 client->user_class = strv_free(client->user_class);
1975 return mfree(client);
1976 }
1977
1978 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
1979
1980 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
1981 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
1982
1983 assert_return(ret, -EINVAL);
1984
1985 client = new0(sd_dhcp_client, 1);
1986 if (!client)
1987 return -ENOMEM;
1988
1989 client->n_ref = 1;
1990 client->state = DHCP_STATE_INIT;
1991 client->ifindex = -1;
1992 client->fd = -1;
1993 client->attempt = 1;
1994 client->mtu = DHCP_DEFAULT_MIN_SIZE;
1995 client->port = DHCP_PORT_CLIENT;
1996
1997 client->anonymize = !!anonymize;
1998 /* NOTE: this could be moved to a function. */
1999 if (anonymize) {
2000 client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
2001 client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
2002 } else {
2003 client->req_opts_size = ELEMENTSOF(default_req_opts);
2004 client->req_opts = memdup(default_req_opts, client->req_opts_size);
2005 }
2006 if (!client->req_opts)
2007 return -ENOMEM;
2008
2009 *ret = TAKE_PTR(client);
2010
2011 return 0;
2012 }