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