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