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>
12 #include <sys/ioctl.h>
13 #include <linux/if_infiniband.h>
15 #include "sd-dhcp-client.h"
17 #include "alloc-util.h"
19 #include "dhcp-identifier.h"
20 #include "dhcp-internal.h"
21 #include "dhcp-lease-internal.h"
22 #include "dhcp-protocol.h"
23 #include "dns-domain.h"
24 #include "event-util.h"
25 #include "hostname-util.h"
27 #include "memory-util.h"
28 #include "random-util.h"
29 #include "string-util.h"
32 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
33 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
35 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
36 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
38 struct sd_dhcp_client
{
44 sd_event_source
*timeout_resend
;
48 union sockaddr_union link
;
49 sd_event_source
*receive_message
;
50 bool request_broadcast
;
52 size_t req_opts_allocated
;
56 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
63 /* 0: Generic (non-LL) (RFC 2132) */
64 uint8_t data
[MAX_CLIENT_ID_LEN
];
67 /* 1: Ethernet Link-Layer (RFC 2132) */
68 uint8_t haddr
[ETH_ALEN
];
71 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
75 /* 255: Node-specific (RFC 4361) */
80 uint8_t data
[MAX_CLIENT_ID_LEN
];
86 char *vendor_class_identifier
;
92 uint64_t max_attempts
;
94 sd_event_source
*timeout_t1
;
95 sd_event_source
*timeout_t2
;
96 sd_event_source
*timeout_expire
;
97 sd_dhcp_client_callback_t callback
;
103 static const uint8_t default_req_opts
[] = {
104 SD_DHCP_OPTION_SUBNET_MASK
,
105 SD_DHCP_OPTION_ROUTER
,
106 SD_DHCP_OPTION_HOST_NAME
,
107 SD_DHCP_OPTION_DOMAIN_NAME
,
108 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
,
111 /* RFC7844 section 3:
112 MAY contain the Parameter Request List option.
114 The client intending to protect its privacy SHOULD only request a
115 minimal number of options in the PRL and SHOULD also randomly shuffle
116 the ordering of option codes in the PRL. If this random ordering
117 cannot be implemented, the client MAY order the option codes in the
118 PRL by option code number (lowest to highest).
120 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
121 static const uint8_t default_req_opts_anonymize
[] = {
122 SD_DHCP_OPTION_SUBNET_MASK
, /* 1 */
123 SD_DHCP_OPTION_ROUTER
, /* 3 */
124 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
, /* 6 */
125 SD_DHCP_OPTION_DOMAIN_NAME
, /* 15 */
126 SD_DHCP_OPTION_ROUTER_DISCOVER
, /* 31 */
127 SD_DHCP_OPTION_STATIC_ROUTE
, /* 33 */
128 SD_DHCP_OPTION_VENDOR_SPECIFIC
, /* 43 */
129 SD_DHCP_OPTION_NETBIOS_NAMESERVER
, /* 44 */
130 SD_DHCP_OPTION_NETBIOS_NODETYPE
, /* 46 */
131 SD_DHCP_OPTION_NETBIOS_SCOPE
, /* 47 */
132 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
, /* 121 */
133 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE
, /* 249 */
134 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY
, /* 252 */
137 static int client_receive_message_raw(
142 static int client_receive_message_udp(
147 static void client_stop(sd_dhcp_client
*client
, int error
);
149 int sd_dhcp_client_set_callback(
150 sd_dhcp_client
*client
,
151 sd_dhcp_client_callback_t cb
,
154 assert_return(client
, -EINVAL
);
156 client
->callback
= cb
;
157 client
->userdata
= userdata
;
162 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client
*client
, int broadcast
) {
163 assert_return(client
, -EINVAL
);
165 client
->request_broadcast
= !!broadcast
;
170 int sd_dhcp_client_set_request_option(sd_dhcp_client
*client
, uint8_t option
) {
173 assert_return(client
, -EINVAL
);
174 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
178 case SD_DHCP_OPTION_PAD
:
179 case SD_DHCP_OPTION_OVERLOAD
:
180 case SD_DHCP_OPTION_MESSAGE_TYPE
:
181 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
:
182 case SD_DHCP_OPTION_END
:
189 for (i
= 0; i
< client
->req_opts_size
; i
++)
190 if (client
->req_opts
[i
] == option
)
193 if (!GREEDY_REALLOC(client
->req_opts
, client
->req_opts_allocated
,
194 client
->req_opts_size
+ 1))
197 client
->req_opts
[client
->req_opts_size
++] = option
;
202 int sd_dhcp_client_set_request_address(
203 sd_dhcp_client
*client
,
204 const struct in_addr
*last_addr
) {
206 assert_return(client
, -EINVAL
);
207 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
210 client
->last_addr
= last_addr
->s_addr
;
212 client
->last_addr
= INADDR_ANY
;
217 int sd_dhcp_client_set_ifindex(sd_dhcp_client
*client
, int ifindex
) {
219 assert_return(client
, -EINVAL
);
220 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
221 assert_return(ifindex
> 0, -EINVAL
);
223 client
->ifindex
= ifindex
;
227 int sd_dhcp_client_set_mac(
228 sd_dhcp_client
*client
,
233 DHCP_CLIENT_DONT_DESTROY(client
);
234 bool need_restart
= false;
236 assert_return(client
, -EINVAL
);
237 assert_return(addr
, -EINVAL
);
238 assert_return(addr_len
> 0 && addr_len
<= MAX_MAC_ADDR_LEN
, -EINVAL
);
239 assert_return(arp_type
> 0, -EINVAL
);
241 if (arp_type
== ARPHRD_ETHER
)
242 assert_return(addr_len
== ETH_ALEN
, -EINVAL
);
243 else if (arp_type
== ARPHRD_INFINIBAND
)
244 assert_return(addr_len
== INFINIBAND_ALEN
, -EINVAL
);
248 if (client
->mac_addr_len
== addr_len
&&
249 memcmp(&client
->mac_addr
, addr
, addr_len
) == 0)
252 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
253 log_dhcp_client(client
, "Changing MAC address on running DHCP client, restarting");
255 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
258 memcpy(&client
->mac_addr
, addr
, addr_len
);
259 client
->mac_addr_len
= addr_len
;
260 client
->arp_type
= arp_type
;
262 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
263 sd_dhcp_client_start(client
);
268 int sd_dhcp_client_get_client_id(
269 sd_dhcp_client
*client
,
271 const uint8_t **data
,
274 assert_return(client
, -EINVAL
);
275 assert_return(type
, -EINVAL
);
276 assert_return(data
, -EINVAL
);
277 assert_return(data_len
, -EINVAL
);
282 if (client
->client_id_len
) {
283 *type
= client
->client_id
.type
;
284 *data
= client
->client_id
.raw
.data
;
285 *data_len
= client
->client_id_len
- sizeof(client
->client_id
.type
);
291 int sd_dhcp_client_set_client_id(
292 sd_dhcp_client
*client
,
297 DHCP_CLIENT_DONT_DESTROY(client
);
298 bool need_restart
= false;
300 assert_return(client
, -EINVAL
);
301 assert_return(data
, -EINVAL
);
302 assert_return(data_len
> 0 && data_len
<= MAX_CLIENT_ID_LEN
, -EINVAL
);
304 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
305 client
->client_id
.type
== type
&&
306 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
309 /* For hardware types, log debug message about unexpected data length.
311 * Note that infiniband's INFINIBAND_ALEN is 20 bytes long, but only
312 * last last 8 bytes of the address are stable and suitable to put into
313 * the client-id. The caller is advised to account for that. */
314 if ((type
== ARPHRD_ETHER
&& data_len
!= ETH_ALEN
) ||
315 (type
== ARPHRD_INFINIBAND
&& data_len
!= 8))
316 log_dhcp_client(client
, "Changing client ID to hardware type %u with "
317 "unexpected address length %zu",
320 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
321 log_dhcp_client(client
, "Changing client ID on running DHCP "
322 "client, restarting");
324 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
327 client
->client_id
.type
= type
;
328 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
329 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
331 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
332 sd_dhcp_client_start(client
);
338 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
339 * without further modification. Otherwise, if duid_type is supported, DUID
340 * is set based on that type. Otherwise, an error is returned.
342 static int dhcp_client_set_iaid_duid_internal(
343 sd_dhcp_client
*client
,
352 DHCP_CLIENT_DONT_DESTROY(client
);
356 assert_return(client
, -EINVAL
);
357 assert_return(duid_len
== 0 || duid
, -EINVAL
);
360 r
= dhcp_validate_duid_len(duid_type
, duid_len
, true);
365 zero(client
->client_id
);
366 client
->client_id
.type
= 255;
370 client
->client_id
.ns
.iaid
= htobe32(iaid
);
372 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
373 client
->mac_addr_len
,
375 &client
->client_id
.ns
.iaid
);
382 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
383 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
384 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
388 if (client
->mac_addr_len
== 0)
391 r
= dhcp_identifier_set_duid_llt(&client
->client_id
.ns
.duid
, llt_time
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
396 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
401 if (client
->mac_addr_len
== 0)
404 r
= dhcp_identifier_set_duid_ll(&client
->client_id
.ns
.duid
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
409 r
= dhcp_identifier_set_duid_uuid(&client
->client_id
.ns
.duid
, &len
);
417 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
418 (iaid_append
? sizeof(client
->client_id
.ns
.iaid
) : 0);
420 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
421 log_dhcp_client(client
, "Configured %sDUID, restarting.", iaid_append
? "IAID+" : "");
422 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
423 sd_dhcp_client_start(client
);
429 int sd_dhcp_client_set_iaid_duid(
430 sd_dhcp_client
*client
,
436 return dhcp_client_set_iaid_duid_internal(client
, true, iaid_set
, iaid
, duid_type
, duid
, duid_len
, 0);
439 int sd_dhcp_client_set_iaid_duid_llt(
440 sd_dhcp_client
*client
,
444 return dhcp_client_set_iaid_duid_internal(client
, true, iaid_set
, iaid
, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
447 int sd_dhcp_client_set_duid(
448 sd_dhcp_client
*client
,
452 return dhcp_client_set_iaid_duid_internal(client
, false, false, 0, duid_type
, duid
, duid_len
, 0);
455 int sd_dhcp_client_set_duid_llt(
456 sd_dhcp_client
*client
,
458 return dhcp_client_set_iaid_duid_internal(client
, false, false, 0, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
461 int sd_dhcp_client_set_hostname(
462 sd_dhcp_client
*client
,
463 const char *hostname
) {
465 assert_return(client
, -EINVAL
);
467 /* Make sure hostnames qualify as DNS and as Linux hostnames */
469 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
472 return free_and_strdup(&client
->hostname
, hostname
);
475 int sd_dhcp_client_set_vendor_class_identifier(
476 sd_dhcp_client
*client
,
479 assert_return(client
, -EINVAL
);
481 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
484 int sd_dhcp_client_set_user_class(
485 sd_dhcp_client
*client
,
486 const char* const* user_class
) {
488 _cleanup_strv_free_
char **s
= NULL
;
491 STRV_FOREACH(p
, (char **) user_class
)
492 if (strlen(*p
) > 255)
493 return -ENAMETOOLONG
;
495 s
= strv_copy((char **) user_class
);
499 client
->user_class
= TAKE_PTR(s
);
504 int sd_dhcp_client_set_client_port(
505 sd_dhcp_client
*client
,
508 assert_return(client
, -EINVAL
);
515 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
516 assert_return(client
, -EINVAL
);
517 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
524 int sd_dhcp_client_set_max_attempts(sd_dhcp_client
*client
, uint64_t max_attempts
) {
525 assert_return(client
, -EINVAL
);
527 client
->max_attempts
= max_attempts
;
532 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
533 assert_return(client
, -EINVAL
);
535 if (!IN_SET(client
->state
, DHCP_STATE_SELECTING
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
536 return -EADDRNOTAVAIL
;
539 *ret
= client
->lease
;
544 static int client_notify(sd_dhcp_client
*client
, int event
) {
547 if (client
->callback
)
548 return client
->callback(client
, event
, client
->userdata
);
553 static int client_initialize(sd_dhcp_client
*client
) {
554 assert_return(client
, -EINVAL
);
556 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
558 client
->fd
= asynchronous_close(client
->fd
);
560 (void) event_source_disable(client
->timeout_resend
);
561 (void) event_source_disable(client
->timeout_t1
);
562 (void) event_source_disable(client
->timeout_t2
);
563 (void) event_source_disable(client
->timeout_expire
);
567 client
->state
= DHCP_STATE_INIT
;
570 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
575 static void client_stop(sd_dhcp_client
*client
, int error
) {
579 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
580 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
581 log_dhcp_client(client
, "STOPPED");
583 log_dhcp_client(client
, "STOPPED: Unknown event");
585 client_notify(client
, error
);
587 client_initialize(client
);
590 static int client_message_init(
591 sd_dhcp_client
*client
,
595 size_t *_optoffset
) {
597 _cleanup_free_ DHCPPacket
*packet
= NULL
;
598 size_t optlen
, optoffset
, size
;
605 assert(client
->start_time
);
609 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
, DHCP_RELEASE
));
611 optlen
= DHCP_MIN_OPTIONS_SIZE
;
612 size
= sizeof(DHCPPacket
) + optlen
;
614 packet
= malloc0(size
);
618 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
619 client
->arp_type
, optlen
, &optoffset
);
623 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
624 refuse to issue an DHCP lease if 'secs' is set to zero */
625 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
628 assert(time_now
>= client
->start_time
);
630 /* seconds between sending first and last DISCOVER
631 * must always be strictly positive to deal with broken servers */
632 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
633 packet
->dhcp
.secs
= htobe16(secs
);
635 /* RFC2132 section 4.1
636 A client that cannot receive unicast IP datagrams until its protocol
637 software has been configured with an IP address SHOULD set the
638 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
639 DHCPREQUEST messages that client sends. The BROADCAST bit will
640 provide a hint to the DHCP server and BOOTP relay agent to broadcast
641 any messages to the client on the client's subnet.
643 Note: some interfaces needs this to be enabled, but some networks
644 needs this to be disabled as broadcasts are filteretd, so this
645 needs to be configurable */
646 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
647 packet
->dhcp
.flags
= htobe16(0x8000);
649 /* RFC2132 section 4.1.1:
650 The client MUST include its hardware address in the ’chaddr’ field, if
651 necessary for delivery of DHCP reply messages. Non-Ethernet
652 interfaces will leave 'chaddr' empty and use the client identifier
653 instead (eg, RFC 4390 section 2.1).
655 if (client
->arp_type
== ARPHRD_ETHER
)
656 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
658 /* If no client identifier exists, construct an RFC 4361-compliant one */
659 if (client
->client_id_len
== 0) {
662 client
->client_id
.type
= 255;
664 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
,
665 true, &client
->client_id
.ns
.iaid
);
669 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
673 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
676 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
677 Identifier option is not set */
678 if (client
->client_id_len
) {
679 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
680 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
681 client
->client_id_len
,
687 /* RFC2131 section 3.5:
688 in its initial DHCPDISCOVER or DHCPREQUEST message, a
689 client may provide the server with a list of specific
690 parameters the client is interested in. If the client
691 includes a list of parameters in a DHCPDISCOVER message,
692 it MUST include that list in any subsequent DHCPREQUEST
696 /* RFC7844 section 3:
697 MAY contain the Parameter Request List option. */
698 /* NOTE: in case that there would be an option to do not send
699 * any PRL at all, the size should be checked before sending */
700 if (client
->req_opts_size
> 0 && type
!= DHCP_RELEASE
) {
701 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
702 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
703 client
->req_opts_size
, client
->req_opts
);
708 /* RFC2131 section 3.5:
709 The client SHOULD include the ’maximum DHCP message size’ option to
710 let the server know how large the server may make its DHCP messages.
712 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
713 than the defined default size unless the Maximum Message Size option
716 RFC3442 "Requirements to Avoid Sizing Constraints":
717 Because a full routing table can be quite large, the standard 576
718 octet maximum size for a DHCP message may be too short to contain
719 some legitimate Classless Static Route options. Because of this,
720 clients implementing the Classless Static Route option SHOULD send a
721 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
722 stack is capable of receiving larger IP datagrams. In this case, the
723 client SHOULD set the value of this option to at least the MTU of the
724 interface that the client is configuring. The client MAY set the
725 value of this option higher, up to the size of the largest UDP packet
726 it is prepared to accept. (Note that the value specified in the
727 Maximum DHCP Message Size option is the total maximum packet size,
728 including IP and UDP headers.)
730 /* RFC7844 section 3:
731 SHOULD NOT contain any other option. */
732 if (!client
->anonymize
&& type
!= DHCP_RELEASE
) {
733 max_size
= htobe16(size
);
734 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
735 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
742 *_optoffset
= optoffset
;
743 *ret
= TAKE_PTR(packet
);
748 static int client_append_fqdn_option(
749 DHCPMessage
*message
,
754 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
757 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
758 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
759 buffer
[1] = 0; /* RCODE1 (deprecated) */
760 buffer
[2] = 0; /* RCODE2 (deprecated) */
762 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
764 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
765 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
770 static int dhcp_client_send_raw(
771 sd_dhcp_client
*client
,
775 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
776 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
778 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
782 static int client_send_discover(sd_dhcp_client
*client
) {
783 _cleanup_free_ DHCPPacket
*discover
= NULL
;
784 size_t optoffset
, optlen
;
788 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
790 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
791 &optlen
, &optoffset
);
795 /* the client may suggest values for the network address
796 and lease time in the DHCPDISCOVER message. The client may include
797 the ’requested IP address’ option to suggest that a particular IP
798 address be assigned, and may include the ’IP address lease time’
799 option to suggest the lease time it would like.
801 if (client
->last_addr
!= INADDR_ANY
) {
802 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
803 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
804 4, &client
->last_addr
);
809 if (client
->hostname
) {
810 /* According to RFC 4702 "clients that send the Client FQDN option in
811 their messages MUST NOT also send the Host Name option". Just send
812 one of the two depending on the hostname type.
814 if (dns_name_is_single_label(client
->hostname
)) {
815 /* it is unclear from RFC 2131 if client should send hostname in
816 DHCPDISCOVER but dhclient does and so we do as well
818 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
819 SD_DHCP_OPTION_HOST_NAME
,
820 strlen(client
->hostname
), client
->hostname
);
822 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
828 if (client
->vendor_class_identifier
) {
829 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
830 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
831 strlen(client
->vendor_class_identifier
),
832 client
->vendor_class_identifier
);
837 if (client
->user_class
) {
838 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
839 SD_DHCP_OPTION_USER_CLASS
,
840 strv_length(client
->user_class
),
846 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
847 SD_DHCP_OPTION_END
, 0, NULL
);
851 /* We currently ignore:
852 The client SHOULD wait a random time between one and ten seconds to
853 desynchronize the use of DHCP at startup.
855 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
859 log_dhcp_client(client
, "DISCOVER");
864 static int client_send_release(sd_dhcp_client
*client
) {
865 _cleanup_free_ DHCPPacket
*release
= NULL
;
866 size_t optoffset
, optlen
;
870 assert(!IN_SET(client
->state
, DHCP_STATE_STOPPED
));
872 r
= client_message_init(client
, &release
, DHCP_RELEASE
,
873 &optlen
, &optoffset
);
877 /* Fill up release IP and MAC */
878 release
->dhcp
.ciaddr
= client
->lease
->address
;
879 memcpy(&release
->dhcp
.chaddr
, &client
->mac_addr
, client
->mac_addr_len
);
881 r
= dhcp_option_append(&release
->dhcp
, optlen
, &optoffset
, 0,
882 SD_DHCP_OPTION_END
, 0, NULL
);
886 r
= dhcp_network_send_udp_socket(client
->fd
,
887 client
->lease
->server_address
,
890 sizeof(DHCPMessage
) + optoffset
);
894 log_dhcp_client(client
, "RELEASE");
899 static int client_send_request(sd_dhcp_client
*client
) {
900 _cleanup_free_ DHCPPacket
*request
= NULL
;
901 size_t optoffset
, optlen
;
906 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
910 switch (client
->state
) {
911 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
912 SELECTING should be REQUESTING)
915 case DHCP_STATE_REQUESTING
:
916 /* Client inserts the address of the selected server in ’server
917 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
918 filled in with the yiaddr value from the chosen DHCPOFFER.
921 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
922 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
923 4, &client
->lease
->server_address
);
927 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
928 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
929 4, &client
->lease
->address
);
935 case DHCP_STATE_INIT_REBOOT
:
936 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
937 option MUST be filled in with client’s notion of its previously
938 assigned address. ’ciaddr’ MUST be zero.
940 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
941 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
942 4, &client
->last_addr
);
947 case DHCP_STATE_RENEWING
:
948 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
949 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
953 case DHCP_STATE_REBINDING
:
954 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
955 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
958 This message MUST be broadcast to the 0xffffffff IP broadcast address.
960 request
->dhcp
.ciaddr
= client
->lease
->address
;
964 case DHCP_STATE_INIT
:
965 case DHCP_STATE_SELECTING
:
966 case DHCP_STATE_REBOOTING
:
967 case DHCP_STATE_BOUND
:
968 case DHCP_STATE_STOPPED
:
972 if (client
->hostname
) {
973 if (dns_name_is_single_label(client
->hostname
))
974 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
975 SD_DHCP_OPTION_HOST_NAME
,
976 strlen(client
->hostname
), client
->hostname
);
978 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
984 if (client
->vendor_class_identifier
) {
985 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
986 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
987 strlen(client
->vendor_class_identifier
),
988 client
->vendor_class_identifier
);
993 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
994 SD_DHCP_OPTION_END
, 0, NULL
);
998 if (client
->state
== DHCP_STATE_RENEWING
) {
999 r
= dhcp_network_send_udp_socket(client
->fd
,
1000 client
->lease
->server_address
,
1003 sizeof(DHCPMessage
) + optoffset
);
1005 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
1010 switch (client
->state
) {
1012 case DHCP_STATE_REQUESTING
:
1013 log_dhcp_client(client
, "REQUEST (requesting)");
1016 case DHCP_STATE_INIT_REBOOT
:
1017 log_dhcp_client(client
, "REQUEST (init-reboot)");
1020 case DHCP_STATE_RENEWING
:
1021 log_dhcp_client(client
, "REQUEST (renewing)");
1024 case DHCP_STATE_REBINDING
:
1025 log_dhcp_client(client
, "REQUEST (rebinding)");
1029 log_dhcp_client(client
, "REQUEST (invalid)");
1036 static int client_start(sd_dhcp_client
*client
);
1038 static int client_timeout_resend(
1043 sd_dhcp_client
*client
= userdata
;
1044 DHCP_CLIENT_DONT_DESTROY(client
);
1045 usec_t next_timeout
= 0;
1052 assert(client
->event
);
1054 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1058 switch (client
->state
) {
1060 case DHCP_STATE_RENEWING
:
1062 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
1066 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1070 case DHCP_STATE_REBINDING
:
1072 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
1076 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1079 case DHCP_STATE_REBOOTING
:
1080 /* start over as we did not receive a timely ack or nak */
1081 r
= client_initialize(client
);
1085 r
= client_start(client
);
1089 log_dhcp_client(client
, "REBOOTED");
1093 case DHCP_STATE_INIT
:
1094 case DHCP_STATE_INIT_REBOOT
:
1095 case DHCP_STATE_SELECTING
:
1096 case DHCP_STATE_REQUESTING
:
1097 case DHCP_STATE_BOUND
:
1099 if (client
->attempt
< client
->max_attempts
)
1104 next_timeout
= time_now
+ ((UINT64_C(1) << MIN(client
->attempt
, (uint64_t) 6)) - 1) * USEC_PER_SEC
;
1108 case DHCP_STATE_STOPPED
:
1113 next_timeout
+= (random_u32() & 0x1fffff);
1115 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1116 clock_boottime_or_monotonic(),
1117 next_timeout
, 10 * USEC_PER_MSEC
,
1118 client_timeout_resend
, client
,
1119 client
->event_priority
, "dhcp4-resend-timer", true);
1123 switch (client
->state
) {
1124 case DHCP_STATE_INIT
:
1125 r
= client_send_discover(client
);
1127 client
->state
= DHCP_STATE_SELECTING
;
1128 client
->attempt
= 0;
1129 } else if (client
->attempt
>= client
->max_attempts
)
1134 case DHCP_STATE_SELECTING
:
1135 r
= client_send_discover(client
);
1136 if (r
< 0 && client
->attempt
>= client
->max_attempts
)
1141 case DHCP_STATE_INIT_REBOOT
:
1142 case DHCP_STATE_REQUESTING
:
1143 case DHCP_STATE_RENEWING
:
1144 case DHCP_STATE_REBINDING
:
1145 r
= client_send_request(client
);
1146 if (r
< 0 && client
->attempt
>= client
->max_attempts
)
1149 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1150 client
->state
= DHCP_STATE_REBOOTING
;
1152 client
->request_sent
= time_now
;
1156 case DHCP_STATE_REBOOTING
:
1157 case DHCP_STATE_BOUND
:
1161 case DHCP_STATE_STOPPED
:
1169 client_stop(client
, r
);
1171 /* Errors were dealt with when stopping the client, don't spill
1172 errors into the event loop handler */
1176 static int client_initialize_io_events(
1177 sd_dhcp_client
*client
,
1178 sd_event_io_handler_t io_callback
) {
1183 assert(client
->event
);
1185 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1186 client
->fd
, EPOLLIN
, io_callback
,
1191 r
= sd_event_source_set_priority(client
->receive_message
,
1192 client
->event_priority
);
1196 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1202 client_stop(client
, r
);
1207 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1212 assert(client
->event
);
1214 if (client
->start_delay
) {
1215 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1216 usec
+= client
->start_delay
;
1219 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1220 clock_boottime_or_monotonic(),
1222 client_timeout_resend
, client
,
1223 client
->event_priority
, "dhcp4-resend-timer", true);
1225 client_stop(client
, r
);
1231 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1232 client_initialize_io_events(client
, io_callback
);
1233 client_initialize_time_events(client
);
1238 static int client_start_delayed(sd_dhcp_client
*client
) {
1241 assert_return(client
, -EINVAL
);
1242 assert_return(client
->event
, -EINVAL
);
1243 assert_return(client
->ifindex
> 0, -EINVAL
);
1244 assert_return(client
->fd
< 0, -EBUSY
);
1245 assert_return(client
->xid
== 0, -EINVAL
);
1246 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1248 client
->xid
= random_u32();
1250 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1251 client
->xid
, client
->mac_addr
,
1252 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1254 client_stop(client
, r
);
1259 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1260 client
->start_time
= now(clock_boottime_or_monotonic());
1262 return client_initialize_events(client
, client_receive_message_raw
);
1265 static int client_start(sd_dhcp_client
*client
) {
1266 client
->start_delay
= 0;
1267 return client_start_delayed(client
);
1270 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1271 sd_dhcp_client
*client
= userdata
;
1272 DHCP_CLIENT_DONT_DESTROY(client
);
1274 log_dhcp_client(client
, "EXPIRED");
1276 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1278 /* lease was lost, start over if not freed or stopped in callback */
1279 if (client
->state
!= DHCP_STATE_STOPPED
) {
1280 client_initialize(client
);
1281 client_start(client
);
1287 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1288 sd_dhcp_client
*client
= userdata
;
1289 DHCP_CLIENT_DONT_DESTROY(client
);
1294 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1295 client
->fd
= asynchronous_close(client
->fd
);
1297 client
->state
= DHCP_STATE_REBINDING
;
1298 client
->attempt
= 0;
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
,
1305 client_stop(client
, r
);
1310 return client_initialize_events(client
, client_receive_message_raw
);
1313 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1314 sd_dhcp_client
*client
= userdata
;
1315 DHCP_CLIENT_DONT_DESTROY(client
);
1317 client
->state
= DHCP_STATE_RENEWING
;
1318 client
->attempt
= 0;
1320 return client_initialize_time_events(client
);
1323 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1324 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1327 r
= dhcp_lease_new(&lease
);
1331 if (client
->client_id_len
) {
1332 r
= dhcp_lease_set_client_id(lease
,
1333 (uint8_t *) &client
->client_id
,
1334 client
->client_id_len
);
1339 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1340 if (r
!= DHCP_OFFER
) {
1341 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1345 lease
->next_server
= offer
->siaddr
;
1346 lease
->address
= offer
->yiaddr
;
1348 if (lease
->address
== 0 ||
1349 lease
->server_address
== 0 ||
1350 lease
->lifetime
== 0) {
1351 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1355 if (!lease
->have_subnet_mask
) {
1356 r
= dhcp_lease_set_default_subnet_mask(lease
);
1358 log_dhcp_client(client
,
1359 "received lease lacks subnet mask, "
1360 "and a fallback one cannot be generated, ignoring");
1365 sd_dhcp_lease_unref(client
->lease
);
1366 client
->lease
= TAKE_PTR(lease
);
1368 if (client_notify(client
, SD_DHCP_CLIENT_EVENT_SELECTING
) < 0)
1371 log_dhcp_client(client
, "OFFER");
1376 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1379 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1380 if (r
!= DHCP_FORCERENEW
)
1383 log_dhcp_client(client
, "FORCERENEW");
1388 static bool lease_equal(const sd_dhcp_lease
*a
, const sd_dhcp_lease
*b
) {
1389 if (a
->address
!= b
->address
)
1392 if (a
->subnet_mask
!= b
->subnet_mask
)
1395 if (a
->router_size
!= b
->router_size
)
1398 for (size_t i
= 0; i
< a
->router_size
; i
++)
1399 if (a
->router
[i
].s_addr
!= b
->router
[i
].s_addr
)
1405 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1406 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1407 _cleanup_free_
char *error_message
= NULL
;
1410 r
= dhcp_lease_new(&lease
);
1414 if (client
->client_id_len
) {
1415 r
= dhcp_lease_set_client_id(lease
,
1416 (uint8_t *) &client
->client_id
,
1417 client
->client_id_len
);
1422 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1423 if (r
== DHCP_NAK
) {
1424 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1425 return -EADDRNOTAVAIL
;
1428 if (r
!= DHCP_ACK
) {
1429 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1433 lease
->next_server
= ack
->siaddr
;
1435 lease
->address
= ack
->yiaddr
;
1437 if (lease
->address
== INADDR_ANY
||
1438 lease
->server_address
== INADDR_ANY
||
1439 lease
->lifetime
== 0) {
1440 log_dhcp_client(client
, "received lease lacks address, server "
1441 "address or lease lifetime, ignoring");
1445 if (lease
->subnet_mask
== INADDR_ANY
) {
1446 r
= dhcp_lease_set_default_subnet_mask(lease
);
1448 log_dhcp_client(client
,
1449 "received lease lacks subnet mask, "
1450 "and a fallback one cannot be generated, ignoring");
1455 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1456 if (client
->lease
) {
1457 if (lease_equal(client
->lease
, lease
))
1458 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1460 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1462 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1465 client
->lease
= TAKE_PTR(lease
);
1467 log_dhcp_client(client
, "ACK");
1472 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1474 assert(client
->request_sent
);
1475 assert(lifetime
> 0);
1482 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1483 + (random_u32() & 0x1fffff);
1486 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1488 uint64_t lifetime_timeout
;
1489 uint64_t t2_timeout
;
1490 uint64_t t1_timeout
;
1491 char time_string
[FORMAT_TIMESPAN_MAX
];
1495 assert(client
->event
);
1496 assert(client
->lease
);
1497 assert(client
->lease
->lifetime
);
1499 /* don't set timers for infinite leases */
1500 if (client
->lease
->lifetime
== 0xffffffff) {
1501 (void) event_source_disable(client
->timeout_t1
);
1502 (void) event_source_disable(client
->timeout_t2
);
1503 (void) event_source_disable(client
->timeout_expire
);
1508 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1511 assert(client
->request_sent
<= time_now
);
1513 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1514 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1515 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1516 /* both T1 and T2 are given */
1517 if (client
->lease
->t1
< client
->lease
->t2
&&
1518 client
->lease
->t2
< client
->lease
->lifetime
) {
1519 /* they are both valid */
1520 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1521 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1524 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1525 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1526 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1527 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1529 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1530 /* only T2 is given, and it is valid */
1531 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1532 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1533 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1534 if (t2_timeout
<= t1_timeout
) {
1535 /* the computed T1 would be invalid, so discard T2 */
1536 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1537 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1539 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1540 /* only T1 is given, and it is valid */
1541 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1542 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1543 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1544 if (t2_timeout
<= t1_timeout
) {
1545 /* the computed T2 would be invalid, so discard T1 */
1546 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1547 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1550 /* fall back to the default timeouts */
1551 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1552 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1553 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1554 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1557 /* arm lifetime timeout */
1558 r
= event_reset_time(client
->event
, &client
->timeout_expire
,
1559 clock_boottime_or_monotonic(),
1560 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1561 client_timeout_expire
, client
,
1562 client
->event_priority
, "dhcp4-lifetime", true);
1566 log_dhcp_client(client
, "lease expires in %s",
1567 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1569 /* don't arm earlier timeouts if this has already expired */
1570 if (lifetime_timeout
<= time_now
)
1573 /* arm T2 timeout */
1574 r
= event_reset_time(client
->event
, &client
->timeout_t2
,
1575 clock_boottime_or_monotonic(),
1576 t2_timeout
, 10 * USEC_PER_MSEC
,
1577 client_timeout_t2
, client
,
1578 client
->event_priority
, "dhcp4-t2-timeout", true);
1582 log_dhcp_client(client
, "T2 expires in %s",
1583 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1585 /* don't arm earlier timeout if this has already expired */
1586 if (t2_timeout
<= time_now
)
1589 /* arm T1 timeout */
1590 r
= event_reset_time(client
->event
, &client
->timeout_t1
,
1591 clock_boottime_or_monotonic(),
1592 t1_timeout
, 10 * USEC_PER_MSEC
,
1593 client_timeout_t1
, client
,
1594 client
->event_priority
, "dhcp4-t1-timer", true);
1598 log_dhcp_client(client
, "T1 expires in %s",
1599 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1604 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1605 DHCP_CLIENT_DONT_DESTROY(client
);
1606 char time_string
[FORMAT_TIMESPAN_MAX
];
1607 int r
= 0, notify_event
= 0;
1610 assert(client
->event
);
1613 switch (client
->state
) {
1614 case DHCP_STATE_SELECTING
:
1616 r
= client_handle_offer(client
, message
, len
);
1619 client
->state
= DHCP_STATE_REQUESTING
;
1620 client
->attempt
= 0;
1622 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1623 clock_boottime_or_monotonic(),
1625 client_timeout_resend
, client
,
1626 client
->event_priority
, "dhcp4-resend-timer", true);
1629 } else if (r
== -ENOMSG
)
1630 /* invalid message, let's ignore it */
1635 case DHCP_STATE_REBOOTING
:
1636 case DHCP_STATE_REQUESTING
:
1637 case DHCP_STATE_RENEWING
:
1638 case DHCP_STATE_REBINDING
:
1640 r
= client_handle_ack(client
, message
, len
);
1642 client
->start_delay
= 0;
1643 (void) event_source_disable(client
->timeout_resend
);
1644 client
->receive_message
=
1645 sd_event_source_unref(client
->receive_message
);
1646 client
->fd
= asynchronous_close(client
->fd
);
1648 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1649 DHCP_STATE_REBOOTING
))
1650 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1651 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1654 client
->state
= DHCP_STATE_BOUND
;
1655 client
->attempt
= 0;
1657 client
->last_addr
= client
->lease
->address
;
1659 r
= client_set_lease_timeouts(client
);
1661 log_dhcp_client(client
, "could not set lease timeouts");
1665 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1667 log_dhcp_client(client
, "could not bind UDP socket");
1673 client_initialize_io_events(client
, client_receive_message_udp
);
1676 client_notify(client
, notify_event
);
1677 if (client
->state
== DHCP_STATE_STOPPED
)
1681 } else if (r
== -EADDRNOTAVAIL
) {
1682 /* got a NAK, let's restart the client */
1683 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1685 r
= client_initialize(client
);
1689 r
= client_start_delayed(client
);
1693 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1694 client
->start_delay
, USEC_PER_SEC
));
1696 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1697 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1700 } else if (r
== -ENOMSG
)
1701 /* invalid message, let's ignore it */
1706 case DHCP_STATE_BOUND
:
1707 r
= client_handle_forcerenew(client
, message
, len
);
1709 r
= client_timeout_t1(NULL
, 0, client
);
1712 } else if (r
== -ENOMSG
)
1713 /* invalid message, let's ignore it */
1718 case DHCP_STATE_INIT
:
1719 case DHCP_STATE_INIT_REBOOT
:
1723 case DHCP_STATE_STOPPED
:
1730 client_stop(client
, r
);
1735 static int client_receive_message_udp(
1741 sd_dhcp_client
*client
= userdata
;
1742 _cleanup_free_ DHCPMessage
*message
= NULL
;
1743 const uint8_t *expected_chaddr
= NULL
;
1744 uint8_t expected_hlen
= 0;
1745 ssize_t len
, buflen
;
1750 buflen
= next_datagram_size_fd(fd
);
1751 if (buflen
== -ENETDOWN
) {
1752 /* the link is down. Don't return an error or the I/O event
1753 source will be disconnected and we won't be able to receive
1754 packets again when the link comes back. */
1760 message
= malloc0(buflen
);
1764 len
= recv(fd
, message
, buflen
, 0);
1766 /* see comment above for why we shouldn't error out on ENETDOWN. */
1767 if (IN_SET(errno
, EAGAIN
, EINTR
, ENETDOWN
))
1770 return log_dhcp_client_errno(client
, errno
,
1771 "Could not receive message from UDP socket: %m");
1773 if ((size_t) len
< sizeof(DHCPMessage
)) {
1774 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1778 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1779 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1783 if (message
->op
!= BOOTREPLY
) {
1784 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1788 if (message
->htype
!= client
->arp_type
) {
1789 log_dhcp_client(client
, "Packet type does not match client type");
1793 if (client
->arp_type
== ARPHRD_ETHER
) {
1794 expected_hlen
= ETH_ALEN
;
1795 expected_chaddr
= &client
->mac_addr
[0];
1798 if (message
->hlen
!= expected_hlen
) {
1799 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1803 if (expected_hlen
> 0 && memcmp(&message
->chaddr
[0], expected_chaddr
, expected_hlen
)) {
1804 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1808 if (client
->state
!= DHCP_STATE_BOUND
&&
1809 be32toh(message
->xid
) != client
->xid
) {
1810 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1811 so ignore the xid in this case */
1812 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1813 be32toh(message
->xid
), client
->xid
);
1817 return client_handle_message(client
, message
, len
);
1820 static int client_receive_message_raw(
1826 sd_dhcp_client
*client
= userdata
;
1827 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1828 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1829 struct iovec iov
= {};
1830 struct msghdr msg
= {
1833 .msg_control
= cmsgbuf
,
1834 .msg_controllen
= sizeof(cmsgbuf
),
1836 struct cmsghdr
*cmsg
;
1837 bool checksum
= true;
1838 ssize_t buflen
, len
;
1844 buflen
= next_datagram_size_fd(fd
);
1845 if (buflen
== -ENETDOWN
)
1850 packet
= malloc0(buflen
);
1854 iov
= IOVEC_MAKE(packet
, buflen
);
1856 len
= recvmsg(fd
, &msg
, 0);
1858 if (IN_SET(errno
, EAGAIN
, EINTR
, ENETDOWN
))
1861 return log_dhcp_client_errno(client
, errno
,
1862 "Could not receive message from raw socket: %m");
1863 } else if ((size_t)len
< sizeof(DHCPPacket
))
1866 CMSG_FOREACH(cmsg
, &msg
)
1867 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1868 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1869 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1870 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1872 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1876 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1880 len
-= DHCP_IP_UDP_SIZE
;
1882 return client_handle_message(client
, &packet
->dhcp
, len
);
1885 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1888 assert_return(client
, -EINVAL
);
1890 r
= client_initialize(client
);
1894 /* RFC7844 section 3.3:
1895 SHOULD perform a complete four-way handshake, starting with a
1896 DHCPDISCOVER, to obtain a new address lease. If the client can
1897 ascertain that this is exactly the same network to which it was
1898 previously connected, and if the link-layer address did not change,
1899 the client MAY issue a DHCPREQUEST to try to reclaim the current
1901 if (client
->last_addr
&& !client
->anonymize
)
1902 client
->state
= DHCP_STATE_INIT_REBOOT
;
1904 r
= client_start(client
);
1906 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1911 int sd_dhcp_client_send_release(sd_dhcp_client
*client
) {
1912 assert_return(client
, -EINVAL
);
1914 client_send_release(client
);
1919 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1920 DHCP_CLIENT_DONT_DESTROY(client
);
1922 assert_return(client
, -EINVAL
);
1924 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1925 client
->state
= DHCP_STATE_STOPPED
;
1930 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1933 assert_return(client
, -EINVAL
);
1934 assert_return(!client
->event
, -EBUSY
);
1937 client
->event
= sd_event_ref(event
);
1939 r
= sd_event_default(&client
->event
);
1944 client
->event_priority
= priority
;
1949 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1950 assert_return(client
, -EINVAL
);
1952 client
->event
= sd_event_unref(client
->event
);
1957 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1958 assert_return(client
, NULL
);
1960 return client
->event
;
1963 static sd_dhcp_client
*dhcp_client_free(sd_dhcp_client
*client
) {
1966 log_dhcp_client(client
, "FREE");
1968 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1969 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1970 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1971 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1973 client_initialize(client
);
1975 sd_dhcp_client_detach_event(client
);
1977 sd_dhcp_lease_unref(client
->lease
);
1979 free(client
->req_opts
);
1980 free(client
->hostname
);
1981 free(client
->vendor_class_identifier
);
1982 client
->user_class
= strv_free(client
->user_class
);
1983 return mfree(client
);
1986 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client
, sd_dhcp_client
, dhcp_client_free
);
1988 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1989 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1991 assert_return(ret
, -EINVAL
);
1993 client
= new(sd_dhcp_client
, 1);
1997 *client
= (sd_dhcp_client
) {
1999 .state
= DHCP_STATE_INIT
,
2002 .mtu
= DHCP_DEFAULT_MIN_SIZE
,
2003 .port
= DHCP_PORT_CLIENT
,
2004 .anonymize
= !!anonymize
,
2005 .max_attempts
= (uint64_t) -1,
2007 /* NOTE: this could be moved to a function. */
2009 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
2010 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
2012 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
2013 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
2015 if (!client
->req_opts
)
2018 *ret
= TAKE_PTR(client
);