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