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