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