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