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