2 This file is part of systemd.
4 Copyright (C) 2013 Intel Corporation. All rights reserved.
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.
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.
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/>.
21 #include <net/ethernet.h>
22 #include <net/if_arp.h>
26 #include <sys/ioctl.h>
27 #include <linux/if_infiniband.h>
29 #include "sd-dhcp-client.h"
31 #include "alloc-util.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"
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)
46 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
47 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
49 struct sd_dhcp_client
{
55 sd_event_source
*timeout_resend
;
59 union sockaddr_union link
;
60 sd_event_source
*receive_message
;
61 bool request_broadcast
;
63 size_t req_opts_allocated
;
67 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
74 /* 0: Generic (non-LL) (RFC 2132) */
75 uint8_t data
[MAX_CLIENT_ID_LEN
];
78 /* 1: Ethernet Link-Layer (RFC 2132) */
79 uint8_t haddr
[ETH_ALEN
];
82 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
86 /* 255: Node-specific (RFC 4361) */
91 uint8_t data
[MAX_CLIENT_ID_LEN
];
97 char *vendor_class_identifier
;
101 unsigned int attempt
;
103 sd_event_source
*timeout_t1
;
104 sd_event_source
*timeout_t2
;
105 sd_event_source
*timeout_expire
;
106 sd_dhcp_client_callback_t callback
;
108 sd_dhcp_lease
*lease
;
112 static const uint8_t default_req_opts
[] = {
113 SD_DHCP_OPTION_SUBNET_MASK
,
114 SD_DHCP_OPTION_ROUTER
,
115 SD_DHCP_OPTION_HOST_NAME
,
116 SD_DHCP_OPTION_DOMAIN_NAME
,
117 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
,
120 /* RFC7844 section 3:
121 MAY contain the Parameter Request List option.
123 The client intending to protect its privacy SHOULD only request a
124 minimal number of options in the PRL and SHOULD also randomly shuffle
125 the ordering of option codes in the PRL. If this random ordering
126 cannot be implemented, the client MAY order the option codes in the
127 PRL by option code number (lowest to highest).
129 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
130 static const uint8_t default_req_opts_anonymize
[] = {
131 SD_DHCP_OPTION_SUBNET_MASK
, /* 1 */
132 SD_DHCP_OPTION_ROUTER
, /* 3 */
133 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
, /* 6 */
134 SD_DHCP_OPTION_DOMAIN_NAME
, /* 15 */
135 SD_DHCP_OPTION_ROUTER_DISCOVER
, /* 31 */
136 SD_DHCP_OPTION_STATIC_ROUTE
, /* 33 */
137 SD_DHCP_OPTION_VENDOR_SPECIFIC
, /* 43 */
138 SD_DHCP_OPTION_NETBIOS_NAMESERVER
, /* 44 */
139 SD_DHCP_OPTION_NETBIOS_NODETYPE
, /* 46 */
140 SD_DHCP_OPTION_NETBIOS_SCOPE
, /* 47 */
141 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
, /* 121 */
142 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE
, /* 249 */
143 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY
, /* 252 */
146 static int client_receive_message_raw(
151 static int client_receive_message_udp(
156 static void client_stop(sd_dhcp_client
*client
, int error
);
158 int sd_dhcp_client_set_callback(
159 sd_dhcp_client
*client
,
160 sd_dhcp_client_callback_t cb
,
163 assert_return(client
, -EINVAL
);
165 client
->callback
= cb
;
166 client
->userdata
= userdata
;
171 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client
*client
, int broadcast
) {
172 assert_return(client
, -EINVAL
);
174 client
->request_broadcast
= !!broadcast
;
179 int sd_dhcp_client_set_request_option(sd_dhcp_client
*client
, uint8_t option
) {
182 assert_return(client
, -EINVAL
);
183 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
187 case SD_DHCP_OPTION_PAD
:
188 case SD_DHCP_OPTION_OVERLOAD
:
189 case SD_DHCP_OPTION_MESSAGE_TYPE
:
190 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
:
191 case SD_DHCP_OPTION_END
:
198 for (i
= 0; i
< client
->req_opts_size
; i
++)
199 if (client
->req_opts
[i
] == option
)
202 if (!GREEDY_REALLOC(client
->req_opts
, client
->req_opts_allocated
,
203 client
->req_opts_size
+ 1))
206 client
->req_opts
[client
->req_opts_size
++] = option
;
211 int sd_dhcp_client_set_request_address(
212 sd_dhcp_client
*client
,
213 const struct in_addr
*last_addr
) {
215 assert_return(client
, -EINVAL
);
216 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
219 client
->last_addr
= last_addr
->s_addr
;
221 client
->last_addr
= INADDR_ANY
;
226 int sd_dhcp_client_set_ifindex(sd_dhcp_client
*client
, int ifindex
) {
228 assert_return(client
, -EINVAL
);
229 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
230 assert_return(ifindex
> 0, -EINVAL
);
232 client
->ifindex
= ifindex
;
236 int sd_dhcp_client_set_mac(
237 sd_dhcp_client
*client
,
242 DHCP_CLIENT_DONT_DESTROY(client
);
243 bool need_restart
= false;
245 assert_return(client
, -EINVAL
);
246 assert_return(addr
, -EINVAL
);
247 assert_return(addr_len
> 0 && addr_len
<= MAX_MAC_ADDR_LEN
, -EINVAL
);
248 assert_return(arp_type
> 0, -EINVAL
);
250 if (arp_type
== ARPHRD_ETHER
)
251 assert_return(addr_len
== ETH_ALEN
, -EINVAL
);
252 else if (arp_type
== ARPHRD_INFINIBAND
)
253 assert_return(addr_len
== INFINIBAND_ALEN
, -EINVAL
);
257 if (client
->mac_addr_len
== addr_len
&&
258 memcmp(&client
->mac_addr
, addr
, addr_len
) == 0)
261 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
262 log_dhcp_client(client
, "Changing MAC address on running DHCP client, restarting");
264 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
267 memcpy(&client
->mac_addr
, addr
, addr_len
);
268 client
->mac_addr_len
= addr_len
;
269 client
->arp_type
= arp_type
;
271 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
272 sd_dhcp_client_start(client
);
277 int sd_dhcp_client_get_client_id(
278 sd_dhcp_client
*client
,
280 const uint8_t **data
,
283 assert_return(client
, -EINVAL
);
284 assert_return(type
, -EINVAL
);
285 assert_return(data
, -EINVAL
);
286 assert_return(data_len
, -EINVAL
);
291 if (client
->client_id_len
) {
292 *type
= client
->client_id
.type
;
293 *data
= client
->client_id
.raw
.data
;
294 *data_len
= client
->client_id_len
- sizeof(client
->client_id
.type
);
300 int sd_dhcp_client_set_client_id(
301 sd_dhcp_client
*client
,
306 DHCP_CLIENT_DONT_DESTROY(client
);
307 bool need_restart
= false;
309 assert_return(client
, -EINVAL
);
310 assert_return(data
, -EINVAL
);
311 assert_return(data_len
> 0 && data_len
<= MAX_CLIENT_ID_LEN
, -EINVAL
);
316 if (data_len
!= ETH_ALEN
)
320 case ARPHRD_INFINIBAND
:
321 if (data_len
!= INFINIBAND_ALEN
)
329 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
330 client
->client_id
.type
== type
&&
331 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
334 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
335 log_dhcp_client(client
, "Changing client ID on running DHCP "
336 "client, restarting");
338 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
341 client
->client_id
.type
= type
;
342 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
343 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
345 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
346 sd_dhcp_client_start(client
);
352 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
353 * without further modification. Otherwise, if duid_type is supported, DUID
354 * is set based on that type. Otherwise, an error is returned.
356 int sd_dhcp_client_set_iaid_duid(
357 sd_dhcp_client
*client
,
363 DHCP_CLIENT_DONT_DESTROY(client
);
367 assert_return(client
, -EINVAL
);
368 assert_return(duid_len
== 0 || duid
!= NULL
, -EINVAL
);
371 r
= dhcp_validate_duid_len(duid_type
, duid_len
);
376 zero(client
->client_id
);
377 client
->client_id
.type
= 255;
379 /* If IAID is not configured, generate it. */
381 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
382 client
->mac_addr_len
,
383 &client
->client_id
.ns
.iaid
);
387 client
->client_id
.ns
.iaid
= htobe32(iaid
);
390 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
391 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
392 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
393 } else if (duid_type
== DUID_TYPE_EN
) {
394 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
400 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
401 sizeof(client
->client_id
.ns
.iaid
);
403 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
404 log_dhcp_client(client
, "Configured IAID+DUID, restarting.");
405 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
406 sd_dhcp_client_start(client
);
412 int sd_dhcp_client_set_hostname(
413 sd_dhcp_client
*client
,
414 const char *hostname
) {
416 assert_return(client
, -EINVAL
);
418 /* Refuse hostnames that neither qualify as DNS nor as Linux hosntames */
420 !(hostname_is_valid(hostname
, false) || dns_name_is_valid(hostname
) > 0))
423 return free_and_strdup(&client
->hostname
, hostname
);
426 int sd_dhcp_client_set_vendor_class_identifier(
427 sd_dhcp_client
*client
,
430 assert_return(client
, -EINVAL
);
432 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
435 int sd_dhcp_client_set_client_port(
436 sd_dhcp_client
*client
,
439 assert_return(client
, -EINVAL
);
446 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
447 assert_return(client
, -EINVAL
);
448 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
455 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
456 assert_return(client
, -EINVAL
);
458 if (client
->state
!= DHCP_STATE_BOUND
&&
459 client
->state
!= DHCP_STATE_RENEWING
&&
460 client
->state
!= DHCP_STATE_REBINDING
)
461 return -EADDRNOTAVAIL
;
464 *ret
= client
->lease
;
469 static void client_notify(sd_dhcp_client
*client
, int event
) {
472 if (client
->callback
)
473 client
->callback(client
, event
, client
->userdata
);
476 static int client_initialize(sd_dhcp_client
*client
) {
477 assert_return(client
, -EINVAL
);
479 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
481 client
->fd
= asynchronous_close(client
->fd
);
483 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
485 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
486 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
487 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
491 client
->state
= DHCP_STATE_INIT
;
494 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
499 static void client_stop(sd_dhcp_client
*client
, int error
) {
503 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
504 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
505 log_dhcp_client(client
, "STOPPED");
507 log_dhcp_client(client
, "STOPPED: Unknown event");
509 client_notify(client
, error
);
511 client_initialize(client
);
514 static int client_message_init(
515 sd_dhcp_client
*client
,
519 size_t *_optoffset
) {
521 _cleanup_free_ DHCPPacket
*packet
= NULL
;
522 size_t optlen
, optoffset
, size
;
529 assert(client
->start_time
);
533 assert(type
== DHCP_DISCOVER
|| type
== DHCP_REQUEST
);
535 optlen
= DHCP_MIN_OPTIONS_SIZE
;
536 size
= sizeof(DHCPPacket
) + optlen
;
538 packet
= malloc0(size
);
542 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
543 client
->arp_type
, optlen
, &optoffset
);
547 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
548 refuse to issue an DHCP lease if 'secs' is set to zero */
549 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
552 assert(time_now
>= client
->start_time
);
554 /* seconds between sending first and last DISCOVER
555 * must always be strictly positive to deal with broken servers */
556 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
557 packet
->dhcp
.secs
= htobe16(secs
);
559 /* RFC2132 section 4.1
560 A client that cannot receive unicast IP datagrams until its protocol
561 software has been configured with an IP address SHOULD set the
562 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
563 DHCPREQUEST messages that client sends. The BROADCAST bit will
564 provide a hint to the DHCP server and BOOTP relay agent to broadcast
565 any messages to the client on the client's subnet.
567 Note: some interfaces needs this to be enabled, but some networks
568 needs this to be disabled as broadcasts are filteretd, so this
569 needs to be configurable */
570 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
571 packet
->dhcp
.flags
= htobe16(0x8000);
573 /* RFC2132 section 4.1.1:
574 The client MUST include its hardware address in the ’chaddr’ field, if
575 necessary for delivery of DHCP reply messages. Non-Ethernet
576 interfaces will leave 'chaddr' empty and use the client identifier
577 instead (eg, RFC 4390 section 2.1).
579 if (client
->arp_type
== ARPHRD_ETHER
)
580 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
582 /* If no client identifier exists, construct an RFC 4361-compliant one */
583 if (client
->client_id_len
== 0) {
586 client
->client_id
.type
= 255;
588 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
, &client
->client_id
.ns
.iaid
);
592 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
596 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
599 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
600 Identifier option is not set */
601 if (client
->client_id_len
) {
602 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
603 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
604 client
->client_id_len
,
610 /* RFC2131 section 3.5:
611 in its initial DHCPDISCOVER or DHCPREQUEST message, a
612 client may provide the server with a list of specific
613 parameters the client is interested in. If the client
614 includes a list of parameters in a DHCPDISCOVER message,
615 it MUST include that list in any subsequent DHCPREQUEST
619 /* RFC7844 section 3:
620 MAY contain the Parameter Request List option. */
621 /* NOTE: in case that there would be an option to do not send
622 * any PRL at all, the size should be checked before sending */
623 if (client
->req_opts_size
> 0) {
624 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
625 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
626 client
->req_opts_size
, client
->req_opts
);
631 /* RFC2131 section 3.5:
632 The client SHOULD include the ’maximum DHCP message size’ option to
633 let the server know how large the server may make its DHCP messages.
635 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
636 than the defined default size unless the Maximum Messge Size option
639 RFC3442 "Requirements to Avoid Sizing Constraints":
640 Because a full routing table can be quite large, the standard 576
641 octet maximum size for a DHCP message may be too short to contain
642 some legitimate Classless Static Route options. Because of this,
643 clients implementing the Classless Static Route option SHOULD send a
644 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
645 stack is capable of receiving larger IP datagrams. In this case, the
646 client SHOULD set the value of this option to at least the MTU of the
647 interface that the client is configuring. The client MAY set the
648 value of this option higher, up to the size of the largest UDP packet
649 it is prepared to accept. (Note that the value specified in the
650 Maximum DHCP Message Size option is the total maximum packet size,
651 including IP and UDP headers.)
653 /* RFC7844 section 3:
654 SHOULD NOT contain any other option. */
655 if (!client
->anonymize
) {
656 max_size
= htobe16(size
);
657 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
658 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
665 *_optoffset
= optoffset
;
672 static int client_append_fqdn_option(
673 DHCPMessage
*message
,
678 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
681 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
682 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
683 buffer
[1] = 0; /* RCODE1 (deprecated) */
684 buffer
[2] = 0; /* RCODE2 (deprecated) */
686 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
688 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
689 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
694 static int dhcp_client_send_raw(
695 sd_dhcp_client
*client
,
699 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
700 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
702 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
706 static int client_send_discover(sd_dhcp_client
*client
) {
707 _cleanup_free_ DHCPPacket
*discover
= NULL
;
708 size_t optoffset
, optlen
;
712 assert(client
->state
== DHCP_STATE_INIT
||
713 client
->state
== DHCP_STATE_SELECTING
);
715 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
716 &optlen
, &optoffset
);
720 /* the client may suggest values for the network address
721 and lease time in the DHCPDISCOVER message. The client may include
722 the ’requested IP address’ option to suggest that a particular IP
723 address be assigned, and may include the ’IP address lease time’
724 option to suggest the lease time it would like.
726 if (client
->last_addr
!= INADDR_ANY
) {
727 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
728 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
729 4, &client
->last_addr
);
734 if (client
->hostname
) {
735 /* According to RFC 4702 "clients that send the Client FQDN option in
736 their messages MUST NOT also send the Host Name option". Just send
737 one of the two depending on the hostname type.
739 if (dns_name_is_single_label(client
->hostname
)) {
740 /* it is unclear from RFC 2131 if client should send hostname in
741 DHCPDISCOVER but dhclient does and so we do as well
743 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
744 SD_DHCP_OPTION_HOST_NAME
,
745 strlen(client
->hostname
), client
->hostname
);
747 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
753 if (client
->vendor_class_identifier
) {
754 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
755 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
756 strlen(client
->vendor_class_identifier
),
757 client
->vendor_class_identifier
);
762 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
763 SD_DHCP_OPTION_END
, 0, NULL
);
767 /* We currently ignore:
768 The client SHOULD wait a random time between one and ten seconds to
769 desynchronize the use of DHCP at startup.
771 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
775 log_dhcp_client(client
, "DISCOVER");
780 static int client_send_request(sd_dhcp_client
*client
) {
781 _cleanup_free_ DHCPPacket
*request
= NULL
;
782 size_t optoffset
, optlen
;
787 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
791 switch (client
->state
) {
792 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
793 SELECTING should be REQUESTING)
796 case DHCP_STATE_REQUESTING
:
797 /* Client inserts the address of the selected server in ’server
798 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
799 filled in with the yiaddr value from the chosen DHCPOFFER.
802 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
803 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
804 4, &client
->lease
->server_address
);
808 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
809 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
810 4, &client
->lease
->address
);
816 case DHCP_STATE_INIT_REBOOT
:
817 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
818 option MUST be filled in with client’s notion of its previously
819 assigned address. ’ciaddr’ MUST be zero.
821 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
822 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
823 4, &client
->last_addr
);
828 case DHCP_STATE_RENEWING
:
829 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
830 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
831 client’s IP address.
835 case DHCP_STATE_REBINDING
:
836 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
837 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
838 client’s IP address.
840 This message MUST be broadcast to the 0xffffffff IP broadcast address.
842 request
->dhcp
.ciaddr
= client
->lease
->address
;
846 case DHCP_STATE_INIT
:
847 case DHCP_STATE_SELECTING
:
848 case DHCP_STATE_REBOOTING
:
849 case DHCP_STATE_BOUND
:
850 case DHCP_STATE_STOPPED
:
854 if (client
->hostname
) {
855 if (dns_name_is_single_label(client
->hostname
))
856 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
857 SD_DHCP_OPTION_HOST_NAME
,
858 strlen(client
->hostname
), client
->hostname
);
860 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
866 if (client
->vendor_class_identifier
) {
867 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
868 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
869 strlen(client
->vendor_class_identifier
),
870 client
->vendor_class_identifier
);
875 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
876 SD_DHCP_OPTION_END
, 0, NULL
);
880 if (client
->state
== DHCP_STATE_RENEWING
) {
881 r
= dhcp_network_send_udp_socket(client
->fd
,
882 client
->lease
->server_address
,
885 sizeof(DHCPMessage
) + optoffset
);
887 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
892 switch (client
->state
) {
894 case DHCP_STATE_REQUESTING
:
895 log_dhcp_client(client
, "REQUEST (requesting)");
898 case DHCP_STATE_INIT_REBOOT
:
899 log_dhcp_client(client
, "REQUEST (init-reboot)");
902 case DHCP_STATE_RENEWING
:
903 log_dhcp_client(client
, "REQUEST (renewing)");
906 case DHCP_STATE_REBINDING
:
907 log_dhcp_client(client
, "REQUEST (rebinding)");
911 log_dhcp_client(client
, "REQUEST (invalid)");
918 static int client_start(sd_dhcp_client
*client
);
920 static int client_timeout_resend(
925 sd_dhcp_client
*client
= userdata
;
926 DHCP_CLIENT_DONT_DESTROY(client
);
927 usec_t next_timeout
= 0;
934 assert(client
->event
);
936 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
940 switch (client
->state
) {
942 case DHCP_STATE_RENEWING
:
944 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
948 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
952 case DHCP_STATE_REBINDING
:
954 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
958 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
961 case DHCP_STATE_REBOOTING
:
962 /* start over as we did not receive a timely ack or nak */
963 r
= client_initialize(client
);
967 r
= client_start(client
);
971 log_dhcp_client(client
, "REBOOTED");
975 case DHCP_STATE_INIT
:
976 case DHCP_STATE_INIT_REBOOT
:
977 case DHCP_STATE_SELECTING
:
978 case DHCP_STATE_REQUESTING
:
979 case DHCP_STATE_BOUND
:
981 if (client
->attempt
< 64)
982 client
->attempt
*= 2;
984 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
988 case DHCP_STATE_STOPPED
:
993 next_timeout
+= (random_u32() & 0x1fffff);
995 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
997 r
= sd_event_add_time(client
->event
,
998 &client
->timeout_resend
,
999 clock_boottime_or_monotonic(),
1000 next_timeout
, 10 * USEC_PER_MSEC
,
1001 client_timeout_resend
, client
);
1005 r
= sd_event_source_set_priority(client
->timeout_resend
,
1006 client
->event_priority
);
1010 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1014 switch (client
->state
) {
1015 case DHCP_STATE_INIT
:
1016 r
= client_send_discover(client
);
1018 client
->state
= DHCP_STATE_SELECTING
;
1019 client
->attempt
= 1;
1021 if (client
->attempt
>= 64)
1027 case DHCP_STATE_SELECTING
:
1028 r
= client_send_discover(client
);
1029 if (r
< 0 && client
->attempt
>= 64)
1034 case DHCP_STATE_INIT_REBOOT
:
1035 case DHCP_STATE_REQUESTING
:
1036 case DHCP_STATE_RENEWING
:
1037 case DHCP_STATE_REBINDING
:
1038 r
= client_send_request(client
);
1039 if (r
< 0 && client
->attempt
>= 64)
1042 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1043 client
->state
= DHCP_STATE_REBOOTING
;
1045 client
->request_sent
= time_now
;
1049 case DHCP_STATE_REBOOTING
:
1050 case DHCP_STATE_BOUND
:
1054 case DHCP_STATE_STOPPED
:
1062 client_stop(client
, r
);
1064 /* Errors were dealt with when stopping the client, don't spill
1065 errors into the event loop handler */
1069 static int client_initialize_io_events(
1070 sd_dhcp_client
*client
,
1071 sd_event_io_handler_t io_callback
) {
1076 assert(client
->event
);
1078 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1079 client
->fd
, EPOLLIN
, io_callback
,
1084 r
= sd_event_source_set_priority(client
->receive_message
,
1085 client
->event_priority
);
1089 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1095 client_stop(client
, r
);
1100 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1105 assert(client
->event
);
1107 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1109 if (client
->start_delay
) {
1110 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1111 usec
+= client
->start_delay
;
1114 r
= sd_event_add_time(client
->event
,
1115 &client
->timeout_resend
,
1116 clock_boottime_or_monotonic(),
1118 client_timeout_resend
, client
);
1122 r
= sd_event_source_set_priority(client
->timeout_resend
,
1123 client
->event_priority
);
1127 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1133 client_stop(client
, r
);
1139 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1140 client_initialize_io_events(client
, io_callback
);
1141 client_initialize_time_events(client
);
1146 static int client_start_delayed(sd_dhcp_client
*client
) {
1149 assert_return(client
, -EINVAL
);
1150 assert_return(client
->event
, -EINVAL
);
1151 assert_return(client
->ifindex
> 0, -EINVAL
);
1152 assert_return(client
->fd
< 0, -EBUSY
);
1153 assert_return(client
->xid
== 0, -EINVAL
);
1154 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1156 client
->xid
= random_u32();
1158 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1159 client
->xid
, client
->mac_addr
,
1160 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1162 client_stop(client
, r
);
1167 if (client
->state
== DHCP_STATE_INIT
|| client
->state
== DHCP_STATE_INIT_REBOOT
)
1168 client
->start_time
= now(clock_boottime_or_monotonic());
1170 return client_initialize_events(client
, client_receive_message_raw
);
1173 static int client_start(sd_dhcp_client
*client
) {
1174 client
->start_delay
= 0;
1175 return client_start_delayed(client
);
1178 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1179 sd_dhcp_client
*client
= userdata
;
1180 DHCP_CLIENT_DONT_DESTROY(client
);
1182 log_dhcp_client(client
, "EXPIRED");
1184 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1186 /* lease was lost, start over if not freed or stopped in callback */
1187 if (client
->state
!= DHCP_STATE_STOPPED
) {
1188 client_initialize(client
);
1189 client_start(client
);
1195 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1196 sd_dhcp_client
*client
= userdata
;
1197 DHCP_CLIENT_DONT_DESTROY(client
);
1202 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1203 client
->fd
= asynchronous_close(client
->fd
);
1205 client
->state
= DHCP_STATE_REBINDING
;
1206 client
->attempt
= 1;
1208 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1209 client
->xid
, client
->mac_addr
,
1210 client
->mac_addr_len
, client
->arp_type
,
1213 client_stop(client
, r
);
1218 return client_initialize_events(client
, client_receive_message_raw
);
1221 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1222 sd_dhcp_client
*client
= userdata
;
1223 DHCP_CLIENT_DONT_DESTROY(client
);
1225 client
->state
= DHCP_STATE_RENEWING
;
1226 client
->attempt
= 1;
1228 return client_initialize_time_events(client
);
1231 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1232 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1235 r
= dhcp_lease_new(&lease
);
1239 if (client
->client_id_len
) {
1240 r
= dhcp_lease_set_client_id(lease
,
1241 (uint8_t *) &client
->client_id
,
1242 client
->client_id_len
);
1247 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1248 if (r
!= DHCP_OFFER
) {
1249 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1253 lease
->next_server
= offer
->siaddr
;
1254 lease
->address
= offer
->yiaddr
;
1256 if (lease
->address
== 0 ||
1257 lease
->server_address
== 0 ||
1258 lease
->lifetime
== 0) {
1259 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1263 if (!lease
->have_subnet_mask
) {
1264 r
= dhcp_lease_set_default_subnet_mask(lease
);
1266 log_dhcp_client(client
, "received lease lacks subnet "
1267 "mask, and a fallback one can not be "
1268 "generated, ignoring");
1273 sd_dhcp_lease_unref(client
->lease
);
1274 client
->lease
= lease
;
1277 log_dhcp_client(client
, "OFFER");
1282 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1285 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1286 if (r
!= DHCP_FORCERENEW
)
1289 log_dhcp_client(client
, "FORCERENEW");
1294 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1295 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1296 _cleanup_free_
char *error_message
= NULL
;
1299 r
= dhcp_lease_new(&lease
);
1303 if (client
->client_id_len
) {
1304 r
= dhcp_lease_set_client_id(lease
,
1305 (uint8_t *) &client
->client_id
,
1306 client
->client_id_len
);
1311 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1312 if (r
== DHCP_NAK
) {
1313 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1314 return -EADDRNOTAVAIL
;
1317 if (r
!= DHCP_ACK
) {
1318 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1322 lease
->next_server
= ack
->siaddr
;
1324 lease
->address
= ack
->yiaddr
;
1326 if (lease
->address
== INADDR_ANY
||
1327 lease
->server_address
== INADDR_ANY
||
1328 lease
->lifetime
== 0) {
1329 log_dhcp_client(client
, "received lease lacks address, server "
1330 "address or lease lifetime, ignoring");
1334 if (lease
->subnet_mask
== INADDR_ANY
) {
1335 r
= dhcp_lease_set_default_subnet_mask(lease
);
1337 log_dhcp_client(client
, "received lease lacks subnet "
1338 "mask, and a fallback one can not be "
1339 "generated, ignoring");
1344 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1345 if (client
->lease
) {
1346 if (client
->lease
->address
!= lease
->address
||
1347 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1348 client
->lease
->router
!= lease
->router
) {
1349 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1351 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1353 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1356 client
->lease
= lease
;
1359 log_dhcp_client(client
, "ACK");
1364 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1366 assert(client
->request_sent
);
1367 assert(lifetime
> 0);
1374 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1375 + (random_u32() & 0x1fffff);
1378 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1380 uint64_t lifetime_timeout
;
1381 uint64_t t2_timeout
;
1382 uint64_t t1_timeout
;
1383 char time_string
[FORMAT_TIMESPAN_MAX
];
1387 assert(client
->event
);
1388 assert(client
->lease
);
1389 assert(client
->lease
->lifetime
);
1391 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1392 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1393 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1395 /* don't set timers for infinite leases */
1396 if (client
->lease
->lifetime
== 0xffffffff)
1399 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1402 assert(client
->request_sent
<= time_now
);
1404 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1405 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1406 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1407 /* both T1 and T2 are given */
1408 if (client
->lease
->t1
< client
->lease
->t2
&&
1409 client
->lease
->t2
< client
->lease
->lifetime
) {
1410 /* they are both valid */
1411 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1412 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1415 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1416 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1417 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1418 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1420 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1421 /* only T2 is given, and it is valid */
1422 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1423 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1424 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1425 if (t2_timeout
<= t1_timeout
) {
1426 /* the computed T1 would be invalid, so discard T2 */
1427 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1428 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1430 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1431 /* only T1 is given, and it is valid */
1432 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1433 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1434 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1435 if (t2_timeout
<= t1_timeout
) {
1436 /* the computed T2 would be invalid, so discard T1 */
1437 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1438 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1441 /* fall back to the default timeouts */
1442 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1443 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1444 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1445 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1448 /* arm lifetime timeout */
1449 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1450 clock_boottime_or_monotonic(),
1451 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1452 client_timeout_expire
, client
);
1456 r
= sd_event_source_set_priority(client
->timeout_expire
,
1457 client
->event_priority
);
1461 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1465 log_dhcp_client(client
, "lease expires in %s",
1466 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1468 /* don't arm earlier timeouts if this has already expired */
1469 if (lifetime_timeout
<= time_now
)
1472 /* arm T2 timeout */
1473 r
= sd_event_add_time(client
->event
,
1474 &client
->timeout_t2
,
1475 clock_boottime_or_monotonic(),
1478 client_timeout_t2
, client
);
1482 r
= sd_event_source_set_priority(client
->timeout_t2
,
1483 client
->event_priority
);
1487 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1491 log_dhcp_client(client
, "T2 expires in %s",
1492 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1494 /* don't arm earlier timeout if this has already expired */
1495 if (t2_timeout
<= time_now
)
1498 /* arm T1 timeout */
1499 r
= sd_event_add_time(client
->event
,
1500 &client
->timeout_t1
,
1501 clock_boottime_or_monotonic(),
1502 t1_timeout
, 10 * USEC_PER_MSEC
,
1503 client_timeout_t1
, client
);
1507 r
= sd_event_source_set_priority(client
->timeout_t1
,
1508 client
->event_priority
);
1512 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1516 log_dhcp_client(client
, "T1 expires in %s",
1517 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1522 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1523 DHCP_CLIENT_DONT_DESTROY(client
);
1524 char time_string
[FORMAT_TIMESPAN_MAX
];
1525 int r
= 0, notify_event
= 0;
1528 assert(client
->event
);
1531 switch (client
->state
) {
1532 case DHCP_STATE_SELECTING
:
1534 r
= client_handle_offer(client
, message
, len
);
1537 client
->timeout_resend
=
1538 sd_event_source_unref(client
->timeout_resend
);
1540 client
->state
= DHCP_STATE_REQUESTING
;
1541 client
->attempt
= 1;
1543 r
= sd_event_add_time(client
->event
,
1544 &client
->timeout_resend
,
1545 clock_boottime_or_monotonic(),
1547 client_timeout_resend
, client
);
1551 r
= sd_event_source_set_priority(client
->timeout_resend
,
1552 client
->event_priority
);
1556 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1559 } else if (r
== -ENOMSG
)
1560 /* invalid message, let's ignore it */
1565 case DHCP_STATE_REBOOTING
:
1566 case DHCP_STATE_REQUESTING
:
1567 case DHCP_STATE_RENEWING
:
1568 case DHCP_STATE_REBINDING
:
1570 r
= client_handle_ack(client
, message
, len
);
1572 client
->start_delay
= 0;
1573 client
->timeout_resend
=
1574 sd_event_source_unref(client
->timeout_resend
);
1575 client
->receive_message
=
1576 sd_event_source_unref(client
->receive_message
);
1577 client
->fd
= asynchronous_close(client
->fd
);
1579 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1580 DHCP_STATE_REBOOTING
))
1581 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1582 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1585 client
->state
= DHCP_STATE_BOUND
;
1586 client
->attempt
= 1;
1588 client
->last_addr
= client
->lease
->address
;
1590 r
= client_set_lease_timeouts(client
);
1592 log_dhcp_client(client
, "could not set lease timeouts");
1596 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1598 log_dhcp_client(client
, "could not bind UDP socket");
1604 client_initialize_io_events(client
, client_receive_message_udp
);
1607 client_notify(client
, notify_event
);
1608 if (client
->state
== DHCP_STATE_STOPPED
)
1612 } else if (r
== -EADDRNOTAVAIL
) {
1613 /* got a NAK, let's restart the client */
1614 client
->timeout_resend
=
1615 sd_event_source_unref(client
->timeout_resend
);
1617 r
= client_initialize(client
);
1621 r
= client_start_delayed(client
);
1625 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1626 client
->start_delay
, USEC_PER_SEC
));
1628 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1629 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1632 } else if (r
== -ENOMSG
)
1633 /* invalid message, let's ignore it */
1638 case DHCP_STATE_BOUND
:
1639 r
= client_handle_forcerenew(client
, message
, len
);
1641 r
= client_timeout_t1(NULL
, 0, client
);
1644 } else if (r
== -ENOMSG
)
1645 /* invalid message, let's ignore it */
1650 case DHCP_STATE_INIT
:
1651 case DHCP_STATE_INIT_REBOOT
:
1655 case DHCP_STATE_STOPPED
:
1662 client_stop(client
, r
);
1667 static int client_receive_message_udp(
1673 sd_dhcp_client
*client
= userdata
;
1674 _cleanup_free_ DHCPMessage
*message
= NULL
;
1675 const struct ether_addr zero_mac
= {};
1676 const struct ether_addr
*expected_chaddr
= NULL
;
1677 uint8_t expected_hlen
= 0;
1678 ssize_t len
, buflen
;
1683 buflen
= next_datagram_size_fd(fd
);
1687 message
= malloc0(buflen
);
1691 len
= recv(fd
, message
, buflen
, 0);
1693 if (errno
== EAGAIN
|| errno
== EINTR
)
1696 return log_dhcp_client_errno(client
, errno
,
1697 "Could not receive message from UDP socket: %m");
1699 if ((size_t) len
< sizeof(DHCPMessage
)) {
1700 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1704 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1705 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1709 if (message
->op
!= BOOTREPLY
) {
1710 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1714 if (message
->htype
!= client
->arp_type
) {
1715 log_dhcp_client(client
, "Packet type does not match client type");
1719 if (client
->arp_type
== ARPHRD_ETHER
) {
1720 expected_hlen
= ETH_ALEN
;
1721 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1723 /* Non-Ethernet links expect zero chaddr */
1725 expected_chaddr
= &zero_mac
;
1728 if (message
->hlen
!= expected_hlen
) {
1729 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1733 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1734 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1738 if (client
->state
!= DHCP_STATE_BOUND
&&
1739 be32toh(message
->xid
) != client
->xid
) {
1740 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1741 so ignore the xid in this case */
1742 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1743 be32toh(message
->xid
), client
->xid
);
1747 return client_handle_message(client
, message
, len
);
1750 static int client_receive_message_raw(
1756 sd_dhcp_client
*client
= userdata
;
1757 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1758 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1759 struct iovec iov
= {};
1760 struct msghdr msg
= {
1763 .msg_control
= cmsgbuf
,
1764 .msg_controllen
= sizeof(cmsgbuf
),
1766 struct cmsghdr
*cmsg
;
1767 bool checksum
= true;
1768 ssize_t buflen
, len
;
1774 buflen
= next_datagram_size_fd(fd
);
1778 packet
= malloc0(buflen
);
1782 iov
.iov_base
= packet
;
1783 iov
.iov_len
= buflen
;
1785 len
= recvmsg(fd
, &msg
, 0);
1787 if (errno
== EAGAIN
|| errno
== EINTR
)
1790 return log_dhcp_client_errno(client
, errno
,
1791 "Could not receive message from raw socket: %m");
1792 } else if ((size_t)len
< sizeof(DHCPPacket
))
1795 CMSG_FOREACH(cmsg
, &msg
) {
1796 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1797 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1798 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1799 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1801 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1806 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1810 len
-= DHCP_IP_UDP_SIZE
;
1812 return client_handle_message(client
, &packet
->dhcp
, len
);
1815 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1818 assert_return(client
, -EINVAL
);
1820 r
= client_initialize(client
);
1824 /* RFC7844 section 3.3:
1825 SHOULD perform a complete four-way handshake, starting with a
1826 DHCPDISCOVER, to obtain a new address lease. If the client can
1827 ascertain that this is exactly the same network to which it was
1828 previously connected, and if the link-layer address did not change,
1829 the client MAY issue a DHCPREQUEST to try to reclaim the current
1831 if (client
->last_addr
&& !client
->anonymize
)
1832 client
->state
= DHCP_STATE_INIT_REBOOT
;
1834 r
= client_start(client
);
1836 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1841 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1842 DHCP_CLIENT_DONT_DESTROY(client
);
1844 assert_return(client
, -EINVAL
);
1846 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1847 client
->state
= DHCP_STATE_STOPPED
;
1852 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1855 assert_return(client
, -EINVAL
);
1856 assert_return(!client
->event
, -EBUSY
);
1859 client
->event
= sd_event_ref(event
);
1861 r
= sd_event_default(&client
->event
);
1866 client
->event_priority
= priority
;
1871 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1872 assert_return(client
, -EINVAL
);
1874 client
->event
= sd_event_unref(client
->event
);
1879 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1880 assert_return(client
, NULL
);
1882 return client
->event
;
1885 sd_dhcp_client
*sd_dhcp_client_ref(sd_dhcp_client
*client
) {
1890 assert(client
->n_ref
>= 1);
1896 sd_dhcp_client
*sd_dhcp_client_unref(sd_dhcp_client
*client
) {
1901 assert(client
->n_ref
>= 1);
1904 if (client
->n_ref
> 0)
1907 log_dhcp_client(client
, "FREE");
1909 client_initialize(client
);
1911 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1913 sd_dhcp_client_detach_event(client
);
1915 sd_dhcp_lease_unref(client
->lease
);
1917 free(client
->req_opts
);
1918 free(client
->hostname
);
1919 free(client
->vendor_class_identifier
);
1920 return mfree(client
);
1923 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1924 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1926 assert_return(ret
, -EINVAL
);
1928 client
= new0(sd_dhcp_client
, 1);
1933 client
->state
= DHCP_STATE_INIT
;
1934 client
->ifindex
= -1;
1936 client
->attempt
= 1;
1937 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1938 client
->port
= DHCP_PORT_CLIENT
;
1940 client
->anonymize
= !!anonymize
;
1941 /* NOTE: this could be moved to a function. */
1943 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
1944 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
1946 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1947 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1949 if (!client
->req_opts
)