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