1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright (C) 2013 Intel Corporation. All rights reserved.
9 #include <net/ethernet.h>
10 #include <net/if_arp.h>
14 #include <sys/ioctl.h>
15 #include <linux/if_infiniband.h>
17 #include "sd-dhcp-client.h"
19 #include "alloc-util.h"
21 #include "dhcp-identifier.h"
22 #include "dhcp-internal.h"
23 #include "dhcp-lease-internal.h"
24 #include "dhcp-protocol.h"
25 #include "dns-domain.h"
26 #include "hostname-util.h"
27 #include "random-util.h"
28 #include "string-util.h"
31 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
32 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
34 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
35 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
37 struct sd_dhcp_client
{
43 sd_event_source
*timeout_resend
;
47 union sockaddr_union link
;
48 sd_event_source
*receive_message
;
49 bool request_broadcast
;
51 size_t req_opts_allocated
;
55 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
62 /* 0: Generic (non-LL) (RFC 2132) */
63 uint8_t data
[MAX_CLIENT_ID_LEN
];
66 /* 1: Ethernet Link-Layer (RFC 2132) */
67 uint8_t haddr
[ETH_ALEN
];
70 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
74 /* 255: Node-specific (RFC 4361) */
79 uint8_t data
[MAX_CLIENT_ID_LEN
];
85 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(
345 sd_dhcp_client
*client
,
352 DHCP_CLIENT_DONT_DESTROY(client
);
356 assert_return(client
, -EINVAL
);
357 assert_return(duid_len
== 0 || duid
!= NULL
, -EINVAL
);
360 r
= dhcp_validate_duid_len(duid_type
, duid_len
);
365 zero(client
->client_id
);
366 client
->client_id
.type
= 255;
369 /* If IAID is not configured, generate it. */
371 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
372 client
->mac_addr_len
,
373 &client
->client_id
.ns
.iaid
);
377 client
->client_id
.ns
.iaid
= htobe32(iaid
);
381 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
382 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
383 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
384 } else if (duid_type
== DUID_TYPE_EN
) {
385 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
391 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
392 (append_iaid
? sizeof(client
->client_id
.ns
.iaid
) : 0);
394 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
395 log_dhcp_client(client
, "Configured IAID+DUID, restarting.");
396 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
397 sd_dhcp_client_start(client
);
403 int sd_dhcp_client_set_iaid_duid(
404 sd_dhcp_client
*client
,
409 return dhcp_client_set_iaid_duid(client
, iaid
, true, duid_type
, duid
, duid_len
);
412 int sd_dhcp_client_set_duid(
413 sd_dhcp_client
*client
,
417 return dhcp_client_set_iaid_duid(client
, 0, false, duid_type
, duid
, duid_len
);
420 int sd_dhcp_client_set_hostname(
421 sd_dhcp_client
*client
,
422 const char *hostname
) {
424 assert_return(client
, -EINVAL
);
426 /* Make sure hostnames qualify as DNS and as Linux hostnames */
428 !(hostname_is_valid(hostname
, false) && dns_name_is_valid(hostname
) > 0))
431 return free_and_strdup(&client
->hostname
, hostname
);
434 int sd_dhcp_client_set_vendor_class_identifier(
435 sd_dhcp_client
*client
,
438 assert_return(client
, -EINVAL
);
440 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
443 int sd_dhcp_client_set_client_port(
444 sd_dhcp_client
*client
,
447 assert_return(client
, -EINVAL
);
454 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
455 assert_return(client
, -EINVAL
);
456 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
463 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
464 assert_return(client
, -EINVAL
);
466 if (!IN_SET(client
->state
, DHCP_STATE_BOUND
, DHCP_STATE_RENEWING
, DHCP_STATE_REBINDING
))
467 return -EADDRNOTAVAIL
;
470 *ret
= client
->lease
;
475 static void client_notify(sd_dhcp_client
*client
, int event
) {
478 if (client
->callback
)
479 client
->callback(client
, event
, client
->userdata
);
482 static int client_initialize(sd_dhcp_client
*client
) {
483 assert_return(client
, -EINVAL
);
485 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
487 client
->fd
= asynchronous_close(client
->fd
);
489 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
491 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
492 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
493 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
497 client
->state
= DHCP_STATE_INIT
;
500 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
505 static void client_stop(sd_dhcp_client
*client
, int error
) {
509 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
510 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
511 log_dhcp_client(client
, "STOPPED");
513 log_dhcp_client(client
, "STOPPED: Unknown event");
515 client_notify(client
, error
);
517 client_initialize(client
);
520 static int client_message_init(
521 sd_dhcp_client
*client
,
525 size_t *_optoffset
) {
527 _cleanup_free_ DHCPPacket
*packet
= NULL
;
528 size_t optlen
, optoffset
, size
;
535 assert(client
->start_time
);
539 assert(IN_SET(type
, DHCP_DISCOVER
, DHCP_REQUEST
));
541 optlen
= DHCP_MIN_OPTIONS_SIZE
;
542 size
= sizeof(DHCPPacket
) + optlen
;
544 packet
= malloc0(size
);
548 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
549 client
->arp_type
, optlen
, &optoffset
);
553 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
554 refuse to issue an DHCP lease if 'secs' is set to zero */
555 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
558 assert(time_now
>= client
->start_time
);
560 /* seconds between sending first and last DISCOVER
561 * must always be strictly positive to deal with broken servers */
562 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
563 packet
->dhcp
.secs
= htobe16(secs
);
565 /* RFC2132 section 4.1
566 A client that cannot receive unicast IP datagrams until its protocol
567 software has been configured with an IP address SHOULD set the
568 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
569 DHCPREQUEST messages that client sends. The BROADCAST bit will
570 provide a hint to the DHCP server and BOOTP relay agent to broadcast
571 any messages to the client on the client's subnet.
573 Note: some interfaces needs this to be enabled, but some networks
574 needs this to be disabled as broadcasts are filteretd, so this
575 needs to be configurable */
576 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
577 packet
->dhcp
.flags
= htobe16(0x8000);
579 /* RFC2132 section 4.1.1:
580 The client MUST include its hardware address in the ’chaddr’ field, if
581 necessary for delivery of DHCP reply messages. Non-Ethernet
582 interfaces will leave 'chaddr' empty and use the client identifier
583 instead (eg, RFC 4390 section 2.1).
585 if (client
->arp_type
== ARPHRD_ETHER
)
586 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
588 /* If no client identifier exists, construct an RFC 4361-compliant one */
589 if (client
->client_id_len
== 0) {
592 client
->client_id
.type
= 255;
594 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
, &client
->client_id
.ns
.iaid
);
598 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
602 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
605 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
606 Identifier option is not set */
607 if (client
->client_id_len
) {
608 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
609 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
610 client
->client_id_len
,
616 /* RFC2131 section 3.5:
617 in its initial DHCPDISCOVER or DHCPREQUEST message, a
618 client may provide the server with a list of specific
619 parameters the client is interested in. If the client
620 includes a list of parameters in a DHCPDISCOVER message,
621 it MUST include that list in any subsequent DHCPREQUEST
625 /* RFC7844 section 3:
626 MAY contain the Parameter Request List option. */
627 /* NOTE: in case that there would be an option to do not send
628 * any PRL at all, the size should be checked before sending */
629 if (client
->req_opts_size
> 0) {
630 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
631 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
632 client
->req_opts_size
, client
->req_opts
);
637 /* RFC2131 section 3.5:
638 The client SHOULD include the ’maximum DHCP message size’ option to
639 let the server know how large the server may make its DHCP messages.
641 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
642 than the defined default size unless the Maximum Messge Size option
645 RFC3442 "Requirements to Avoid Sizing Constraints":
646 Because a full routing table can be quite large, the standard 576
647 octet maximum size for a DHCP message may be too short to contain
648 some legitimate Classless Static Route options. Because of this,
649 clients implementing the Classless Static Route option SHOULD send a
650 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
651 stack is capable of receiving larger IP datagrams. In this case, the
652 client SHOULD set the value of this option to at least the MTU of the
653 interface that the client is configuring. The client MAY set the
654 value of this option higher, up to the size of the largest UDP packet
655 it is prepared to accept. (Note that the value specified in the
656 Maximum DHCP Message Size option is the total maximum packet size,
657 including IP and UDP headers.)
659 /* RFC7844 section 3:
660 SHOULD NOT contain any other option. */
661 if (!client
->anonymize
) {
662 max_size
= htobe16(size
);
663 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
664 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
671 *_optoffset
= optoffset
;
672 *ret
= TAKE_PTR(packet
);
677 static int client_append_fqdn_option(
678 DHCPMessage
*message
,
683 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
686 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
687 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
688 buffer
[1] = 0; /* RCODE1 (deprecated) */
689 buffer
[2] = 0; /* RCODE2 (deprecated) */
691 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
693 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
694 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
699 static int dhcp_client_send_raw(
700 sd_dhcp_client
*client
,
704 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
705 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
707 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
711 static int client_send_discover(sd_dhcp_client
*client
) {
712 _cleanup_free_ DHCPPacket
*discover
= NULL
;
713 size_t optoffset
, optlen
;
717 assert(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_SELECTING
));
719 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
720 &optlen
, &optoffset
);
724 /* the client may suggest values for the network address
725 and lease time in the DHCPDISCOVER message. The client may include
726 the ’requested IP address’ option to suggest that a particular IP
727 address be assigned, and may include the ’IP address lease time’
728 option to suggest the lease time it would like.
730 if (client
->last_addr
!= INADDR_ANY
) {
731 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
732 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
733 4, &client
->last_addr
);
738 if (client
->hostname
) {
739 /* According to RFC 4702 "clients that send the Client FQDN option in
740 their messages MUST NOT also send the Host Name option". Just send
741 one of the two depending on the hostname type.
743 if (dns_name_is_single_label(client
->hostname
)) {
744 /* it is unclear from RFC 2131 if client should send hostname in
745 DHCPDISCOVER but dhclient does and so we do as well
747 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
748 SD_DHCP_OPTION_HOST_NAME
,
749 strlen(client
->hostname
), client
->hostname
);
751 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
757 if (client
->vendor_class_identifier
) {
758 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
759 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
760 strlen(client
->vendor_class_identifier
),
761 client
->vendor_class_identifier
);
766 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
767 SD_DHCP_OPTION_END
, 0, NULL
);
771 /* We currently ignore:
772 The client SHOULD wait a random time between one and ten seconds to
773 desynchronize the use of DHCP at startup.
775 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
779 log_dhcp_client(client
, "DISCOVER");
784 static int client_send_request(sd_dhcp_client
*client
) {
785 _cleanup_free_ DHCPPacket
*request
= NULL
;
786 size_t optoffset
, optlen
;
791 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
795 switch (client
->state
) {
796 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
797 SELECTING should be REQUESTING)
800 case DHCP_STATE_REQUESTING
:
801 /* Client inserts the address of the selected server in ’server
802 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
803 filled in with the yiaddr value from the chosen DHCPOFFER.
806 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
807 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
808 4, &client
->lease
->server_address
);
812 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
813 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
814 4, &client
->lease
->address
);
820 case DHCP_STATE_INIT_REBOOT
:
821 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
822 option MUST be filled in with client’s notion of its previously
823 assigned address. ’ciaddr’ MUST be zero.
825 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
826 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
827 4, &client
->last_addr
);
832 case DHCP_STATE_RENEWING
:
833 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
834 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
835 client’s IP address.
838 case DHCP_STATE_REBINDING
:
839 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
840 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
841 client’s IP address.
843 This message MUST be broadcast to the 0xffffffff IP broadcast address.
845 request
->dhcp
.ciaddr
= client
->lease
->address
;
849 case DHCP_STATE_INIT
:
850 case DHCP_STATE_SELECTING
:
851 case DHCP_STATE_REBOOTING
:
852 case DHCP_STATE_BOUND
:
853 case DHCP_STATE_STOPPED
:
857 if (client
->hostname
) {
858 if (dns_name_is_single_label(client
->hostname
))
859 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
860 SD_DHCP_OPTION_HOST_NAME
,
861 strlen(client
->hostname
), client
->hostname
);
863 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
869 if (client
->vendor_class_identifier
) {
870 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
871 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
872 strlen(client
->vendor_class_identifier
),
873 client
->vendor_class_identifier
);
878 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
879 SD_DHCP_OPTION_END
, 0, NULL
);
883 if (client
->state
== DHCP_STATE_RENEWING
) {
884 r
= dhcp_network_send_udp_socket(client
->fd
,
885 client
->lease
->server_address
,
888 sizeof(DHCPMessage
) + optoffset
);
890 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
895 switch (client
->state
) {
897 case DHCP_STATE_REQUESTING
:
898 log_dhcp_client(client
, "REQUEST (requesting)");
901 case DHCP_STATE_INIT_REBOOT
:
902 log_dhcp_client(client
, "REQUEST (init-reboot)");
905 case DHCP_STATE_RENEWING
:
906 log_dhcp_client(client
, "REQUEST (renewing)");
909 case DHCP_STATE_REBINDING
:
910 log_dhcp_client(client
, "REQUEST (rebinding)");
914 log_dhcp_client(client
, "REQUEST (invalid)");
921 static int client_start(sd_dhcp_client
*client
);
923 static int client_timeout_resend(
928 sd_dhcp_client
*client
= userdata
;
929 DHCP_CLIENT_DONT_DESTROY(client
);
930 usec_t next_timeout
= 0;
937 assert(client
->event
);
939 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
943 switch (client
->state
) {
945 case DHCP_STATE_RENEWING
:
947 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
951 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
955 case DHCP_STATE_REBINDING
:
957 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
961 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
964 case DHCP_STATE_REBOOTING
:
965 /* start over as we did not receive a timely ack or nak */
966 r
= client_initialize(client
);
970 r
= client_start(client
);
974 log_dhcp_client(client
, "REBOOTED");
978 case DHCP_STATE_INIT
:
979 case DHCP_STATE_INIT_REBOOT
:
980 case DHCP_STATE_SELECTING
:
981 case DHCP_STATE_REQUESTING
:
982 case DHCP_STATE_BOUND
:
984 if (client
->attempt
< 64)
985 client
->attempt
*= 2;
987 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
991 case DHCP_STATE_STOPPED
:
996 next_timeout
+= (random_u32() & 0x1fffff);
998 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1000 r
= sd_event_add_time(client
->event
,
1001 &client
->timeout_resend
,
1002 clock_boottime_or_monotonic(),
1003 next_timeout
, 10 * USEC_PER_MSEC
,
1004 client_timeout_resend
, client
);
1008 r
= sd_event_source_set_priority(client
->timeout_resend
,
1009 client
->event_priority
);
1013 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1017 switch (client
->state
) {
1018 case DHCP_STATE_INIT
:
1019 r
= client_send_discover(client
);
1021 client
->state
= DHCP_STATE_SELECTING
;
1022 client
->attempt
= 1;
1024 if (client
->attempt
>= 64)
1030 case DHCP_STATE_SELECTING
:
1031 r
= client_send_discover(client
);
1032 if (r
< 0 && client
->attempt
>= 64)
1037 case DHCP_STATE_INIT_REBOOT
:
1038 case DHCP_STATE_REQUESTING
:
1039 case DHCP_STATE_RENEWING
:
1040 case DHCP_STATE_REBINDING
:
1041 r
= client_send_request(client
);
1042 if (r
< 0 && client
->attempt
>= 64)
1045 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1046 client
->state
= DHCP_STATE_REBOOTING
;
1048 client
->request_sent
= time_now
;
1052 case DHCP_STATE_REBOOTING
:
1053 case DHCP_STATE_BOUND
:
1057 case DHCP_STATE_STOPPED
:
1065 client_stop(client
, r
);
1067 /* Errors were dealt with when stopping the client, don't spill
1068 errors into the event loop handler */
1072 static int client_initialize_io_events(
1073 sd_dhcp_client
*client
,
1074 sd_event_io_handler_t io_callback
) {
1079 assert(client
->event
);
1081 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1082 client
->fd
, EPOLLIN
, io_callback
,
1087 r
= sd_event_source_set_priority(client
->receive_message
,
1088 client
->event_priority
);
1092 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1098 client_stop(client
, r
);
1103 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1108 assert(client
->event
);
1110 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1112 if (client
->start_delay
) {
1113 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1114 usec
+= client
->start_delay
;
1117 r
= sd_event_add_time(client
->event
,
1118 &client
->timeout_resend
,
1119 clock_boottime_or_monotonic(),
1121 client_timeout_resend
, client
);
1125 r
= sd_event_source_set_priority(client
->timeout_resend
,
1126 client
->event_priority
);
1130 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1136 client_stop(client
, r
);
1142 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1143 client_initialize_io_events(client
, io_callback
);
1144 client_initialize_time_events(client
);
1149 static int client_start_delayed(sd_dhcp_client
*client
) {
1152 assert_return(client
, -EINVAL
);
1153 assert_return(client
->event
, -EINVAL
);
1154 assert_return(client
->ifindex
> 0, -EINVAL
);
1155 assert_return(client
->fd
< 0, -EBUSY
);
1156 assert_return(client
->xid
== 0, -EINVAL
);
1157 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1159 client
->xid
= random_u32();
1161 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1162 client
->xid
, client
->mac_addr
,
1163 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1165 client_stop(client
, r
);
1170 if (IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
))
1171 client
->start_time
= now(clock_boottime_or_monotonic());
1173 return client_initialize_events(client
, client_receive_message_raw
);
1176 static int client_start(sd_dhcp_client
*client
) {
1177 client
->start_delay
= 0;
1178 return client_start_delayed(client
);
1181 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1182 sd_dhcp_client
*client
= userdata
;
1183 DHCP_CLIENT_DONT_DESTROY(client
);
1185 log_dhcp_client(client
, "EXPIRED");
1187 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1189 /* lease was lost, start over if not freed or stopped in callback */
1190 if (client
->state
!= DHCP_STATE_STOPPED
) {
1191 client_initialize(client
);
1192 client_start(client
);
1198 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1199 sd_dhcp_client
*client
= userdata
;
1200 DHCP_CLIENT_DONT_DESTROY(client
);
1205 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1206 client
->fd
= asynchronous_close(client
->fd
);
1208 client
->state
= DHCP_STATE_REBINDING
;
1209 client
->attempt
= 1;
1211 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1212 client
->xid
, client
->mac_addr
,
1213 client
->mac_addr_len
, client
->arp_type
,
1216 client_stop(client
, r
);
1221 return client_initialize_events(client
, client_receive_message_raw
);
1224 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1225 sd_dhcp_client
*client
= userdata
;
1226 DHCP_CLIENT_DONT_DESTROY(client
);
1228 client
->state
= DHCP_STATE_RENEWING
;
1229 client
->attempt
= 1;
1231 return client_initialize_time_events(client
);
1234 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1235 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1238 r
= dhcp_lease_new(&lease
);
1242 if (client
->client_id_len
) {
1243 r
= dhcp_lease_set_client_id(lease
,
1244 (uint8_t *) &client
->client_id
,
1245 client
->client_id_len
);
1250 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1251 if (r
!= DHCP_OFFER
) {
1252 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1256 lease
->next_server
= offer
->siaddr
;
1257 lease
->address
= offer
->yiaddr
;
1259 if (lease
->address
== 0 ||
1260 lease
->server_address
== 0 ||
1261 lease
->lifetime
== 0) {
1262 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1266 if (!lease
->have_subnet_mask
) {
1267 r
= dhcp_lease_set_default_subnet_mask(lease
);
1269 log_dhcp_client(client
,
1270 "received lease lacks subnet mask, "
1271 "and a fallback one cannot be generated, ignoring");
1276 sd_dhcp_lease_unref(client
->lease
);
1277 client
->lease
= TAKE_PTR(lease
);
1279 log_dhcp_client(client
, "OFFER");
1284 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1287 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1288 if (r
!= DHCP_FORCERENEW
)
1291 log_dhcp_client(client
, "FORCERENEW");
1296 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1297 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1298 _cleanup_free_
char *error_message
= NULL
;
1301 r
= dhcp_lease_new(&lease
);
1305 if (client
->client_id_len
) {
1306 r
= dhcp_lease_set_client_id(lease
,
1307 (uint8_t *) &client
->client_id
,
1308 client
->client_id_len
);
1313 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1314 if (r
== DHCP_NAK
) {
1315 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1316 return -EADDRNOTAVAIL
;
1319 if (r
!= DHCP_ACK
) {
1320 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1324 lease
->next_server
= ack
->siaddr
;
1326 lease
->address
= ack
->yiaddr
;
1328 if (lease
->address
== INADDR_ANY
||
1329 lease
->server_address
== INADDR_ANY
||
1330 lease
->lifetime
== 0) {
1331 log_dhcp_client(client
, "received lease lacks address, server "
1332 "address or lease lifetime, ignoring");
1336 if (lease
->subnet_mask
== INADDR_ANY
) {
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 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1347 if (client
->lease
) {
1348 if (client
->lease
->address
!= lease
->address
||
1349 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1350 client
->lease
->router
!= lease
->router
) {
1351 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1353 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1355 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1358 client
->lease
= TAKE_PTR(lease
);
1360 log_dhcp_client(client
, "ACK");
1365 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1367 assert(client
->request_sent
);
1368 assert(lifetime
> 0);
1375 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1376 + (random_u32() & 0x1fffff);
1379 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1381 uint64_t lifetime_timeout
;
1382 uint64_t t2_timeout
;
1383 uint64_t t1_timeout
;
1384 char time_string
[FORMAT_TIMESPAN_MAX
];
1388 assert(client
->event
);
1389 assert(client
->lease
);
1390 assert(client
->lease
->lifetime
);
1392 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1393 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1394 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1396 /* don't set timers for infinite leases */
1397 if (client
->lease
->lifetime
== 0xffffffff)
1400 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1403 assert(client
->request_sent
<= time_now
);
1405 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1406 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1407 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1408 /* both T1 and T2 are given */
1409 if (client
->lease
->t1
< client
->lease
->t2
&&
1410 client
->lease
->t2
< client
->lease
->lifetime
) {
1411 /* they are both valid */
1412 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1413 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1416 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1417 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1418 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1419 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1421 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1422 /* only T2 is given, and it is valid */
1423 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1424 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1425 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1426 if (t2_timeout
<= t1_timeout
) {
1427 /* the computed T1 would be invalid, so discard T2 */
1428 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1429 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1431 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1432 /* only T1 is given, and it is valid */
1433 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1434 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1435 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1436 if (t2_timeout
<= t1_timeout
) {
1437 /* the computed T2 would be invalid, so discard T1 */
1438 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1439 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1442 /* fall back to the default timeouts */
1443 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1444 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1445 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1446 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1449 /* arm lifetime timeout */
1450 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1451 clock_boottime_or_monotonic(),
1452 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1453 client_timeout_expire
, client
);
1457 r
= sd_event_source_set_priority(client
->timeout_expire
,
1458 client
->event_priority
);
1462 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1466 log_dhcp_client(client
, "lease expires in %s",
1467 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1469 /* don't arm earlier timeouts if this has already expired */
1470 if (lifetime_timeout
<= time_now
)
1473 /* arm T2 timeout */
1474 r
= sd_event_add_time(client
->event
,
1475 &client
->timeout_t2
,
1476 clock_boottime_or_monotonic(),
1479 client_timeout_t2
, client
);
1483 r
= sd_event_source_set_priority(client
->timeout_t2
,
1484 client
->event_priority
);
1488 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1492 log_dhcp_client(client
, "T2 expires in %s",
1493 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1495 /* don't arm earlier timeout if this has already expired */
1496 if (t2_timeout
<= time_now
)
1499 /* arm T1 timeout */
1500 r
= sd_event_add_time(client
->event
,
1501 &client
->timeout_t1
,
1502 clock_boottime_or_monotonic(),
1503 t1_timeout
, 10 * USEC_PER_MSEC
,
1504 client_timeout_t1
, client
);
1508 r
= sd_event_source_set_priority(client
->timeout_t1
,
1509 client
->event_priority
);
1513 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1517 log_dhcp_client(client
, "T1 expires in %s",
1518 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1523 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1524 DHCP_CLIENT_DONT_DESTROY(client
);
1525 char time_string
[FORMAT_TIMESPAN_MAX
];
1526 int r
= 0, notify_event
= 0;
1529 assert(client
->event
);
1532 switch (client
->state
) {
1533 case DHCP_STATE_SELECTING
:
1535 r
= client_handle_offer(client
, message
, len
);
1538 client
->timeout_resend
=
1539 sd_event_source_unref(client
->timeout_resend
);
1541 client
->state
= DHCP_STATE_REQUESTING
;
1542 client
->attempt
= 1;
1544 r
= sd_event_add_time(client
->event
,
1545 &client
->timeout_resend
,
1546 clock_boottime_or_monotonic(),
1548 client_timeout_resend
, client
);
1552 r
= sd_event_source_set_priority(client
->timeout_resend
,
1553 client
->event_priority
);
1557 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1560 } else if (r
== -ENOMSG
)
1561 /* invalid message, let's ignore it */
1566 case DHCP_STATE_REBOOTING
:
1567 case DHCP_STATE_REQUESTING
:
1568 case DHCP_STATE_RENEWING
:
1569 case DHCP_STATE_REBINDING
:
1571 r
= client_handle_ack(client
, message
, len
);
1573 client
->start_delay
= 0;
1574 client
->timeout_resend
=
1575 sd_event_source_unref(client
->timeout_resend
);
1576 client
->receive_message
=
1577 sd_event_source_unref(client
->receive_message
);
1578 client
->fd
= asynchronous_close(client
->fd
);
1580 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1581 DHCP_STATE_REBOOTING
))
1582 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1583 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1586 client
->state
= DHCP_STATE_BOUND
;
1587 client
->attempt
= 1;
1589 client
->last_addr
= client
->lease
->address
;
1591 r
= client_set_lease_timeouts(client
);
1593 log_dhcp_client(client
, "could not set lease timeouts");
1597 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1599 log_dhcp_client(client
, "could not bind UDP socket");
1605 client_initialize_io_events(client
, client_receive_message_udp
);
1608 client_notify(client
, notify_event
);
1609 if (client
->state
== DHCP_STATE_STOPPED
)
1613 } else if (r
== -EADDRNOTAVAIL
) {
1614 /* got a NAK, let's restart the client */
1615 client
->timeout_resend
=
1616 sd_event_source_unref(client
->timeout_resend
);
1618 r
= client_initialize(client
);
1622 r
= client_start_delayed(client
);
1626 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1627 client
->start_delay
, USEC_PER_SEC
));
1629 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1630 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1633 } else if (r
== -ENOMSG
)
1634 /* invalid message, let's ignore it */
1639 case DHCP_STATE_BOUND
:
1640 r
= client_handle_forcerenew(client
, message
, len
);
1642 r
= client_timeout_t1(NULL
, 0, client
);
1645 } else if (r
== -ENOMSG
)
1646 /* invalid message, let's ignore it */
1651 case DHCP_STATE_INIT
:
1652 case DHCP_STATE_INIT_REBOOT
:
1656 case DHCP_STATE_STOPPED
:
1663 client_stop(client
, r
);
1668 static int client_receive_message_udp(
1674 sd_dhcp_client
*client
= userdata
;
1675 _cleanup_free_ DHCPMessage
*message
= NULL
;
1676 const struct ether_addr zero_mac
= {};
1677 const struct ether_addr
*expected_chaddr
= NULL
;
1678 uint8_t expected_hlen
= 0;
1679 ssize_t len
, buflen
;
1684 buflen
= next_datagram_size_fd(fd
);
1688 message
= malloc0(buflen
);
1692 len
= recv(fd
, message
, buflen
, 0);
1694 if (IN_SET(errno
, EAGAIN
, EINTR
))
1697 return log_dhcp_client_errno(client
, errno
,
1698 "Could not receive message from UDP socket: %m");
1700 if ((size_t) len
< sizeof(DHCPMessage
)) {
1701 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1705 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1706 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1710 if (message
->op
!= BOOTREPLY
) {
1711 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1715 if (message
->htype
!= client
->arp_type
) {
1716 log_dhcp_client(client
, "Packet type does not match client type");
1720 if (client
->arp_type
== ARPHRD_ETHER
) {
1721 expected_hlen
= ETH_ALEN
;
1722 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1724 /* Non-Ethernet links expect zero chaddr */
1726 expected_chaddr
= &zero_mac
;
1729 if (message
->hlen
!= expected_hlen
) {
1730 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1734 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1735 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1739 if (client
->state
!= DHCP_STATE_BOUND
&&
1740 be32toh(message
->xid
) != client
->xid
) {
1741 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1742 so ignore the xid in this case */
1743 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1744 be32toh(message
->xid
), client
->xid
);
1748 return client_handle_message(client
, message
, len
);
1751 static int client_receive_message_raw(
1757 sd_dhcp_client
*client
= userdata
;
1758 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1759 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1760 struct iovec iov
= {};
1761 struct msghdr msg
= {
1764 .msg_control
= cmsgbuf
,
1765 .msg_controllen
= sizeof(cmsgbuf
),
1767 struct cmsghdr
*cmsg
;
1768 bool checksum
= true;
1769 ssize_t buflen
, len
;
1775 buflen
= next_datagram_size_fd(fd
);
1779 packet
= malloc0(buflen
);
1783 iov
.iov_base
= packet
;
1784 iov
.iov_len
= buflen
;
1786 len
= recvmsg(fd
, &msg
, 0);
1788 if (IN_SET(errno
, EAGAIN
, EINTR
))
1791 return log_dhcp_client_errno(client
, errno
,
1792 "Could not receive message from raw socket: %m");
1793 } else if ((size_t)len
< sizeof(DHCPPacket
))
1796 CMSG_FOREACH(cmsg
, &msg
) {
1797 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1798 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1799 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1800 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1802 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1807 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1811 len
-= DHCP_IP_UDP_SIZE
;
1813 return client_handle_message(client
, &packet
->dhcp
, len
);
1816 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1819 assert_return(client
, -EINVAL
);
1821 r
= client_initialize(client
);
1825 /* RFC7844 section 3.3:
1826 SHOULD perform a complete four-way handshake, starting with a
1827 DHCPDISCOVER, to obtain a new address lease. If the client can
1828 ascertain that this is exactly the same network to which it was
1829 previously connected, and if the link-layer address did not change,
1830 the client MAY issue a DHCPREQUEST to try to reclaim the current
1832 if (client
->last_addr
&& !client
->anonymize
)
1833 client
->state
= DHCP_STATE_INIT_REBOOT
;
1835 r
= client_start(client
);
1837 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1842 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1843 DHCP_CLIENT_DONT_DESTROY(client
);
1845 assert_return(client
, -EINVAL
);
1847 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1848 client
->state
= DHCP_STATE_STOPPED
;
1853 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1856 assert_return(client
, -EINVAL
);
1857 assert_return(!client
->event
, -EBUSY
);
1860 client
->event
= sd_event_ref(event
);
1862 r
= sd_event_default(&client
->event
);
1867 client
->event_priority
= priority
;
1872 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1873 assert_return(client
, -EINVAL
);
1875 client
->event
= sd_event_unref(client
->event
);
1880 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1881 assert_return(client
, NULL
);
1883 return client
->event
;
1886 sd_dhcp_client
*sd_dhcp_client_ref(sd_dhcp_client
*client
) {
1891 assert(client
->n_ref
>= 1);
1897 sd_dhcp_client
*sd_dhcp_client_unref(sd_dhcp_client
*client
) {
1902 assert(client
->n_ref
>= 1);
1905 if (client
->n_ref
> 0)
1908 log_dhcp_client(client
, "FREE");
1910 client_initialize(client
);
1912 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1914 sd_dhcp_client_detach_event(client
);
1916 sd_dhcp_lease_unref(client
->lease
);
1918 free(client
->req_opts
);
1919 free(client
->hostname
);
1920 free(client
->vendor_class_identifier
);
1921 return mfree(client
);
1924 int sd_dhcp_client_new(sd_dhcp_client
**ret
, int anonymize
) {
1925 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1927 assert_return(ret
, -EINVAL
);
1929 client
= new0(sd_dhcp_client
, 1);
1934 client
->state
= DHCP_STATE_INIT
;
1935 client
->ifindex
= -1;
1937 client
->attempt
= 1;
1938 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1939 client
->port
= DHCP_PORT_CLIENT
;
1941 client
->anonymize
= !!anonymize
;
1942 /* NOTE: this could be moved to a function. */
1944 client
->req_opts_size
= ELEMENTSOF(default_req_opts_anonymize
);
1945 client
->req_opts
= memdup(default_req_opts_anonymize
, client
->req_opts_size
);
1947 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1948 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1950 if (!client
->req_opts
)
1953 *ret
= TAKE_PTR(client
);