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