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