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