]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp-client.c
Merge pull request #12378 from rbalint/vt-kbd-reset-check
[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, DHCP_RELEASE));
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 && type != DHCP_RELEASE) {
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 && type != DHCP_RELEASE) {
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_release(sd_dhcp_client *client) {
865 _cleanup_free_ DHCPPacket *release = NULL;
866 size_t optoffset, optlen;
867 int r;
868
869 assert(client);
870 assert(!IN_SET(client->state, DHCP_STATE_STOPPED));
871
872 r = client_message_init(client, &release, DHCP_RELEASE,
873 &optlen, &optoffset);
874 if (r < 0)
875 return r;
876
877 /* Fill up release IP and MAC */
878 release->dhcp.ciaddr = client->lease->address;
879 memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
880
881 r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
882 SD_DHCP_OPTION_END, 0, NULL);
883 if (r < 0)
884 return r;
885
886 r = dhcp_network_send_udp_socket(client->fd,
887 client->lease->server_address,
888 DHCP_PORT_SERVER,
889 &release->dhcp,
890 sizeof(DHCPMessage) + optoffset);
891 if (r < 0)
892 return r;
893
894 log_dhcp_client(client, "RELEASE");
895
896 return 0;
897 }
898
899 static int client_send_request(sd_dhcp_client *client) {
900 _cleanup_free_ DHCPPacket *request = NULL;
901 size_t optoffset, optlen;
902 int r;
903
904 assert(client);
905
906 r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset);
907 if (r < 0)
908 return r;
909
910 switch (client->state) {
911 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
912 SELECTING should be REQUESTING)
913 */
914
915 case DHCP_STATE_REQUESTING:
916 /* Client inserts the address of the selected server in ’server
917 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
918 filled in with the yiaddr value from the chosen DHCPOFFER.
919 */
920
921 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
922 SD_DHCP_OPTION_SERVER_IDENTIFIER,
923 4, &client->lease->server_address);
924 if (r < 0)
925 return r;
926
927 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
928 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
929 4, &client->lease->address);
930 if (r < 0)
931 return r;
932
933 break;
934
935 case DHCP_STATE_INIT_REBOOT:
936 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
937 option MUST be filled in with client’s notion of its previously
938 assigned address. ’ciaddr’ MUST be zero.
939 */
940 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
941 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
942 4, &client->last_addr);
943 if (r < 0)
944 return r;
945 break;
946
947 case DHCP_STATE_RENEWING:
948 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
949 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
950 client’s IP address.
951 */
952
953 case DHCP_STATE_REBINDING:
954 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
955 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
956 client’s IP address.
957
958 This message MUST be broadcast to the 0xffffffff IP broadcast address.
959 */
960 request->dhcp.ciaddr = client->lease->address;
961
962 break;
963
964 case DHCP_STATE_INIT:
965 case DHCP_STATE_SELECTING:
966 case DHCP_STATE_REBOOTING:
967 case DHCP_STATE_BOUND:
968 case DHCP_STATE_STOPPED:
969 return -EINVAL;
970 }
971
972 if (client->hostname) {
973 if (dns_name_is_single_label(client->hostname))
974 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
975 SD_DHCP_OPTION_HOST_NAME,
976 strlen(client->hostname), client->hostname);
977 else
978 r = client_append_fqdn_option(&request->dhcp, optlen, &optoffset,
979 client->hostname);
980 if (r < 0)
981 return r;
982 }
983
984 if (client->vendor_class_identifier) {
985 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
986 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
987 strlen(client->vendor_class_identifier),
988 client->vendor_class_identifier);
989 if (r < 0)
990 return r;
991 }
992
993 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
994 SD_DHCP_OPTION_END, 0, NULL);
995 if (r < 0)
996 return r;
997
998 if (client->state == DHCP_STATE_RENEWING) {
999 r = dhcp_network_send_udp_socket(client->fd,
1000 client->lease->server_address,
1001 DHCP_PORT_SERVER,
1002 &request->dhcp,
1003 sizeof(DHCPMessage) + optoffset);
1004 } else {
1005 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
1006 }
1007 if (r < 0)
1008 return r;
1009
1010 switch (client->state) {
1011
1012 case DHCP_STATE_REQUESTING:
1013 log_dhcp_client(client, "REQUEST (requesting)");
1014 break;
1015
1016 case DHCP_STATE_INIT_REBOOT:
1017 log_dhcp_client(client, "REQUEST (init-reboot)");
1018 break;
1019
1020 case DHCP_STATE_RENEWING:
1021 log_dhcp_client(client, "REQUEST (renewing)");
1022 break;
1023
1024 case DHCP_STATE_REBINDING:
1025 log_dhcp_client(client, "REQUEST (rebinding)");
1026 break;
1027
1028 default:
1029 log_dhcp_client(client, "REQUEST (invalid)");
1030 break;
1031 }
1032
1033 return 0;
1034 }
1035
1036 static int client_start(sd_dhcp_client *client);
1037
1038 static int client_timeout_resend(
1039 sd_event_source *s,
1040 uint64_t usec,
1041 void *userdata) {
1042
1043 sd_dhcp_client *client = userdata;
1044 DHCP_CLIENT_DONT_DESTROY(client);
1045 usec_t next_timeout = 0;
1046 uint64_t time_now;
1047 uint32_t time_left;
1048 int r;
1049
1050 assert(s);
1051 assert(client);
1052 assert(client->event);
1053
1054 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1055 if (r < 0)
1056 goto error;
1057
1058 switch (client->state) {
1059
1060 case DHCP_STATE_RENEWING:
1061
1062 time_left = (client->lease->t2 - client->lease->t1) / 2;
1063 if (time_left < 60)
1064 time_left = 60;
1065
1066 next_timeout = time_now + time_left * USEC_PER_SEC;
1067
1068 break;
1069
1070 case DHCP_STATE_REBINDING:
1071
1072 time_left = (client->lease->lifetime - client->lease->t2) / 2;
1073 if (time_left < 60)
1074 time_left = 60;
1075
1076 next_timeout = time_now + time_left * USEC_PER_SEC;
1077 break;
1078
1079 case DHCP_STATE_REBOOTING:
1080 /* start over as we did not receive a timely ack or nak */
1081 r = client_initialize(client);
1082 if (r < 0)
1083 goto error;
1084
1085 r = client_start(client);
1086 if (r < 0)
1087 goto error;
1088 else {
1089 log_dhcp_client(client, "REBOOTED");
1090 return 0;
1091 }
1092
1093 case DHCP_STATE_INIT:
1094 case DHCP_STATE_INIT_REBOOT:
1095 case DHCP_STATE_SELECTING:
1096 case DHCP_STATE_REQUESTING:
1097 case DHCP_STATE_BOUND:
1098
1099 if (client->attempt < client->max_attempts)
1100 client->attempt++;
1101 else
1102 goto error;
1103
1104 next_timeout = time_now + ((UINT64_C(1) << MIN(client->attempt, (uint64_t) 6)) - 1) * USEC_PER_SEC;
1105
1106 break;
1107
1108 case DHCP_STATE_STOPPED:
1109 r = -EINVAL;
1110 goto error;
1111 }
1112
1113 next_timeout += (random_u32() & 0x1fffff);
1114
1115 r = event_reset_time(client->event, &client->timeout_resend,
1116 clock_boottime_or_monotonic(),
1117 next_timeout, 10 * USEC_PER_MSEC,
1118 client_timeout_resend, client,
1119 client->event_priority, "dhcp4-resend-timer", true);
1120 if (r < 0)
1121 goto error;
1122
1123 switch (client->state) {
1124 case DHCP_STATE_INIT:
1125 r = client_send_discover(client);
1126 if (r >= 0) {
1127 client->state = DHCP_STATE_SELECTING;
1128 client->attempt = 0;
1129 } else if (client->attempt >= client->max_attempts)
1130 goto error;
1131
1132 break;
1133
1134 case DHCP_STATE_SELECTING:
1135 r = client_send_discover(client);
1136 if (r < 0 && client->attempt >= client->max_attempts)
1137 goto error;
1138
1139 break;
1140
1141 case DHCP_STATE_INIT_REBOOT:
1142 case DHCP_STATE_REQUESTING:
1143 case DHCP_STATE_RENEWING:
1144 case DHCP_STATE_REBINDING:
1145 r = client_send_request(client);
1146 if (r < 0 && client->attempt >= client->max_attempts)
1147 goto error;
1148
1149 if (client->state == DHCP_STATE_INIT_REBOOT)
1150 client->state = DHCP_STATE_REBOOTING;
1151
1152 client->request_sent = time_now;
1153
1154 break;
1155
1156 case DHCP_STATE_REBOOTING:
1157 case DHCP_STATE_BOUND:
1158
1159 break;
1160
1161 case DHCP_STATE_STOPPED:
1162 r = -EINVAL;
1163 goto error;
1164 }
1165
1166 return 0;
1167
1168 error:
1169 client_stop(client, r);
1170
1171 /* Errors were dealt with when stopping the client, don't spill
1172 errors into the event loop handler */
1173 return 0;
1174 }
1175
1176 static int client_initialize_io_events(
1177 sd_dhcp_client *client,
1178 sd_event_io_handler_t io_callback) {
1179
1180 int r;
1181
1182 assert(client);
1183 assert(client->event);
1184
1185 r = sd_event_add_io(client->event, &client->receive_message,
1186 client->fd, EPOLLIN, io_callback,
1187 client);
1188 if (r < 0)
1189 goto error;
1190
1191 r = sd_event_source_set_priority(client->receive_message,
1192 client->event_priority);
1193 if (r < 0)
1194 goto error;
1195
1196 r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
1197 if (r < 0)
1198 goto error;
1199
1200 error:
1201 if (r < 0)
1202 client_stop(client, r);
1203
1204 return 0;
1205 }
1206
1207 static int client_initialize_time_events(sd_dhcp_client *client) {
1208 uint64_t usec = 0;
1209 int r;
1210
1211 assert(client);
1212 assert(client->event);
1213
1214 if (client->start_delay) {
1215 assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
1216 usec += client->start_delay;
1217 }
1218
1219 r = event_reset_time(client->event, &client->timeout_resend,
1220 clock_boottime_or_monotonic(),
1221 usec, 0,
1222 client_timeout_resend, client,
1223 client->event_priority, "dhcp4-resend-timer", true);
1224 if (r < 0)
1225 client_stop(client, r);
1226
1227 return 0;
1228
1229 }
1230
1231 static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
1232 client_initialize_io_events(client, io_callback);
1233 client_initialize_time_events(client);
1234
1235 return 0;
1236 }
1237
1238 static int client_start_delayed(sd_dhcp_client *client) {
1239 int r;
1240
1241 assert_return(client, -EINVAL);
1242 assert_return(client->event, -EINVAL);
1243 assert_return(client->ifindex > 0, -EINVAL);
1244 assert_return(client->fd < 0, -EBUSY);
1245 assert_return(client->xid == 0, -EINVAL);
1246 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY);
1247
1248 client->xid = random_u32();
1249
1250 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1251 client->xid, client->mac_addr,
1252 client->mac_addr_len, client->arp_type, client->port);
1253 if (r < 0) {
1254 client_stop(client, r);
1255 return r;
1256 }
1257 client->fd = r;
1258
1259 if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT))
1260 client->start_time = now(clock_boottime_or_monotonic());
1261
1262 return client_initialize_events(client, client_receive_message_raw);
1263 }
1264
1265 static int client_start(sd_dhcp_client *client) {
1266 client->start_delay = 0;
1267 return client_start_delayed(client);
1268 }
1269
1270 static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
1271 sd_dhcp_client *client = userdata;
1272 DHCP_CLIENT_DONT_DESTROY(client);
1273
1274 log_dhcp_client(client, "EXPIRED");
1275
1276 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1277
1278 /* lease was lost, start over if not freed or stopped in callback */
1279 if (client->state != DHCP_STATE_STOPPED) {
1280 client_initialize(client);
1281 client_start(client);
1282 }
1283
1284 return 0;
1285 }
1286
1287 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
1288 sd_dhcp_client *client = userdata;
1289 DHCP_CLIENT_DONT_DESTROY(client);
1290 int r;
1291
1292 assert(client);
1293
1294 client->receive_message = sd_event_source_unref(client->receive_message);
1295 client->fd = asynchronous_close(client->fd);
1296
1297 client->state = DHCP_STATE_REBINDING;
1298 client->attempt = 0;
1299
1300 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1301 client->xid, client->mac_addr,
1302 client->mac_addr_len, client->arp_type,
1303 client->port);
1304 if (r < 0) {
1305 client_stop(client, r);
1306 return 0;
1307 }
1308 client->fd = r;
1309
1310 return client_initialize_events(client, client_receive_message_raw);
1311 }
1312
1313 static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
1314 sd_dhcp_client *client = userdata;
1315 DHCP_CLIENT_DONT_DESTROY(client);
1316
1317 client->state = DHCP_STATE_RENEWING;
1318 client->attempt = 0;
1319
1320 return client_initialize_time_events(client);
1321 }
1322
1323 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
1324 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1325 int r;
1326
1327 r = dhcp_lease_new(&lease);
1328 if (r < 0)
1329 return r;
1330
1331 if (client->client_id_len) {
1332 r = dhcp_lease_set_client_id(lease,
1333 (uint8_t *) &client->client_id,
1334 client->client_id_len);
1335 if (r < 0)
1336 return r;
1337 }
1338
1339 r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease, NULL);
1340 if (r != DHCP_OFFER) {
1341 log_dhcp_client(client, "received message was not an OFFER, ignoring");
1342 return -ENOMSG;
1343 }
1344
1345 lease->next_server = offer->siaddr;
1346 lease->address = offer->yiaddr;
1347
1348 if (lease->address == 0 ||
1349 lease->server_address == 0 ||
1350 lease->lifetime == 0) {
1351 log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
1352 return -ENOMSG;
1353 }
1354
1355 if (!lease->have_subnet_mask) {
1356 r = dhcp_lease_set_default_subnet_mask(lease);
1357 if (r < 0) {
1358 log_dhcp_client(client,
1359 "received lease lacks subnet mask, "
1360 "and a fallback one cannot be generated, ignoring");
1361 return -ENOMSG;
1362 }
1363 }
1364
1365 sd_dhcp_lease_unref(client->lease);
1366 client->lease = TAKE_PTR(lease);
1367
1368 if (client_notify(client, SD_DHCP_CLIENT_EVENT_SELECTING) < 0)
1369 return -ENOMSG;
1370
1371 log_dhcp_client(client, "OFFER");
1372
1373 return 0;
1374 }
1375
1376 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
1377 int r;
1378
1379 r = dhcp_option_parse(force, len, NULL, NULL, NULL);
1380 if (r != DHCP_FORCERENEW)
1381 return -ENOMSG;
1382
1383 log_dhcp_client(client, "FORCERENEW");
1384
1385 return 0;
1386 }
1387
1388 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
1389 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1390 _cleanup_free_ char *error_message = NULL;
1391 int r;
1392
1393 r = dhcp_lease_new(&lease);
1394 if (r < 0)
1395 return r;
1396
1397 if (client->client_id_len) {
1398 r = dhcp_lease_set_client_id(lease,
1399 (uint8_t *) &client->client_id,
1400 client->client_id_len);
1401 if (r < 0)
1402 return r;
1403 }
1404
1405 r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease, &error_message);
1406 if (r == DHCP_NAK) {
1407 log_dhcp_client(client, "NAK: %s", strna(error_message));
1408 return -EADDRNOTAVAIL;
1409 }
1410
1411 if (r != DHCP_ACK) {
1412 log_dhcp_client(client, "received message was not an ACK, ignoring");
1413 return -ENOMSG;
1414 }
1415
1416 lease->next_server = ack->siaddr;
1417
1418 lease->address = ack->yiaddr;
1419
1420 if (lease->address == INADDR_ANY ||
1421 lease->server_address == INADDR_ANY ||
1422 lease->lifetime == 0) {
1423 log_dhcp_client(client, "received lease lacks address, server "
1424 "address or lease lifetime, ignoring");
1425 return -ENOMSG;
1426 }
1427
1428 if (lease->subnet_mask == INADDR_ANY) {
1429 r = dhcp_lease_set_default_subnet_mask(lease);
1430 if (r < 0) {
1431 log_dhcp_client(client,
1432 "received lease lacks subnet mask, "
1433 "and a fallback one cannot be generated, ignoring");
1434 return -ENOMSG;
1435 }
1436 }
1437
1438 r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1439 if (client->lease) {
1440 if (client->lease->address != lease->address ||
1441 client->lease->subnet_mask != lease->subnet_mask ||
1442 client->lease->router != lease->router) {
1443 r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
1444 } else
1445 r = SD_DHCP_CLIENT_EVENT_RENEW;
1446
1447 client->lease = sd_dhcp_lease_unref(client->lease);
1448 }
1449
1450 client->lease = TAKE_PTR(lease);
1451
1452 log_dhcp_client(client, "ACK");
1453
1454 return r;
1455 }
1456
1457 static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) {
1458 assert(client);
1459 assert(client->request_sent);
1460 assert(lifetime > 0);
1461
1462 if (lifetime > 3)
1463 lifetime -= 3;
1464 else
1465 lifetime = 0;
1466
1467 return client->request_sent + (lifetime * USEC_PER_SEC * factor) +
1468 + (random_u32() & 0x1fffff);
1469 }
1470
1471 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1472 usec_t time_now;
1473 uint64_t lifetime_timeout;
1474 uint64_t t2_timeout;
1475 uint64_t t1_timeout;
1476 char time_string[FORMAT_TIMESPAN_MAX];
1477 int r;
1478
1479 assert(client);
1480 assert(client->event);
1481 assert(client->lease);
1482 assert(client->lease->lifetime);
1483
1484 /* don't set timers for infinite leases */
1485 if (client->lease->lifetime == 0xffffffff) {
1486 (void) event_source_disable(client->timeout_t1);
1487 (void) event_source_disable(client->timeout_t2);
1488 (void) event_source_disable(client->timeout_expire);
1489
1490 return 0;
1491 }
1492
1493 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1494 if (r < 0)
1495 return r;
1496 assert(client->request_sent <= time_now);
1497
1498 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1499 lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1500 if (client->lease->t1 > 0 && client->lease->t2 > 0) {
1501 /* both T1 and T2 are given */
1502 if (client->lease->t1 < client->lease->t2 &&
1503 client->lease->t2 < client->lease->lifetime) {
1504 /* they are both valid */
1505 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1506 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1507 } else {
1508 /* discard both */
1509 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1510 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1511 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1512 client->lease->t1 = client->lease->lifetime / 2;
1513 }
1514 } else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) {
1515 /* only T2 is given, and it is valid */
1516 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1517 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1518 client->lease->t1 = client->lease->lifetime / 2;
1519 if (t2_timeout <= t1_timeout) {
1520 /* the computed T1 would be invalid, so discard T2 */
1521 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1522 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1523 }
1524 } else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) {
1525 /* only T1 is given, and it is valid */
1526 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1527 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1528 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1529 if (t2_timeout <= t1_timeout) {
1530 /* the computed T2 would be invalid, so discard T1 */
1531 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1532 client->lease->t2 = client->lease->lifetime / 2;
1533 }
1534 } else {
1535 /* fall back to the default timeouts */
1536 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1537 client->lease->t1 = client->lease->lifetime / 2;
1538 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1539 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1540 }
1541
1542 /* arm lifetime timeout */
1543 r = event_reset_time(client->event, &client->timeout_expire,
1544 clock_boottime_or_monotonic(),
1545 lifetime_timeout, 10 * USEC_PER_MSEC,
1546 client_timeout_expire, client,
1547 client->event_priority, "dhcp4-lifetime", true);
1548 if (r < 0)
1549 return r;
1550
1551 log_dhcp_client(client, "lease expires in %s",
1552 format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime_timeout - time_now, USEC_PER_SEC));
1553
1554 /* don't arm earlier timeouts if this has already expired */
1555 if (lifetime_timeout <= time_now)
1556 return 0;
1557
1558 /* arm T2 timeout */
1559 r = event_reset_time(client->event, &client->timeout_t2,
1560 clock_boottime_or_monotonic(),
1561 t2_timeout, 10 * USEC_PER_MSEC,
1562 client_timeout_t2, client,
1563 client->event_priority, "dhcp4-t2-timeout", true);
1564 if (r < 0)
1565 return r;
1566
1567 log_dhcp_client(client, "T2 expires in %s",
1568 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t2_timeout - time_now, USEC_PER_SEC));
1569
1570 /* don't arm earlier timeout if this has already expired */
1571 if (t2_timeout <= time_now)
1572 return 0;
1573
1574 /* arm T1 timeout */
1575 r = event_reset_time(client->event, &client->timeout_t1,
1576 clock_boottime_or_monotonic(),
1577 t1_timeout, 10 * USEC_PER_MSEC,
1578 client_timeout_t1, client,
1579 client->event_priority, "dhcp4-t1-timer", true);
1580 if (r < 0)
1581 return r;
1582
1583 log_dhcp_client(client, "T1 expires in %s",
1584 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t1_timeout - time_now, USEC_PER_SEC));
1585
1586 return 0;
1587 }
1588
1589 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
1590 DHCP_CLIENT_DONT_DESTROY(client);
1591 char time_string[FORMAT_TIMESPAN_MAX];
1592 int r = 0, notify_event = 0;
1593
1594 assert(client);
1595 assert(client->event);
1596 assert(message);
1597
1598 switch (client->state) {
1599 case DHCP_STATE_SELECTING:
1600
1601 r = client_handle_offer(client, message, len);
1602 if (r >= 0) {
1603
1604 client->state = DHCP_STATE_REQUESTING;
1605 client->attempt = 0;
1606
1607 r = event_reset_time(client->event, &client->timeout_resend,
1608 clock_boottime_or_monotonic(),
1609 0, 0,
1610 client_timeout_resend, client,
1611 client->event_priority, "dhcp4-resend-timer", true);
1612 if (r < 0)
1613 goto error;
1614 } else if (r == -ENOMSG)
1615 /* invalid message, let's ignore it */
1616 return 0;
1617
1618 break;
1619
1620 case DHCP_STATE_REBOOTING:
1621 case DHCP_STATE_REQUESTING:
1622 case DHCP_STATE_RENEWING:
1623 case DHCP_STATE_REBINDING:
1624
1625 r = client_handle_ack(client, message, len);
1626 if (r >= 0) {
1627 client->start_delay = 0;
1628 (void) event_source_disable(client->timeout_resend);
1629 client->receive_message =
1630 sd_event_source_unref(client->receive_message);
1631 client->fd = asynchronous_close(client->fd);
1632
1633 if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1634 DHCP_STATE_REBOOTING))
1635 notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1636 else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
1637 notify_event = r;
1638
1639 client->state = DHCP_STATE_BOUND;
1640 client->attempt = 0;
1641
1642 client->last_addr = client->lease->address;
1643
1644 r = client_set_lease_timeouts(client);
1645 if (r < 0) {
1646 log_dhcp_client(client, "could not set lease timeouts");
1647 goto error;
1648 }
1649
1650 r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port);
1651 if (r < 0) {
1652 log_dhcp_client(client, "could not bind UDP socket");
1653 goto error;
1654 }
1655
1656 client->fd = r;
1657
1658 client_initialize_io_events(client, client_receive_message_udp);
1659
1660 if (notify_event) {
1661 client_notify(client, notify_event);
1662 if (client->state == DHCP_STATE_STOPPED)
1663 return 0;
1664 }
1665
1666 } else if (r == -EADDRNOTAVAIL) {
1667 /* got a NAK, let's restart the client */
1668 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1669
1670 r = client_initialize(client);
1671 if (r < 0)
1672 goto error;
1673
1674 r = client_start_delayed(client);
1675 if (r < 0)
1676 goto error;
1677
1678 log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1679 client->start_delay, USEC_PER_SEC));
1680
1681 client->start_delay = CLAMP(client->start_delay * 2,
1682 RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
1683
1684 return 0;
1685 } else if (r == -ENOMSG)
1686 /* invalid message, let's ignore it */
1687 return 0;
1688
1689 break;
1690
1691 case DHCP_STATE_BOUND:
1692 r = client_handle_forcerenew(client, message, len);
1693 if (r >= 0) {
1694 r = client_timeout_t1(NULL, 0, client);
1695 if (r < 0)
1696 goto error;
1697 } else if (r == -ENOMSG)
1698 /* invalid message, let's ignore it */
1699 return 0;
1700
1701 break;
1702
1703 case DHCP_STATE_INIT:
1704 case DHCP_STATE_INIT_REBOOT:
1705
1706 break;
1707
1708 case DHCP_STATE_STOPPED:
1709 r = -EINVAL;
1710 goto error;
1711 }
1712
1713 error:
1714 if (r < 0)
1715 client_stop(client, r);
1716
1717 return r;
1718 }
1719
1720 static int client_receive_message_udp(
1721 sd_event_source *s,
1722 int fd,
1723 uint32_t revents,
1724 void *userdata) {
1725
1726 sd_dhcp_client *client = userdata;
1727 _cleanup_free_ DHCPMessage *message = NULL;
1728 const uint8_t *expected_chaddr = NULL;
1729 uint8_t expected_hlen = 0;
1730 ssize_t len, buflen;
1731
1732 assert(s);
1733 assert(client);
1734
1735 buflen = next_datagram_size_fd(fd);
1736 if (buflen == -ENETDOWN) {
1737 /* the link is down. Don't return an error or the I/O event
1738 source will be disconnected and we won't be able to receive
1739 packets again when the link comes back. */
1740 return 0;
1741 }
1742 if (buflen < 0)
1743 return buflen;
1744
1745 message = malloc0(buflen);
1746 if (!message)
1747 return -ENOMEM;
1748
1749 len = recv(fd, message, buflen, 0);
1750 if (len < 0) {
1751 /* see comment above for why we shouldn't error out on ENETDOWN. */
1752 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1753 return 0;
1754
1755 return log_dhcp_client_errno(client, errno,
1756 "Could not receive message from UDP socket: %m");
1757 }
1758 if ((size_t) len < sizeof(DHCPMessage)) {
1759 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
1760 return 0;
1761 }
1762
1763 if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1764 log_dhcp_client(client, "Not a DHCP message: ignoring");
1765 return 0;
1766 }
1767
1768 if (message->op != BOOTREPLY) {
1769 log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
1770 return 0;
1771 }
1772
1773 if (message->htype != client->arp_type) {
1774 log_dhcp_client(client, "Packet type does not match client type");
1775 return 0;
1776 }
1777
1778 if (client->arp_type == ARPHRD_ETHER) {
1779 expected_hlen = ETH_ALEN;
1780 expected_chaddr = &client->mac_addr[0];
1781 }
1782
1783 if (message->hlen != expected_hlen) {
1784 log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
1785 return 0;
1786 }
1787
1788 if (expected_hlen > 0 && memcmp(&message->chaddr[0], expected_chaddr, expected_hlen)) {
1789 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
1790 return 0;
1791 }
1792
1793 if (client->state != DHCP_STATE_BOUND &&
1794 be32toh(message->xid) != client->xid) {
1795 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1796 so ignore the xid in this case */
1797 log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
1798 be32toh(message->xid), client->xid);
1799 return 0;
1800 }
1801
1802 return client_handle_message(client, message, len);
1803 }
1804
1805 static int client_receive_message_raw(
1806 sd_event_source *s,
1807 int fd,
1808 uint32_t revents,
1809 void *userdata) {
1810
1811 sd_dhcp_client *client = userdata;
1812 _cleanup_free_ DHCPPacket *packet = NULL;
1813 uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1814 struct iovec iov = {};
1815 struct msghdr msg = {
1816 .msg_iov = &iov,
1817 .msg_iovlen = 1,
1818 .msg_control = cmsgbuf,
1819 .msg_controllen = sizeof(cmsgbuf),
1820 };
1821 struct cmsghdr *cmsg;
1822 bool checksum = true;
1823 ssize_t buflen, len;
1824 int r;
1825
1826 assert(s);
1827 assert(client);
1828
1829 buflen = next_datagram_size_fd(fd);
1830 if (buflen == -ENETDOWN)
1831 return 0;
1832 if (buflen < 0)
1833 return buflen;
1834
1835 packet = malloc0(buflen);
1836 if (!packet)
1837 return -ENOMEM;
1838
1839 iov = IOVEC_MAKE(packet, buflen);
1840
1841 len = recvmsg(fd, &msg, 0);
1842 if (len < 0) {
1843 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1844 return 0;
1845
1846 return log_dhcp_client_errno(client, errno,
1847 "Could not receive message from raw socket: %m");
1848 } else if ((size_t)len < sizeof(DHCPPacket))
1849 return 0;
1850
1851 CMSG_FOREACH(cmsg, &msg)
1852 if (cmsg->cmsg_level == SOL_PACKET &&
1853 cmsg->cmsg_type == PACKET_AUXDATA &&
1854 cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1855 struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1856
1857 checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1858 break;
1859 }
1860
1861 r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
1862 if (r < 0)
1863 return 0;
1864
1865 len -= DHCP_IP_UDP_SIZE;
1866
1867 return client_handle_message(client, &packet->dhcp, len);
1868 }
1869
1870 int sd_dhcp_client_start(sd_dhcp_client *client) {
1871 int r;
1872
1873 assert_return(client, -EINVAL);
1874
1875 r = client_initialize(client);
1876 if (r < 0)
1877 return r;
1878
1879 /* RFC7844 section 3.3:
1880 SHOULD perform a complete four-way handshake, starting with a
1881 DHCPDISCOVER, to obtain a new address lease. If the client can
1882 ascertain that this is exactly the same network to which it was
1883 previously connected, and if the link-layer address did not change,
1884 the client MAY issue a DHCPREQUEST to try to reclaim the current
1885 address. */
1886 if (client->last_addr && !client->anonymize)
1887 client->state = DHCP_STATE_INIT_REBOOT;
1888
1889 r = client_start(client);
1890 if (r >= 0)
1891 log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
1892
1893 return r;
1894 }
1895
1896 int sd_dhcp_client_send_release(sd_dhcp_client *client) {
1897 assert_return(client, -EINVAL);
1898
1899 client_send_release(client);
1900
1901 return 0;
1902 }
1903
1904 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1905 DHCP_CLIENT_DONT_DESTROY(client);
1906
1907 assert_return(client, -EINVAL);
1908
1909 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
1910 client->state = DHCP_STATE_STOPPED;
1911
1912 return 0;
1913 }
1914
1915 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
1916 int r;
1917
1918 assert_return(client, -EINVAL);
1919 assert_return(!client->event, -EBUSY);
1920
1921 if (event)
1922 client->event = sd_event_ref(event);
1923 else {
1924 r = sd_event_default(&client->event);
1925 if (r < 0)
1926 return 0;
1927 }
1928
1929 client->event_priority = priority;
1930
1931 return 0;
1932 }
1933
1934 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1935 assert_return(client, -EINVAL);
1936
1937 client->event = sd_event_unref(client->event);
1938
1939 return 0;
1940 }
1941
1942 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1943 assert_return(client, NULL);
1944
1945 return client->event;
1946 }
1947
1948 static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
1949 assert(client);
1950
1951 log_dhcp_client(client, "FREE");
1952
1953 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
1954 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
1955 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
1956 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
1957
1958 client_initialize(client);
1959
1960 sd_dhcp_client_detach_event(client);
1961
1962 sd_dhcp_lease_unref(client->lease);
1963
1964 free(client->req_opts);
1965 free(client->hostname);
1966 free(client->vendor_class_identifier);
1967 client->user_class = strv_free(client->user_class);
1968 return mfree(client);
1969 }
1970
1971 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
1972
1973 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
1974 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
1975
1976 assert_return(ret, -EINVAL);
1977
1978 client = new(sd_dhcp_client, 1);
1979 if (!client)
1980 return -ENOMEM;
1981
1982 *client = (sd_dhcp_client) {
1983 .n_ref = 1,
1984 .state = DHCP_STATE_INIT,
1985 .ifindex = -1,
1986 .fd = -1,
1987 .mtu = DHCP_DEFAULT_MIN_SIZE,
1988 .port = DHCP_PORT_CLIENT,
1989 .anonymize = !!anonymize,
1990 .max_attempts = (uint64_t) -1,
1991 };
1992 /* NOTE: this could be moved to a function. */
1993 if (anonymize) {
1994 client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
1995 client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
1996 } else {
1997 client->req_opts_size = ELEMENTSOF(default_req_opts);
1998 client->req_opts = memdup(default_req_opts, client->req_opts_size);
1999 }
2000 if (!client->req_opts)
2001 return -ENOMEM;
2002
2003 *ret = TAKE_PTR(client);
2004
2005 return 0;
2006 }