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