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