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 "hostname-util.h"
25 #include "random-util.h"
26 #include "string-util.h"
30 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
31 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
33 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
34 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
36 struct sd_dhcp_client
{
42 sd_event_source
*timeout_resend
;
46 union sockaddr_union link
;
47 sd_event_source
*receive_message
;
48 bool request_broadcast
;
50 size_t req_opts_allocated
;
54 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
61 /* 0: Generic (non-LL) (RFC 2132) */
62 uint8_t data
[MAX_CLIENT_ID_LEN
];
65 /* 1: Ethernet Link-Layer (RFC 2132) */
66 uint8_t haddr
[ETH_ALEN
];
69 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
73 /* 255: Node-specific (RFC 4361) */
78 uint8_t data
[MAX_CLIENT_ID_LEN
];
84 char *vendor_class_identifier
;
91 sd_event_source
*timeout_t1
;
92 sd_event_source
*timeout_t2
;
93 sd_event_source
*timeout_expire
;
94 sd_dhcp_client_callback_t callback
;
100 static const uint8_t default_req_opts
[] = {
101 SD_DHCP_OPTION_SUBNET_MASK
,
102 SD_DHCP_OPTION_ROUTER
,
103 SD_DHCP_OPTION_HOST_NAME
,
104 SD_DHCP_OPTION_DOMAIN_NAME
,
105 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
,
108 /* RFC7844 section 3:
109 MAY contain the Parameter Request List option.
111 The client intending to protect its privacy SHOULD only request a
112 minimal number of options in the PRL and SHOULD also randomly shuffle
113 the ordering of option codes in the PRL. If this random ordering
114 cannot be implemented, the client MAY order the option codes in the
115 PRL by option code number (lowest to highest).
117 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
118 static const uint8_t default_req_opts_anonymize
[] = {
119 SD_DHCP_OPTION_SUBNET_MASK
, /* 1 */
120 SD_DHCP_OPTION_ROUTER
, /* 3 */
121 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
, /* 6 */
122 SD_DHCP_OPTION_DOMAIN_NAME
, /* 15 */
123 SD_DHCP_OPTION_ROUTER_DISCOVER
, /* 31 */
124 SD_DHCP_OPTION_STATIC_ROUTE
, /* 33 */
125 SD_DHCP_OPTION_VENDOR_SPECIFIC
, /* 43 */
126 SD_DHCP_OPTION_NETBIOS_NAMESERVER
, /* 44 */
127 SD_DHCP_OPTION_NETBIOS_NODETYPE
, /* 46 */
128 SD_DHCP_OPTION_NETBIOS_SCOPE
, /* 47 */
129 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
, /* 121 */
130 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE
, /* 249 */
131 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY
, /* 252 */
134 static int client_receive_message_raw(
139 static int client_receive_message_udp(
144 static void client_stop(sd_dhcp_client
*client
, int error
);
146 int sd_dhcp_client_set_callback(
147 sd_dhcp_client
*client
,
148 sd_dhcp_client_callback_t cb
,
151 assert_return(client
, -EINVAL
);
153 client
->callback
= cb
;
154 client
->userdata
= userdata
;
159 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client
*client
, int broadcast
) {
160 assert_return(client
, -EINVAL
);
162 client
->request_broadcast
= !!broadcast
;
167 int sd_dhcp_client_set_request_option(sd_dhcp_client
*client
, uint8_t option
) {
170 assert_return(client
, -EINVAL
);
171 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
175 case SD_DHCP_OPTION_PAD
:
176 case SD_DHCP_OPTION_OVERLOAD
:
177 case SD_DHCP_OPTION_MESSAGE_TYPE
:
178 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
:
179 case SD_DHCP_OPTION_END
:
186 for (i
= 0; i
< client
->req_opts_size
; i
++)
187 if (client
->req_opts
[i
] == option
)
190 if (!GREEDY_REALLOC(client
->req_opts
, client
->req_opts_allocated
,
191 client
->req_opts_size
+ 1))
194 client
->req_opts
[client
->req_opts_size
++] = option
;
199 int sd_dhcp_client_set_request_address(
200 sd_dhcp_client
*client
,
201 const struct in_addr
*last_addr
) {
203 assert_return(client
, -EINVAL
);
204 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
207 client
->last_addr
= last_addr
->s_addr
;
209 client
->last_addr
= INADDR_ANY
;
214 int sd_dhcp_client_set_ifindex(sd_dhcp_client
*client
, int ifindex
) {
216 assert_return(client
, -EINVAL
);
217 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
218 assert_return(ifindex
> 0, -EINVAL
);
220 client
->ifindex
= ifindex
;
224 int sd_dhcp_client_set_mac(
225 sd_dhcp_client
*client
,
230 DHCP_CLIENT_DONT_DESTROY(client
);
231 bool need_restart
= false;
233 assert_return(client
, -EINVAL
);
234 assert_return(addr
, -EINVAL
);
235 assert_return(addr_len
> 0 && addr_len
<= MAX_MAC_ADDR_LEN
, -EINVAL
);
236 assert_return(arp_type
> 0, -EINVAL
);
238 if (arp_type
== ARPHRD_ETHER
)
239 assert_return(addr_len
== ETH_ALEN
, -EINVAL
);
240 else if (arp_type
== ARPHRD_INFINIBAND
)
241 assert_return(addr_len
== INFINIBAND_ALEN
, -EINVAL
);
245 if (client
->mac_addr_len
== addr_len
&&
246 memcmp(&client
->mac_addr
, addr
, addr_len
) == 0)
249 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
250 log_dhcp_client(client
, "Changing MAC address on running DHCP client, restarting");
252 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
255 memcpy(&client
->mac_addr
, addr
, addr_len
);
256 client
->mac_addr_len
= addr_len
;
257 client
->arp_type
= arp_type
;
259 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
260 sd_dhcp_client_start(client
);
265 int sd_dhcp_client_get_client_id(
266 sd_dhcp_client
*client
,
268 const uint8_t **data
,
271 assert_return(client
, -EINVAL
);
272 assert_return(type
, -EINVAL
);
273 assert_return(data
, -EINVAL
);
274 assert_return(data_len
, -EINVAL
);
279 if (client
->client_id_len
) {
280 *type
= client
->client_id
.type
;
281 *data
= client
->client_id
.raw
.data
;
282 *data_len
= client
->client_id_len
- sizeof(client
->client_id
.type
);
288 int sd_dhcp_client_set_client_id(
289 sd_dhcp_client
*client
,
294 DHCP_CLIENT_DONT_DESTROY(client
);
295 bool need_restart
= false;
297 assert_return(client
, -EINVAL
);
298 assert_return(data
, -EINVAL
);
299 assert_return(data_len
> 0 && data_len
<= MAX_CLIENT_ID_LEN
, -EINVAL
);
304 if (data_len
!= ETH_ALEN
)
308 case ARPHRD_INFINIBAND
:
309 if (data_len
!= INFINIBAND_ALEN
)
317 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
318 client
->client_id
.type
== type
&&
319 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
322 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
323 log_dhcp_client(client
, "Changing client ID on running DHCP "
324 "client, restarting");
326 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
329 client
->client_id
.type
= type
;
330 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
331 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
333 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
334 sd_dhcp_client_start(client
);
340 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
341 * without further modification. Otherwise, if duid_type is supported, DUID
342 * is set based on that type. Otherwise, an error is returned.
344 static int dhcp_client_set_iaid_duid_internal(
345 sd_dhcp_client
*client
,
353 DHCP_CLIENT_DONT_DESTROY(client
);
357 assert_return(client
, -EINVAL
);
358 assert_return(duid_len
== 0 || duid
!= NULL
, -EINVAL
);
361 r
= dhcp_validate_duid_len(duid_type
, duid_len
);
366 zero(client
->client_id
);
367 client
->client_id
.type
= 255;
370 /* If IAID is not configured, generate it. */
372 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
373 client
->mac_addr_len
,
375 &client
->client_id
.ns
.iaid
);
379 client
->client_id
.ns
.iaid
= htobe32(iaid
);
383 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
384 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
385 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
389 if (client
->mac_addr_len
== 0)
392 r
= dhcp_identifier_set_duid_llt(&client
->client_id
.ns
.duid
, llt_time
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
397 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
402 if (client
->mac_addr_len
== 0)
405 r
= dhcp_identifier_set_duid_ll(&client
->client_id
.ns
.duid
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
410 r
= dhcp_identifier_set_duid_uuid(&client
->client_id
.ns
.duid
, &len
);
418 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
419 (append_iaid
? sizeof(client
->client_id
.ns
.iaid
) : 0);
421 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
422 log_dhcp_client(client
, "Configured %sDUID, restarting.", append_iaid
? "IAID+" : "");
423 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
424 sd_dhcp_client_start(client
);
430 int sd_dhcp_client_set_iaid_duid(
431 sd_dhcp_client
*client
,
436 return dhcp_client_set_iaid_duid_internal(client
, iaid
, true, duid_type
, duid
, duid_len
, 0);
439 int sd_dhcp_client_set_iaid_duid_llt(
440 sd_dhcp_client
*client
,
443 return dhcp_client_set_iaid_duid_internal(client
, iaid
, true, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
446 int sd_dhcp_client_set_duid(
447 sd_dhcp_client
*client
,
451 return dhcp_client_set_iaid_duid_internal(client
, 0, false, duid_type
, duid
, duid_len
, 0);
454 int sd_dhcp_client_set_duid_llt(
455 sd_dhcp_client
*client
,
457 return dhcp_client_set_iaid_duid_internal(client
, 0, false, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
460 int sd_dhcp_client_set_hostname(
461 sd_dhcp_client
*client
,
462 const char *hostname
) {
464 assert_return(client
, -EINVAL
);
466 /* Make sure hostnames qualify as DNS and as Linux hostnames */
468 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
471 return free_and_strdup(&client
->hostname
, hostname
);
474 int sd_dhcp_client_set_vendor_class_identifier(
475 sd_dhcp_client
*client
,
478 assert_return(client
, -EINVAL
);
480 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
483 int sd_dhcp_client_set_user_class(
484 sd_dhcp_client
*client
,
485 const char* const* user_class
) {
487 _cleanup_strv_free_
char **s
= NULL
;
490 STRV_FOREACH(p
, (char **) user_class
)
491 if (strlen(*p
) > 255)
492 return -ENAMETOOLONG
;
494 s
= strv_copy((char **) user_class
);
498 client
->user_class
= TAKE_PTR(s
);
503 int sd_dhcp_client_set_client_port(
504 sd_dhcp_client
*client
,
507 assert_return(client
, -EINVAL
);
514 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
515 assert_return(client
, -EINVAL
);
516 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
523 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
524 assert_return(client
, -EINVAL
);
526 if (!IN_SET(client
->state
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
527 return -EADDRNOTAVAIL
;
530 *ret
= client
->lease
;
535 static void client_notify(sd_dhcp_client
*client
, int event
) {
538 if (client
->callback
)
539 client
->callback(client
, event
, client
->userdata
);
542 static int client_initialize(sd_dhcp_client
*client
) {
543 assert_return(client
, -EINVAL
);
545 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
547 client
->fd
= asynchronous_close(client
->fd
);
549 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
551 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
552 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
553 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
557 client
->state
= DHCP_STATE_INIT
;
560 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
565 static void client_stop(sd_dhcp_client
*client
, int error
) {
569 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
570 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
571 log_dhcp_client(client
, "STOPPED");
573 log_dhcp_client(client
, "STOPPED: Unknown event");
575 client_notify(client
, error
);
577 client_initialize(client
);
580 static int client_message_init(
581 sd_dhcp_client
*client
,
585 size_t *_optoffset
) {
587 _cleanup_free_ DHCPPacket
*packet
= NULL
;
588 size_t optlen
, optoffset
, size
;
595 assert(client
->start_time
);
599 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
));
601 optlen
= DHCP_MIN_OPTIONS_SIZE
;
602 size
= sizeof(DHCPPacket
) + optlen
;
604 packet
= malloc0(size
);
608 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
609 client
->arp_type
, optlen
, &optoffset
);
613 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
614 refuse to issue an DHCP lease if 'secs' is set to zero */
615 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
618 assert(time_now
>= client
->start_time
);
620 /* seconds between sending first and last DISCOVER
621 * must always be strictly positive to deal with broken servers */
622 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
623 packet
->dhcp
.secs
= htobe16(secs
);
625 /* RFC2132 section 4.1
626 A client that cannot receive unicast IP datagrams until its protocol
627 software has been configured with an IP address SHOULD set the
628 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
629 DHCPREQUEST messages that client sends. The BROADCAST bit will
630 provide a hint to the DHCP server and BOOTP relay agent to broadcast
631 any messages to the client on the client's subnet.
633 Note: some interfaces needs this to be enabled, but some networks
634 needs this to be disabled as broadcasts are filteretd, so this
635 needs to be configurable */
636 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
637 packet
->dhcp
.flags
= htobe16(0x8000);
639 /* RFC2132 section 4.1.1:
640 The client MUST include its hardware address in the ’chaddr’ field, if
641 necessary for delivery of DHCP reply messages. Non-Ethernet
642 interfaces will leave 'chaddr' empty and use the client identifier
643 instead (eg, RFC 4390 section 2.1).
645 if (client
->arp_type
== ARPHRD_ETHER
)
646 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
648 /* If no client identifier exists, construct an RFC 4361-compliant one */
649 if (client
->client_id_len
== 0) {
652 client
->client_id
.type
= 255;
654 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
,
655 true, &client
->client_id
.ns
.iaid
);
659 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
663 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
666 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
667 Identifier option is not set */
668 if (client
->client_id_len
) {
669 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
670 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
671 client
->client_id_len
,
677 /* RFC2131 section 3.5:
678 in its initial DHCPDISCOVER or DHCPREQUEST message, a
679 client may provide the server with a list of specific
680 parameters the client is interested in. If the client
681 includes a list of parameters in a DHCPDISCOVER message,
682 it MUST include that list in any subsequent DHCPREQUEST
686 /* RFC7844 section 3:
687 MAY contain the Parameter Request List option. */
688 /* NOTE: in case that there would be an option to do not send
689 * any PRL at all, the size should be checked before sending */
690 if (client
->req_opts_size
> 0) {
691 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
692 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
693 client
->req_opts_size
, client
->req_opts
);
698 /* RFC2131 section 3.5:
699 The client SHOULD include the ’maximum DHCP message size’ option to
700 let the server know how large the server may make its DHCP messages.
702 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
703 than the defined default size unless the Maximum Message Size option
706 RFC3442 "Requirements to Avoid Sizing Constraints":
707 Because a full routing table can be quite large, the standard 576
708 octet maximum size for a DHCP message may be too short to contain
709 some legitimate Classless Static Route options. Because of this,
710 clients implementing the Classless Static Route option SHOULD send a
711 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
712 stack is capable of receiving larger IP datagrams. In this case, the
713 client SHOULD set the value of this option to at least the MTU of the
714 interface that the client is configuring. The client MAY set the
715 value of this option higher, up to the size of the largest UDP packet
716 it is prepared to accept. (Note that the value specified in the
717 Maximum DHCP Message Size option is the total maximum packet size,
718 including IP and UDP headers.)
720 /* RFC7844 section 3:
721 SHOULD NOT contain any other option. */
722 if (!client
->anonymize
) {
723 max_size
= htobe16(size
);
724 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
725 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
732 *_optoffset
= optoffset
;
733 *ret
= TAKE_PTR(packet
);
738 static int client_append_fqdn_option(
739 DHCPMessage
*message
,
744 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
747 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
748 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
749 buffer
[1] = 0; /* RCODE1 (deprecated) */
750 buffer
[2] = 0; /* RCODE2 (deprecated) */
752 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
754 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
755 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
760 static int dhcp_client_send_raw(
761 sd_dhcp_client
*client
,
765 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
766 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
768 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
772 static int client_send_discover(sd_dhcp_client
*client
) {
773 _cleanup_free_ DHCPPacket
*discover
= NULL
;
774 size_t optoffset
, optlen
;
778 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
780 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
781 &optlen
, &optoffset
);
785 /* the client may suggest values for the network address
786 and lease time in the DHCPDISCOVER message. The client may include
787 the ’requested IP address’ option to suggest that a particular IP
788 address be assigned, and may include the ’IP address lease time’
789 option to suggest the lease time it would like.
791 if (client
->last_addr
!= INADDR_ANY
) {
792 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
793 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
794 4, &client
->last_addr
);
799 if (client
->hostname
) {
800 /* According to RFC 4702 "clients that send the Client FQDN option in
801 their messages MUST NOT also send the Host Name option". Just send
802 one of the two depending on the hostname type.
804 if (dns_name_is_single_label(client
->hostname
)) {
805 /* it is unclear from RFC 2131 if client should send hostname in
806 DHCPDISCOVER but dhclient does and so we do as well
808 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
809 SD_DHCP_OPTION_HOST_NAME
,
810 strlen(client
->hostname
), client
->hostname
);
812 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
818 if (client
->vendor_class_identifier
) {
819 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
820 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
821 strlen(client
->vendor_class_identifier
),
822 client
->vendor_class_identifier
);
827 if (client
->user_class
) {
828 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
829 SD_DHCP_OPTION_USER_CLASS
,
830 strv_length(client
->user_class
),
836 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
837 SD_DHCP_OPTION_END
, 0, NULL
);
841 /* We currently ignore:
842 The client SHOULD wait a random time between one and ten seconds to
843 desynchronize the use of DHCP at startup.
845 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
849 log_dhcp_client(client
, "DISCOVER");
854 static int client_send_request(sd_dhcp_client
*client
) {
855 _cleanup_free_ DHCPPacket
*request
= NULL
;
856 size_t optoffset
, optlen
;
861 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
865 switch (client
->state
) {
866 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
867 SELECTING should be REQUESTING)
870 case DHCP_STATE_REQUESTING
:
871 /* Client inserts the address of the selected server in ’server
872 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
873 filled in with the yiaddr value from the chosen DHCPOFFER.
876 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
877 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
878 4, &client
->lease
->server_address
);
882 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
883 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
884 4, &client
->lease
->address
);
890 case DHCP_STATE_INIT_REBOOT
:
891 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
892 option MUST be filled in with client’s notion of its previously
893 assigned address. ’ciaddr’ MUST be zero.
895 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
896 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
897 4, &client
->last_addr
);
902 case DHCP_STATE_RENEWING
:
903 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
904 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
908 case DHCP_STATE_REBINDING
:
909 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
910 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
913 This message MUST be broadcast to the 0xffffffff IP broadcast address.
915 request
->dhcp
.ciaddr
= client
->lease
->address
;
919 case DHCP_STATE_INIT
:
920 case DHCP_STATE_SELECTING
:
921 case DHCP_STATE_REBOOTING
:
922 case DHCP_STATE_BOUND
:
923 case DHCP_STATE_STOPPED
:
927 if (client
->hostname
) {
928 if (dns_name_is_single_label(client
->hostname
))
929 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
930 SD_DHCP_OPTION_HOST_NAME
,
931 strlen(client
->hostname
), client
->hostname
);
933 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
939 if (client
->vendor_class_identifier
) {
940 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
941 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
942 strlen(client
->vendor_class_identifier
),
943 client
->vendor_class_identifier
);
948 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
949 SD_DHCP_OPTION_END
, 0, NULL
);
953 if (client
->state
== DHCP_STATE_RENEWING
) {
954 r
= dhcp_network_send_udp_socket(client
->fd
,
955 client
->lease
->server_address
,
958 sizeof(DHCPMessage
) + optoffset
);
960 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
965 switch (client
->state
) {
967 case DHCP_STATE_REQUESTING
:
968 log_dhcp_client(client
, "REQUEST (requesting)");
971 case DHCP_STATE_INIT_REBOOT
:
972 log_dhcp_client(client
, "REQUEST (init-reboot)");
975 case DHCP_STATE_RENEWING
:
976 log_dhcp_client(client
, "REQUEST (renewing)");
979 case DHCP_STATE_REBINDING
:
980 log_dhcp_client(client
, "REQUEST (rebinding)");
984 log_dhcp_client(client
, "REQUEST (invalid)");
991 static int client_start(sd_dhcp_client
*client
);
993 static int client_timeout_resend(
998 sd_dhcp_client
*client
= userdata
;
999 DHCP_CLIENT_DONT_DESTROY(client
);
1000 usec_t next_timeout
= 0;
1007 assert(client
->event
);
1009 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1013 switch (client
->state
) {
1015 case DHCP_STATE_RENEWING
:
1017 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
1021 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1025 case DHCP_STATE_REBINDING
:
1027 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
1031 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1034 case DHCP_STATE_REBOOTING
:
1035 /* start over as we did not receive a timely ack or nak */
1036 r
= client_initialize(client
);
1040 r
= client_start(client
);
1044 log_dhcp_client(client
, "REBOOTED");
1048 case DHCP_STATE_INIT
:
1049 case DHCP_STATE_INIT_REBOOT
:
1050 case DHCP_STATE_SELECTING
:
1051 case DHCP_STATE_REQUESTING
:
1052 case DHCP_STATE_BOUND
:
1054 if (client
->attempt
< 64)
1055 client
->attempt
*= 2;
1057 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
1061 case DHCP_STATE_STOPPED
:
1066 next_timeout
+= (random_u32() & 0x1fffff);
1068 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1070 r
= sd_event_add_time(client
->event
,
1071 &client
->timeout_resend
,
1072 clock_boottime_or_monotonic(),
1073 next_timeout
, 10 * USEC_PER_MSEC
,
1074 client_timeout_resend
, client
);
1078 r
= sd_event_source_set_priority(client
->timeout_resend
,
1079 client
->event_priority
);
1083 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1087 switch (client
->state
) {
1088 case DHCP_STATE_INIT
:
1089 r
= client_send_discover(client
);
1091 client
->state
= DHCP_STATE_SELECTING
;
1092 client
->attempt
= 1;
1094 if (client
->attempt
>= 64)
1100 case DHCP_STATE_SELECTING
:
1101 r
= client_send_discover(client
);
1102 if (r
< 0 && client
->attempt
>= 64)
1107 case DHCP_STATE_INIT_REBOOT
:
1108 case DHCP_STATE_REQUESTING
:
1109 case DHCP_STATE_RENEWING
:
1110 case DHCP_STATE_REBINDING
:
1111 r
= client_send_request(client
);
1112 if (r
< 0 && client
->attempt
>= 64)
1115 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1116 client
->state
= DHCP_STATE_REBOOTING
;
1118 client
->request_sent
= time_now
;
1122 case DHCP_STATE_REBOOTING
:
1123 case DHCP_STATE_BOUND
:
1127 case DHCP_STATE_STOPPED
:
1135 client_stop(client
, r
);
1137 /* Errors were dealt with when stopping the client, don't spill
1138 errors into the event loop handler */
1142 static int client_initialize_io_events(
1143 sd_dhcp_client
*client
,
1144 sd_event_io_handler_t io_callback
) {
1149 assert(client
->event
);
1151 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1152 client
->fd
, EPOLLIN
, io_callback
,
1157 r
= sd_event_source_set_priority(client
->receive_message
,
1158 client
->event_priority
);
1162 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1168 client_stop(client
, r
);
1173 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1178 assert(client
->event
);
1180 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1182 if (client
->start_delay
) {
1183 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1184 usec
+= client
->start_delay
;
1187 r
= sd_event_add_time(client
->event
,
1188 &client
->timeout_resend
,
1189 clock_boottime_or_monotonic(),
1191 client_timeout_resend
, client
);
1195 r
= sd_event_source_set_priority(client
->timeout_resend
,
1196 client
->event_priority
);
1200 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1206 client_stop(client
, r
);
1212 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1213 client_initialize_io_events(client
, io_callback
);
1214 client_initialize_time_events(client
);
1219 static int client_start_delayed(sd_dhcp_client
*client
) {
1222 assert_return(client
, -EINVAL
);
1223 assert_return(client
->event
, -EINVAL
);
1224 assert_return(client
->ifindex
> 0, -EINVAL
);
1225 assert_return(client
->fd
< 0, -EBUSY
);
1226 assert_return(client
->xid
== 0, -EINVAL
);
1227 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1229 client
->xid
= random_u32();
1231 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1232 client
->xid
, client
->mac_addr
,
1233 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1235 client_stop(client
, r
);
1240 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1241 client
->start_time
= now(clock_boottime_or_monotonic());
1243 return client_initialize_events(client
, client_receive_message_raw
);
1246 static int client_start(sd_dhcp_client
*client
) {
1247 client
->start_delay
= 0;
1248 return client_start_delayed(client
);
1251 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1252 sd_dhcp_client
*client
= userdata
;
1253 DHCP_CLIENT_DONT_DESTROY(client
);
1255 log_dhcp_client(client
, "EXPIRED");
1257 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1259 /* lease was lost, start over if not freed or stopped in callback */
1260 if (client
->state
!= DHCP_STATE_STOPPED
) {
1261 client_initialize(client
);
1262 client_start(client
);
1268 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1269 sd_dhcp_client
*client
= userdata
;
1270 DHCP_CLIENT_DONT_DESTROY(client
);
1275 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1276 client
->fd
= asynchronous_close(client
->fd
);
1278 client
->state
= DHCP_STATE_REBINDING
;
1279 client
->attempt
= 1;
1281 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1282 client
->xid
, client
->mac_addr
,
1283 client
->mac_addr_len
, client
->arp_type
,
1286 client_stop(client
, r
);
1291 return client_initialize_events(client
, client_receive_message_raw
);
1294 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1295 sd_dhcp_client
*client
= userdata
;
1296 DHCP_CLIENT_DONT_DESTROY(client
);
1298 client
->state
= DHCP_STATE_RENEWING
;
1299 client
->attempt
= 1;
1301 return client_initialize_time_events(client
);
1304 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1305 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1308 r
= dhcp_lease_new(&lease
);
1312 if (client
->client_id_len
) {
1313 r
= dhcp_lease_set_client_id(lease
,
1314 (uint8_t *) &client
->client_id
,
1315 client
->client_id_len
);
1320 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1321 if (r
!= DHCP_OFFER
) {
1322 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1326 lease
->next_server
= offer
->siaddr
;
1327 lease
->address
= offer
->yiaddr
;
1329 if (lease
->address
== 0 ||
1330 lease
->server_address
== 0 ||
1331 lease
->lifetime
== 0) {
1332 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1336 if (!lease
->have_subnet_mask
) {
1337 r
= dhcp_lease_set_default_subnet_mask(lease
);
1339 log_dhcp_client(client
,
1340 "received lease lacks subnet mask, "
1341 "and a fallback one cannot be generated, ignoring");
1346 sd_dhcp_lease_unref(client
->lease
);
1347 client
->lease
= TAKE_PTR(lease
);
1349 log_dhcp_client(client
, "OFFER");
1354 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1357 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1358 if (r
!= DHCP_FORCERENEW
)
1361 log_dhcp_client(client
, "FORCERENEW");
1366 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1367 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1368 _cleanup_free_
char *error_message
= NULL
;
1371 r
= dhcp_lease_new(&lease
);
1375 if (client
->client_id_len
) {
1376 r
= dhcp_lease_set_client_id(lease
,
1377 (uint8_t *) &client
->client_id
,
1378 client
->client_id_len
);
1383 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1384 if (r
== DHCP_NAK
) {
1385 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1386 return -EADDRNOTAVAIL
;
1389 if (r
!= DHCP_ACK
) {
1390 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1394 lease
->next_server
= ack
->siaddr
;
1396 lease
->address
= ack
->yiaddr
;
1398 if (lease
->address
== INADDR_ANY
||
1399 lease
->server_address
== INADDR_ANY
||
1400 lease
->lifetime
== 0) {
1401 log_dhcp_client(client
, "received lease lacks address, server "
1402 "address or lease lifetime, ignoring");
1406 if (lease
->subnet_mask
== INADDR_ANY
) {
1407 r
= dhcp_lease_set_default_subnet_mask(lease
);
1409 log_dhcp_client(client
,
1410 "received lease lacks subnet mask, "
1411 "and a fallback one cannot be generated, ignoring");
1416 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1417 if (client
->lease
) {
1418 if (client
->lease
->address
!= lease
->address
||
1419 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1420 client
->lease
->router
!= lease
->router
) {
1421 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1423 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1425 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1428 client
->lease
= TAKE_PTR(lease
);
1430 log_dhcp_client(client
, "ACK");
1435 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1437 assert(client
->request_sent
);
1438 assert(lifetime
> 0);
1445 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1446 + (random_u32() & 0x1fffff);
1449 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1451 uint64_t lifetime_timeout
;
1452 uint64_t t2_timeout
;
1453 uint64_t t1_timeout
;
1454 char time_string
[FORMAT_TIMESPAN_MAX
];
1458 assert(client
->event
);
1459 assert(client
->lease
);
1460 assert(client
->lease
->lifetime
);
1462 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1463 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1464 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1466 /* don't set timers for infinite leases */
1467 if (client
->lease
->lifetime
== 0xffffffff)
1470 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1473 assert(client
->request_sent
<= time_now
);
1475 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1476 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1477 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1478 /* both T1 and T2 are given */
1479 if (client
->lease
->t1
< client
->lease
->t2
&&
1480 client
->lease
->t2
< client
->lease
->lifetime
) {
1481 /* they are both valid */
1482 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1483 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1486 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1487 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1488 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1489 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1491 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1492 /* only T2 is given, and it is valid */
1493 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1494 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1495 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1496 if (t2_timeout
<= t1_timeout
) {
1497 /* the computed T1 would be invalid, so discard T2 */
1498 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1499 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1501 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1502 /* only T1 is given, and it is valid */
1503 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1504 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1505 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1506 if (t2_timeout
<= t1_timeout
) {
1507 /* the computed T2 would be invalid, so discard T1 */
1508 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1509 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1512 /* fall back to the default timeouts */
1513 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1514 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1515 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1516 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1519 /* arm lifetime timeout */
1520 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1521 clock_boottime_or_monotonic(),
1522 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1523 client_timeout_expire
, client
);
1527 r
= sd_event_source_set_priority(client
->timeout_expire
,
1528 client
->event_priority
);
1532 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1536 log_dhcp_client(client
, "lease expires in %s",
1537 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1539 /* don't arm earlier timeouts if this has already expired */
1540 if (lifetime_timeout
<= time_now
)
1543 /* arm T2 timeout */
1544 r
= sd_event_add_time(client
->event
,
1545 &client
->timeout_t2
,
1546 clock_boottime_or_monotonic(),
1549 client_timeout_t2
, client
);
1553 r
= sd_event_source_set_priority(client
->timeout_t2
,
1554 client
->event_priority
);
1558 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1562 log_dhcp_client(client
, "T2 expires in %s",
1563 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1565 /* don't arm earlier timeout if this has already expired */
1566 if (t2_timeout
<= time_now
)
1569 /* arm T1 timeout */
1570 r
= sd_event_add_time(client
->event
,
1571 &client
->timeout_t1
,
1572 clock_boottime_or_monotonic(),
1573 t1_timeout
, 10 * USEC_PER_MSEC
,
1574 client_timeout_t1
, client
);
1578 r
= sd_event_source_set_priority(client
->timeout_t1
,
1579 client
->event_priority
);
1583 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1587 log_dhcp_client(client
, "T1 expires in %s",
1588 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1593 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1594 DHCP_CLIENT_DONT_DESTROY(client
);
1595 char time_string
[FORMAT_TIMESPAN_MAX
];
1596 int r
= 0, notify_event
= 0;
1599 assert(client
->event
);
1602 switch (client
->state
) {
1603 case DHCP_STATE_SELECTING
:
1605 r
= client_handle_offer(client
, message
, len
);
1608 client
->timeout_resend
=
1609 sd_event_source_unref(client
->timeout_resend
);
1611 client
->state
= DHCP_STATE_REQUESTING
;
1612 client
->attempt
= 1;
1614 r
= sd_event_add_time(client
->event
,
1615 &client
->timeout_resend
,
1616 clock_boottime_or_monotonic(),
1618 client_timeout_resend
, client
);
1622 r
= sd_event_source_set_priority(client
->timeout_resend
,
1623 client
->event_priority
);
1627 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1630 } else if (r
== -ENOMSG
)
1631 /* invalid message, let's ignore it */
1636 case DHCP_STATE_REBOOTING
:
1637 case DHCP_STATE_REQUESTING
:
1638 case DHCP_STATE_RENEWING
:
1639 case DHCP_STATE_REBINDING
:
1641 r
= client_handle_ack(client
, message
, len
);
1643 client
->start_delay
= 0;
1644 client
->timeout_resend
=
1645 sd_event_source_unref(client
->timeout_resend
);
1646 client
->receive_message
=
1647 sd_event_source_unref(client
->receive_message
);
1648 client
->fd
= asynchronous_close(client
->fd
);
1650 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1651 DHCP_STATE_REBOOTING
))
1652 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1653 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1656 client
->state
= DHCP_STATE_BOUND
;
1657 client
->attempt
= 1;
1659 client
->last_addr
= client
->lease
->address
;
1661 r
= client_set_lease_timeouts(client
);
1663 log_dhcp_client(client
, "could not set lease timeouts");
1667 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1669 log_dhcp_client(client
, "could not bind UDP socket");
1675 client_initialize_io_events(client
, client_receive_message_udp
);
1678 client_notify(client
, notify_event
);
1679 if (client
->state
== DHCP_STATE_STOPPED
)
1683 } else if (r
== -EADDRNOTAVAIL
) {
1684 /* got a NAK, let's restart the client */
1685 client
->timeout_resend
=
1686 sd_event_source_unref(client
->timeout_resend
);
1688 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1690 r
= client_initialize(client
);
1694 r
= client_start_delayed(client
);
1698 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1699 client
->start_delay
, USEC_PER_SEC
));
1701 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1702 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1705 } else if (r
== -ENOMSG
)
1706 /* invalid message, let's ignore it */
1711 case DHCP_STATE_BOUND
:
1712 r
= client_handle_forcerenew(client
, message
, len
);
1714 r
= client_timeout_t1(NULL
, 0, client
);
1717 } else if (r
== -ENOMSG
)
1718 /* invalid message, let's ignore it */
1723 case DHCP_STATE_INIT
:
1724 case DHCP_STATE_INIT_REBOOT
:
1728 case DHCP_STATE_STOPPED
:
1735 client_stop(client
, r
);
1740 static int client_receive_message_udp(
1746 sd_dhcp_client
*client
= userdata
;
1747 _cleanup_free_ DHCPMessage
*message
= NULL
;
1748 const struct ether_addr zero_mac
= {};
1749 const struct ether_addr
*expected_chaddr
= NULL
;
1750 uint8_t expected_hlen
= 0;
1751 ssize_t len
, buflen
;
1756 buflen
= next_datagram_size_fd(fd
);
1760 message
= malloc0(buflen
);
1764 len
= recv(fd
, message
, buflen
, 0);
1766 if (IN_SET(errno
, EAGAIN
, EINTR
))
1769 return log_dhcp_client_errno(client
, errno
,
1770 "Could not receive message from UDP socket: %m");
1772 if ((size_t) len
< sizeof(DHCPMessage
)) {
1773 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1777 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1778 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1782 if (message
->op
!= BOOTREPLY
) {
1783 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1787 if (message
->htype
!= client
->arp_type
) {
1788 log_dhcp_client(client
, "Packet type does not match client type");
1792 if (client
->arp_type
== ARPHRD_ETHER
) {
1793 expected_hlen
= ETH_ALEN
;
1794 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1796 /* Non-Ethernet links expect zero chaddr */
1798 expected_chaddr
= &zero_mac
;
1801 if (message
->hlen
!= expected_hlen
) {
1802 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1806 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1807 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1811 if (client
->state
!= DHCP_STATE_BOUND
&&
1812 be32toh(message
->xid
) != client
->xid
) {
1813 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1814 so ignore the xid in this case */
1815 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1816 be32toh(message
->xid
), client
->xid
);
1820 return client_handle_message(client
, message
, len
);
1823 static int client_receive_message_raw(
1829 sd_dhcp_client
*client
= userdata
;
1830 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1831 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1832 struct iovec iov
= {};
1833 struct msghdr msg
= {
1836 .msg_control
= cmsgbuf
,
1837 .msg_controllen
= sizeof(cmsgbuf
),
1839 struct cmsghdr
*cmsg
;
1840 bool checksum
= true;
1841 ssize_t buflen
, len
;
1847 buflen
= next_datagram_size_fd(fd
);
1851 packet
= malloc0(buflen
);
1855 iov
.iov_base
= packet
;
1856 iov
.iov_len
= buflen
;
1858 len
= recvmsg(fd
, &msg
, 0);
1860 if (IN_SET(errno
, EAGAIN
, EINTR
))
1863 return log_dhcp_client_errno(client
, errno
,
1864 "Could not receive message from raw socket: %m");
1865 } else if ((size_t)len
< sizeof(DHCPPacket
))
1868 CMSG_FOREACH(cmsg
, &msg
) {
1869 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1870 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1871 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1872 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1874 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1879 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1883 len
-= DHCP_IP_UDP_SIZE
;
1885 return client_handle_message(client
, &packet
->dhcp
, len
);
1888 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1891 assert_return(client
, -EINVAL
);
1893 r
= client_initialize(client
);
1897 /* RFC7844 section 3.3:
1898 SHOULD perform a complete four-way handshake, starting with a
1899 DHCPDISCOVER, to obtain a new address lease. If the client can
1900 ascertain that this is exactly the same network to which it was
1901 previously connected, and if the link-layer address did not change,
1902 the client MAY issue a DHCPREQUEST to try to reclaim the current
1904 if (client
->last_addr
&& !client
->anonymize
)
1905 client
->state
= DHCP_STATE_INIT_REBOOT
;
1907 r
= client_start(client
);
1909 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1914 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1915 DHCP_CLIENT_DONT_DESTROY(client
);
1917 assert_return(client
, -EINVAL
);
1919 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1920 client
->state
= DHCP_STATE_STOPPED
;
1925 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1928 assert_return(client
, -EINVAL
);
1929 assert_return(!client
->event
, -EBUSY
);
1932 client
->event
= sd_event_ref(event
);
1934 r
= sd_event_default(&client
->event
);
1939 client
->event_priority
= priority
;
1944 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1945 assert_return(client
, -EINVAL
);
1947 client
->event
= sd_event_unref(client
->event
);
1952 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1953 assert_return(client
, NULL
);
1955 return client
->event
;
1958 static sd_dhcp_client
*dhcp_client_free(sd_dhcp_client
*client
) {
1961 log_dhcp_client(client
, "FREE");
1963 client_initialize(client
);
1965 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1967 sd_dhcp_client_detach_event(client
);
1969 sd_dhcp_lease_unref(client
->lease
);
1971 free(client
->req_opts
);
1972 free(client
->hostname
);
1973 free(client
->vendor_class_identifier
);
1974 client
->user_class
= strv_free(client
->user_class
);
1975 return mfree(client
);
1978 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client
, sd_dhcp_client
, dhcp_client_free
);
1980 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1981 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1983 assert_return(ret
, -EINVAL
);
1985 client
= new(sd_dhcp_client
, 1);
1989 *client
= (sd_dhcp_client
) {
1991 .state
= DHCP_STATE_INIT
,
1995 .mtu
= DHCP_DEFAULT_MIN_SIZE
,
1996 .port
= DHCP_PORT_CLIENT
,
1997 .anonymize
= !!anonymize
,
1999 /* NOTE: this could be moved to a function. */
2001 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
2002 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
2004 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
2005 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
2007 if (!client
->req_opts
)
2010 *ret
= TAKE_PTR(client
);