1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright (C) 2013 Intel Corporation. All rights reserved.
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <net/ethernet.h>
23 #include <net/if_arp.h>
27 #include <sys/ioctl.h>
28 #include <linux/if_infiniband.h>
30 #include "sd-dhcp-client.h"
32 #include "alloc-util.h"
34 #include "dhcp-identifier.h"
35 #include "dhcp-internal.h"
36 #include "dhcp-lease-internal.h"
37 #include "dhcp-protocol.h"
38 #include "dns-domain.h"
39 #include "hostname-util.h"
40 #include "random-util.h"
41 #include "string-util.h"
44 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
45 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
47 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
48 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
50 struct sd_dhcp_client
{
56 sd_event_source
*timeout_resend
;
60 union sockaddr_union link
;
61 sd_event_source
*receive_message
;
62 bool request_broadcast
;
64 size_t req_opts_allocated
;
68 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
75 /* 0: Generic (non-LL) (RFC 2132) */
76 uint8_t data
[MAX_CLIENT_ID_LEN
];
79 /* 1: Ethernet Link-Layer (RFC 2132) */
80 uint8_t haddr
[ETH_ALEN
];
83 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
87 /* 255: Node-specific (RFC 4361) */
92 uint8_t data
[MAX_CLIENT_ID_LEN
];
98 char *vendor_class_identifier
;
102 unsigned int attempt
;
104 sd_event_source
*timeout_t1
;
105 sd_event_source
*timeout_t2
;
106 sd_event_source
*timeout_expire
;
107 sd_dhcp_client_callback_t callback
;
109 sd_dhcp_lease
*lease
;
113 static const uint8_t default_req_opts
[] = {
114 SD_DHCP_OPTION_SUBNET_MASK
,
115 SD_DHCP_OPTION_ROUTER
,
116 SD_DHCP_OPTION_HOST_NAME
,
117 SD_DHCP_OPTION_DOMAIN_NAME
,
118 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
,
121 /* RFC7844 section 3:
122 MAY contain the Parameter Request List option.
124 The client intending to protect its privacy SHOULD only request a
125 minimal number of options in the PRL and SHOULD also randomly shuffle
126 the ordering of option codes in the PRL. If this random ordering
127 cannot be implemented, the client MAY order the option codes in the
128 PRL by option code number (lowest to highest).
130 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
131 static const uint8_t default_req_opts_anonymize
[] = {
132 SD_DHCP_OPTION_SUBNET_MASK
, /* 1 */
133 SD_DHCP_OPTION_ROUTER
, /* 3 */
134 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
, /* 6 */
135 SD_DHCP_OPTION_DOMAIN_NAME
, /* 15 */
136 SD_DHCP_OPTION_ROUTER_DISCOVER
, /* 31 */
137 SD_DHCP_OPTION_STATIC_ROUTE
, /* 33 */
138 SD_DHCP_OPTION_VENDOR_SPECIFIC
, /* 43 */
139 SD_DHCP_OPTION_NETBIOS_NAMESERVER
, /* 44 */
140 SD_DHCP_OPTION_NETBIOS_NODETYPE
, /* 46 */
141 SD_DHCP_OPTION_NETBIOS_SCOPE
, /* 47 */
142 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
, /* 121 */
143 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE
, /* 249 */
144 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY
, /* 252 */
147 static int client_receive_message_raw(
152 static int client_receive_message_udp(
157 static void client_stop(sd_dhcp_client
*client
, int error
);
159 int sd_dhcp_client_set_callback(
160 sd_dhcp_client
*client
,
161 sd_dhcp_client_callback_t cb
,
164 assert_return(client
, -EINVAL
);
166 client
->callback
= cb
;
167 client
->userdata
= userdata
;
172 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client
*client
, int broadcast
) {
173 assert_return(client
, -EINVAL
);
175 client
->request_broadcast
= !!broadcast
;
180 int sd_dhcp_client_set_request_option(sd_dhcp_client
*client
, uint8_t option
) {
183 assert_return(client
, -EINVAL
);
184 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
188 case SD_DHCP_OPTION_PAD
:
189 case SD_DHCP_OPTION_OVERLOAD
:
190 case SD_DHCP_OPTION_MESSAGE_TYPE
:
191 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
:
192 case SD_DHCP_OPTION_END
:
199 for (i
= 0; i
< client
->req_opts_size
; i
++)
200 if (client
->req_opts
[i
] == option
)
203 if (!GREEDY_REALLOC(client
->req_opts
, client
->req_opts_allocated
,
204 client
->req_opts_size
+ 1))
207 client
->req_opts
[client
->req_opts_size
++] = option
;
212 int sd_dhcp_client_set_request_address(
213 sd_dhcp_client
*client
,
214 const struct in_addr
*last_addr
) {
216 assert_return(client
, -EINVAL
);
217 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
220 client
->last_addr
= last_addr
->s_addr
;
222 client
->last_addr
= INADDR_ANY
;
227 int sd_dhcp_client_set_ifindex(sd_dhcp_client
*client
, int ifindex
) {
229 assert_return(client
, -EINVAL
);
230 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
231 assert_return(ifindex
> 0, -EINVAL
);
233 client
->ifindex
= ifindex
;
237 int sd_dhcp_client_set_mac(
238 sd_dhcp_client
*client
,
243 DHCP_CLIENT_DONT_DESTROY(client
);
244 bool need_restart
= false;
246 assert_return(client
, -EINVAL
);
247 assert_return(addr
, -EINVAL
);
248 assert_return(addr_len
> 0 && addr_len
<= MAX_MAC_ADDR_LEN
, -EINVAL
);
249 assert_return(arp_type
> 0, -EINVAL
);
251 if (arp_type
== ARPHRD_ETHER
)
252 assert_return(addr_len
== ETH_ALEN
, -EINVAL
);
253 else if (arp_type
== ARPHRD_INFINIBAND
)
254 assert_return(addr_len
== INFINIBAND_ALEN
, -EINVAL
);
258 if (client
->mac_addr_len
== addr_len
&&
259 memcmp(&client
->mac_addr
, addr
, addr_len
) == 0)
262 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
263 log_dhcp_client(client
, "Changing MAC address on running DHCP client, restarting");
265 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
268 memcpy(&client
->mac_addr
, addr
, addr_len
);
269 client
->mac_addr_len
= addr_len
;
270 client
->arp_type
= arp_type
;
272 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
273 sd_dhcp_client_start(client
);
278 int sd_dhcp_client_get_client_id(
279 sd_dhcp_client
*client
,
281 const uint8_t **data
,
284 assert_return(client
, -EINVAL
);
285 assert_return(type
, -EINVAL
);
286 assert_return(data
, -EINVAL
);
287 assert_return(data_len
, -EINVAL
);
292 if (client
->client_id_len
) {
293 *type
= client
->client_id
.type
;
294 *data
= client
->client_id
.raw
.data
;
295 *data_len
= client
->client_id_len
- sizeof(client
->client_id
.type
);
301 int sd_dhcp_client_set_client_id(
302 sd_dhcp_client
*client
,
307 DHCP_CLIENT_DONT_DESTROY(client
);
308 bool need_restart
= false;
310 assert_return(client
, -EINVAL
);
311 assert_return(data
, -EINVAL
);
312 assert_return(data_len
> 0 && data_len
<= MAX_CLIENT_ID_LEN
, -EINVAL
);
317 if (data_len
!= ETH_ALEN
)
321 case ARPHRD_INFINIBAND
:
322 if (data_len
!= INFINIBAND_ALEN
)
330 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
331 client
->client_id
.type
== type
&&
332 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
335 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
336 log_dhcp_client(client
, "Changing client ID on running DHCP "
337 "client, restarting");
339 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
342 client
->client_id
.type
= type
;
343 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
344 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
346 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
347 sd_dhcp_client_start(client
);
353 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
354 * without further modification. Otherwise, if duid_type is supported, DUID
355 * is set based on that type. Otherwise, an error is returned.
357 int sd_dhcp_client_set_iaid_duid(
358 sd_dhcp_client
*client
,
364 DHCP_CLIENT_DONT_DESTROY(client
);
368 assert_return(client
, -EINVAL
);
369 assert_return(duid_len
== 0 || duid
!= NULL
, -EINVAL
);
372 r
= dhcp_validate_duid_len(duid_type
, duid_len
);
377 zero(client
->client_id
);
378 client
->client_id
.type
= 255;
380 /* If IAID is not configured, generate it. */
382 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
383 client
->mac_addr_len
,
384 &client
->client_id
.ns
.iaid
);
388 client
->client_id
.ns
.iaid
= htobe32(iaid
);
391 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
392 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
393 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
394 } else if (duid_type
== DUID_TYPE_EN
) {
395 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
401 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
402 sizeof(client
->client_id
.ns
.iaid
);
404 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
405 log_dhcp_client(client
, "Configured IAID+DUID, restarting.");
406 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
407 sd_dhcp_client_start(client
);
413 int sd_dhcp_client_set_hostname(
414 sd_dhcp_client
*client
,
415 const char *hostname
) {
417 assert_return(client
, -EINVAL
);
419 /* Make sure hostnames qualify as DNS and as Linux hostnames */
421 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
424 return free_and_strdup(&client
->hostname
, hostname
);
427 int sd_dhcp_client_set_vendor_class_identifier(
428 sd_dhcp_client
*client
,
431 assert_return(client
, -EINVAL
);
433 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
436 int sd_dhcp_client_set_client_port(
437 sd_dhcp_client
*client
,
440 assert_return(client
, -EINVAL
);
447 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
448 assert_return(client
, -EINVAL
);
449 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
456 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
457 assert_return(client
, -EINVAL
);
459 if (!IN_SET(client
->state
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
460 return -EADDRNOTAVAIL
;
463 *ret
= client
->lease
;
468 static void client_notify(sd_dhcp_client
*client
, int event
) {
471 if (client
->callback
)
472 client
->callback(client
, event
, client
->userdata
);
475 static int client_initialize(sd_dhcp_client
*client
) {
476 assert_return(client
, -EINVAL
);
478 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
480 client
->fd
= asynchronous_close(client
->fd
);
482 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
484 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
485 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
486 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
490 client
->state
= DHCP_STATE_INIT
;
493 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
498 static void client_stop(sd_dhcp_client
*client
, int error
) {
502 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
503 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
504 log_dhcp_client(client
, "STOPPED");
506 log_dhcp_client(client
, "STOPPED: Unknown event");
508 client_notify(client
, error
);
510 client_initialize(client
);
513 static int client_message_init(
514 sd_dhcp_client
*client
,
518 size_t *_optoffset
) {
520 _cleanup_free_ DHCPPacket
*packet
= NULL
;
521 size_t optlen
, optoffset
, size
;
528 assert(client
->start_time
);
532 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
));
534 optlen
= DHCP_MIN_OPTIONS_SIZE
;
535 size
= sizeof(DHCPPacket
) + optlen
;
537 packet
= malloc0(size
);
541 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
542 client
->arp_type
, optlen
, &optoffset
);
546 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
547 refuse to issue an DHCP lease if 'secs' is set to zero */
548 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
551 assert(time_now
>= client
->start_time
);
553 /* seconds between sending first and last DISCOVER
554 * must always be strictly positive to deal with broken servers */
555 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
556 packet
->dhcp
.secs
= htobe16(secs
);
558 /* RFC2132 section 4.1
559 A client that cannot receive unicast IP datagrams until its protocol
560 software has been configured with an IP address SHOULD set the
561 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
562 DHCPREQUEST messages that client sends. The BROADCAST bit will
563 provide a hint to the DHCP server and BOOTP relay agent to broadcast
564 any messages to the client on the client's subnet.
566 Note: some interfaces needs this to be enabled, but some networks
567 needs this to be disabled as broadcasts are filteretd, so this
568 needs to be configurable */
569 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
570 packet
->dhcp
.flags
= htobe16(0x8000);
572 /* RFC2132 section 4.1.1:
573 The client MUST include its hardware address in the ’chaddr’ field, if
574 necessary for delivery of DHCP reply messages. Non-Ethernet
575 interfaces will leave 'chaddr' empty and use the client identifier
576 instead (eg, RFC 4390 section 2.1).
578 if (client
->arp_type
== ARPHRD_ETHER
)
579 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
581 /* If no client identifier exists, construct an RFC 4361-compliant one */
582 if (client
->client_id_len
== 0) {
585 client
->client_id
.type
= 255;
587 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
, &client
->client_id
.ns
.iaid
);
591 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
595 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
598 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
599 Identifier option is not set */
600 if (client
->client_id_len
) {
601 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
602 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
603 client
->client_id_len
,
609 /* RFC2131 section 3.5:
610 in its initial DHCPDISCOVER or DHCPREQUEST message, a
611 client may provide the server with a list of specific
612 parameters the client is interested in. If the client
613 includes a list of parameters in a DHCPDISCOVER message,
614 it MUST include that list in any subsequent DHCPREQUEST
618 /* RFC7844 section 3:
619 MAY contain the Parameter Request List option. */
620 /* NOTE: in case that there would be an option to do not send
621 * any PRL at all, the size should be checked before sending */
622 if (client
->req_opts_size
> 0) {
623 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
624 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
625 client
->req_opts_size
, client
->req_opts
);
630 /* RFC2131 section 3.5:
631 The client SHOULD include the ’maximum DHCP message size’ option to
632 let the server know how large the server may make its DHCP messages.
634 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
635 than the defined default size unless the Maximum Messge Size option
638 RFC3442 "Requirements to Avoid Sizing Constraints":
639 Because a full routing table can be quite large, the standard 576
640 octet maximum size for a DHCP message may be too short to contain
641 some legitimate Classless Static Route options. Because of this,
642 clients implementing the Classless Static Route option SHOULD send a
643 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
644 stack is capable of receiving larger IP datagrams. In this case, the
645 client SHOULD set the value of this option to at least the MTU of the
646 interface that the client is configuring. The client MAY set the
647 value of this option higher, up to the size of the largest UDP packet
648 it is prepared to accept. (Note that the value specified in the
649 Maximum DHCP Message Size option is the total maximum packet size,
650 including IP and UDP headers.)
652 /* RFC7844 section 3:
653 SHOULD NOT contain any other option. */
654 if (!client
->anonymize
) {
655 max_size
= htobe16(size
);
656 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
657 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
664 *_optoffset
= optoffset
;
671 static int client_append_fqdn_option(
672 DHCPMessage
*message
,
677 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
680 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
681 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
682 buffer
[1] = 0; /* RCODE1 (deprecated) */
683 buffer
[2] = 0; /* RCODE2 (deprecated) */
685 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
687 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
688 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
693 static int dhcp_client_send_raw(
694 sd_dhcp_client
*client
,
698 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
699 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
701 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
705 static int client_send_discover(sd_dhcp_client
*client
) {
706 _cleanup_free_ DHCPPacket
*discover
= NULL
;
707 size_t optoffset
, optlen
;
711 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
713 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
714 &optlen
, &optoffset
);
718 /* the client may suggest values for the network address
719 and lease time in the DHCPDISCOVER message. The client may include
720 the ’requested IP address’ option to suggest that a particular IP
721 address be assigned, and may include the ’IP address lease time’
722 option to suggest the lease time it would like.
724 if (client
->last_addr
!= INADDR_ANY
) {
725 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
726 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
727 4, &client
->last_addr
);
732 if (client
->hostname
) {
733 /* According to RFC 4702 "clients that send the Client FQDN option in
734 their messages MUST NOT also send the Host Name option". Just send
735 one of the two depending on the hostname type.
737 if (dns_name_is_single_label(client
->hostname
)) {
738 /* it is unclear from RFC 2131 if client should send hostname in
739 DHCPDISCOVER but dhclient does and so we do as well
741 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
742 SD_DHCP_OPTION_HOST_NAME
,
743 strlen(client
->hostname
), client
->hostname
);
745 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
751 if (client
->vendor_class_identifier
) {
752 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
753 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
754 strlen(client
->vendor_class_identifier
),
755 client
->vendor_class_identifier
);
760 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
761 SD_DHCP_OPTION_END
, 0, NULL
);
765 /* We currently ignore:
766 The client SHOULD wait a random time between one and ten seconds to
767 desynchronize the use of DHCP at startup.
769 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
773 log_dhcp_client(client
, "DISCOVER");
778 static int client_send_request(sd_dhcp_client
*client
) {
779 _cleanup_free_ DHCPPacket
*request
= NULL
;
780 size_t optoffset
, optlen
;
785 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
789 switch (client
->state
) {
790 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
791 SELECTING should be REQUESTING)
794 case DHCP_STATE_REQUESTING
:
795 /* Client inserts the address of the selected server in ’server
796 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
797 filled in with the yiaddr value from the chosen DHCPOFFER.
800 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
801 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
802 4, &client
->lease
->server_address
);
806 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
807 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
808 4, &client
->lease
->address
);
814 case DHCP_STATE_INIT_REBOOT
:
815 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
816 option MUST be filled in with client’s notion of its previously
817 assigned address. ’ciaddr’ MUST be zero.
819 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
820 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
821 4, &client
->last_addr
);
826 case DHCP_STATE_RENEWING
:
827 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
828 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
829 client’s IP address.
832 case DHCP_STATE_REBINDING
:
833 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
834 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
835 client’s IP address.
837 This message MUST be broadcast to the 0xffffffff IP broadcast address.
839 request
->dhcp
.ciaddr
= client
->lease
->address
;
843 case DHCP_STATE_INIT
:
844 case DHCP_STATE_SELECTING
:
845 case DHCP_STATE_REBOOTING
:
846 case DHCP_STATE_BOUND
:
847 case DHCP_STATE_STOPPED
:
851 if (client
->hostname
) {
852 if (dns_name_is_single_label(client
->hostname
))
853 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
854 SD_DHCP_OPTION_HOST_NAME
,
855 strlen(client
->hostname
), client
->hostname
);
857 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
863 if (client
->vendor_class_identifier
) {
864 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
865 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
866 strlen(client
->vendor_class_identifier
),
867 client
->vendor_class_identifier
);
872 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
873 SD_DHCP_OPTION_END
, 0, NULL
);
877 if (client
->state
== DHCP_STATE_RENEWING
) {
878 r
= dhcp_network_send_udp_socket(client
->fd
,
879 client
->lease
->server_address
,
882 sizeof(DHCPMessage
) + optoffset
);
884 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
889 switch (client
->state
) {
891 case DHCP_STATE_REQUESTING
:
892 log_dhcp_client(client
, "REQUEST (requesting)");
895 case DHCP_STATE_INIT_REBOOT
:
896 log_dhcp_client(client
, "REQUEST (init-reboot)");
899 case DHCP_STATE_RENEWING
:
900 log_dhcp_client(client
, "REQUEST (renewing)");
903 case DHCP_STATE_REBINDING
:
904 log_dhcp_client(client
, "REQUEST (rebinding)");
908 log_dhcp_client(client
, "REQUEST (invalid)");
915 static int client_start(sd_dhcp_client
*client
);
917 static int client_timeout_resend(
922 sd_dhcp_client
*client
= userdata
;
923 DHCP_CLIENT_DONT_DESTROY(client
);
924 usec_t next_timeout
= 0;
931 assert(client
->event
);
933 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
937 switch (client
->state
) {
939 case DHCP_STATE_RENEWING
:
941 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
945 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
949 case DHCP_STATE_REBINDING
:
951 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
955 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
958 case DHCP_STATE_REBOOTING
:
959 /* start over as we did not receive a timely ack or nak */
960 r
= client_initialize(client
);
964 r
= client_start(client
);
968 log_dhcp_client(client
, "REBOOTED");
972 case DHCP_STATE_INIT
:
973 case DHCP_STATE_INIT_REBOOT
:
974 case DHCP_STATE_SELECTING
:
975 case DHCP_STATE_REQUESTING
:
976 case DHCP_STATE_BOUND
:
978 if (client
->attempt
< 64)
979 client
->attempt
*= 2;
981 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
985 case DHCP_STATE_STOPPED
:
990 next_timeout
+= (random_u32() & 0x1fffff);
992 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
994 r
= sd_event_add_time(client
->event
,
995 &client
->timeout_resend
,
996 clock_boottime_or_monotonic(),
997 next_timeout
, 10 * USEC_PER_MSEC
,
998 client_timeout_resend
, client
);
1002 r
= sd_event_source_set_priority(client
->timeout_resend
,
1003 client
->event_priority
);
1007 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1011 switch (client
->state
) {
1012 case DHCP_STATE_INIT
:
1013 r
= client_send_discover(client
);
1015 client
->state
= DHCP_STATE_SELECTING
;
1016 client
->attempt
= 1;
1018 if (client
->attempt
>= 64)
1024 case DHCP_STATE_SELECTING
:
1025 r
= client_send_discover(client
);
1026 if (r
< 0 && client
->attempt
>= 64)
1031 case DHCP_STATE_INIT_REBOOT
:
1032 case DHCP_STATE_REQUESTING
:
1033 case DHCP_STATE_RENEWING
:
1034 case DHCP_STATE_REBINDING
:
1035 r
= client_send_request(client
);
1036 if (r
< 0 && client
->attempt
>= 64)
1039 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1040 client
->state
= DHCP_STATE_REBOOTING
;
1042 client
->request_sent
= time_now
;
1046 case DHCP_STATE_REBOOTING
:
1047 case DHCP_STATE_BOUND
:
1051 case DHCP_STATE_STOPPED
:
1059 client_stop(client
, r
);
1061 /* Errors were dealt with when stopping the client, don't spill
1062 errors into the event loop handler */
1066 static int client_initialize_io_events(
1067 sd_dhcp_client
*client
,
1068 sd_event_io_handler_t io_callback
) {
1073 assert(client
->event
);
1075 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1076 client
->fd
, EPOLLIN
, io_callback
,
1081 r
= sd_event_source_set_priority(client
->receive_message
,
1082 client
->event_priority
);
1086 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1092 client_stop(client
, r
);
1097 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1102 assert(client
->event
);
1104 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1106 if (client
->start_delay
) {
1107 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1108 usec
+= client
->start_delay
;
1111 r
= sd_event_add_time(client
->event
,
1112 &client
->timeout_resend
,
1113 clock_boottime_or_monotonic(),
1115 client_timeout_resend
, client
);
1119 r
= sd_event_source_set_priority(client
->timeout_resend
,
1120 client
->event_priority
);
1124 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1130 client_stop(client
, r
);
1136 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1137 client_initialize_io_events(client
, io_callback
);
1138 client_initialize_time_events(client
);
1143 static int client_start_delayed(sd_dhcp_client
*client
) {
1146 assert_return(client
, -EINVAL
);
1147 assert_return(client
->event
, -EINVAL
);
1148 assert_return(client
->ifindex
> 0, -EINVAL
);
1149 assert_return(client
->fd
< 0, -EBUSY
);
1150 assert_return(client
->xid
== 0, -EINVAL
);
1151 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1153 client
->xid
= random_u32();
1155 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1156 client
->xid
, client
->mac_addr
,
1157 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1159 client_stop(client
, r
);
1164 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1165 client
->start_time
= now(clock_boottime_or_monotonic());
1167 return client_initialize_events(client
, client_receive_message_raw
);
1170 static int client_start(sd_dhcp_client
*client
) {
1171 client
->start_delay
= 0;
1172 return client_start_delayed(client
);
1175 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1176 sd_dhcp_client
*client
= userdata
;
1177 DHCP_CLIENT_DONT_DESTROY(client
);
1179 log_dhcp_client(client
, "EXPIRED");
1181 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1183 /* lease was lost, start over if not freed or stopped in callback */
1184 if (client
->state
!= DHCP_STATE_STOPPED
) {
1185 client_initialize(client
);
1186 client_start(client
);
1192 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1193 sd_dhcp_client
*client
= userdata
;
1194 DHCP_CLIENT_DONT_DESTROY(client
);
1199 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1200 client
->fd
= asynchronous_close(client
->fd
);
1202 client
->state
= DHCP_STATE_REBINDING
;
1203 client
->attempt
= 1;
1205 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1206 client
->xid
, client
->mac_addr
,
1207 client
->mac_addr_len
, client
->arp_type
,
1210 client_stop(client
, r
);
1215 return client_initialize_events(client
, client_receive_message_raw
);
1218 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1219 sd_dhcp_client
*client
= userdata
;
1220 DHCP_CLIENT_DONT_DESTROY(client
);
1222 client
->state
= DHCP_STATE_RENEWING
;
1223 client
->attempt
= 1;
1225 return client_initialize_time_events(client
);
1228 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1229 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1232 r
= dhcp_lease_new(&lease
);
1236 if (client
->client_id_len
) {
1237 r
= dhcp_lease_set_client_id(lease
,
1238 (uint8_t *) &client
->client_id
,
1239 client
->client_id_len
);
1244 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1245 if (r
!= DHCP_OFFER
) {
1246 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1250 lease
->next_server
= offer
->siaddr
;
1251 lease
->address
= offer
->yiaddr
;
1253 if (lease
->address
== 0 ||
1254 lease
->server_address
== 0 ||
1255 lease
->lifetime
== 0) {
1256 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1260 if (!lease
->have_subnet_mask
) {
1261 r
= dhcp_lease_set_default_subnet_mask(lease
);
1263 log_dhcp_client(client
,
1264 "received lease lacks subnet mask, "
1265 "and a fallback one cannot be generated, ignoring");
1270 sd_dhcp_lease_unref(client
->lease
);
1271 client
->lease
= lease
;
1274 log_dhcp_client(client
, "OFFER");
1279 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1282 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1283 if (r
!= DHCP_FORCERENEW
)
1286 log_dhcp_client(client
, "FORCERENEW");
1291 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1292 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1293 _cleanup_free_
char *error_message
= NULL
;
1296 r
= dhcp_lease_new(&lease
);
1300 if (client
->client_id_len
) {
1301 r
= dhcp_lease_set_client_id(lease
,
1302 (uint8_t *) &client
->client_id
,
1303 client
->client_id_len
);
1308 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1309 if (r
== DHCP_NAK
) {
1310 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1311 return -EADDRNOTAVAIL
;
1314 if (r
!= DHCP_ACK
) {
1315 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1319 lease
->next_server
= ack
->siaddr
;
1321 lease
->address
= ack
->yiaddr
;
1323 if (lease
->address
== INADDR_ANY
||
1324 lease
->server_address
== INADDR_ANY
||
1325 lease
->lifetime
== 0) {
1326 log_dhcp_client(client
, "received lease lacks address, server "
1327 "address or lease lifetime, ignoring");
1331 if (lease
->subnet_mask
== INADDR_ANY
) {
1332 r
= dhcp_lease_set_default_subnet_mask(lease
);
1334 log_dhcp_client(client
,
1335 "received lease lacks subnet mask, "
1336 "and a fallback one cannot be generated, ignoring");
1341 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1342 if (client
->lease
) {
1343 if (client
->lease
->address
!= lease
->address
||
1344 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1345 client
->lease
->router
!= lease
->router
) {
1346 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1348 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1350 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1353 client
->lease
= lease
;
1356 log_dhcp_client(client
, "ACK");
1361 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1363 assert(client
->request_sent
);
1364 assert(lifetime
> 0);
1371 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1372 + (random_u32() & 0x1fffff);
1375 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1377 uint64_t lifetime_timeout
;
1378 uint64_t t2_timeout
;
1379 uint64_t t1_timeout
;
1380 char time_string
[FORMAT_TIMESPAN_MAX
];
1384 assert(client
->event
);
1385 assert(client
->lease
);
1386 assert(client
->lease
->lifetime
);
1388 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1389 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1390 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1392 /* don't set timers for infinite leases */
1393 if (client
->lease
->lifetime
== 0xffffffff)
1396 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1399 assert(client
->request_sent
<= time_now
);
1401 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1402 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1403 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1404 /* both T1 and T2 are given */
1405 if (client
->lease
->t1
< client
->lease
->t2
&&
1406 client
->lease
->t2
< client
->lease
->lifetime
) {
1407 /* they are both valid */
1408 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1409 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1412 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1413 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1414 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1415 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1417 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1418 /* only T2 is given, and it is valid */
1419 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1420 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1421 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1422 if (t2_timeout
<= t1_timeout
) {
1423 /* the computed T1 would be invalid, so discard T2 */
1424 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1425 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1427 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1428 /* only T1 is given, and it is valid */
1429 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1430 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1431 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1432 if (t2_timeout
<= t1_timeout
) {
1433 /* the computed T2 would be invalid, so discard T1 */
1434 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1435 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1438 /* fall back to the default timeouts */
1439 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1440 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1441 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1442 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1445 /* arm lifetime timeout */
1446 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1447 clock_boottime_or_monotonic(),
1448 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1449 client_timeout_expire
, client
);
1453 r
= sd_event_source_set_priority(client
->timeout_expire
,
1454 client
->event_priority
);
1458 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1462 log_dhcp_client(client
, "lease expires in %s",
1463 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1465 /* don't arm earlier timeouts if this has already expired */
1466 if (lifetime_timeout
<= time_now
)
1469 /* arm T2 timeout */
1470 r
= sd_event_add_time(client
->event
,
1471 &client
->timeout_t2
,
1472 clock_boottime_or_monotonic(),
1475 client_timeout_t2
, client
);
1479 r
= sd_event_source_set_priority(client
->timeout_t2
,
1480 client
->event_priority
);
1484 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1488 log_dhcp_client(client
, "T2 expires in %s",
1489 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1491 /* don't arm earlier timeout if this has already expired */
1492 if (t2_timeout
<= time_now
)
1495 /* arm T1 timeout */
1496 r
= sd_event_add_time(client
->event
,
1497 &client
->timeout_t1
,
1498 clock_boottime_or_monotonic(),
1499 t1_timeout
, 10 * USEC_PER_MSEC
,
1500 client_timeout_t1
, client
);
1504 r
= sd_event_source_set_priority(client
->timeout_t1
,
1505 client
->event_priority
);
1509 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1513 log_dhcp_client(client
, "T1 expires in %s",
1514 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1519 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1520 DHCP_CLIENT_DONT_DESTROY(client
);
1521 char time_string
[FORMAT_TIMESPAN_MAX
];
1522 int r
= 0, notify_event
= 0;
1525 assert(client
->event
);
1528 switch (client
->state
) {
1529 case DHCP_STATE_SELECTING
:
1531 r
= client_handle_offer(client
, message
, len
);
1534 client
->timeout_resend
=
1535 sd_event_source_unref(client
->timeout_resend
);
1537 client
->state
= DHCP_STATE_REQUESTING
;
1538 client
->attempt
= 1;
1540 r
= sd_event_add_time(client
->event
,
1541 &client
->timeout_resend
,
1542 clock_boottime_or_monotonic(),
1544 client_timeout_resend
, client
);
1548 r
= sd_event_source_set_priority(client
->timeout_resend
,
1549 client
->event_priority
);
1553 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1556 } else if (r
== -ENOMSG
)
1557 /* invalid message, let's ignore it */
1562 case DHCP_STATE_REBOOTING
:
1563 case DHCP_STATE_REQUESTING
:
1564 case DHCP_STATE_RENEWING
:
1565 case DHCP_STATE_REBINDING
:
1567 r
= client_handle_ack(client
, message
, len
);
1569 client
->start_delay
= 0;
1570 client
->timeout_resend
=
1571 sd_event_source_unref(client
->timeout_resend
);
1572 client
->receive_message
=
1573 sd_event_source_unref(client
->receive_message
);
1574 client
->fd
= asynchronous_close(client
->fd
);
1576 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1577 DHCP_STATE_REBOOTING
))
1578 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1579 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1582 client
->state
= DHCP_STATE_BOUND
;
1583 client
->attempt
= 1;
1585 client
->last_addr
= client
->lease
->address
;
1587 r
= client_set_lease_timeouts(client
);
1589 log_dhcp_client(client
, "could not set lease timeouts");
1593 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1595 log_dhcp_client(client
, "could not bind UDP socket");
1601 client_initialize_io_events(client
, client_receive_message_udp
);
1604 client_notify(client
, notify_event
);
1605 if (client
->state
== DHCP_STATE_STOPPED
)
1609 } else if (r
== -EADDRNOTAVAIL
) {
1610 /* got a NAK, let's restart the client */
1611 client
->timeout_resend
=
1612 sd_event_source_unref(client
->timeout_resend
);
1614 r
= client_initialize(client
);
1618 r
= client_start_delayed(client
);
1622 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1623 client
->start_delay
, USEC_PER_SEC
));
1625 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1626 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1629 } else if (r
== -ENOMSG
)
1630 /* invalid message, let's ignore it */
1635 case DHCP_STATE_BOUND
:
1636 r
= client_handle_forcerenew(client
, message
, len
);
1638 r
= client_timeout_t1(NULL
, 0, client
);
1641 } else if (r
== -ENOMSG
)
1642 /* invalid message, let's ignore it */
1647 case DHCP_STATE_INIT
:
1648 case DHCP_STATE_INIT_REBOOT
:
1652 case DHCP_STATE_STOPPED
:
1659 client_stop(client
, r
);
1664 static int client_receive_message_udp(
1670 sd_dhcp_client
*client
= userdata
;
1671 _cleanup_free_ DHCPMessage
*message
= NULL
;
1672 const struct ether_addr zero_mac
= {};
1673 const struct ether_addr
*expected_chaddr
= NULL
;
1674 uint8_t expected_hlen
= 0;
1675 ssize_t len
, buflen
;
1680 buflen
= next_datagram_size_fd(fd
);
1684 message
= malloc0(buflen
);
1688 len
= recv(fd
, message
, buflen
, 0);
1690 if (IN_SET(errno
, EAGAIN
, EINTR
))
1693 return log_dhcp_client_errno(client
, errno
,
1694 "Could not receive message from UDP socket: %m");
1696 if ((size_t) len
< sizeof(DHCPMessage
)) {
1697 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1701 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1702 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1706 if (message
->op
!= BOOTREPLY
) {
1707 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1711 if (message
->htype
!= client
->arp_type
) {
1712 log_dhcp_client(client
, "Packet type does not match client type");
1716 if (client
->arp_type
== ARPHRD_ETHER
) {
1717 expected_hlen
= ETH_ALEN
;
1718 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1720 /* Non-Ethernet links expect zero chaddr */
1722 expected_chaddr
= &zero_mac
;
1725 if (message
->hlen
!= expected_hlen
) {
1726 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1730 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1731 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1735 if (client
->state
!= DHCP_STATE_BOUND
&&
1736 be32toh(message
->xid
) != client
->xid
) {
1737 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1738 so ignore the xid in this case */
1739 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1740 be32toh(message
->xid
), client
->xid
);
1744 return client_handle_message(client
, message
, len
);
1747 static int client_receive_message_raw(
1753 sd_dhcp_client
*client
= userdata
;
1754 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1755 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1756 struct iovec iov
= {};
1757 struct msghdr msg
= {
1760 .msg_control
= cmsgbuf
,
1761 .msg_controllen
= sizeof(cmsgbuf
),
1763 struct cmsghdr
*cmsg
;
1764 bool checksum
= true;
1765 ssize_t buflen
, len
;
1771 buflen
= next_datagram_size_fd(fd
);
1775 packet
= malloc0(buflen
);
1779 iov
.iov_base
= packet
;
1780 iov
.iov_len
= buflen
;
1782 len
= recvmsg(fd
, &msg
, 0);
1784 if (IN_SET(errno
, EAGAIN
, EINTR
))
1787 return log_dhcp_client_errno(client
, errno
,
1788 "Could not receive message from raw socket: %m");
1789 } else if ((size_t)len
< sizeof(DHCPPacket
))
1792 CMSG_FOREACH(cmsg
, &msg
) {
1793 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1794 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1795 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1796 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1798 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1803 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1807 len
-= DHCP_IP_UDP_SIZE
;
1809 return client_handle_message(client
, &packet
->dhcp
, len
);
1812 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1815 assert_return(client
, -EINVAL
);
1817 r
= client_initialize(client
);
1821 /* RFC7844 section 3.3:
1822 SHOULD perform a complete four-way handshake, starting with a
1823 DHCPDISCOVER, to obtain a new address lease. If the client can
1824 ascertain that this is exactly the same network to which it was
1825 previously connected, and if the link-layer address did not change,
1826 the client MAY issue a DHCPREQUEST to try to reclaim the current
1828 if (client
->last_addr
&& !client
->anonymize
)
1829 client
->state
= DHCP_STATE_INIT_REBOOT
;
1831 r
= client_start(client
);
1833 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1838 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1839 DHCP_CLIENT_DONT_DESTROY(client
);
1841 assert_return(client
, -EINVAL
);
1843 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1844 client
->state
= DHCP_STATE_STOPPED
;
1849 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1852 assert_return(client
, -EINVAL
);
1853 assert_return(!client
->event
, -EBUSY
);
1856 client
->event
= sd_event_ref(event
);
1858 r
= sd_event_default(&client
->event
);
1863 client
->event_priority
= priority
;
1868 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1869 assert_return(client
, -EINVAL
);
1871 client
->event
= sd_event_unref(client
->event
);
1876 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1877 assert_return(client
, NULL
);
1879 return client
->event
;
1882 sd_dhcp_client
*sd_dhcp_client_ref(sd_dhcp_client
*client
) {
1887 assert(client
->n_ref
>= 1);
1893 sd_dhcp_client
*sd_dhcp_client_unref(sd_dhcp_client
*client
) {
1898 assert(client
->n_ref
>= 1);
1901 if (client
->n_ref
> 0)
1904 log_dhcp_client(client
, "FREE");
1906 client_initialize(client
);
1908 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1910 sd_dhcp_client_detach_event(client
);
1912 sd_dhcp_lease_unref(client
->lease
);
1914 free(client
->req_opts
);
1915 free(client
->hostname
);
1916 free(client
->vendor_class_identifier
);
1917 return mfree(client
);
1920 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1921 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1923 assert_return(ret
, -EINVAL
);
1925 client
= new0(sd_dhcp_client
, 1);
1930 client
->state
= DHCP_STATE_INIT
;
1931 client
->ifindex
= -1;
1933 client
->attempt
= 1;
1934 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1935 client
->port
= DHCP_PORT_CLIENT
;
1937 client
->anonymize
= !!anonymize
;
1938 /* NOTE: this could be moved to a function. */
1940 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
1941 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
1943 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1944 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1946 if (!client
->req_opts
)