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