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 "random-util.h"
28 #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
;
93 sd_event_source
*timeout_t1
;
94 sd_event_source
*timeout_t2
;
95 sd_event_source
*timeout_expire
;
96 sd_dhcp_client_callback_t callback
;
102 static const uint8_t default_req_opts
[] = {
103 SD_DHCP_OPTION_SUBNET_MASK
,
104 SD_DHCP_OPTION_ROUTER
,
105 SD_DHCP_OPTION_HOST_NAME
,
106 SD_DHCP_OPTION_DOMAIN_NAME
,
107 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
,
110 /* RFC7844 section 3:
111 MAY contain the Parameter Request List option.
113 The client intending to protect its privacy SHOULD only request a
114 minimal number of options in the PRL and SHOULD also randomly shuffle
115 the ordering of option codes in the PRL. If this random ordering
116 cannot be implemented, the client MAY order the option codes in the
117 PRL by option code number (lowest to highest).
119 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
120 static const uint8_t default_req_opts_anonymize
[] = {
121 SD_DHCP_OPTION_SUBNET_MASK
, /* 1 */
122 SD_DHCP_OPTION_ROUTER
, /* 3 */
123 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
, /* 6 */
124 SD_DHCP_OPTION_DOMAIN_NAME
, /* 15 */
125 SD_DHCP_OPTION_ROUTER_DISCOVER
, /* 31 */
126 SD_DHCP_OPTION_STATIC_ROUTE
, /* 33 */
127 SD_DHCP_OPTION_VENDOR_SPECIFIC
, /* 43 */
128 SD_DHCP_OPTION_NETBIOS_NAMESERVER
, /* 44 */
129 SD_DHCP_OPTION_NETBIOS_NODETYPE
, /* 46 */
130 SD_DHCP_OPTION_NETBIOS_SCOPE
, /* 47 */
131 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
, /* 121 */
132 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE
, /* 249 */
133 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY
, /* 252 */
136 static int client_receive_message_raw(
141 static int client_receive_message_udp(
146 static void client_stop(sd_dhcp_client
*client
, int error
);
148 int sd_dhcp_client_set_callback(
149 sd_dhcp_client
*client
,
150 sd_dhcp_client_callback_t cb
,
153 assert_return(client
, -EINVAL
);
155 client
->callback
= cb
;
156 client
->userdata
= userdata
;
161 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client
*client
, int broadcast
) {
162 assert_return(client
, -EINVAL
);
164 client
->request_broadcast
= !!broadcast
;
169 int sd_dhcp_client_set_request_option(sd_dhcp_client
*client
, uint8_t option
) {
172 assert_return(client
, -EINVAL
);
173 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
177 case SD_DHCP_OPTION_PAD
:
178 case SD_DHCP_OPTION_OVERLOAD
:
179 case SD_DHCP_OPTION_MESSAGE_TYPE
:
180 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
:
181 case SD_DHCP_OPTION_END
:
188 for (i
= 0; i
< client
->req_opts_size
; i
++)
189 if (client
->req_opts
[i
] == option
)
192 if (!GREEDY_REALLOC(client
->req_opts
, client
->req_opts_allocated
,
193 client
->req_opts_size
+ 1))
196 client
->req_opts
[client
->req_opts_size
++] = option
;
201 int sd_dhcp_client_set_request_address(
202 sd_dhcp_client
*client
,
203 const struct in_addr
*last_addr
) {
205 assert_return(client
, -EINVAL
);
206 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
209 client
->last_addr
= last_addr
->s_addr
;
211 client
->last_addr
= INADDR_ANY
;
216 int sd_dhcp_client_set_ifindex(sd_dhcp_client
*client
, int ifindex
) {
218 assert_return(client
, -EINVAL
);
219 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
220 assert_return(ifindex
> 0, -EINVAL
);
222 client
->ifindex
= ifindex
;
226 int sd_dhcp_client_set_mac(
227 sd_dhcp_client
*client
,
232 DHCP_CLIENT_DONT_DESTROY(client
);
233 bool need_restart
= false;
235 assert_return(client
, -EINVAL
);
236 assert_return(addr
, -EINVAL
);
237 assert_return(addr_len
> 0 && addr_len
<= MAX_MAC_ADDR_LEN
, -EINVAL
);
238 assert_return(arp_type
> 0, -EINVAL
);
240 if (arp_type
== ARPHRD_ETHER
)
241 assert_return(addr_len
== ETH_ALEN
, -EINVAL
);
242 else if (arp_type
== ARPHRD_INFINIBAND
)
243 assert_return(addr_len
== INFINIBAND_ALEN
, -EINVAL
);
247 if (client
->mac_addr_len
== addr_len
&&
248 memcmp(&client
->mac_addr
, addr
, addr_len
) == 0)
251 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
252 log_dhcp_client(client
, "Changing MAC address on running DHCP client, restarting");
254 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
257 memcpy(&client
->mac_addr
, addr
, addr_len
);
258 client
->mac_addr_len
= addr_len
;
259 client
->arp_type
= arp_type
;
261 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
262 sd_dhcp_client_start(client
);
267 int sd_dhcp_client_get_client_id(
268 sd_dhcp_client
*client
,
270 const uint8_t **data
,
273 assert_return(client
, -EINVAL
);
274 assert_return(type
, -EINVAL
);
275 assert_return(data
, -EINVAL
);
276 assert_return(data_len
, -EINVAL
);
281 if (client
->client_id_len
) {
282 *type
= client
->client_id
.type
;
283 *data
= client
->client_id
.raw
.data
;
284 *data_len
= client
->client_id_len
- sizeof(client
->client_id
.type
);
290 int sd_dhcp_client_set_client_id(
291 sd_dhcp_client
*client
,
296 DHCP_CLIENT_DONT_DESTROY(client
);
297 bool need_restart
= false;
299 assert_return(client
, -EINVAL
);
300 assert_return(data
, -EINVAL
);
301 assert_return(data_len
> 0 && data_len
<= MAX_CLIENT_ID_LEN
, -EINVAL
);
306 if (data_len
!= ETH_ALEN
)
310 case ARPHRD_INFINIBAND
:
311 /* Infiniband addresses are 20 bytes (INFINIBAND_ALEN), however only
312 * the last 8 bytes are stable and suitable for putting into the client-id. */
321 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
322 client
->client_id
.type
== type
&&
323 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
326 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
327 log_dhcp_client(client
, "Changing client ID on running DHCP "
328 "client, restarting");
330 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
333 client
->client_id
.type
= type
;
334 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
335 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
337 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
338 sd_dhcp_client_start(client
);
344 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
345 * without further modification. Otherwise, if duid_type is supported, DUID
346 * is set based on that type. Otherwise, an error is returned.
348 static int dhcp_client_set_iaid_duid_internal(
349 sd_dhcp_client
*client
,
358 DHCP_CLIENT_DONT_DESTROY(client
);
362 assert_return(client
, -EINVAL
);
363 assert_return(duid_len
== 0 || duid
!= NULL
, -EINVAL
);
366 r
= dhcp_validate_duid_len(duid_type
, duid_len
);
371 zero(client
->client_id
);
372 client
->client_id
.type
= 255;
376 client
->client_id
.ns
.iaid
= htobe32(iaid
);
378 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
379 client
->mac_addr_len
,
381 &client
->client_id
.ns
.iaid
);
388 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
389 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
390 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
394 if (client
->mac_addr_len
== 0)
397 r
= dhcp_identifier_set_duid_llt(&client
->client_id
.ns
.duid
, llt_time
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
402 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
407 if (client
->mac_addr_len
== 0)
410 r
= dhcp_identifier_set_duid_ll(&client
->client_id
.ns
.duid
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
415 r
= dhcp_identifier_set_duid_uuid(&client
->client_id
.ns
.duid
, &len
);
423 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
424 (iaid_append
? sizeof(client
->client_id
.ns
.iaid
) : 0);
426 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
427 log_dhcp_client(client
, "Configured %sDUID, restarting.", iaid_append
? "IAID+" : "");
428 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
429 sd_dhcp_client_start(client
);
435 int sd_dhcp_client_set_iaid_duid(
436 sd_dhcp_client
*client
,
442 return dhcp_client_set_iaid_duid_internal(client
, true, iaid_set
, iaid
, duid_type
, duid
, duid_len
, 0);
445 int sd_dhcp_client_set_iaid_duid_llt(
446 sd_dhcp_client
*client
,
450 return dhcp_client_set_iaid_duid_internal(client
, true, iaid_set
, iaid
, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
453 int sd_dhcp_client_set_duid(
454 sd_dhcp_client
*client
,
458 return dhcp_client_set_iaid_duid_internal(client
, false, false, 0, duid_type
, duid
, duid_len
, 0);
461 int sd_dhcp_client_set_duid_llt(
462 sd_dhcp_client
*client
,
464 return dhcp_client_set_iaid_duid_internal(client
, false, false, 0, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
467 int sd_dhcp_client_set_hostname(
468 sd_dhcp_client
*client
,
469 const char *hostname
) {
471 assert_return(client
, -EINVAL
);
473 /* Make sure hostnames qualify as DNS and as Linux hostnames */
475 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
478 return free_and_strdup(&client
->hostname
, hostname
);
481 int sd_dhcp_client_set_vendor_class_identifier(
482 sd_dhcp_client
*client
,
485 assert_return(client
, -EINVAL
);
487 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
490 int sd_dhcp_client_set_user_class(
491 sd_dhcp_client
*client
,
492 const char* const* user_class
) {
494 _cleanup_strv_free_
char **s
= NULL
;
497 STRV_FOREACH(p
, (char **) user_class
)
498 if (strlen(*p
) > 255)
499 return -ENAMETOOLONG
;
501 s
= strv_copy((char **) user_class
);
505 client
->user_class
= TAKE_PTR(s
);
510 int sd_dhcp_client_set_client_port(
511 sd_dhcp_client
*client
,
514 assert_return(client
, -EINVAL
);
521 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
522 assert_return(client
, -EINVAL
);
523 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
530 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
531 assert_return(client
, -EINVAL
);
533 if (!IN_SET(client
->state
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
534 return -EADDRNOTAVAIL
;
537 *ret
= client
->lease
;
542 static void client_notify(sd_dhcp_client
*client
, int event
) {
545 if (client
->callback
)
546 client
->callback(client
, event
, client
->userdata
);
549 static int client_initialize(sd_dhcp_client
*client
) {
550 assert_return(client
, -EINVAL
);
552 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
554 client
->fd
= asynchronous_close(client
->fd
);
556 (void) event_source_disable(client
->timeout_resend
);
557 (void) event_source_disable(client
->timeout_t1
);
558 (void) event_source_disable(client
->timeout_t2
);
559 (void) event_source_disable(client
->timeout_expire
);
563 client
->state
= DHCP_STATE_INIT
;
566 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
571 static void client_stop(sd_dhcp_client
*client
, int error
) {
575 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
576 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
577 log_dhcp_client(client
, "STOPPED");
579 log_dhcp_client(client
, "STOPPED: Unknown event");
581 client_notify(client
, error
);
583 client_initialize(client
);
586 static int client_message_init(
587 sd_dhcp_client
*client
,
591 size_t *_optoffset
) {
593 _cleanup_free_ DHCPPacket
*packet
= NULL
;
594 size_t optlen
, optoffset
, size
;
601 assert(client
->start_time
);
605 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
));
607 optlen
= DHCP_MIN_OPTIONS_SIZE
;
608 size
= sizeof(DHCPPacket
) + optlen
;
610 packet
= malloc0(size
);
614 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
615 client
->arp_type
, optlen
, &optoffset
);
619 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
620 refuse to issue an DHCP lease if 'secs' is set to zero */
621 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
624 assert(time_now
>= client
->start_time
);
626 /* seconds between sending first and last DISCOVER
627 * must always be strictly positive to deal with broken servers */
628 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
629 packet
->dhcp
.secs
= htobe16(secs
);
631 /* RFC2132 section 4.1
632 A client that cannot receive unicast IP datagrams until its protocol
633 software has been configured with an IP address SHOULD set the
634 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
635 DHCPREQUEST messages that client sends. The BROADCAST bit will
636 provide a hint to the DHCP server and BOOTP relay agent to broadcast
637 any messages to the client on the client's subnet.
639 Note: some interfaces needs this to be enabled, but some networks
640 needs this to be disabled as broadcasts are filteretd, so this
641 needs to be configurable */
642 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
643 packet
->dhcp
.flags
= htobe16(0x8000);
645 /* RFC2132 section 4.1.1:
646 The client MUST include its hardware address in the ’chaddr’ field, if
647 necessary for delivery of DHCP reply messages. Non-Ethernet
648 interfaces will leave 'chaddr' empty and use the client identifier
649 instead (eg, RFC 4390 section 2.1).
651 if (client
->arp_type
== ARPHRD_ETHER
)
652 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
654 /* If no client identifier exists, construct an RFC 4361-compliant one */
655 if (client
->client_id_len
== 0) {
658 client
->client_id
.type
= 255;
660 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
,
661 true, &client
->client_id
.ns
.iaid
);
665 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
669 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
672 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
673 Identifier option is not set */
674 if (client
->client_id_len
) {
675 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
676 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
677 client
->client_id_len
,
683 /* RFC2131 section 3.5:
684 in its initial DHCPDISCOVER or DHCPREQUEST message, a
685 client may provide the server with a list of specific
686 parameters the client is interested in. If the client
687 includes a list of parameters in a DHCPDISCOVER message,
688 it MUST include that list in any subsequent DHCPREQUEST
692 /* RFC7844 section 3:
693 MAY contain the Parameter Request List option. */
694 /* NOTE: in case that there would be an option to do not send
695 * any PRL at all, the size should be checked before sending */
696 if (client
->req_opts_size
> 0) {
697 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
698 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
699 client
->req_opts_size
, client
->req_opts
);
704 /* RFC2131 section 3.5:
705 The client SHOULD include the ’maximum DHCP message size’ option to
706 let the server know how large the server may make its DHCP messages.
708 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
709 than the defined default size unless the Maximum Message Size option
712 RFC3442 "Requirements to Avoid Sizing Constraints":
713 Because a full routing table can be quite large, the standard 576
714 octet maximum size for a DHCP message may be too short to contain
715 some legitimate Classless Static Route options. Because of this,
716 clients implementing the Classless Static Route option SHOULD send a
717 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
718 stack is capable of receiving larger IP datagrams. In this case, the
719 client SHOULD set the value of this option to at least the MTU of the
720 interface that the client is configuring. The client MAY set the
721 value of this option higher, up to the size of the largest UDP packet
722 it is prepared to accept. (Note that the value specified in the
723 Maximum DHCP Message Size option is the total maximum packet size,
724 including IP and UDP headers.)
726 /* RFC7844 section 3:
727 SHOULD NOT contain any other option. */
728 if (!client
->anonymize
) {
729 max_size
= htobe16(size
);
730 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
731 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
738 *_optoffset
= optoffset
;
739 *ret
= TAKE_PTR(packet
);
744 static int client_append_fqdn_option(
745 DHCPMessage
*message
,
750 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
753 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
754 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
755 buffer
[1] = 0; /* RCODE1 (deprecated) */
756 buffer
[2] = 0; /* RCODE2 (deprecated) */
758 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
760 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
761 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
766 static int dhcp_client_send_raw(
767 sd_dhcp_client
*client
,
771 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
772 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
774 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
778 static int client_send_discover(sd_dhcp_client
*client
) {
779 _cleanup_free_ DHCPPacket
*discover
= NULL
;
780 size_t optoffset
, optlen
;
784 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
786 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
787 &optlen
, &optoffset
);
791 /* the client may suggest values for the network address
792 and lease time in the DHCPDISCOVER message. The client may include
793 the ’requested IP address’ option to suggest that a particular IP
794 address be assigned, and may include the ’IP address lease time’
795 option to suggest the lease time it would like.
797 if (client
->last_addr
!= INADDR_ANY
) {
798 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
799 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
800 4, &client
->last_addr
);
805 if (client
->hostname
) {
806 /* According to RFC 4702 "clients that send the Client FQDN option in
807 their messages MUST NOT also send the Host Name option". Just send
808 one of the two depending on the hostname type.
810 if (dns_name_is_single_label(client
->hostname
)) {
811 /* it is unclear from RFC 2131 if client should send hostname in
812 DHCPDISCOVER but dhclient does and so we do as well
814 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
815 SD_DHCP_OPTION_HOST_NAME
,
816 strlen(client
->hostname
), client
->hostname
);
818 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
824 if (client
->vendor_class_identifier
) {
825 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
826 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
827 strlen(client
->vendor_class_identifier
),
828 client
->vendor_class_identifier
);
833 if (client
->user_class
) {
834 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
835 SD_DHCP_OPTION_USER_CLASS
,
836 strv_length(client
->user_class
),
842 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
843 SD_DHCP_OPTION_END
, 0, NULL
);
847 /* We currently ignore:
848 The client SHOULD wait a random time between one and ten seconds to
849 desynchronize the use of DHCP at startup.
851 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
855 log_dhcp_client(client
, "DISCOVER");
860 static int client_send_request(sd_dhcp_client
*client
) {
861 _cleanup_free_ DHCPPacket
*request
= NULL
;
862 size_t optoffset
, optlen
;
867 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
871 switch (client
->state
) {
872 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
873 SELECTING should be REQUESTING)
876 case DHCP_STATE_REQUESTING
:
877 /* Client inserts the address of the selected server in ’server
878 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
879 filled in with the yiaddr value from the chosen DHCPOFFER.
882 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
883 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
884 4, &client
->lease
->server_address
);
888 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
889 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
890 4, &client
->lease
->address
);
896 case DHCP_STATE_INIT_REBOOT
:
897 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
898 option MUST be filled in with client’s notion of its previously
899 assigned address. ’ciaddr’ MUST be zero.
901 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
902 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
903 4, &client
->last_addr
);
908 case DHCP_STATE_RENEWING
:
909 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
910 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
914 case DHCP_STATE_REBINDING
:
915 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
916 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
919 This message MUST be broadcast to the 0xffffffff IP broadcast address.
921 request
->dhcp
.ciaddr
= client
->lease
->address
;
925 case DHCP_STATE_INIT
:
926 case DHCP_STATE_SELECTING
:
927 case DHCP_STATE_REBOOTING
:
928 case DHCP_STATE_BOUND
:
929 case DHCP_STATE_STOPPED
:
933 if (client
->hostname
) {
934 if (dns_name_is_single_label(client
->hostname
))
935 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
936 SD_DHCP_OPTION_HOST_NAME
,
937 strlen(client
->hostname
), client
->hostname
);
939 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
945 if (client
->vendor_class_identifier
) {
946 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
947 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
948 strlen(client
->vendor_class_identifier
),
949 client
->vendor_class_identifier
);
954 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
955 SD_DHCP_OPTION_END
, 0, NULL
);
959 if (client
->state
== DHCP_STATE_RENEWING
) {
960 r
= dhcp_network_send_udp_socket(client
->fd
,
961 client
->lease
->server_address
,
964 sizeof(DHCPMessage
) + optoffset
);
966 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
971 switch (client
->state
) {
973 case DHCP_STATE_REQUESTING
:
974 log_dhcp_client(client
, "REQUEST (requesting)");
977 case DHCP_STATE_INIT_REBOOT
:
978 log_dhcp_client(client
, "REQUEST (init-reboot)");
981 case DHCP_STATE_RENEWING
:
982 log_dhcp_client(client
, "REQUEST (renewing)");
985 case DHCP_STATE_REBINDING
:
986 log_dhcp_client(client
, "REQUEST (rebinding)");
990 log_dhcp_client(client
, "REQUEST (invalid)");
997 static int client_start(sd_dhcp_client
*client
);
999 static int client_timeout_resend(
1004 sd_dhcp_client
*client
= userdata
;
1005 DHCP_CLIENT_DONT_DESTROY(client
);
1006 usec_t next_timeout
= 0;
1013 assert(client
->event
);
1015 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1019 switch (client
->state
) {
1021 case DHCP_STATE_RENEWING
:
1023 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
1027 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1031 case DHCP_STATE_REBINDING
:
1033 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
1037 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1040 case DHCP_STATE_REBOOTING
:
1041 /* start over as we did not receive a timely ack or nak */
1042 r
= client_initialize(client
);
1046 r
= client_start(client
);
1050 log_dhcp_client(client
, "REBOOTED");
1054 case DHCP_STATE_INIT
:
1055 case DHCP_STATE_INIT_REBOOT
:
1056 case DHCP_STATE_SELECTING
:
1057 case DHCP_STATE_REQUESTING
:
1058 case DHCP_STATE_BOUND
:
1060 if (client
->attempt
< 64)
1061 client
->attempt
*= 2;
1063 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
1067 case DHCP_STATE_STOPPED
:
1072 next_timeout
+= (random_u32() & 0x1fffff);
1074 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1075 clock_boottime_or_monotonic(),
1076 next_timeout
, 10 * USEC_PER_MSEC
,
1077 client_timeout_resend
, client
,
1078 client
->event_priority
, "dhcp4-resend-timer", true);
1082 switch (client
->state
) {
1083 case DHCP_STATE_INIT
:
1084 r
= client_send_discover(client
);
1086 client
->state
= DHCP_STATE_SELECTING
;
1087 client
->attempt
= 1;
1089 if (client
->attempt
>= 64)
1095 case DHCP_STATE_SELECTING
:
1096 r
= client_send_discover(client
);
1097 if (r
< 0 && client
->attempt
>= 64)
1102 case DHCP_STATE_INIT_REBOOT
:
1103 case DHCP_STATE_REQUESTING
:
1104 case DHCP_STATE_RENEWING
:
1105 case DHCP_STATE_REBINDING
:
1106 r
= client_send_request(client
);
1107 if (r
< 0 && client
->attempt
>= 64)
1110 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1111 client
->state
= DHCP_STATE_REBOOTING
;
1113 client
->request_sent
= time_now
;
1117 case DHCP_STATE_REBOOTING
:
1118 case DHCP_STATE_BOUND
:
1122 case DHCP_STATE_STOPPED
:
1130 client_stop(client
, r
);
1132 /* Errors were dealt with when stopping the client, don't spill
1133 errors into the event loop handler */
1137 static int client_initialize_io_events(
1138 sd_dhcp_client
*client
,
1139 sd_event_io_handler_t io_callback
) {
1144 assert(client
->event
);
1146 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1147 client
->fd
, EPOLLIN
, io_callback
,
1152 r
= sd_event_source_set_priority(client
->receive_message
,
1153 client
->event_priority
);
1157 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1163 client_stop(client
, r
);
1168 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1173 assert(client
->event
);
1175 if (client
->start_delay
) {
1176 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1177 usec
+= client
->start_delay
;
1180 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1181 clock_boottime_or_monotonic(),
1183 client_timeout_resend
, client
,
1184 client
->event_priority
, "dhcp4-resend-timer", true);
1186 client_stop(client
, r
);
1192 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1193 client_initialize_io_events(client
, io_callback
);
1194 client_initialize_time_events(client
);
1199 static int client_start_delayed(sd_dhcp_client
*client
) {
1202 assert_return(client
, -EINVAL
);
1203 assert_return(client
->event
, -EINVAL
);
1204 assert_return(client
->ifindex
> 0, -EINVAL
);
1205 assert_return(client
->fd
< 0, -EBUSY
);
1206 assert_return(client
->xid
== 0, -EINVAL
);
1207 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1209 client
->xid
= random_u32();
1211 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1212 client
->xid
, client
->mac_addr
,
1213 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1215 client_stop(client
, r
);
1220 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1221 client
->start_time
= now(clock_boottime_or_monotonic());
1223 return client_initialize_events(client
, client_receive_message_raw
);
1226 static int client_start(sd_dhcp_client
*client
) {
1227 client
->start_delay
= 0;
1228 return client_start_delayed(client
);
1231 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1232 sd_dhcp_client
*client
= userdata
;
1233 DHCP_CLIENT_DONT_DESTROY(client
);
1235 log_dhcp_client(client
, "EXPIRED");
1237 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1239 /* lease was lost, start over if not freed or stopped in callback */
1240 if (client
->state
!= DHCP_STATE_STOPPED
) {
1241 client_initialize(client
);
1242 client_start(client
);
1248 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1249 sd_dhcp_client
*client
= userdata
;
1250 DHCP_CLIENT_DONT_DESTROY(client
);
1255 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1256 client
->fd
= asynchronous_close(client
->fd
);
1258 client
->state
= DHCP_STATE_REBINDING
;
1259 client
->attempt
= 1;
1261 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1262 client
->xid
, client
->mac_addr
,
1263 client
->mac_addr_len
, client
->arp_type
,
1266 client_stop(client
, r
);
1271 return client_initialize_events(client
, client_receive_message_raw
);
1274 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1275 sd_dhcp_client
*client
= userdata
;
1276 DHCP_CLIENT_DONT_DESTROY(client
);
1278 client
->state
= DHCP_STATE_RENEWING
;
1279 client
->attempt
= 1;
1281 return client_initialize_time_events(client
);
1284 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1285 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1288 r
= dhcp_lease_new(&lease
);
1292 if (client
->client_id_len
) {
1293 r
= dhcp_lease_set_client_id(lease
,
1294 (uint8_t *) &client
->client_id
,
1295 client
->client_id_len
);
1300 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1301 if (r
!= DHCP_OFFER
) {
1302 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1306 lease
->next_server
= offer
->siaddr
;
1307 lease
->address
= offer
->yiaddr
;
1309 if (lease
->address
== 0 ||
1310 lease
->server_address
== 0 ||
1311 lease
->lifetime
== 0) {
1312 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1316 if (!lease
->have_subnet_mask
) {
1317 r
= dhcp_lease_set_default_subnet_mask(lease
);
1319 log_dhcp_client(client
,
1320 "received lease lacks subnet mask, "
1321 "and a fallback one cannot be generated, ignoring");
1326 sd_dhcp_lease_unref(client
->lease
);
1327 client
->lease
= TAKE_PTR(lease
);
1329 log_dhcp_client(client
, "OFFER");
1334 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1337 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1338 if (r
!= DHCP_FORCERENEW
)
1341 log_dhcp_client(client
, "FORCERENEW");
1346 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1347 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1348 _cleanup_free_
char *error_message
= NULL
;
1351 r
= dhcp_lease_new(&lease
);
1355 if (client
->client_id_len
) {
1356 r
= dhcp_lease_set_client_id(lease
,
1357 (uint8_t *) &client
->client_id
,
1358 client
->client_id_len
);
1363 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1364 if (r
== DHCP_NAK
) {
1365 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1366 return -EADDRNOTAVAIL
;
1369 if (r
!= DHCP_ACK
) {
1370 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1374 lease
->next_server
= ack
->siaddr
;
1376 lease
->address
= ack
->yiaddr
;
1378 if (lease
->address
== INADDR_ANY
||
1379 lease
->server_address
== INADDR_ANY
||
1380 lease
->lifetime
== 0) {
1381 log_dhcp_client(client
, "received lease lacks address, server "
1382 "address or lease lifetime, ignoring");
1386 if (lease
->subnet_mask
== INADDR_ANY
) {
1387 r
= dhcp_lease_set_default_subnet_mask(lease
);
1389 log_dhcp_client(client
,
1390 "received lease lacks subnet mask, "
1391 "and a fallback one cannot be generated, ignoring");
1396 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1397 if (client
->lease
) {
1398 if (client
->lease
->address
!= lease
->address
||
1399 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1400 client
->lease
->router
!= lease
->router
) {
1401 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1403 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1405 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1408 client
->lease
= TAKE_PTR(lease
);
1410 log_dhcp_client(client
, "ACK");
1415 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1417 assert(client
->request_sent
);
1418 assert(lifetime
> 0);
1425 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1426 + (random_u32() & 0x1fffff);
1429 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1431 uint64_t lifetime_timeout
;
1432 uint64_t t2_timeout
;
1433 uint64_t t1_timeout
;
1434 char time_string
[FORMAT_TIMESPAN_MAX
];
1438 assert(client
->event
);
1439 assert(client
->lease
);
1440 assert(client
->lease
->lifetime
);
1442 /* don't set timers for infinite leases */
1443 if (client
->lease
->lifetime
== 0xffffffff) {
1444 (void) event_source_disable(client
->timeout_t1
);
1445 (void) event_source_disable(client
->timeout_t2
);
1446 (void) event_source_disable(client
->timeout_expire
);
1451 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1454 assert(client
->request_sent
<= time_now
);
1456 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1457 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1458 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1459 /* both T1 and T2 are given */
1460 if (client
->lease
->t1
< client
->lease
->t2
&&
1461 client
->lease
->t2
< client
->lease
->lifetime
) {
1462 /* they are both valid */
1463 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1464 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1467 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1468 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1469 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1470 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1472 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1473 /* only T2 is given, and it is valid */
1474 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1475 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1476 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1477 if (t2_timeout
<= t1_timeout
) {
1478 /* the computed T1 would be invalid, so discard T2 */
1479 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1480 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1482 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1483 /* only T1 is given, and it is valid */
1484 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1485 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1486 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1487 if (t2_timeout
<= t1_timeout
) {
1488 /* the computed T2 would be invalid, so discard T1 */
1489 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1490 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1493 /* fall back to the default timeouts */
1494 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1495 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1496 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1497 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1500 /* arm lifetime timeout */
1501 r
= event_reset_time(client
->event
, &client
->timeout_expire
,
1502 clock_boottime_or_monotonic(),
1503 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1504 client_timeout_expire
, client
,
1505 client
->event_priority
, "dhcp4-lifetime", true);
1509 log_dhcp_client(client
, "lease expires in %s",
1510 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1512 /* don't arm earlier timeouts if this has already expired */
1513 if (lifetime_timeout
<= time_now
)
1516 /* arm T2 timeout */
1517 r
= event_reset_time(client
->event
, &client
->timeout_t2
,
1518 clock_boottime_or_monotonic(),
1519 t2_timeout
, 10 * USEC_PER_MSEC
,
1520 client_timeout_t2
, client
,
1521 client
->event_priority
, "dhcp4-t2-timeout", true);
1525 log_dhcp_client(client
, "T2 expires in %s",
1526 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1528 /* don't arm earlier timeout if this has already expired */
1529 if (t2_timeout
<= time_now
)
1532 /* arm T1 timeout */
1533 r
= event_reset_time(client
->event
, &client
->timeout_t1
,
1534 clock_boottime_or_monotonic(),
1535 t1_timeout
, 10 * USEC_PER_MSEC
,
1536 client_timeout_t1
, client
,
1537 client
->event_priority
, "dhcp4-t1-timer", true);
1541 log_dhcp_client(client
, "T1 expires in %s",
1542 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1547 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1548 DHCP_CLIENT_DONT_DESTROY(client
);
1549 char time_string
[FORMAT_TIMESPAN_MAX
];
1550 int r
= 0, notify_event
= 0;
1553 assert(client
->event
);
1556 switch (client
->state
) {
1557 case DHCP_STATE_SELECTING
:
1559 r
= client_handle_offer(client
, message
, len
);
1562 client
->state
= DHCP_STATE_REQUESTING
;
1563 client
->attempt
= 1;
1565 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1566 clock_boottime_or_monotonic(),
1568 client_timeout_resend
, client
,
1569 client
->event_priority
, "dhcp4-resend-timer", true);
1572 } else if (r
== -ENOMSG
)
1573 /* invalid message, let's ignore it */
1578 case DHCP_STATE_REBOOTING
:
1579 case DHCP_STATE_REQUESTING
:
1580 case DHCP_STATE_RENEWING
:
1581 case DHCP_STATE_REBINDING
:
1583 r
= client_handle_ack(client
, message
, len
);
1585 client
->start_delay
= 0;
1586 (void) event_source_disable(client
->timeout_resend
);
1587 client
->receive_message
=
1588 sd_event_source_unref(client
->receive_message
);
1589 client
->fd
= asynchronous_close(client
->fd
);
1591 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1592 DHCP_STATE_REBOOTING
))
1593 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1594 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1597 client
->state
= DHCP_STATE_BOUND
;
1598 client
->attempt
= 1;
1600 client
->last_addr
= client
->lease
->address
;
1602 r
= client_set_lease_timeouts(client
);
1604 log_dhcp_client(client
, "could not set lease timeouts");
1608 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1610 log_dhcp_client(client
, "could not bind UDP socket");
1616 client_initialize_io_events(client
, client_receive_message_udp
);
1619 client_notify(client
, notify_event
);
1620 if (client
->state
== DHCP_STATE_STOPPED
)
1624 } else if (r
== -EADDRNOTAVAIL
) {
1625 /* got a NAK, let's restart the client */
1626 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1628 r
= client_initialize(client
);
1632 r
= client_start_delayed(client
);
1636 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1637 client
->start_delay
, USEC_PER_SEC
));
1639 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1640 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1643 } else if (r
== -ENOMSG
)
1644 /* invalid message, let's ignore it */
1649 case DHCP_STATE_BOUND
:
1650 r
= client_handle_forcerenew(client
, message
, len
);
1652 r
= client_timeout_t1(NULL
, 0, client
);
1655 } else if (r
== -ENOMSG
)
1656 /* invalid message, let's ignore it */
1661 case DHCP_STATE_INIT
:
1662 case DHCP_STATE_INIT_REBOOT
:
1666 case DHCP_STATE_STOPPED
:
1673 client_stop(client
, r
);
1678 static int client_receive_message_udp(
1684 sd_dhcp_client
*client
= userdata
;
1685 _cleanup_free_ DHCPMessage
*message
= NULL
;
1686 const struct ether_addr zero_mac
= {};
1687 const struct ether_addr
*expected_chaddr
= NULL
;
1688 uint8_t expected_hlen
= 0;
1689 ssize_t len
, buflen
;
1694 buflen
= next_datagram_size_fd(fd
);
1698 message
= malloc0(buflen
);
1702 len
= recv(fd
, message
, buflen
, 0);
1704 if (IN_SET(errno
, EAGAIN
, EINTR
))
1707 return log_dhcp_client_errno(client
, errno
,
1708 "Could not receive message from UDP socket: %m");
1710 if ((size_t) len
< sizeof(DHCPMessage
)) {
1711 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1715 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1716 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1720 if (message
->op
!= BOOTREPLY
) {
1721 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1725 if (message
->htype
!= client
->arp_type
) {
1726 log_dhcp_client(client
, "Packet type does not match client type");
1730 if (client
->arp_type
== ARPHRD_ETHER
) {
1731 expected_hlen
= ETH_ALEN
;
1732 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1734 /* Non-Ethernet links expect zero chaddr */
1736 expected_chaddr
= &zero_mac
;
1739 if (message
->hlen
!= expected_hlen
) {
1740 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1744 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1745 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1749 if (client
->state
!= DHCP_STATE_BOUND
&&
1750 be32toh(message
->xid
) != client
->xid
) {
1751 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1752 so ignore the xid in this case */
1753 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1754 be32toh(message
->xid
), client
->xid
);
1758 return client_handle_message(client
, message
, len
);
1761 static int client_receive_message_raw(
1767 sd_dhcp_client
*client
= userdata
;
1768 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1769 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1770 struct iovec iov
= {};
1771 struct msghdr msg
= {
1774 .msg_control
= cmsgbuf
,
1775 .msg_controllen
= sizeof(cmsgbuf
),
1777 struct cmsghdr
*cmsg
;
1778 bool checksum
= true;
1779 ssize_t buflen
, len
;
1785 buflen
= next_datagram_size_fd(fd
);
1789 packet
= malloc0(buflen
);
1793 iov
= IOVEC_MAKE(packet
, buflen
);
1795 len
= recvmsg(fd
, &msg
, 0);
1797 if (IN_SET(errno
, EAGAIN
, EINTR
))
1800 return log_dhcp_client_errno(client
, errno
,
1801 "Could not receive message from raw socket: %m");
1802 } else if ((size_t)len
< sizeof(DHCPPacket
))
1805 CMSG_FOREACH(cmsg
, &msg
) {
1806 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1807 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1808 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1809 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1811 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1816 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1820 len
-= DHCP_IP_UDP_SIZE
;
1822 return client_handle_message(client
, &packet
->dhcp
, len
);
1825 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1828 assert_return(client
, -EINVAL
);
1830 r
= client_initialize(client
);
1834 /* RFC7844 section 3.3:
1835 SHOULD perform a complete four-way handshake, starting with a
1836 DHCPDISCOVER, to obtain a new address lease. If the client can
1837 ascertain that this is exactly the same network to which it was
1838 previously connected, and if the link-layer address did not change,
1839 the client MAY issue a DHCPREQUEST to try to reclaim the current
1841 if (client
->last_addr
&& !client
->anonymize
)
1842 client
->state
= DHCP_STATE_INIT_REBOOT
;
1844 r
= client_start(client
);
1846 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1851 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1852 DHCP_CLIENT_DONT_DESTROY(client
);
1854 assert_return(client
, -EINVAL
);
1856 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1857 client
->state
= DHCP_STATE_STOPPED
;
1862 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1865 assert_return(client
, -EINVAL
);
1866 assert_return(!client
->event
, -EBUSY
);
1869 client
->event
= sd_event_ref(event
);
1871 r
= sd_event_default(&client
->event
);
1876 client
->event_priority
= priority
;
1881 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1882 assert_return(client
, -EINVAL
);
1884 client
->event
= sd_event_unref(client
->event
);
1889 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1890 assert_return(client
, NULL
);
1892 return client
->event
;
1895 static sd_dhcp_client
*dhcp_client_free(sd_dhcp_client
*client
) {
1898 log_dhcp_client(client
, "FREE");
1900 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1901 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1902 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1903 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1905 client_initialize(client
);
1907 sd_dhcp_client_detach_event(client
);
1909 sd_dhcp_lease_unref(client
->lease
);
1911 free(client
->req_opts
);
1912 free(client
->hostname
);
1913 free(client
->vendor_class_identifier
);
1914 client
->user_class
= strv_free(client
->user_class
);
1915 return mfree(client
);
1918 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client
, sd_dhcp_client
, dhcp_client_free
);
1920 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1921 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1923 assert_return(ret
, -EINVAL
);
1925 client
= new(sd_dhcp_client
, 1);
1929 *client
= (sd_dhcp_client
) {
1931 .state
= DHCP_STATE_INIT
,
1935 .mtu
= DHCP_DEFAULT_MIN_SIZE
,
1936 .port
= DHCP_PORT_CLIENT
,
1937 .anonymize
= !!anonymize
,
1939 /* NOTE: this could be moved to a function. */
1941 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
1942 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
1944 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1945 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1947 if (!client
->req_opts
)
1950 *ret
= TAKE_PTR(client
);