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