1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright © 2013 Intel Corporation. All rights reserved.
7 #include <net/ethernet.h>
8 #include <net/if_arp.h>
11 #include <sys/ioctl.h>
12 #include <linux/if_infiniband.h>
14 #include "sd-dhcp-client.h"
16 #include "alloc-util.h"
18 #include "dhcp-identifier.h"
19 #include "dhcp-internal.h"
20 #include "dhcp-lease-internal.h"
21 #include "dhcp-protocol.h"
22 #include "dns-domain.h"
23 #include "event-util.h"
24 #include "hostname-util.h"
26 #include "memory-util.h"
27 #include "random-util.h"
28 #include "string-util.h"
31 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
32 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
34 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
35 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
37 struct sd_dhcp_option
{
45 struct sd_dhcp_client
{
51 sd_event_source
*timeout_resend
;
55 union sockaddr_union link
;
56 sd_event_source
*receive_message
;
57 bool request_broadcast
;
59 size_t req_opts_allocated
;
63 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
70 /* 0: Generic (non-LL) (RFC 2132) */
71 uint8_t data
[MAX_CLIENT_ID_LEN
];
74 /* 1: Ethernet Link-Layer (RFC 2132) */
75 uint8_t haddr
[ETH_ALEN
];
78 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
82 /* 255: Node-specific (RFC 4361) */
87 uint8_t data
[MAX_CLIENT_ID_LEN
];
93 char *vendor_class_identifier
;
99 uint64_t max_attempts
;
100 OrderedHashmap
*options
;
102 sd_event_source
*timeout_t1
;
103 sd_event_source
*timeout_t2
;
104 sd_event_source
*timeout_expire
;
105 sd_dhcp_client_callback_t callback
;
107 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
);
313 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
314 client
->client_id
.type
== type
&&
315 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
318 /* For hardware types, log debug message about unexpected data length.
320 * Note that infiniband's INFINIBAND_ALEN is 20 bytes long, but only
321 * last last 8 bytes of the address are stable and suitable to put into
322 * the client-id. The caller is advised to account for that. */
323 if ((type
== ARPHRD_ETHER
&& data_len
!= ETH_ALEN
) ||
324 (type
== ARPHRD_INFINIBAND
&& data_len
!= 8))
325 log_dhcp_client(client
, "Changing client ID to hardware type %u with "
326 "unexpected address length %zu",
329 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
330 log_dhcp_client(client
, "Changing client ID on running DHCP "
331 "client, restarting");
333 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
336 client
->client_id
.type
= type
;
337 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
338 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
340 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
341 sd_dhcp_client_start(client
);
347 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
348 * without further modification. Otherwise, if duid_type is supported, DUID
349 * is set based on that type. Otherwise, an error is returned.
351 static int dhcp_client_set_iaid_duid_internal(
352 sd_dhcp_client
*client
,
361 DHCP_CLIENT_DONT_DESTROY(client
);
365 assert_return(client
, -EINVAL
);
366 assert_return(duid_len
== 0 || duid
, -EINVAL
);
369 r
= dhcp_validate_duid_len(duid_type
, duid_len
, true);
374 zero(client
->client_id
);
375 client
->client_id
.type
= 255;
379 client
->client_id
.ns
.iaid
= htobe32(iaid
);
381 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
382 client
->mac_addr_len
,
384 &client
->client_id
.ns
.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
;
397 if (client
->mac_addr_len
== 0)
400 r
= dhcp_identifier_set_duid_llt(&client
->client_id
.ns
.duid
, llt_time
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
405 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
410 if (client
->mac_addr_len
== 0)
413 r
= dhcp_identifier_set_duid_ll(&client
->client_id
.ns
.duid
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
418 r
= dhcp_identifier_set_duid_uuid(&client
->client_id
.ns
.duid
, &len
);
426 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
427 (iaid_append
? sizeof(client
->client_id
.ns
.iaid
) : 0);
429 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
430 log_dhcp_client(client
, "Configured %sDUID, restarting.", iaid_append
? "IAID+" : "");
431 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
432 sd_dhcp_client_start(client
);
438 int sd_dhcp_client_set_iaid_duid(
439 sd_dhcp_client
*client
,
445 return dhcp_client_set_iaid_duid_internal(client
, true, iaid_set
, iaid
, duid_type
, duid
, duid_len
, 0);
448 int sd_dhcp_client_set_iaid_duid_llt(
449 sd_dhcp_client
*client
,
453 return dhcp_client_set_iaid_duid_internal(client
, true, iaid_set
, iaid
, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
456 int sd_dhcp_client_set_duid(
457 sd_dhcp_client
*client
,
461 return dhcp_client_set_iaid_duid_internal(client
, false, false, 0, duid_type
, duid
, duid_len
, 0);
464 int sd_dhcp_client_set_duid_llt(
465 sd_dhcp_client
*client
,
467 return dhcp_client_set_iaid_duid_internal(client
, false, false, 0, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
470 int sd_dhcp_client_set_hostname(
471 sd_dhcp_client
*client
,
472 const char *hostname
) {
474 assert_return(client
, -EINVAL
);
476 /* Make sure hostnames qualify as DNS and as Linux hostnames */
478 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
481 return free_and_strdup(&client
->hostname
, hostname
);
484 int sd_dhcp_client_set_vendor_class_identifier(
485 sd_dhcp_client
*client
,
488 assert_return(client
, -EINVAL
);
490 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
493 int sd_dhcp_client_set_user_class(
494 sd_dhcp_client
*client
,
495 const char* const* user_class
) {
497 _cleanup_strv_free_
char **s
= NULL
;
500 STRV_FOREACH(p
, (char **) user_class
)
501 if (strlen(*p
) > 255)
502 return -ENAMETOOLONG
;
504 s
= strv_copy((char **) user_class
);
508 client
->user_class
= TAKE_PTR(s
);
513 int sd_dhcp_client_set_client_port(
514 sd_dhcp_client
*client
,
517 assert_return(client
, -EINVAL
);
524 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
525 assert_return(client
, -EINVAL
);
526 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
533 int sd_dhcp_client_set_max_attempts(sd_dhcp_client
*client
, uint64_t max_attempts
) {
534 assert_return(client
, -EINVAL
);
536 client
->max_attempts
= max_attempts
;
541 static sd_dhcp_option
* dhcp_option_free(sd_dhcp_option
*i
) {
549 int sd_dhcp_option_new(uint8_t option
, void *data
, size_t length
, sd_dhcp_option
**ret
) {
550 assert_return(ret
, -EINVAL
);
551 assert_return(length
== 0 || data
, -EINVAL
);
553 _cleanup_free_
void *q
= memdup(data
, length
);
557 sd_dhcp_option
*p
= new(sd_dhcp_option
, 1);
561 *p
= (sd_dhcp_option
) {
572 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option
, sd_dhcp_option
, dhcp_option_free
);
573 DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
574 dhcp_option_hash_ops
,
577 trivial_compare_func
,
579 sd_dhcp_option_unref
);
581 int sd_dhcp_client_set_dhcp_option(sd_dhcp_client
*client
, sd_dhcp_option
*v
) {
584 assert_return(client
, -EINVAL
);
585 assert_return(v
, -EINVAL
);
587 r
= ordered_hashmap_ensure_allocated(&client
->options
, &dhcp_option_hash_ops
);
591 r
= ordered_hashmap_put(client
->options
, UINT_TO_PTR(v
->option
), v
);
595 sd_dhcp_option_ref(v
);
599 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
600 assert_return(client
, -EINVAL
);
602 if (!IN_SET(client
->state
, DHCP_STATE_SELECTING
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
603 return -EADDRNOTAVAIL
;
606 *ret
= client
->lease
;
611 int sd_dhcp_client_set_service_type(sd_dhcp_client
*client
, int type
) {
612 assert_return(client
, -EINVAL
);
614 client
->ip_service_type
= type
;
619 static int client_notify(sd_dhcp_client
*client
, int event
) {
622 if (client
->callback
)
623 return client
->callback(client
, event
, client
->userdata
);
628 static int client_initialize(sd_dhcp_client
*client
) {
629 assert_return(client
, -EINVAL
);
631 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
633 client
->fd
= asynchronous_close(client
->fd
);
635 (void) event_source_disable(client
->timeout_resend
);
636 (void) event_source_disable(client
->timeout_t1
);
637 (void) event_source_disable(client
->timeout_t2
);
638 (void) event_source_disable(client
->timeout_expire
);
642 client
->state
= DHCP_STATE_INIT
;
645 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
650 static void client_stop(sd_dhcp_client
*client
, int error
) {
654 log_dhcp_client_errno(client
, error
, "STOPPED: %m");
655 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
656 log_dhcp_client(client
, "STOPPED");
658 log_dhcp_client(client
, "STOPPED: Unknown event");
660 client_notify(client
, error
);
662 client_initialize(client
);
665 static int client_message_init(
666 sd_dhcp_client
*client
,
670 size_t *_optoffset
) {
672 _cleanup_free_ DHCPPacket
*packet
= NULL
;
673 size_t optlen
, optoffset
, size
;
680 assert(client
->start_time
);
684 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
, DHCP_RELEASE
));
686 optlen
= DHCP_MIN_OPTIONS_SIZE
;
687 size
= sizeof(DHCPPacket
) + optlen
;
689 packet
= malloc0(size
);
693 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
694 client
->arp_type
, optlen
, &optoffset
);
698 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
699 refuse to issue an DHCP lease if 'secs' is set to zero */
700 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
703 assert(time_now
>= client
->start_time
);
705 /* seconds between sending first and last DISCOVER
706 * must always be strictly positive to deal with broken servers */
707 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
708 packet
->dhcp
.secs
= htobe16(secs
);
710 /* RFC2132 section 4.1
711 A client that cannot receive unicast IP datagrams until its protocol
712 software has been configured with an IP address SHOULD set the
713 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
714 DHCPREQUEST messages that client sends. The BROADCAST bit will
715 provide a hint to the DHCP server and BOOTP relay agent to broadcast
716 any messages to the client on the client's subnet.
718 Note: some interfaces needs this to be enabled, but some networks
719 needs this to be disabled as broadcasts are filteretd, so this
720 needs to be configurable */
721 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
722 packet
->dhcp
.flags
= htobe16(0x8000);
724 /* RFC2132 section 4.1.1:
725 The client MUST include its hardware address in the ’chaddr’ field, if
726 necessary for delivery of DHCP reply messages. Non-Ethernet
727 interfaces will leave 'chaddr' empty and use the client identifier
728 instead (eg, RFC 4390 section 2.1).
730 if (client
->arp_type
== ARPHRD_ETHER
)
731 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
733 /* If no client identifier exists, construct an RFC 4361-compliant one */
734 if (client
->client_id_len
== 0) {
737 client
->client_id
.type
= 255;
739 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
,
740 true, &client
->client_id
.ns
.iaid
);
744 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
748 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
751 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
752 Identifier option is not set */
753 if (client
->client_id_len
) {
754 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
755 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
756 client
->client_id_len
,
762 /* RFC2131 section 3.5:
763 in its initial DHCPDISCOVER or DHCPREQUEST message, a
764 client may provide the server with a list of specific
765 parameters the client is interested in. If the client
766 includes a list of parameters in a DHCPDISCOVER message,
767 it MUST include that list in any subsequent DHCPREQUEST
771 /* RFC7844 section 3:
772 MAY contain the Parameter Request List option. */
773 /* NOTE: in case that there would be an option to do not send
774 * any PRL at all, the size should be checked before sending */
775 if (client
->req_opts_size
> 0 && type
!= DHCP_RELEASE
) {
776 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
777 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
778 client
->req_opts_size
, client
->req_opts
);
783 /* RFC2131 section 3.5:
784 The client SHOULD include the ’maximum DHCP message size’ option to
785 let the server know how large the server may make its DHCP messages.
787 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
788 than the defined default size unless the Maximum Message Size option
791 RFC3442 "Requirements to Avoid Sizing Constraints":
792 Because a full routing table can be quite large, the standard 576
793 octet maximum size for a DHCP message may be too short to contain
794 some legitimate Classless Static Route options. Because of this,
795 clients implementing the Classless Static Route option SHOULD send a
796 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
797 stack is capable of receiving larger IP datagrams. In this case, the
798 client SHOULD set the value of this option to at least the MTU of the
799 interface that the client is configuring. The client MAY set the
800 value of this option higher, up to the size of the largest UDP packet
801 it is prepared to accept. (Note that the value specified in the
802 Maximum DHCP Message Size option is the total maximum packet size,
803 including IP and UDP headers.)
805 /* RFC7844 section 3:
806 SHOULD NOT contain any other option. */
807 if (!client
->anonymize
&& type
!= DHCP_RELEASE
) {
808 max_size
= htobe16(size
);
809 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
810 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
817 *_optoffset
= optoffset
;
818 *ret
= TAKE_PTR(packet
);
823 static int client_append_fqdn_option(
824 DHCPMessage
*message
,
829 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
832 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
833 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
834 buffer
[1] = 0; /* RCODE1 (deprecated) */
835 buffer
[2] = 0; /* RCODE2 (deprecated) */
837 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
839 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
840 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
845 static int dhcp_client_send_raw(
846 sd_dhcp_client
*client
,
850 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
851 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
, client
->ip_service_type
);
853 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
857 static int client_send_discover(sd_dhcp_client
*client
) {
858 _cleanup_free_ DHCPPacket
*discover
= NULL
;
859 size_t optoffset
, optlen
;
865 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
867 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
868 &optlen
, &optoffset
);
872 /* the client may suggest values for the network address
873 and lease time in the DHCPDISCOVER message. The client may include
874 the ’requested IP address’ option to suggest that a particular IP
875 address be assigned, and may include the ’IP address lease time’
876 option to suggest the lease time it would like.
878 /* RFC7844 section 3:
879 SHOULD NOT contain any other option. */
880 if (!client
->anonymize
&& client
->last_addr
!= INADDR_ANY
) {
881 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
882 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
883 4, &client
->last_addr
);
888 if (client
->hostname
) {
889 /* According to RFC 4702 "clients that send the Client FQDN option in
890 their messages MUST NOT also send the Host Name option". Just send
891 one of the two depending on the hostname type.
893 if (dns_name_is_single_label(client
->hostname
)) {
894 /* it is unclear from RFC 2131 if client should send hostname in
895 DHCPDISCOVER but dhclient does and so we do as well
897 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
898 SD_DHCP_OPTION_HOST_NAME
,
899 strlen(client
->hostname
), client
->hostname
);
901 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
907 if (client
->vendor_class_identifier
) {
908 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
909 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
910 strlen(client
->vendor_class_identifier
),
911 client
->vendor_class_identifier
);
916 if (client
->user_class
) {
917 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
918 SD_DHCP_OPTION_USER_CLASS
,
919 strv_length(client
->user_class
),
925 ORDERED_HASHMAP_FOREACH(j
, client
->options
, i
) {
926 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
927 j
->option
, j
->length
, j
->data
);
932 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
933 SD_DHCP_OPTION_END
, 0, NULL
);
937 /* We currently ignore:
938 The client SHOULD wait a random time between one and ten seconds to
939 desynchronize the use of DHCP at startup.
941 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
945 log_dhcp_client(client
, "DISCOVER");
950 static int client_send_request(sd_dhcp_client
*client
) {
951 _cleanup_free_ DHCPPacket
*request
= NULL
;
952 size_t optoffset
, optlen
;
957 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
961 switch (client
->state
) {
962 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
963 SELECTING should be REQUESTING)
966 case DHCP_STATE_REQUESTING
:
967 /* Client inserts the address of the selected server in ’server
968 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
969 filled in with the yiaddr value from the chosen DHCPOFFER.
972 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
973 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
974 4, &client
->lease
->server_address
);
978 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
979 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
980 4, &client
->lease
->address
);
986 case DHCP_STATE_INIT_REBOOT
:
987 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
988 option MUST be filled in with client’s notion of its previously
989 assigned address. ’ciaddr’ MUST be zero.
991 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
992 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
993 4, &client
->last_addr
);
998 case DHCP_STATE_RENEWING
:
999 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1000 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1001 client’s IP address.
1004 case DHCP_STATE_REBINDING
:
1005 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1006 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1007 client’s IP address.
1009 This message MUST be broadcast to the 0xffffffff IP broadcast address.
1011 request
->dhcp
.ciaddr
= client
->lease
->address
;
1015 case DHCP_STATE_INIT
:
1016 case DHCP_STATE_SELECTING
:
1017 case DHCP_STATE_REBOOTING
:
1018 case DHCP_STATE_BOUND
:
1019 case DHCP_STATE_STOPPED
:
1023 if (client
->hostname
) {
1024 if (dns_name_is_single_label(client
->hostname
))
1025 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
1026 SD_DHCP_OPTION_HOST_NAME
,
1027 strlen(client
->hostname
), client
->hostname
);
1029 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
1035 if (client
->vendor_class_identifier
) {
1036 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
1037 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
1038 strlen(client
->vendor_class_identifier
),
1039 client
->vendor_class_identifier
);
1044 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
1045 SD_DHCP_OPTION_END
, 0, NULL
);
1049 if (client
->state
== DHCP_STATE_RENEWING
)
1050 r
= dhcp_network_send_udp_socket(client
->fd
,
1051 client
->lease
->server_address
,
1054 sizeof(DHCPMessage
) + optoffset
);
1056 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
1060 switch (client
->state
) {
1062 case DHCP_STATE_REQUESTING
:
1063 log_dhcp_client(client
, "REQUEST (requesting)");
1066 case DHCP_STATE_INIT_REBOOT
:
1067 log_dhcp_client(client
, "REQUEST (init-reboot)");
1070 case DHCP_STATE_RENEWING
:
1071 log_dhcp_client(client
, "REQUEST (renewing)");
1074 case DHCP_STATE_REBINDING
:
1075 log_dhcp_client(client
, "REQUEST (rebinding)");
1079 log_dhcp_client(client
, "REQUEST (invalid)");
1086 static int client_start(sd_dhcp_client
*client
);
1088 static int client_timeout_resend(
1093 sd_dhcp_client
*client
= userdata
;
1094 DHCP_CLIENT_DONT_DESTROY(client
);
1095 usec_t next_timeout
= 0;
1102 assert(client
->event
);
1104 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1108 switch (client
->state
) {
1110 case DHCP_STATE_RENEWING
:
1112 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
1116 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1120 case DHCP_STATE_REBINDING
:
1122 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
1126 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1129 case DHCP_STATE_REBOOTING
:
1130 /* start over as we did not receive a timely ack or nak */
1131 r
= client_initialize(client
);
1135 r
= client_start(client
);
1139 log_dhcp_client(client
, "REBOOTED");
1143 case DHCP_STATE_INIT
:
1144 case DHCP_STATE_INIT_REBOOT
:
1145 case DHCP_STATE_SELECTING
:
1146 case DHCP_STATE_REQUESTING
:
1147 case DHCP_STATE_BOUND
:
1149 if (client
->attempt
< client
->max_attempts
)
1154 next_timeout
= time_now
+ ((UINT64_C(1) << MIN(client
->attempt
, (uint64_t) 6)) - 1) * USEC_PER_SEC
;
1158 case DHCP_STATE_STOPPED
:
1163 next_timeout
+= (random_u32() & 0x1fffff);
1165 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1166 clock_boottime_or_monotonic(),
1167 next_timeout
, 10 * USEC_PER_MSEC
,
1168 client_timeout_resend
, client
,
1169 client
->event_priority
, "dhcp4-resend-timer", true);
1173 switch (client
->state
) {
1174 case DHCP_STATE_INIT
:
1175 r
= client_send_discover(client
);
1177 client
->state
= DHCP_STATE_SELECTING
;
1178 client
->attempt
= 0;
1179 } else if (client
->attempt
>= client
->max_attempts
)
1184 case DHCP_STATE_SELECTING
:
1185 r
= client_send_discover(client
);
1186 if (r
< 0 && client
->attempt
>= client
->max_attempts
)
1191 case DHCP_STATE_INIT_REBOOT
:
1192 case DHCP_STATE_REQUESTING
:
1193 case DHCP_STATE_RENEWING
:
1194 case DHCP_STATE_REBINDING
:
1195 r
= client_send_request(client
);
1196 if (r
< 0 && client
->attempt
>= client
->max_attempts
)
1199 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1200 client
->state
= DHCP_STATE_REBOOTING
;
1202 client
->request_sent
= time_now
;
1206 case DHCP_STATE_REBOOTING
:
1207 case DHCP_STATE_BOUND
:
1211 case DHCP_STATE_STOPPED
:
1219 client_stop(client
, r
);
1221 /* Errors were dealt with when stopping the client, don't spill
1222 errors into the event loop handler */
1226 static int client_initialize_io_events(
1227 sd_dhcp_client
*client
,
1228 sd_event_io_handler_t io_callback
) {
1233 assert(client
->event
);
1235 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1236 client
->fd
, EPOLLIN
, io_callback
,
1241 r
= sd_event_source_set_priority(client
->receive_message
,
1242 client
->event_priority
);
1246 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1252 client_stop(client
, r
);
1257 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1262 assert(client
->event
);
1264 if (client
->start_delay
> 0) {
1265 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1266 usec
+= client
->start_delay
;
1269 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1270 clock_boottime_or_monotonic(),
1272 client_timeout_resend
, client
,
1273 client
->event_priority
, "dhcp4-resend-timer", true);
1275 client_stop(client
, r
);
1281 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1282 client_initialize_io_events(client
, io_callback
);
1283 client_initialize_time_events(client
);
1288 static int client_start_delayed(sd_dhcp_client
*client
) {
1291 assert_return(client
, -EINVAL
);
1292 assert_return(client
->event
, -EINVAL
);
1293 assert_return(client
->ifindex
> 0, -EINVAL
);
1294 assert_return(client
->fd
< 0, -EBUSY
);
1295 assert_return(client
->xid
== 0, -EINVAL
);
1296 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1298 client
->xid
= random_u32();
1300 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1301 client
->xid
, client
->mac_addr
,
1302 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1304 client_stop(client
, r
);
1309 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1310 client
->start_time
= now(clock_boottime_or_monotonic());
1312 return client_initialize_events(client
, client_receive_message_raw
);
1315 static int client_start(sd_dhcp_client
*client
) {
1316 client
->start_delay
= 0;
1317 return client_start_delayed(client
);
1320 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1321 sd_dhcp_client
*client
= userdata
;
1322 DHCP_CLIENT_DONT_DESTROY(client
);
1324 log_dhcp_client(client
, "EXPIRED");
1326 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1328 /* lease was lost, start over if not freed or stopped in callback */
1329 if (client
->state
!= DHCP_STATE_STOPPED
) {
1330 client_initialize(client
);
1331 client_start(client
);
1337 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1338 sd_dhcp_client
*client
= userdata
;
1339 DHCP_CLIENT_DONT_DESTROY(client
);
1344 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1345 client
->fd
= asynchronous_close(client
->fd
);
1347 client
->state
= DHCP_STATE_REBINDING
;
1348 client
->attempt
= 0;
1350 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1351 client
->xid
, client
->mac_addr
,
1352 client
->mac_addr_len
, client
->arp_type
,
1355 client_stop(client
, r
);
1360 return client_initialize_events(client
, client_receive_message_raw
);
1363 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1364 sd_dhcp_client
*client
= userdata
;
1365 DHCP_CLIENT_DONT_DESTROY(client
);
1367 client
->state
= DHCP_STATE_RENEWING
;
1368 client
->attempt
= 0;
1370 return client_initialize_time_events(client
);
1373 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1374 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1377 r
= dhcp_lease_new(&lease
);
1381 if (client
->client_id_len
) {
1382 r
= dhcp_lease_set_client_id(lease
,
1383 (uint8_t *) &client
->client_id
,
1384 client
->client_id_len
);
1389 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1390 if (r
!= DHCP_OFFER
) {
1391 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1395 lease
->next_server
= offer
->siaddr
;
1396 lease
->address
= offer
->yiaddr
;
1398 if (lease
->address
== 0 ||
1399 lease
->server_address
== 0 ||
1400 lease
->lifetime
== 0) {
1401 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1405 if (!lease
->have_subnet_mask
) {
1406 r
= dhcp_lease_set_default_subnet_mask(lease
);
1408 log_dhcp_client(client
,
1409 "received lease lacks subnet mask, "
1410 "and a fallback one cannot be generated, ignoring");
1415 sd_dhcp_lease_unref(client
->lease
);
1416 client
->lease
= TAKE_PTR(lease
);
1418 if (client_notify(client
, SD_DHCP_CLIENT_EVENT_SELECTING
) < 0)
1421 log_dhcp_client(client
, "OFFER");
1426 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1429 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1430 if (r
!= DHCP_FORCERENEW
)
1433 log_dhcp_client(client
, "FORCERENEW");
1438 static bool lease_equal(const sd_dhcp_lease
*a
, const sd_dhcp_lease
*b
) {
1439 if (a
->address
!= b
->address
)
1442 if (a
->subnet_mask
!= b
->subnet_mask
)
1445 if (a
->router_size
!= b
->router_size
)
1448 for (size_t i
= 0; i
< a
->router_size
; i
++)
1449 if (a
->router
[i
].s_addr
!= b
->router
[i
].s_addr
)
1455 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1456 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1457 _cleanup_free_
char *error_message
= NULL
;
1460 r
= dhcp_lease_new(&lease
);
1464 if (client
->client_id_len
) {
1465 r
= dhcp_lease_set_client_id(lease
,
1466 (uint8_t *) &client
->client_id
,
1467 client
->client_id_len
);
1472 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1473 if (r
== DHCP_NAK
) {
1474 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1475 return -EADDRNOTAVAIL
;
1478 if (r
!= DHCP_ACK
) {
1479 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1483 lease
->next_server
= ack
->siaddr
;
1485 lease
->address
= ack
->yiaddr
;
1487 if (lease
->address
== INADDR_ANY
||
1488 lease
->server_address
== INADDR_ANY
||
1489 lease
->lifetime
== 0) {
1490 log_dhcp_client(client
, "received lease lacks address, server "
1491 "address or lease lifetime, ignoring");
1495 if (lease
->subnet_mask
== INADDR_ANY
) {
1496 r
= dhcp_lease_set_default_subnet_mask(lease
);
1498 log_dhcp_client(client
,
1499 "received lease lacks subnet mask, "
1500 "and a fallback one cannot be generated, ignoring");
1505 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1506 if (client
->lease
) {
1507 if (lease_equal(client
->lease
, lease
))
1508 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1510 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1512 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1515 client
->lease
= TAKE_PTR(lease
);
1517 log_dhcp_client(client
, "ACK");
1522 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1524 assert(client
->request_sent
);
1525 assert(lifetime
> 0);
1532 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1533 + (random_u32() & 0x1fffff);
1536 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1538 uint64_t lifetime_timeout
;
1539 uint64_t t2_timeout
;
1540 uint64_t t1_timeout
;
1541 char time_string
[FORMAT_TIMESPAN_MAX
];
1545 assert(client
->event
);
1546 assert(client
->lease
);
1547 assert(client
->lease
->lifetime
);
1549 /* don't set timers for infinite leases */
1550 if (client
->lease
->lifetime
== 0xffffffff) {
1551 (void) event_source_disable(client
->timeout_t1
);
1552 (void) event_source_disable(client
->timeout_t2
);
1553 (void) event_source_disable(client
->timeout_expire
);
1558 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1561 assert(client
->request_sent
<= time_now
);
1563 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1564 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1565 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1566 /* both T1 and T2 are given */
1567 if (client
->lease
->t1
< client
->lease
->t2
&&
1568 client
->lease
->t2
< client
->lease
->lifetime
) {
1569 /* they are both valid */
1570 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1571 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1574 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1575 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1576 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1577 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1579 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1580 /* only T2 is given, and it is valid */
1581 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1582 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1583 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1584 if (t2_timeout
<= t1_timeout
) {
1585 /* the computed T1 would be invalid, so discard T2 */
1586 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1587 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1589 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1590 /* only T1 is given, and it is valid */
1591 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1592 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1593 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1594 if (t2_timeout
<= t1_timeout
) {
1595 /* the computed T2 would be invalid, so discard T1 */
1596 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1597 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1600 /* fall back to the default timeouts */
1601 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1602 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1603 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1604 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1607 /* arm lifetime timeout */
1608 r
= event_reset_time(client
->event
, &client
->timeout_expire
,
1609 clock_boottime_or_monotonic(),
1610 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1611 client_timeout_expire
, client
,
1612 client
->event_priority
, "dhcp4-lifetime", true);
1616 log_dhcp_client(client
, "lease expires in %s",
1617 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1619 /* don't arm earlier timeouts if this has already expired */
1620 if (lifetime_timeout
<= time_now
)
1623 /* arm T2 timeout */
1624 r
= event_reset_time(client
->event
, &client
->timeout_t2
,
1625 clock_boottime_or_monotonic(),
1626 t2_timeout
, 10 * USEC_PER_MSEC
,
1627 client_timeout_t2
, client
,
1628 client
->event_priority
, "dhcp4-t2-timeout", true);
1632 log_dhcp_client(client
, "T2 expires in %s",
1633 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1635 /* don't arm earlier timeout if this has already expired */
1636 if (t2_timeout
<= time_now
)
1639 /* arm T1 timeout */
1640 r
= event_reset_time(client
->event
, &client
->timeout_t1
,
1641 clock_boottime_or_monotonic(),
1642 t1_timeout
, 10 * USEC_PER_MSEC
,
1643 client_timeout_t1
, client
,
1644 client
->event_priority
, "dhcp4-t1-timer", true);
1648 log_dhcp_client(client
, "T1 expires in %s",
1649 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1654 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1655 DHCP_CLIENT_DONT_DESTROY(client
);
1656 char time_string
[FORMAT_TIMESPAN_MAX
];
1657 int r
= 0, notify_event
= 0;
1660 assert(client
->event
);
1663 switch (client
->state
) {
1664 case DHCP_STATE_SELECTING
:
1666 r
= client_handle_offer(client
, message
, len
);
1669 client
->state
= DHCP_STATE_REQUESTING
;
1670 client
->attempt
= 0;
1672 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1673 clock_boottime_or_monotonic(),
1675 client_timeout_resend
, client
,
1676 client
->event_priority
, "dhcp4-resend-timer", true);
1679 } else if (r
== -ENOMSG
)
1680 /* invalid message, let's ignore it */
1685 case DHCP_STATE_REBOOTING
:
1686 case DHCP_STATE_REQUESTING
:
1687 case DHCP_STATE_RENEWING
:
1688 case DHCP_STATE_REBINDING
:
1690 r
= client_handle_ack(client
, message
, len
);
1692 client
->start_delay
= 0;
1693 (void) event_source_disable(client
->timeout_resend
);
1694 client
->receive_message
=
1695 sd_event_source_unref(client
->receive_message
);
1696 client
->fd
= asynchronous_close(client
->fd
);
1698 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1699 DHCP_STATE_REBOOTING
))
1700 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1701 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1704 client
->state
= DHCP_STATE_BOUND
;
1705 client
->attempt
= 0;
1707 client
->last_addr
= client
->lease
->address
;
1709 r
= client_set_lease_timeouts(client
);
1711 log_dhcp_client(client
, "could not set lease timeouts");
1715 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
, client
->ip_service_type
);
1717 log_dhcp_client(client
, "could not bind UDP socket");
1723 client_initialize_io_events(client
, client_receive_message_udp
);
1726 client_notify(client
, notify_event
);
1727 if (client
->state
== DHCP_STATE_STOPPED
)
1731 } else if (r
== -EADDRNOTAVAIL
) {
1732 /* got a NAK, let's restart the client */
1733 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1735 r
= client_initialize(client
);
1739 r
= client_start_delayed(client
);
1743 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1744 client
->start_delay
, USEC_PER_SEC
));
1746 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1747 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1750 } else if (r
== -ENOMSG
)
1751 /* invalid message, let's ignore it */
1756 case DHCP_STATE_BOUND
:
1757 r
= client_handle_forcerenew(client
, message
, len
);
1759 r
= client_timeout_t1(NULL
, 0, client
);
1762 } else if (r
== -ENOMSG
)
1763 /* invalid message, let's ignore it */
1768 case DHCP_STATE_INIT
:
1769 case DHCP_STATE_INIT_REBOOT
:
1773 case DHCP_STATE_STOPPED
:
1780 client_stop(client
, r
);
1785 static int client_receive_message_udp(
1791 sd_dhcp_client
*client
= userdata
;
1792 _cleanup_free_ DHCPMessage
*message
= NULL
;
1793 const uint8_t *expected_chaddr
= NULL
;
1794 uint8_t expected_hlen
= 0;
1795 ssize_t len
, buflen
;
1800 buflen
= next_datagram_size_fd(fd
);
1801 if (buflen
== -ENETDOWN
) {
1802 /* the link is down. Don't return an error or the I/O event
1803 source will be disconnected and we won't be able to receive
1804 packets again when the link comes back. */
1810 message
= malloc0(buflen
);
1814 len
= recv(fd
, message
, buflen
, 0);
1816 /* see comment above for why we shouldn't error out on ENETDOWN. */
1817 if (IN_SET(errno
, EAGAIN
, EINTR
, ENETDOWN
))
1820 return log_dhcp_client_errno(client
, errno
,
1821 "Could not receive message from UDP socket: %m");
1823 if ((size_t) len
< sizeof(DHCPMessage
)) {
1824 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1828 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1829 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1833 if (message
->op
!= BOOTREPLY
) {
1834 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1838 if (message
->htype
!= client
->arp_type
) {
1839 log_dhcp_client(client
, "Packet type does not match client type");
1843 if (client
->arp_type
== ARPHRD_ETHER
) {
1844 expected_hlen
= ETH_ALEN
;
1845 expected_chaddr
= &client
->mac_addr
[0];
1848 if (message
->hlen
!= expected_hlen
) {
1849 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1853 if (expected_hlen
> 0 && memcmp(&message
->chaddr
[0], expected_chaddr
, expected_hlen
)) {
1854 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1858 if (client
->state
!= DHCP_STATE_BOUND
&&
1859 be32toh(message
->xid
) != client
->xid
) {
1860 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1861 so ignore the xid in this case */
1862 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1863 be32toh(message
->xid
), client
->xid
);
1867 return client_handle_message(client
, message
, len
);
1870 static int client_receive_message_raw(
1876 sd_dhcp_client
*client
= userdata
;
1877 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1878 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1879 struct iovec iov
= {};
1880 struct msghdr msg
= {
1883 .msg_control
= cmsgbuf
,
1884 .msg_controllen
= sizeof(cmsgbuf
),
1886 struct cmsghdr
*cmsg
;
1887 bool checksum
= true;
1888 ssize_t buflen
, len
;
1894 buflen
= next_datagram_size_fd(fd
);
1895 if (buflen
== -ENETDOWN
)
1900 packet
= malloc0(buflen
);
1904 iov
= IOVEC_MAKE(packet
, buflen
);
1906 len
= recvmsg(fd
, &msg
, 0);
1908 if (IN_SET(errno
, EAGAIN
, EINTR
, ENETDOWN
))
1911 return log_dhcp_client_errno(client
, errno
,
1912 "Could not receive message from raw socket: %m");
1913 } else if ((size_t)len
< sizeof(DHCPPacket
))
1916 CMSG_FOREACH(cmsg
, &msg
)
1917 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1918 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1919 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1920 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1922 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1926 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1930 len
-= DHCP_IP_UDP_SIZE
;
1932 return client_handle_message(client
, &packet
->dhcp
, len
);
1935 int sd_dhcp_client_send_renew(sd_dhcp_client
*client
) {
1936 assert_return(client
, -EINVAL
);
1937 assert_return(client
->fd
>= 0, -EINVAL
);
1939 client
->start_delay
= 0;
1940 client
->attempt
= 1;
1941 client
->state
= DHCP_STATE_RENEWING
;
1943 return client_initialize_time_events(client
);
1946 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1949 assert_return(client
, -EINVAL
);
1951 r
= client_initialize(client
);
1955 /* RFC7844 section 3.3:
1956 SHOULD perform a complete four-way handshake, starting with a
1957 DHCPDISCOVER, to obtain a new address lease. If the client can
1958 ascertain that this is exactly the same network to which it was
1959 previously connected, and if the link-layer address did not change,
1960 the client MAY issue a DHCPREQUEST to try to reclaim the current
1962 if (client
->last_addr
&& !client
->anonymize
)
1963 client
->state
= DHCP_STATE_INIT_REBOOT
;
1965 r
= client_start(client
);
1967 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1972 int sd_dhcp_client_send_release(sd_dhcp_client
*client
) {
1973 assert_return(client
, -EINVAL
);
1974 assert_return(client
->state
!= DHCP_STATE_STOPPED
, -ESTALE
);
1975 assert_return(client
->lease
, -EUNATCH
);
1977 _cleanup_free_ DHCPPacket
*release
= NULL
;
1978 size_t optoffset
, optlen
;
1981 r
= client_message_init(client
, &release
, DHCP_RELEASE
, &optlen
, &optoffset
);
1985 /* Fill up release IP and MAC */
1986 release
->dhcp
.ciaddr
= client
->lease
->address
;
1987 memcpy(&release
->dhcp
.chaddr
, &client
->mac_addr
, client
->mac_addr_len
);
1989 r
= dhcp_option_append(&release
->dhcp
, optlen
, &optoffset
, 0,
1990 SD_DHCP_OPTION_END
, 0, NULL
);
1994 r
= dhcp_network_send_udp_socket(client
->fd
,
1995 client
->lease
->server_address
,
1998 sizeof(DHCPMessage
) + optoffset
);
2002 log_dhcp_client(client
, "RELEASE");
2007 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
2008 DHCP_CLIENT_DONT_DESTROY(client
);
2010 assert_return(client
, -EINVAL
);
2012 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
2013 client
->state
= DHCP_STATE_STOPPED
;
2018 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
2021 assert_return(client
, -EINVAL
);
2022 assert_return(!client
->event
, -EBUSY
);
2025 client
->event
= sd_event_ref(event
);
2027 r
= sd_event_default(&client
->event
);
2032 client
->event_priority
= priority
;
2037 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
2038 assert_return(client
, -EINVAL
);
2040 client
->event
= sd_event_unref(client
->event
);
2045 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
2046 assert_return(client
, NULL
);
2048 return client
->event
;
2051 static sd_dhcp_client
*dhcp_client_free(sd_dhcp_client
*client
) {
2055 log_dhcp_client(client
, "FREE");
2057 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
2058 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
2059 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
2060 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
2062 client_initialize(client
);
2064 sd_dhcp_client_detach_event(client
);
2066 sd_dhcp_lease_unref(client
->lease
);
2068 free(client
->req_opts
);
2069 free(client
->hostname
);
2070 free(client
->vendor_class_identifier
);
2071 client
->user_class
= strv_free(client
->user_class
);
2072 ordered_hashmap_free(client
->options
);
2073 return mfree(client
);
2076 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client
, sd_dhcp_client
, dhcp_client_free
);
2078 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
2079 assert_return(ret
, -EINVAL
);
2081 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= new(sd_dhcp_client
, 1);
2085 *client
= (sd_dhcp_client
) {
2087 .state
= DHCP_STATE_INIT
,
2090 .mtu
= DHCP_DEFAULT_MIN_SIZE
,
2091 .port
= DHCP_PORT_CLIENT
,
2092 .anonymize
= !!anonymize
,
2093 .max_attempts
= (uint64_t) -1,
2094 .ip_service_type
= -1,
2096 /* NOTE: this could be moved to a function. */
2098 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
2099 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
2101 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
2102 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
2104 if (!client
->req_opts
)
2107 *ret
= TAKE_PTR(client
);