]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp-client.c
Merge pull request #10218 from keszybz/export-sd-device-hwdb
[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 int 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 r = client_initialize(client);
1687 if (r < 0)
1688 goto error;
1689
1690 r = client_start_delayed(client);
1691 if (r < 0)
1692 goto error;
1693
1694 log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1695 client->start_delay, USEC_PER_SEC));
1696
1697 client->start_delay = CLAMP(client->start_delay * 2,
1698 RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
1699
1700 return 0;
1701 } else if (r == -ENOMSG)
1702 /* invalid message, let's ignore it */
1703 return 0;
1704
1705 break;
1706
1707 case DHCP_STATE_BOUND:
1708 r = client_handle_forcerenew(client, message, len);
1709 if (r >= 0) {
1710 r = client_timeout_t1(NULL, 0, client);
1711 if (r < 0)
1712 goto error;
1713 } else if (r == -ENOMSG)
1714 /* invalid message, let's ignore it */
1715 return 0;
1716
1717 break;
1718
1719 case DHCP_STATE_INIT:
1720 case DHCP_STATE_INIT_REBOOT:
1721
1722 break;
1723
1724 case DHCP_STATE_STOPPED:
1725 r = -EINVAL;
1726 goto error;
1727 }
1728
1729 error:
1730 if (r < 0)
1731 client_stop(client, r);
1732
1733 return r;
1734 }
1735
1736 static int client_receive_message_udp(
1737 sd_event_source *s,
1738 int fd,
1739 uint32_t revents,
1740 void *userdata) {
1741
1742 sd_dhcp_client *client = userdata;
1743 _cleanup_free_ DHCPMessage *message = NULL;
1744 const struct ether_addr zero_mac = {};
1745 const struct ether_addr *expected_chaddr = NULL;
1746 uint8_t expected_hlen = 0;
1747 ssize_t len, buflen;
1748
1749 assert(s);
1750 assert(client);
1751
1752 buflen = next_datagram_size_fd(fd);
1753 if (buflen < 0)
1754 return buflen;
1755
1756 message = malloc0(buflen);
1757 if (!message)
1758 return -ENOMEM;
1759
1760 len = recv(fd, message, buflen, 0);
1761 if (len < 0) {
1762 if (IN_SET(errno, EAGAIN, EINTR))
1763 return 0;
1764
1765 return log_dhcp_client_errno(client, errno,
1766 "Could not receive message from UDP socket: %m");
1767 }
1768 if ((size_t) len < sizeof(DHCPMessage)) {
1769 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
1770 return 0;
1771 }
1772
1773 if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1774 log_dhcp_client(client, "Not a DHCP message: ignoring");
1775 return 0;
1776 }
1777
1778 if (message->op != BOOTREPLY) {
1779 log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
1780 return 0;
1781 }
1782
1783 if (message->htype != client->arp_type) {
1784 log_dhcp_client(client, "Packet type does not match client type");
1785 return 0;
1786 }
1787
1788 if (client->arp_type == ARPHRD_ETHER) {
1789 expected_hlen = ETH_ALEN;
1790 expected_chaddr = (const struct ether_addr *) &client->mac_addr;
1791 } else {
1792 /* Non-Ethernet links expect zero chaddr */
1793 expected_hlen = 0;
1794 expected_chaddr = &zero_mac;
1795 }
1796
1797 if (message->hlen != expected_hlen) {
1798 log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
1799 return 0;
1800 }
1801
1802 if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
1803 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
1804 return 0;
1805 }
1806
1807 if (client->state != DHCP_STATE_BOUND &&
1808 be32toh(message->xid) != client->xid) {
1809 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1810 so ignore the xid in this case */
1811 log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
1812 be32toh(message->xid), client->xid);
1813 return 0;
1814 }
1815
1816 return client_handle_message(client, message, len);
1817 }
1818
1819 static int client_receive_message_raw(
1820 sd_event_source *s,
1821 int fd,
1822 uint32_t revents,
1823 void *userdata) {
1824
1825 sd_dhcp_client *client = userdata;
1826 _cleanup_free_ DHCPPacket *packet = NULL;
1827 uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1828 struct iovec iov = {};
1829 struct msghdr msg = {
1830 .msg_iov = &iov,
1831 .msg_iovlen = 1,
1832 .msg_control = cmsgbuf,
1833 .msg_controllen = sizeof(cmsgbuf),
1834 };
1835 struct cmsghdr *cmsg;
1836 bool checksum = true;
1837 ssize_t buflen, len;
1838 int r;
1839
1840 assert(s);
1841 assert(client);
1842
1843 buflen = next_datagram_size_fd(fd);
1844 if (buflen < 0)
1845 return buflen;
1846
1847 packet = malloc0(buflen);
1848 if (!packet)
1849 return -ENOMEM;
1850
1851 iov.iov_base = packet;
1852 iov.iov_len = buflen;
1853
1854 len = recvmsg(fd, &msg, 0);
1855 if (len < 0) {
1856 if (IN_SET(errno, EAGAIN, EINTR))
1857 return 0;
1858
1859 return log_dhcp_client_errno(client, errno,
1860 "Could not receive message from raw socket: %m");
1861 } else if ((size_t)len < sizeof(DHCPPacket))
1862 return 0;
1863
1864 CMSG_FOREACH(cmsg, &msg) {
1865 if (cmsg->cmsg_level == SOL_PACKET &&
1866 cmsg->cmsg_type == PACKET_AUXDATA &&
1867 cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1868 struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1869
1870 checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1871 break;
1872 }
1873 }
1874
1875 r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
1876 if (r < 0)
1877 return 0;
1878
1879 len -= DHCP_IP_UDP_SIZE;
1880
1881 return client_handle_message(client, &packet->dhcp, len);
1882 }
1883
1884 int sd_dhcp_client_start(sd_dhcp_client *client) {
1885 int r;
1886
1887 assert_return(client, -EINVAL);
1888
1889 r = client_initialize(client);
1890 if (r < 0)
1891 return r;
1892
1893 /* RFC7844 section 3.3:
1894 SHOULD perform a complete four-way handshake, starting with a
1895 DHCPDISCOVER, to obtain a new address lease. If the client can
1896 ascertain that this is exactly the same network to which it was
1897 previously connected, and if the link-layer address did not change,
1898 the client MAY issue a DHCPREQUEST to try to reclaim the current
1899 address. */
1900 if (client->last_addr && !client->anonymize)
1901 client->state = DHCP_STATE_INIT_REBOOT;
1902
1903 r = client_start(client);
1904 if (r >= 0)
1905 log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
1906
1907 return r;
1908 }
1909
1910 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1911 DHCP_CLIENT_DONT_DESTROY(client);
1912
1913 assert_return(client, -EINVAL);
1914
1915 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
1916 client->state = DHCP_STATE_STOPPED;
1917
1918 return 0;
1919 }
1920
1921 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
1922 int r;
1923
1924 assert_return(client, -EINVAL);
1925 assert_return(!client->event, -EBUSY);
1926
1927 if (event)
1928 client->event = sd_event_ref(event);
1929 else {
1930 r = sd_event_default(&client->event);
1931 if (r < 0)
1932 return 0;
1933 }
1934
1935 client->event_priority = priority;
1936
1937 return 0;
1938 }
1939
1940 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1941 assert_return(client, -EINVAL);
1942
1943 client->event = sd_event_unref(client->event);
1944
1945 return 0;
1946 }
1947
1948 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1949 assert_return(client, NULL);
1950
1951 return client->event;
1952 }
1953
1954 static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
1955 assert(client);
1956
1957 log_dhcp_client(client, "FREE");
1958
1959 client_initialize(client);
1960
1961 client->receive_message = sd_event_source_unref(client->receive_message);
1962
1963 sd_dhcp_client_detach_event(client);
1964
1965 sd_dhcp_lease_unref(client->lease);
1966
1967 free(client->req_opts);
1968 free(client->hostname);
1969 free(client->vendor_class_identifier);
1970 client->user_class = strv_free(client->user_class);
1971 return mfree(client);
1972 }
1973
1974 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
1975
1976 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
1977 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
1978
1979 assert_return(ret, -EINVAL);
1980
1981 client = new0(sd_dhcp_client, 1);
1982 if (!client)
1983 return -ENOMEM;
1984
1985 client->n_ref = 1;
1986 client->state = DHCP_STATE_INIT;
1987 client->ifindex = -1;
1988 client->fd = -1;
1989 client->attempt = 1;
1990 client->mtu = DHCP_DEFAULT_MIN_SIZE;
1991 client->port = DHCP_PORT_CLIENT;
1992
1993 client->anonymize = !!anonymize;
1994 /* NOTE: this could be moved to a function. */
1995 if (anonymize) {
1996 client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
1997 client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
1998 } else {
1999 client->req_opts_size = ELEMENTSOF(default_req_opts);
2000 client->req_opts = memdup(default_req_opts, client->req_opts_size);
2001 }
2002 if (!client->req_opts)
2003 return -ENOMEM;
2004
2005 *ret = TAKE_PTR(client);
2006
2007 return 0;
2008 }