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