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