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
,
374 &client
->client_id
.ns
.iaid
);
378 client
->client_id
.ns
.iaid
= htobe32(iaid
);
382 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
383 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
384 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
388 if (client
->mac_addr_len
== 0)
391 r
= dhcp_identifier_set_duid_llt(&client
->client_id
.ns
.duid
, llt_time
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
396 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
401 if (client
->mac_addr_len
== 0)
404 r
= dhcp_identifier_set_duid_ll(&client
->client_id
.ns
.duid
, client
->mac_addr
, client
->mac_addr_len
, client
->arp_type
, &len
);
409 r
= dhcp_identifier_set_duid_uuid(&client
->client_id
.ns
.duid
, &len
);
417 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
418 (append_iaid
? sizeof(client
->client_id
.ns
.iaid
) : 0);
420 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
421 log_dhcp_client(client
, "Configured %sDUID, restarting.", append_iaid
? "IAID+" : "");
422 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
423 sd_dhcp_client_start(client
);
429 int sd_dhcp_client_set_iaid_duid(
430 sd_dhcp_client
*client
,
435 return dhcp_client_set_iaid_duid_internal(client
, iaid
, true, duid_type
, duid
, duid_len
, 0);
438 int sd_dhcp_client_set_iaid_duid_llt(
439 sd_dhcp_client
*client
,
442 return dhcp_client_set_iaid_duid_internal(client
, iaid
, true, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
445 int sd_dhcp_client_set_duid(
446 sd_dhcp_client
*client
,
450 return dhcp_client_set_iaid_duid_internal(client
, 0, false, duid_type
, duid
, duid_len
, 0);
453 int sd_dhcp_client_set_duid_llt(
454 sd_dhcp_client
*client
,
456 return dhcp_client_set_iaid_duid_internal(client
, 0, false, DUID_TYPE_LLT
, NULL
, 0, llt_time
);
459 int sd_dhcp_client_set_hostname(
460 sd_dhcp_client
*client
,
461 const char *hostname
) {
463 assert_return(client
, -EINVAL
);
465 /* Make sure hostnames qualify as DNS and as Linux hostnames */
467 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
470 return free_and_strdup(&client
->hostname
, hostname
);
473 int sd_dhcp_client_set_vendor_class_identifier(
474 sd_dhcp_client
*client
,
477 assert_return(client
, -EINVAL
);
479 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
482 int sd_dhcp_client_set_user_class(
483 sd_dhcp_client
*client
,
484 const char* const* user_class
) {
486 _cleanup_strv_free_
char **s
= NULL
;
489 STRV_FOREACH(p
, (char **) user_class
)
490 if (strlen(*p
) > 255)
491 return -ENAMETOOLONG
;
493 s
= strv_copy((char **) user_class
);
497 client
->user_class
= TAKE_PTR(s
);
502 int sd_dhcp_client_set_client_port(
503 sd_dhcp_client
*client
,
506 assert_return(client
, -EINVAL
);
513 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
514 assert_return(client
, -EINVAL
);
515 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
522 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
523 assert_return(client
, -EINVAL
);
525 if (!IN_SET(client
->state
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
526 return -EADDRNOTAVAIL
;
529 *ret
= client
->lease
;
534 static void client_notify(sd_dhcp_client
*client
, int event
) {
537 if (client
->callback
)
538 client
->callback(client
, event
, client
->userdata
);
541 static int client_initialize(sd_dhcp_client
*client
) {
542 assert_return(client
, -EINVAL
);
544 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
546 client
->fd
= asynchronous_close(client
->fd
);
548 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
550 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
551 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
552 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
556 client
->state
= DHCP_STATE_INIT
;
559 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
564 static void client_stop(sd_dhcp_client
*client
, int error
) {
568 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
569 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
570 log_dhcp_client(client
, "STOPPED");
572 log_dhcp_client(client
, "STOPPED: Unknown event");
574 client_notify(client
, error
);
576 client_initialize(client
);
579 static int client_message_init(
580 sd_dhcp_client
*client
,
584 size_t *_optoffset
) {
586 _cleanup_free_ DHCPPacket
*packet
= NULL
;
587 size_t optlen
, optoffset
, size
;
594 assert(client
->start_time
);
598 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
));
600 optlen
= DHCP_MIN_OPTIONS_SIZE
;
601 size
= sizeof(DHCPPacket
) + optlen
;
603 packet
= malloc0(size
);
607 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
608 client
->arp_type
, optlen
, &optoffset
);
612 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
613 refuse to issue an DHCP lease if 'secs' is set to zero */
614 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
617 assert(time_now
>= client
->start_time
);
619 /* seconds between sending first and last DISCOVER
620 * must always be strictly positive to deal with broken servers */
621 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
622 packet
->dhcp
.secs
= htobe16(secs
);
624 /* RFC2132 section 4.1
625 A client that cannot receive unicast IP datagrams until its protocol
626 software has been configured with an IP address SHOULD set the
627 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
628 DHCPREQUEST messages that client sends. The BROADCAST bit will
629 provide a hint to the DHCP server and BOOTP relay agent to broadcast
630 any messages to the client on the client's subnet.
632 Note: some interfaces needs this to be enabled, but some networks
633 needs this to be disabled as broadcasts are filteretd, so this
634 needs to be configurable */
635 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
636 packet
->dhcp
.flags
= htobe16(0x8000);
638 /* RFC2132 section 4.1.1:
639 The client MUST include its hardware address in the ’chaddr’ field, if
640 necessary for delivery of DHCP reply messages. Non-Ethernet
641 interfaces will leave 'chaddr' empty and use the client identifier
642 instead (eg, RFC 4390 section 2.1).
644 if (client
->arp_type
== ARPHRD_ETHER
)
645 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
647 /* If no client identifier exists, construct an RFC 4361-compliant one */
648 if (client
->client_id_len
== 0) {
651 client
->client_id
.type
= 255;
653 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
, &client
->client_id
.ns
.iaid
);
657 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
661 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
664 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
665 Identifier option is not set */
666 if (client
->client_id_len
) {
667 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
668 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
669 client
->client_id_len
,
675 /* RFC2131 section 3.5:
676 in its initial DHCPDISCOVER or DHCPREQUEST message, a
677 client may provide the server with a list of specific
678 parameters the client is interested in. If the client
679 includes a list of parameters in a DHCPDISCOVER message,
680 it MUST include that list in any subsequent DHCPREQUEST
684 /* RFC7844 section 3:
685 MAY contain the Parameter Request List option. */
686 /* NOTE: in case that there would be an option to do not send
687 * any PRL at all, the size should be checked before sending */
688 if (client
->req_opts_size
> 0) {
689 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
690 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
691 client
->req_opts_size
, client
->req_opts
);
696 /* RFC2131 section 3.5:
697 The client SHOULD include the ’maximum DHCP message size’ option to
698 let the server know how large the server may make its DHCP messages.
700 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
701 than the defined default size unless the Maximum Message Size option
704 RFC3442 "Requirements to Avoid Sizing Constraints":
705 Because a full routing table can be quite large, the standard 576
706 octet maximum size for a DHCP message may be too short to contain
707 some legitimate Classless Static Route options. Because of this,
708 clients implementing the Classless Static Route option SHOULD send a
709 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
710 stack is capable of receiving larger IP datagrams. In this case, the
711 client SHOULD set the value of this option to at least the MTU of the
712 interface that the client is configuring. The client MAY set the
713 value of this option higher, up to the size of the largest UDP packet
714 it is prepared to accept. (Note that the value specified in the
715 Maximum DHCP Message Size option is the total maximum packet size,
716 including IP and UDP headers.)
718 /* RFC7844 section 3:
719 SHOULD NOT contain any other option. */
720 if (!client
->anonymize
) {
721 max_size
= htobe16(size
);
722 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
723 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
730 *_optoffset
= optoffset
;
731 *ret
= TAKE_PTR(packet
);
736 static int client_append_fqdn_option(
737 DHCPMessage
*message
,
742 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
745 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
746 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
747 buffer
[1] = 0; /* RCODE1 (deprecated) */
748 buffer
[2] = 0; /* RCODE2 (deprecated) */
750 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
752 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
753 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
758 static int dhcp_client_send_raw(
759 sd_dhcp_client
*client
,
763 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
764 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
766 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
770 static int client_send_discover(sd_dhcp_client
*client
) {
771 _cleanup_free_ DHCPPacket
*discover
= NULL
;
772 size_t optoffset
, optlen
;
776 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
778 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
779 &optlen
, &optoffset
);
783 /* the client may suggest values for the network address
784 and lease time in the DHCPDISCOVER message. The client may include
785 the ’requested IP address’ option to suggest that a particular IP
786 address be assigned, and may include the ’IP address lease time’
787 option to suggest the lease time it would like.
789 if (client
->last_addr
!= INADDR_ANY
) {
790 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
791 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
792 4, &client
->last_addr
);
797 if (client
->hostname
) {
798 /* According to RFC 4702 "clients that send the Client FQDN option in
799 their messages MUST NOT also send the Host Name option". Just send
800 one of the two depending on the hostname type.
802 if (dns_name_is_single_label(client
->hostname
)) {
803 /* it is unclear from RFC 2131 if client should send hostname in
804 DHCPDISCOVER but dhclient does and so we do as well
806 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
807 SD_DHCP_OPTION_HOST_NAME
,
808 strlen(client
->hostname
), client
->hostname
);
810 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
816 if (client
->vendor_class_identifier
) {
817 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
818 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
819 strlen(client
->vendor_class_identifier
),
820 client
->vendor_class_identifier
);
825 if (client
->user_class
) {
826 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
827 SD_DHCP_OPTION_USER_CLASS
,
828 strv_length(client
->user_class
),
834 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
835 SD_DHCP_OPTION_END
, 0, NULL
);
839 /* We currently ignore:
840 The client SHOULD wait a random time between one and ten seconds to
841 desynchronize the use of DHCP at startup.
843 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
847 log_dhcp_client(client
, "DISCOVER");
852 static int client_send_request(sd_dhcp_client
*client
) {
853 _cleanup_free_ DHCPPacket
*request
= NULL
;
854 size_t optoffset
, optlen
;
859 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
863 switch (client
->state
) {
864 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
865 SELECTING should be REQUESTING)
868 case DHCP_STATE_REQUESTING
:
869 /* Client inserts the address of the selected server in ’server
870 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
871 filled in with the yiaddr value from the chosen DHCPOFFER.
874 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
875 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
876 4, &client
->lease
->server_address
);
880 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
881 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
882 4, &client
->lease
->address
);
888 case DHCP_STATE_INIT_REBOOT
:
889 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
890 option MUST be filled in with client’s notion of its previously
891 assigned address. ’ciaddr’ MUST be zero.
893 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
894 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
895 4, &client
->last_addr
);
900 case DHCP_STATE_RENEWING
:
901 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
902 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
906 case DHCP_STATE_REBINDING
:
907 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
908 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
911 This message MUST be broadcast to the 0xffffffff IP broadcast address.
913 request
->dhcp
.ciaddr
= client
->lease
->address
;
917 case DHCP_STATE_INIT
:
918 case DHCP_STATE_SELECTING
:
919 case DHCP_STATE_REBOOTING
:
920 case DHCP_STATE_BOUND
:
921 case DHCP_STATE_STOPPED
:
925 if (client
->hostname
) {
926 if (dns_name_is_single_label(client
->hostname
))
927 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
928 SD_DHCP_OPTION_HOST_NAME
,
929 strlen(client
->hostname
), client
->hostname
);
931 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
937 if (client
->vendor_class_identifier
) {
938 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
939 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
940 strlen(client
->vendor_class_identifier
),
941 client
->vendor_class_identifier
);
946 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
947 SD_DHCP_OPTION_END
, 0, NULL
);
951 if (client
->state
== DHCP_STATE_RENEWING
) {
952 r
= dhcp_network_send_udp_socket(client
->fd
,
953 client
->lease
->server_address
,
956 sizeof(DHCPMessage
) + optoffset
);
958 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
963 switch (client
->state
) {
965 case DHCP_STATE_REQUESTING
:
966 log_dhcp_client(client
, "REQUEST (requesting)");
969 case DHCP_STATE_INIT_REBOOT
:
970 log_dhcp_client(client
, "REQUEST (init-reboot)");
973 case DHCP_STATE_RENEWING
:
974 log_dhcp_client(client
, "REQUEST (renewing)");
977 case DHCP_STATE_REBINDING
:
978 log_dhcp_client(client
, "REQUEST (rebinding)");
982 log_dhcp_client(client
, "REQUEST (invalid)");
989 static int client_start(sd_dhcp_client
*client
);
991 static int client_timeout_resend(
996 sd_dhcp_client
*client
= userdata
;
997 DHCP_CLIENT_DONT_DESTROY(client
);
998 usec_t next_timeout
= 0;
1005 assert(client
->event
);
1007 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1011 switch (client
->state
) {
1013 case DHCP_STATE_RENEWING
:
1015 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
1019 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1023 case DHCP_STATE_REBINDING
:
1025 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
1029 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
1032 case DHCP_STATE_REBOOTING
:
1033 /* start over as we did not receive a timely ack or nak */
1034 r
= client_initialize(client
);
1038 r
= client_start(client
);
1042 log_dhcp_client(client
, "REBOOTED");
1046 case DHCP_STATE_INIT
:
1047 case DHCP_STATE_INIT_REBOOT
:
1048 case DHCP_STATE_SELECTING
:
1049 case DHCP_STATE_REQUESTING
:
1050 case DHCP_STATE_BOUND
:
1052 if (client
->attempt
< 64)
1053 client
->attempt
*= 2;
1055 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
1059 case DHCP_STATE_STOPPED
:
1064 next_timeout
+= (random_u32() & 0x1fffff);
1066 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1068 r
= sd_event_add_time(client
->event
,
1069 &client
->timeout_resend
,
1070 clock_boottime_or_monotonic(),
1071 next_timeout
, 10 * USEC_PER_MSEC
,
1072 client_timeout_resend
, client
);
1076 r
= sd_event_source_set_priority(client
->timeout_resend
,
1077 client
->event_priority
);
1081 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1085 switch (client
->state
) {
1086 case DHCP_STATE_INIT
:
1087 r
= client_send_discover(client
);
1089 client
->state
= DHCP_STATE_SELECTING
;
1090 client
->attempt
= 1;
1092 if (client
->attempt
>= 64)
1098 case DHCP_STATE_SELECTING
:
1099 r
= client_send_discover(client
);
1100 if (r
< 0 && client
->attempt
>= 64)
1105 case DHCP_STATE_INIT_REBOOT
:
1106 case DHCP_STATE_REQUESTING
:
1107 case DHCP_STATE_RENEWING
:
1108 case DHCP_STATE_REBINDING
:
1109 r
= client_send_request(client
);
1110 if (r
< 0 && client
->attempt
>= 64)
1113 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1114 client
->state
= DHCP_STATE_REBOOTING
;
1116 client
->request_sent
= time_now
;
1120 case DHCP_STATE_REBOOTING
:
1121 case DHCP_STATE_BOUND
:
1125 case DHCP_STATE_STOPPED
:
1133 client_stop(client
, r
);
1135 /* Errors were dealt with when stopping the client, don't spill
1136 errors into the event loop handler */
1140 static int client_initialize_io_events(
1141 sd_dhcp_client
*client
,
1142 sd_event_io_handler_t io_callback
) {
1147 assert(client
->event
);
1149 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1150 client
->fd
, EPOLLIN
, io_callback
,
1155 r
= sd_event_source_set_priority(client
->receive_message
,
1156 client
->event_priority
);
1160 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1166 client_stop(client
, r
);
1171 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1176 assert(client
->event
);
1178 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1180 if (client
->start_delay
) {
1181 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1182 usec
+= client
->start_delay
;
1185 r
= sd_event_add_time(client
->event
,
1186 &client
->timeout_resend
,
1187 clock_boottime_or_monotonic(),
1189 client_timeout_resend
, client
);
1193 r
= sd_event_source_set_priority(client
->timeout_resend
,
1194 client
->event_priority
);
1198 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1204 client_stop(client
, r
);
1210 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1211 client_initialize_io_events(client
, io_callback
);
1212 client_initialize_time_events(client
);
1217 static int client_start_delayed(sd_dhcp_client
*client
) {
1220 assert_return(client
, -EINVAL
);
1221 assert_return(client
->event
, -EINVAL
);
1222 assert_return(client
->ifindex
> 0, -EINVAL
);
1223 assert_return(client
->fd
< 0, -EBUSY
);
1224 assert_return(client
->xid
== 0, -EINVAL
);
1225 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1227 client
->xid
= random_u32();
1229 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1230 client
->xid
, client
->mac_addr
,
1231 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1233 client_stop(client
, r
);
1238 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1239 client
->start_time
= now(clock_boottime_or_monotonic());
1241 return client_initialize_events(client
, client_receive_message_raw
);
1244 static int client_start(sd_dhcp_client
*client
) {
1245 client
->start_delay
= 0;
1246 return client_start_delayed(client
);
1249 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1250 sd_dhcp_client
*client
= userdata
;
1251 DHCP_CLIENT_DONT_DESTROY(client
);
1253 log_dhcp_client(client
, "EXPIRED");
1255 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1257 /* lease was lost, start over if not freed or stopped in callback */
1258 if (client
->state
!= DHCP_STATE_STOPPED
) {
1259 client_initialize(client
);
1260 client_start(client
);
1266 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1267 sd_dhcp_client
*client
= userdata
;
1268 DHCP_CLIENT_DONT_DESTROY(client
);
1273 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1274 client
->fd
= asynchronous_close(client
->fd
);
1276 client
->state
= DHCP_STATE_REBINDING
;
1277 client
->attempt
= 1;
1279 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1280 client
->xid
, client
->mac_addr
,
1281 client
->mac_addr_len
, client
->arp_type
,
1284 client_stop(client
, r
);
1289 return client_initialize_events(client
, client_receive_message_raw
);
1292 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1293 sd_dhcp_client
*client
= userdata
;
1294 DHCP_CLIENT_DONT_DESTROY(client
);
1296 client
->state
= DHCP_STATE_RENEWING
;
1297 client
->attempt
= 1;
1299 return client_initialize_time_events(client
);
1302 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1303 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1306 r
= dhcp_lease_new(&lease
);
1310 if (client
->client_id_len
) {
1311 r
= dhcp_lease_set_client_id(lease
,
1312 (uint8_t *) &client
->client_id
,
1313 client
->client_id_len
);
1318 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1319 if (r
!= DHCP_OFFER
) {
1320 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1324 lease
->next_server
= offer
->siaddr
;
1325 lease
->address
= offer
->yiaddr
;
1327 if (lease
->address
== 0 ||
1328 lease
->server_address
== 0 ||
1329 lease
->lifetime
== 0) {
1330 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1334 if (!lease
->have_subnet_mask
) {
1335 r
= dhcp_lease_set_default_subnet_mask(lease
);
1337 log_dhcp_client(client
,
1338 "received lease lacks subnet mask, "
1339 "and a fallback one cannot be generated, ignoring");
1344 sd_dhcp_lease_unref(client
->lease
);
1345 client
->lease
= TAKE_PTR(lease
);
1347 log_dhcp_client(client
, "OFFER");
1352 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1355 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1356 if (r
!= DHCP_FORCERENEW
)
1359 log_dhcp_client(client
, "FORCERENEW");
1364 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1365 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1366 _cleanup_free_
char *error_message
= NULL
;
1369 r
= dhcp_lease_new(&lease
);
1373 if (client
->client_id_len
) {
1374 r
= dhcp_lease_set_client_id(lease
,
1375 (uint8_t *) &client
->client_id
,
1376 client
->client_id_len
);
1381 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1382 if (r
== DHCP_NAK
) {
1383 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1384 return -EADDRNOTAVAIL
;
1387 if (r
!= DHCP_ACK
) {
1388 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1392 lease
->next_server
= ack
->siaddr
;
1394 lease
->address
= ack
->yiaddr
;
1396 if (lease
->address
== INADDR_ANY
||
1397 lease
->server_address
== INADDR_ANY
||
1398 lease
->lifetime
== 0) {
1399 log_dhcp_client(client
, "received lease lacks address, server "
1400 "address or lease lifetime, ignoring");
1404 if (lease
->subnet_mask
== INADDR_ANY
) {
1405 r
= dhcp_lease_set_default_subnet_mask(lease
);
1407 log_dhcp_client(client
,
1408 "received lease lacks subnet mask, "
1409 "and a fallback one cannot be generated, ignoring");
1414 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1415 if (client
->lease
) {
1416 if (client
->lease
->address
!= lease
->address
||
1417 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1418 client
->lease
->router
!= lease
->router
) {
1419 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1421 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1423 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1426 client
->lease
= TAKE_PTR(lease
);
1428 log_dhcp_client(client
, "ACK");
1433 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1435 assert(client
->request_sent
);
1436 assert(lifetime
> 0);
1443 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1444 + (random_u32() & 0x1fffff);
1447 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1449 uint64_t lifetime_timeout
;
1450 uint64_t t2_timeout
;
1451 uint64_t t1_timeout
;
1452 char time_string
[FORMAT_TIMESPAN_MAX
];
1456 assert(client
->event
);
1457 assert(client
->lease
);
1458 assert(client
->lease
->lifetime
);
1460 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1461 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1462 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1464 /* don't set timers for infinite leases */
1465 if (client
->lease
->lifetime
== 0xffffffff)
1468 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1471 assert(client
->request_sent
<= time_now
);
1473 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1474 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1475 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1476 /* both T1 and T2 are given */
1477 if (client
->lease
->t1
< client
->lease
->t2
&&
1478 client
->lease
->t2
< client
->lease
->lifetime
) {
1479 /* they are both valid */
1480 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1481 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1484 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1485 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1486 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1487 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1489 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1490 /* only T2 is given, and it is valid */
1491 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1492 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1493 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1494 if (t2_timeout
<= t1_timeout
) {
1495 /* the computed T1 would be invalid, so discard T2 */
1496 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1497 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1499 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1500 /* only T1 is given, and it is valid */
1501 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1502 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1503 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1504 if (t2_timeout
<= t1_timeout
) {
1505 /* the computed T2 would be invalid, so discard T1 */
1506 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1507 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1510 /* fall back to the default timeouts */
1511 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1512 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1513 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1514 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1517 /* arm lifetime timeout */
1518 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1519 clock_boottime_or_monotonic(),
1520 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1521 client_timeout_expire
, client
);
1525 r
= sd_event_source_set_priority(client
->timeout_expire
,
1526 client
->event_priority
);
1530 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1534 log_dhcp_client(client
, "lease expires in %s",
1535 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1537 /* don't arm earlier timeouts if this has already expired */
1538 if (lifetime_timeout
<= time_now
)
1541 /* arm T2 timeout */
1542 r
= sd_event_add_time(client
->event
,
1543 &client
->timeout_t2
,
1544 clock_boottime_or_monotonic(),
1547 client_timeout_t2
, client
);
1551 r
= sd_event_source_set_priority(client
->timeout_t2
,
1552 client
->event_priority
);
1556 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1560 log_dhcp_client(client
, "T2 expires in %s",
1561 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1563 /* don't arm earlier timeout if this has already expired */
1564 if (t2_timeout
<= time_now
)
1567 /* arm T1 timeout */
1568 r
= sd_event_add_time(client
->event
,
1569 &client
->timeout_t1
,
1570 clock_boottime_or_monotonic(),
1571 t1_timeout
, 10 * USEC_PER_MSEC
,
1572 client_timeout_t1
, client
);
1576 r
= sd_event_source_set_priority(client
->timeout_t1
,
1577 client
->event_priority
);
1581 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1585 log_dhcp_client(client
, "T1 expires in %s",
1586 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1591 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1592 DHCP_CLIENT_DONT_DESTROY(client
);
1593 char time_string
[FORMAT_TIMESPAN_MAX
];
1594 int r
= 0, notify_event
= 0;
1597 assert(client
->event
);
1600 switch (client
->state
) {
1601 case DHCP_STATE_SELECTING
:
1603 r
= client_handle_offer(client
, message
, len
);
1606 client
->timeout_resend
=
1607 sd_event_source_unref(client
->timeout_resend
);
1609 client
->state
= DHCP_STATE_REQUESTING
;
1610 client
->attempt
= 1;
1612 r
= sd_event_add_time(client
->event
,
1613 &client
->timeout_resend
,
1614 clock_boottime_or_monotonic(),
1616 client_timeout_resend
, client
);
1620 r
= sd_event_source_set_priority(client
->timeout_resend
,
1621 client
->event_priority
);
1625 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1628 } else if (r
== -ENOMSG
)
1629 /* invalid message, let's ignore it */
1634 case DHCP_STATE_REBOOTING
:
1635 case DHCP_STATE_REQUESTING
:
1636 case DHCP_STATE_RENEWING
:
1637 case DHCP_STATE_REBINDING
:
1639 r
= client_handle_ack(client
, message
, len
);
1641 client
->start_delay
= 0;
1642 client
->timeout_resend
=
1643 sd_event_source_unref(client
->timeout_resend
);
1644 client
->receive_message
=
1645 sd_event_source_unref(client
->receive_message
);
1646 client
->fd
= asynchronous_close(client
->fd
);
1648 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1649 DHCP_STATE_REBOOTING
))
1650 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1651 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1654 client
->state
= DHCP_STATE_BOUND
;
1655 client
->attempt
= 1;
1657 client
->last_addr
= client
->lease
->address
;
1659 r
= client_set_lease_timeouts(client
);
1661 log_dhcp_client(client
, "could not set lease timeouts");
1665 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1667 log_dhcp_client(client
, "could not bind UDP socket");
1673 client_initialize_io_events(client
, client_receive_message_udp
);
1676 client_notify(client
, notify_event
);
1677 if (client
->state
== DHCP_STATE_STOPPED
)
1681 } else if (r
== -EADDRNOTAVAIL
) {
1682 /* got a NAK, let's restart the client */
1683 client
->timeout_resend
=
1684 sd_event_source_unref(client
->timeout_resend
);
1686 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1688 r
= client_initialize(client
);
1692 r
= client_start_delayed(client
);
1696 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1697 client
->start_delay
, USEC_PER_SEC
));
1699 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1700 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1703 } else if (r
== -ENOMSG
)
1704 /* invalid message, let's ignore it */
1709 case DHCP_STATE_BOUND
:
1710 r
= client_handle_forcerenew(client
, message
, len
);
1712 r
= client_timeout_t1(NULL
, 0, client
);
1715 } else if (r
== -ENOMSG
)
1716 /* invalid message, let's ignore it */
1721 case DHCP_STATE_INIT
:
1722 case DHCP_STATE_INIT_REBOOT
:
1726 case DHCP_STATE_STOPPED
:
1733 client_stop(client
, r
);
1738 static int client_receive_message_udp(
1744 sd_dhcp_client
*client
= userdata
;
1745 _cleanup_free_ DHCPMessage
*message
= NULL
;
1746 const struct ether_addr zero_mac
= {};
1747 const struct ether_addr
*expected_chaddr
= NULL
;
1748 uint8_t expected_hlen
= 0;
1749 ssize_t len
, buflen
;
1754 buflen
= next_datagram_size_fd(fd
);
1758 message
= malloc0(buflen
);
1762 len
= recv(fd
, message
, buflen
, 0);
1764 if (IN_SET(errno
, EAGAIN
, EINTR
))
1767 return log_dhcp_client_errno(client
, errno
,
1768 "Could not receive message from UDP socket: %m");
1770 if ((size_t) len
< sizeof(DHCPMessage
)) {
1771 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1775 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1776 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1780 if (message
->op
!= BOOTREPLY
) {
1781 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1785 if (message
->htype
!= client
->arp_type
) {
1786 log_dhcp_client(client
, "Packet type does not match client type");
1790 if (client
->arp_type
== ARPHRD_ETHER
) {
1791 expected_hlen
= ETH_ALEN
;
1792 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1794 /* Non-Ethernet links expect zero chaddr */
1796 expected_chaddr
= &zero_mac
;
1799 if (message
->hlen
!= expected_hlen
) {
1800 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1804 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1805 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1809 if (client
->state
!= DHCP_STATE_BOUND
&&
1810 be32toh(message
->xid
) != client
->xid
) {
1811 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1812 so ignore the xid in this case */
1813 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1814 be32toh(message
->xid
), client
->xid
);
1818 return client_handle_message(client
, message
, len
);
1821 static int client_receive_message_raw(
1827 sd_dhcp_client
*client
= userdata
;
1828 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1829 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1830 struct iovec iov
= {};
1831 struct msghdr msg
= {
1834 .msg_control
= cmsgbuf
,
1835 .msg_controllen
= sizeof(cmsgbuf
),
1837 struct cmsghdr
*cmsg
;
1838 bool checksum
= true;
1839 ssize_t buflen
, len
;
1845 buflen
= next_datagram_size_fd(fd
);
1849 packet
= malloc0(buflen
);
1853 iov
.iov_base
= packet
;
1854 iov
.iov_len
= buflen
;
1856 len
= recvmsg(fd
, &msg
, 0);
1858 if (IN_SET(errno
, EAGAIN
, EINTR
))
1861 return log_dhcp_client_errno(client
, errno
,
1862 "Could not receive message from raw socket: %m");
1863 } else if ((size_t)len
< sizeof(DHCPPacket
))
1866 CMSG_FOREACH(cmsg
, &msg
) {
1867 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1868 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1869 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1870 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1872 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1877 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1881 len
-= DHCP_IP_UDP_SIZE
;
1883 return client_handle_message(client
, &packet
->dhcp
, len
);
1886 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1889 assert_return(client
, -EINVAL
);
1891 r
= client_initialize(client
);
1895 /* RFC7844 section 3.3:
1896 SHOULD perform a complete four-way handshake, starting with a
1897 DHCPDISCOVER, to obtain a new address lease. If the client can
1898 ascertain that this is exactly the same network to which it was
1899 previously connected, and if the link-layer address did not change,
1900 the client MAY issue a DHCPREQUEST to try to reclaim the current
1902 if (client
->last_addr
&& !client
->anonymize
)
1903 client
->state
= DHCP_STATE_INIT_REBOOT
;
1905 r
= client_start(client
);
1907 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1912 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1913 DHCP_CLIENT_DONT_DESTROY(client
);
1915 assert_return(client
, -EINVAL
);
1917 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1918 client
->state
= DHCP_STATE_STOPPED
;
1923 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1926 assert_return(client
, -EINVAL
);
1927 assert_return(!client
->event
, -EBUSY
);
1930 client
->event
= sd_event_ref(event
);
1932 r
= sd_event_default(&client
->event
);
1937 client
->event_priority
= priority
;
1942 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1943 assert_return(client
, -EINVAL
);
1945 client
->event
= sd_event_unref(client
->event
);
1950 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1951 assert_return(client
, NULL
);
1953 return client
->event
;
1956 static sd_dhcp_client
*dhcp_client_free(sd_dhcp_client
*client
) {
1959 log_dhcp_client(client
, "FREE");
1961 client_initialize(client
);
1963 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1965 sd_dhcp_client_detach_event(client
);
1967 sd_dhcp_lease_unref(client
->lease
);
1969 free(client
->req_opts
);
1970 free(client
->hostname
);
1971 free(client
->vendor_class_identifier
);
1972 client
->user_class
= strv_free(client
->user_class
);
1973 return mfree(client
);
1976 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client
, sd_dhcp_client
, dhcp_client_free
);
1978 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1979 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1981 assert_return(ret
, -EINVAL
);
1983 client
= new0(sd_dhcp_client
, 1);
1988 client
->state
= DHCP_STATE_INIT
;
1989 client
->ifindex
= -1;
1991 client
->attempt
= 1;
1992 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1993 client
->port
= DHCP_PORT_CLIENT
;
1995 client
->anonymize
= !!anonymize
;
1996 /* NOTE: this could be moved to a function. */
1998 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
1999 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
2001 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
2002 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
2004 if (!client
->req_opts
)
2007 *ret
= TAKE_PTR(client
);