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 if (data_len
!= INFINIBAND_ALEN
)
319 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
320 client
->client_id
.type
== type
&&
321 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
324 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
325 log_dhcp_client(client
, "Changing client ID on running DHCP "
326 "client, restarting");
328 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
331 client
->client_id
.type
= type
;
332 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
333 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
335 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
336 sd_dhcp_client_start(client
);
342 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
343 * without further modification. Otherwise, if duid_type is supported, DUID
344 * is set based on that type. Otherwise, an error is returned.
346 static int dhcp_client_set_iaid_duid_internal(
347 sd_dhcp_client
*client
,
355 DHCP_CLIENT_DONT_DESTROY(client
);
359 assert_return(client
, -EINVAL
);
360 assert_return(duid_len
== 0 || duid
!= NULL
, -EINVAL
);
363 r
= dhcp_validate_duid_len(duid_type
, duid_len
);
368 zero(client
->client_id
);
369 client
->client_id
.type
= 255;
372 /* If IAID is not configured, generate it. */
374 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
375 client
->mac_addr_len
,
377 &client
->client_id
.ns
.iaid
);
381 client
->client_id
.ns
.iaid
= htobe32(iaid
);
385 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
386 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
387 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
391 if (client
->mac_addr_len
== 0)
394 r
= dhcp_identifier_set_duid_llt(&client
->client_id
.ns
.duid
, llt_time
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
399 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
404 if (client
->mac_addr_len
== 0)
407 r
= dhcp_identifier_set_duid_ll(&client
->client_id
.ns
.duid
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
412 r
= dhcp_identifier_set_duid_uuid(&client
->client_id
.ns
.duid
, &len
);
420 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
421 (append_iaid
? sizeof(client
->client_id
.ns
.iaid
) : 0);
423 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
424 log_dhcp_client(client
, "Configured %sDUID, restarting.", append_iaid
? "IAID+" : "");
425 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
426 sd_dhcp_client_start(client
);
432 int sd_dhcp_client_set_iaid_duid(
433 sd_dhcp_client
*client
,
438 return dhcp_client_set_iaid_duid_internal(client
, iaid
, true, duid_type
, duid
, duid_len
, 0);
441 int sd_dhcp_client_set_iaid_duid_llt(
442 sd_dhcp_client
*client
,
445 return dhcp_client_set_iaid_duid_internal(client
, iaid
, true, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
448 int sd_dhcp_client_set_duid(
449 sd_dhcp_client
*client
,
453 return dhcp_client_set_iaid_duid_internal(client
, 0, false, duid_type
, duid
, duid_len
, 0);
456 int sd_dhcp_client_set_duid_llt(
457 sd_dhcp_client
*client
,
459 return dhcp_client_set_iaid_duid_internal(client
, 0, false, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
462 int sd_dhcp_client_set_hostname(
463 sd_dhcp_client
*client
,
464 const char *hostname
) {
466 assert_return(client
, -EINVAL
);
468 /* Make sure hostnames qualify as DNS and as Linux hostnames */
470 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
473 return free_and_strdup(&client
->hostname
, hostname
);
476 int sd_dhcp_client_set_vendor_class_identifier(
477 sd_dhcp_client
*client
,
480 assert_return(client
, -EINVAL
);
482 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
485 int sd_dhcp_client_set_user_class(
486 sd_dhcp_client
*client
,
487 const char* const* user_class
) {
489 _cleanup_strv_free_
char **s
= NULL
;
492 STRV_FOREACH(p
, (char **) user_class
)
493 if (strlen(*p
) > 255)
494 return -ENAMETOOLONG
;
496 s
= strv_copy((char **) user_class
);
500 client
->user_class
= TAKE_PTR(s
);
505 int sd_dhcp_client_set_client_port(
506 sd_dhcp_client
*client
,
509 assert_return(client
, -EINVAL
);
516 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
517 assert_return(client
, -EINVAL
);
518 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
525 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
526 assert_return(client
, -EINVAL
);
528 if (!IN_SET(client
->state
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
529 return -EADDRNOTAVAIL
;
532 *ret
= client
->lease
;
537 static void client_notify(sd_dhcp_client
*client
, int event
) {
540 if (client
->callback
)
541 client
->callback(client
, event
, client
->userdata
);
544 static int client_initialize(sd_dhcp_client
*client
) {
545 assert_return(client
, -EINVAL
);
547 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
549 client
->fd
= asynchronous_close(client
->fd
);
551 (void) event_source_disable(client
->timeout_resend
);
552 (void) event_source_disable(client
->timeout_t1
);
553 (void) event_source_disable(client
->timeout_t2
);
554 (void) event_source_disable(client
->timeout_expire
);
558 client
->state
= DHCP_STATE_INIT
;
561 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
566 static void client_stop(sd_dhcp_client
*client
, int error
) {
570 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
571 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
572 log_dhcp_client(client
, "STOPPED");
574 log_dhcp_client(client
, "STOPPED: Unknown event");
576 client_notify(client
, error
);
578 client_initialize(client
);
581 static int client_message_init(
582 sd_dhcp_client
*client
,
586 size_t *_optoffset
) {
588 _cleanup_free_ DHCPPacket
*packet
= NULL
;
589 size_t optlen
, optoffset
, size
;
596 assert(client
->start_time
);
600 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
));
602 optlen
= DHCP_MIN_OPTIONS_SIZE
;
603 size
= sizeof(DHCPPacket
) + optlen
;
605 packet
= malloc0(size
);
609 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
610 client
->arp_type
, optlen
, &optoffset
);
614 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
615 refuse to issue an DHCP lease if 'secs' is set to zero */
616 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
619 assert(time_now
>= client
->start_time
);
621 /* seconds between sending first and last DISCOVER
622 * must always be strictly positive to deal with broken servers */
623 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
624 packet
->dhcp
.secs
= htobe16(secs
);
626 /* RFC2132 section 4.1
627 A client that cannot receive unicast IP datagrams until its protocol
628 software has been configured with an IP address SHOULD set the
629 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
630 DHCPREQUEST messages that client sends. The BROADCAST bit will
631 provide a hint to the DHCP server and BOOTP relay agent to broadcast
632 any messages to the client on the client's subnet.
634 Note: some interfaces needs this to be enabled, but some networks
635 needs this to be disabled as broadcasts are filteretd, so this
636 needs to be configurable */
637 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
638 packet
->dhcp
.flags
= htobe16(0x8000);
640 /* RFC2132 section 4.1.1:
641 The client MUST include its hardware address in the ’chaddr’ field, if
642 necessary for delivery of DHCP reply messages. Non-Ethernet
643 interfaces will leave 'chaddr' empty and use the client identifier
644 instead (eg, RFC 4390 section 2.1).
646 if (client
->arp_type
== ARPHRD_ETHER
)
647 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
649 /* If no client identifier exists, construct an RFC 4361-compliant one */
650 if (client
->client_id_len
== 0) {
653 client
->client_id
.type
= 255;
655 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
,
656 true, &client
->client_id
.ns
.iaid
);
660 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
664 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
667 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
668 Identifier option is not set */
669 if (client
->client_id_len
) {
670 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
671 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
672 client
->client_id_len
,
678 /* RFC2131 section 3.5:
679 in its initial DHCPDISCOVER or DHCPREQUEST message, a
680 client may provide the server with a list of specific
681 parameters the client is interested in. If the client
682 includes a list of parameters in a DHCPDISCOVER message,
683 it MUST include that list in any subsequent DHCPREQUEST
687 /* RFC7844 section 3:
688 MAY contain the Parameter Request List option. */
689 /* NOTE: in case that there would be an option to do not send
690 * any PRL at all, the size should be checked before sending */
691 if (client
->req_opts_size
> 0) {
692 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
693 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
694 client
->req_opts_size
, client
->req_opts
);
699 /* RFC2131 section 3.5:
700 The client SHOULD include the ’maximum DHCP message size’ option to
701 let the server know how large the server may make its DHCP messages.
703 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
704 than the defined default size unless the Maximum Message Size option
707 RFC3442 "Requirements to Avoid Sizing Constraints":
708 Because a full routing table can be quite large, the standard 576
709 octet maximum size for a DHCP message may be too short to contain
710 some legitimate Classless Static Route options. Because of this,
711 clients implementing the Classless Static Route option SHOULD send a
712 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
713 stack is capable of receiving larger IP datagrams. In this case, the
714 client SHOULD set the value of this option to at least the MTU of the
715 interface that the client is configuring. The client MAY set the
716 value of this option higher, up to the size of the largest UDP packet
717 it is prepared to accept. (Note that the value specified in the
718 Maximum DHCP Message Size option is the total maximum packet size,
719 including IP and UDP headers.)
721 /* RFC7844 section 3:
722 SHOULD NOT contain any other option. */
723 if (!client
->anonymize
) {
724 max_size
= htobe16(size
);
725 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
726 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
733 *_optoffset
= optoffset
;
734 *ret
= TAKE_PTR(packet
);
739 static int client_append_fqdn_option(
740 DHCPMessage
*message
,
745 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
748 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
749 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
750 buffer
[1] = 0; /* RCODE1 (deprecated) */
751 buffer
[2] = 0; /* RCODE2 (deprecated) */
753 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
755 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
756 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
761 static int dhcp_client_send_raw(
762 sd_dhcp_client
*client
,
766 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
767 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
769 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
773 static int client_send_discover(sd_dhcp_client
*client
) {
774 _cleanup_free_ DHCPPacket
*discover
= NULL
;
775 size_t optoffset
, optlen
;
779 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
781 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
782 &optlen
, &optoffset
);
786 /* the client may suggest values for the network address
787 and lease time in the DHCPDISCOVER message. The client may include
788 the ’requested IP address’ option to suggest that a particular IP
789 address be assigned, and may include the ’IP address lease time’
790 option to suggest the lease time it would like.
792 if (client
->last_addr
!= INADDR_ANY
) {
793 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
794 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
795 4, &client
->last_addr
);
800 if (client
->hostname
) {
801 /* According to RFC 4702 "clients that send the Client FQDN option in
802 their messages MUST NOT also send the Host Name option". Just send
803 one of the two depending on the hostname type.
805 if (dns_name_is_single_label(client
->hostname
)) {
806 /* it is unclear from RFC 2131 if client should send hostname in
807 DHCPDISCOVER but dhclient does and so we do as well
809 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
810 SD_DHCP_OPTION_HOST_NAME
,
811 strlen(client
->hostname
), client
->hostname
);
813 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
819 if (client
->vendor_class_identifier
) {
820 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
821 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
822 strlen(client
->vendor_class_identifier
),
823 client
->vendor_class_identifier
);
828 if (client
->user_class
) {
829 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
830 SD_DHCP_OPTION_USER_CLASS
,
831 strv_length(client
->user_class
),
837 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
838 SD_DHCP_OPTION_END
, 0, NULL
);
842 /* We currently ignore:
843 The client SHOULD wait a random time between one and ten seconds to
844 desynchronize the use of DHCP at startup.
846 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
850 log_dhcp_client(client
, "DISCOVER");
855 static int client_send_request(sd_dhcp_client
*client
) {
856 _cleanup_free_ DHCPPacket
*request
= NULL
;
857 size_t optoffset
, optlen
;
862 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
866 switch (client
->state
) {
867 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
868 SELECTING should be REQUESTING)
871 case DHCP_STATE_REQUESTING
:
872 /* Client inserts the address of the selected server in ’server
873 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
874 filled in with the yiaddr value from the chosen DHCPOFFER.
877 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
878 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
879 4, &client
->lease
->server_address
);
883 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
884 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
885 4, &client
->lease
->address
);
891 case DHCP_STATE_INIT_REBOOT
:
892 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
893 option MUST be filled in with client’s notion of its previously
894 assigned address. ’ciaddr’ MUST be zero.
896 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
897 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
898 4, &client
->last_addr
);
903 case DHCP_STATE_RENEWING
:
904 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
905 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
909 case DHCP_STATE_REBINDING
:
910 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
911 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
914 This message MUST be broadcast to the 0xffffffff IP broadcast address.
916 request
->dhcp
.ciaddr
= client
->lease
->address
;
920 case DHCP_STATE_INIT
:
921 case DHCP_STATE_SELECTING
:
922 case DHCP_STATE_REBOOTING
:
923 case DHCP_STATE_BOUND
:
924 case DHCP_STATE_STOPPED
:
928 if (client
->hostname
) {
929 if (dns_name_is_single_label(client
->hostname
))
930 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
931 SD_DHCP_OPTION_HOST_NAME
,
932 strlen(client
->hostname
), client
->hostname
);
934 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
940 if (client
->vendor_class_identifier
) {
941 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
942 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
943 strlen(client
->vendor_class_identifier
),
944 client
->vendor_class_identifier
);
949 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
950 SD_DHCP_OPTION_END
, 0, NULL
);
954 if (client
->state
== DHCP_STATE_RENEWING
) {
955 r
= dhcp_network_send_udp_socket(client
->fd
,
956 client
->lease
->server_address
,
959 sizeof(DHCPMessage
) + optoffset
);
961 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
966 switch (client
->state
) {
968 case DHCP_STATE_REQUESTING
:
969 log_dhcp_client(client
, "REQUEST (requesting)");
972 case DHCP_STATE_INIT_REBOOT
:
973 log_dhcp_client(client
, "REQUEST (init-reboot)");
976 case DHCP_STATE_RENEWING
:
977 log_dhcp_client(client
, "REQUEST (renewing)");
980 case DHCP_STATE_REBINDING
:
981 log_dhcp_client(client
, "REQUEST (rebinding)");
985 log_dhcp_client(client
, "REQUEST (invalid)");
992 static int client_start(sd_dhcp_client
*client
);
994 static int client_timeout_resend(
999 sd_dhcp_client
*client
= userdata
;
1000 DHCP_CLIENT_DONT_DESTROY(client
);
1001 usec_t next_timeout
= 0;
1008 assert(client
->event
);
1010 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1014 switch (client
->state
) {
1016 case DHCP_STATE_RENEWING
:
1018 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
1022 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1026 case DHCP_STATE_REBINDING
:
1028 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
1032 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1035 case DHCP_STATE_REBOOTING
:
1036 /* start over as we did not receive a timely ack or nak */
1037 r
= client_initialize(client
);
1041 r
= client_start(client
);
1045 log_dhcp_client(client
, "REBOOTED");
1049 case DHCP_STATE_INIT
:
1050 case DHCP_STATE_INIT_REBOOT
:
1051 case DHCP_STATE_SELECTING
:
1052 case DHCP_STATE_REQUESTING
:
1053 case DHCP_STATE_BOUND
:
1055 if (client
->attempt
< 64)
1056 client
->attempt
*= 2;
1058 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
1062 case DHCP_STATE_STOPPED
:
1067 next_timeout
+= (random_u32() & 0x1fffff);
1069 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1070 clock_boottime_or_monotonic(),
1071 next_timeout
, 10 * USEC_PER_MSEC
,
1072 client_timeout_resend
, client
,
1073 client
->event_priority
, "dhcp4-resend-timer", true);
1077 switch (client
->state
) {
1078 case DHCP_STATE_INIT
:
1079 r
= client_send_discover(client
);
1081 client
->state
= DHCP_STATE_SELECTING
;
1082 client
->attempt
= 1;
1084 if (client
->attempt
>= 64)
1090 case DHCP_STATE_SELECTING
:
1091 r
= client_send_discover(client
);
1092 if (r
< 0 && client
->attempt
>= 64)
1097 case DHCP_STATE_INIT_REBOOT
:
1098 case DHCP_STATE_REQUESTING
:
1099 case DHCP_STATE_RENEWING
:
1100 case DHCP_STATE_REBINDING
:
1101 r
= client_send_request(client
);
1102 if (r
< 0 && client
->attempt
>= 64)
1105 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1106 client
->state
= DHCP_STATE_REBOOTING
;
1108 client
->request_sent
= time_now
;
1112 case DHCP_STATE_REBOOTING
:
1113 case DHCP_STATE_BOUND
:
1117 case DHCP_STATE_STOPPED
:
1125 client_stop(client
, r
);
1127 /* Errors were dealt with when stopping the client, don't spill
1128 errors into the event loop handler */
1132 static int client_initialize_io_events(
1133 sd_dhcp_client
*client
,
1134 sd_event_io_handler_t io_callback
) {
1139 assert(client
->event
);
1141 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1142 client
->fd
, EPOLLIN
, io_callback
,
1147 r
= sd_event_source_set_priority(client
->receive_message
,
1148 client
->event_priority
);
1152 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1158 client_stop(client
, r
);
1163 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1168 assert(client
->event
);
1170 if (client
->start_delay
) {
1171 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1172 usec
+= client
->start_delay
;
1175 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1176 clock_boottime_or_monotonic(),
1178 client_timeout_resend
, client
,
1179 client
->event_priority
, "dhcp4-resend-timer", true);
1181 client_stop(client
, r
);
1187 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1188 client_initialize_io_events(client
, io_callback
);
1189 client_initialize_time_events(client
);
1194 static int client_start_delayed(sd_dhcp_client
*client
) {
1197 assert_return(client
, -EINVAL
);
1198 assert_return(client
->event
, -EINVAL
);
1199 assert_return(client
->ifindex
> 0, -EINVAL
);
1200 assert_return(client
->fd
< 0, -EBUSY
);
1201 assert_return(client
->xid
== 0, -EINVAL
);
1202 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1204 client
->xid
= random_u32();
1206 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1207 client
->xid
, client
->mac_addr
,
1208 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1210 client_stop(client
, r
);
1215 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1216 client
->start_time
= now(clock_boottime_or_monotonic());
1218 return client_initialize_events(client
, client_receive_message_raw
);
1221 static int client_start(sd_dhcp_client
*client
) {
1222 client
->start_delay
= 0;
1223 return client_start_delayed(client
);
1226 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1227 sd_dhcp_client
*client
= userdata
;
1228 DHCP_CLIENT_DONT_DESTROY(client
);
1230 log_dhcp_client(client
, "EXPIRED");
1232 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1234 /* lease was lost, start over if not freed or stopped in callback */
1235 if (client
->state
!= DHCP_STATE_STOPPED
) {
1236 client_initialize(client
);
1237 client_start(client
);
1243 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1244 sd_dhcp_client
*client
= userdata
;
1245 DHCP_CLIENT_DONT_DESTROY(client
);
1250 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1251 client
->fd
= asynchronous_close(client
->fd
);
1253 client
->state
= DHCP_STATE_REBINDING
;
1254 client
->attempt
= 1;
1256 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1257 client
->xid
, client
->mac_addr
,
1258 client
->mac_addr_len
, client
->arp_type
,
1261 client_stop(client
, r
);
1266 return client_initialize_events(client
, client_receive_message_raw
);
1269 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1270 sd_dhcp_client
*client
= userdata
;
1271 DHCP_CLIENT_DONT_DESTROY(client
);
1273 client
->state
= DHCP_STATE_RENEWING
;
1274 client
->attempt
= 1;
1276 return client_initialize_time_events(client
);
1279 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1280 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1283 r
= dhcp_lease_new(&lease
);
1287 if (client
->client_id_len
) {
1288 r
= dhcp_lease_set_client_id(lease
,
1289 (uint8_t *) &client
->client_id
,
1290 client
->client_id_len
);
1295 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1296 if (r
!= DHCP_OFFER
) {
1297 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1301 lease
->next_server
= offer
->siaddr
;
1302 lease
->address
= offer
->yiaddr
;
1304 if (lease
->address
== 0 ||
1305 lease
->server_address
== 0 ||
1306 lease
->lifetime
== 0) {
1307 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1311 if (!lease
->have_subnet_mask
) {
1312 r
= dhcp_lease_set_default_subnet_mask(lease
);
1314 log_dhcp_client(client
,
1315 "received lease lacks subnet mask, "
1316 "and a fallback one cannot be generated, ignoring");
1321 sd_dhcp_lease_unref(client
->lease
);
1322 client
->lease
= TAKE_PTR(lease
);
1324 log_dhcp_client(client
, "OFFER");
1329 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1332 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1333 if (r
!= DHCP_FORCERENEW
)
1336 log_dhcp_client(client
, "FORCERENEW");
1341 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1342 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1343 _cleanup_free_
char *error_message
= NULL
;
1346 r
= dhcp_lease_new(&lease
);
1350 if (client
->client_id_len
) {
1351 r
= dhcp_lease_set_client_id(lease
,
1352 (uint8_t *) &client
->client_id
,
1353 client
->client_id_len
);
1358 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1359 if (r
== DHCP_NAK
) {
1360 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1361 return -EADDRNOTAVAIL
;
1364 if (r
!= DHCP_ACK
) {
1365 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1369 lease
->next_server
= ack
->siaddr
;
1371 lease
->address
= ack
->yiaddr
;
1373 if (lease
->address
== INADDR_ANY
||
1374 lease
->server_address
== INADDR_ANY
||
1375 lease
->lifetime
== 0) {
1376 log_dhcp_client(client
, "received lease lacks address, server "
1377 "address or lease lifetime, ignoring");
1381 if (lease
->subnet_mask
== INADDR_ANY
) {
1382 r
= dhcp_lease_set_default_subnet_mask(lease
);
1384 log_dhcp_client(client
,
1385 "received lease lacks subnet mask, "
1386 "and a fallback one cannot be generated, ignoring");
1391 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1392 if (client
->lease
) {
1393 if (client
->lease
->address
!= lease
->address
||
1394 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1395 client
->lease
->router
!= lease
->router
) {
1396 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1398 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1400 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1403 client
->lease
= TAKE_PTR(lease
);
1405 log_dhcp_client(client
, "ACK");
1410 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1412 assert(client
->request_sent
);
1413 assert(lifetime
> 0);
1420 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1421 + (random_u32() & 0x1fffff);
1424 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1426 uint64_t lifetime_timeout
;
1427 uint64_t t2_timeout
;
1428 uint64_t t1_timeout
;
1429 char time_string
[FORMAT_TIMESPAN_MAX
];
1433 assert(client
->event
);
1434 assert(client
->lease
);
1435 assert(client
->lease
->lifetime
);
1437 /* don't set timers for infinite leases */
1438 if (client
->lease
->lifetime
== 0xffffffff) {
1439 (void) event_source_disable(client
->timeout_t1
);
1440 (void) event_source_disable(client
->timeout_t2
);
1441 (void) event_source_disable(client
->timeout_expire
);
1446 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1449 assert(client
->request_sent
<= time_now
);
1451 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1452 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1453 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1454 /* both T1 and T2 are given */
1455 if (client
->lease
->t1
< client
->lease
->t2
&&
1456 client
->lease
->t2
< client
->lease
->lifetime
) {
1457 /* they are both valid */
1458 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1459 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1462 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1463 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1464 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1465 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1467 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1468 /* only T2 is given, and it is valid */
1469 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1470 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1471 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1472 if (t2_timeout
<= t1_timeout
) {
1473 /* the computed T1 would be invalid, so discard T2 */
1474 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1475 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1477 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1478 /* only T1 is given, and it is valid */
1479 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1480 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1481 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1482 if (t2_timeout
<= t1_timeout
) {
1483 /* the computed T2 would be invalid, so discard T1 */
1484 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1485 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1488 /* fall back to the default timeouts */
1489 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1490 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1491 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1492 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1495 /* arm lifetime timeout */
1496 r
= event_reset_time(client
->event
, &client
->timeout_expire
,
1497 clock_boottime_or_monotonic(),
1498 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1499 client_timeout_expire
, client
,
1500 client
->event_priority
, "dhcp4-lifetime", true);
1504 log_dhcp_client(client
, "lease expires in %s",
1505 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1507 /* don't arm earlier timeouts if this has already expired */
1508 if (lifetime_timeout
<= time_now
)
1511 /* arm T2 timeout */
1512 r
= event_reset_time(client
->event
, &client
->timeout_t2
,
1513 clock_boottime_or_monotonic(),
1514 t2_timeout
, 10 * USEC_PER_MSEC
,
1515 client_timeout_t2
, client
,
1516 client
->event_priority
, "dhcp4-t2-timeout", true);
1520 log_dhcp_client(client
, "T2 expires in %s",
1521 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1523 /* don't arm earlier timeout if this has already expired */
1524 if (t2_timeout
<= time_now
)
1527 /* arm T1 timeout */
1528 r
= event_reset_time(client
->event
, &client
->timeout_t1
,
1529 clock_boottime_or_monotonic(),
1530 t1_timeout
, 10 * USEC_PER_MSEC
,
1531 client_timeout_t1
, client
,
1532 client
->event_priority
, "dhcp4-t1-timer", true);
1536 log_dhcp_client(client
, "T1 expires in %s",
1537 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1542 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1543 DHCP_CLIENT_DONT_DESTROY(client
);
1544 char time_string
[FORMAT_TIMESPAN_MAX
];
1545 int r
= 0, notify_event
= 0;
1548 assert(client
->event
);
1551 switch (client
->state
) {
1552 case DHCP_STATE_SELECTING
:
1554 r
= client_handle_offer(client
, message
, len
);
1557 client
->state
= DHCP_STATE_REQUESTING
;
1558 client
->attempt
= 1;
1560 r
= event_reset_time(client
->event
, &client
->timeout_resend
,
1561 clock_boottime_or_monotonic(),
1563 client_timeout_resend
, client
,
1564 client
->event_priority
, "dhcp4-resend-timer", true);
1567 } else if (r
== -ENOMSG
)
1568 /* invalid message, let's ignore it */
1573 case DHCP_STATE_REBOOTING
:
1574 case DHCP_STATE_REQUESTING
:
1575 case DHCP_STATE_RENEWING
:
1576 case DHCP_STATE_REBINDING
:
1578 r
= client_handle_ack(client
, message
, len
);
1580 client
->start_delay
= 0;
1581 (void) event_source_disable(client
->timeout_resend
);
1582 client
->receive_message
=
1583 sd_event_source_unref(client
->receive_message
);
1584 client
->fd
= asynchronous_close(client
->fd
);
1586 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1587 DHCP_STATE_REBOOTING
))
1588 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1589 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1592 client
->state
= DHCP_STATE_BOUND
;
1593 client
->attempt
= 1;
1595 client
->last_addr
= client
->lease
->address
;
1597 r
= client_set_lease_timeouts(client
);
1599 log_dhcp_client(client
, "could not set lease timeouts");
1603 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1605 log_dhcp_client(client
, "could not bind UDP socket");
1611 client_initialize_io_events(client
, client_receive_message_udp
);
1614 client_notify(client
, notify_event
);
1615 if (client
->state
== DHCP_STATE_STOPPED
)
1619 } else if (r
== -EADDRNOTAVAIL
) {
1620 /* got a NAK, let's restart the client */
1621 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1623 r
= client_initialize(client
);
1627 r
= client_start_delayed(client
);
1631 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1632 client
->start_delay
, USEC_PER_SEC
));
1634 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1635 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1638 } else if (r
== -ENOMSG
)
1639 /* invalid message, let's ignore it */
1644 case DHCP_STATE_BOUND
:
1645 r
= client_handle_forcerenew(client
, message
, len
);
1647 r
= client_timeout_t1(NULL
, 0, client
);
1650 } else if (r
== -ENOMSG
)
1651 /* invalid message, let's ignore it */
1656 case DHCP_STATE_INIT
:
1657 case DHCP_STATE_INIT_REBOOT
:
1661 case DHCP_STATE_STOPPED
:
1668 client_stop(client
, r
);
1673 static int client_receive_message_udp(
1679 sd_dhcp_client
*client
= userdata
;
1680 _cleanup_free_ DHCPMessage
*message
= NULL
;
1681 const struct ether_addr zero_mac
= {};
1682 const struct ether_addr
*expected_chaddr
= NULL
;
1683 uint8_t expected_hlen
= 0;
1684 ssize_t len
, buflen
;
1689 buflen
= next_datagram_size_fd(fd
);
1693 message
= malloc0(buflen
);
1697 len
= recv(fd
, message
, buflen
, 0);
1699 if (IN_SET(errno
, EAGAIN
, EINTR
))
1702 return log_dhcp_client_errno(client
, errno
,
1703 "Could not receive message from UDP socket: %m");
1705 if ((size_t) len
< sizeof(DHCPMessage
)) {
1706 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1710 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1711 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1715 if (message
->op
!= BOOTREPLY
) {
1716 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1720 if (message
->htype
!= client
->arp_type
) {
1721 log_dhcp_client(client
, "Packet type does not match client type");
1725 if (client
->arp_type
== ARPHRD_ETHER
) {
1726 expected_hlen
= ETH_ALEN
;
1727 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1729 /* Non-Ethernet links expect zero chaddr */
1731 expected_chaddr
= &zero_mac
;
1734 if (message
->hlen
!= expected_hlen
) {
1735 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1739 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1740 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1744 if (client
->state
!= DHCP_STATE_BOUND
&&
1745 be32toh(message
->xid
) != client
->xid
) {
1746 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1747 so ignore the xid in this case */
1748 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1749 be32toh(message
->xid
), client
->xid
);
1753 return client_handle_message(client
, message
, len
);
1756 static int client_receive_message_raw(
1762 sd_dhcp_client
*client
= userdata
;
1763 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1764 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1765 struct iovec iov
= {};
1766 struct msghdr msg
= {
1769 .msg_control
= cmsgbuf
,
1770 .msg_controllen
= sizeof(cmsgbuf
),
1772 struct cmsghdr
*cmsg
;
1773 bool checksum
= true;
1774 ssize_t buflen
, len
;
1780 buflen
= next_datagram_size_fd(fd
);
1784 packet
= malloc0(buflen
);
1788 iov
= IOVEC_MAKE(packet
, buflen
);
1790 len
= recvmsg(fd
, &msg
, 0);
1792 if (IN_SET(errno
, EAGAIN
, EINTR
))
1795 return log_dhcp_client_errno(client
, errno
,
1796 "Could not receive message from raw socket: %m");
1797 } else if ((size_t)len
< sizeof(DHCPPacket
))
1800 CMSG_FOREACH(cmsg
, &msg
) {
1801 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1802 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1803 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1804 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1806 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1811 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1815 len
-= DHCP_IP_UDP_SIZE
;
1817 return client_handle_message(client
, &packet
->dhcp
, len
);
1820 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1823 assert_return(client
, -EINVAL
);
1825 r
= client_initialize(client
);
1829 /* RFC7844 section 3.3:
1830 SHOULD perform a complete four-way handshake, starting with a
1831 DHCPDISCOVER, to obtain a new address lease. If the client can
1832 ascertain that this is exactly the same network to which it was
1833 previously connected, and if the link-layer address did not change,
1834 the client MAY issue a DHCPREQUEST to try to reclaim the current
1836 if (client
->last_addr
&& !client
->anonymize
)
1837 client
->state
= DHCP_STATE_INIT_REBOOT
;
1839 r
= client_start(client
);
1841 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1846 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1847 DHCP_CLIENT_DONT_DESTROY(client
);
1849 assert_return(client
, -EINVAL
);
1851 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1852 client
->state
= DHCP_STATE_STOPPED
;
1857 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1860 assert_return(client
, -EINVAL
);
1861 assert_return(!client
->event
, -EBUSY
);
1864 client
->event
= sd_event_ref(event
);
1866 r
= sd_event_default(&client
->event
);
1871 client
->event_priority
= priority
;
1876 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1877 assert_return(client
, -EINVAL
);
1879 client
->event
= sd_event_unref(client
->event
);
1884 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1885 assert_return(client
, NULL
);
1887 return client
->event
;
1890 static sd_dhcp_client
*dhcp_client_free(sd_dhcp_client
*client
) {
1893 log_dhcp_client(client
, "FREE");
1895 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1896 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1897 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1898 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1900 client_initialize(client
);
1902 sd_dhcp_client_detach_event(client
);
1904 sd_dhcp_lease_unref(client
->lease
);
1906 free(client
->req_opts
);
1907 free(client
->hostname
);
1908 free(client
->vendor_class_identifier
);
1909 client
->user_class
= strv_free(client
->user_class
);
1910 return mfree(client
);
1913 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client
, sd_dhcp_client
, dhcp_client_free
);
1915 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1916 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1918 assert_return(ret
, -EINVAL
);
1920 client
= new(sd_dhcp_client
, 1);
1924 *client
= (sd_dhcp_client
) {
1926 .state
= DHCP_STATE_INIT
,
1930 .mtu
= DHCP_DEFAULT_MIN_SIZE
,
1931 .port
= DHCP_PORT_CLIENT
,
1932 .anonymize
= !!anonymize
,
1934 /* NOTE: this could be moved to a function. */
1936 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
1937 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
1939 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1940 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1942 if (!client
->req_opts
)
1945 *ret
= TAKE_PTR(client
);