2 This file is part of systemd.
4 Copyright (C) 2013 Intel Corporation. All rights reserved.
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include <net/ethernet.h>
22 #include <net/if_arp.h>
26 #include <sys/ioctl.h>
27 #include <linux/if_infiniband.h>
29 #include "sd-dhcp-client.h"
31 #include "alloc-util.h"
33 #include "dhcp-identifier.h"
34 #include "dhcp-internal.h"
35 #include "dhcp-lease-internal.h"
36 #include "dhcp-protocol.h"
37 #include "dns-domain.h"
38 #include "hostname-util.h"
39 #include "random-util.h"
40 #include "string-util.h"
43 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
44 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
46 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
47 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
49 struct sd_dhcp_client
{
55 sd_event_source
*timeout_resend
;
59 union sockaddr_union link
;
60 sd_event_source
*receive_message
;
61 bool request_broadcast
;
63 size_t req_opts_allocated
;
66 uint8_t mac_addr
[MAX_MAC_ADDR_LEN
];
73 /* 0: Generic (non-LL) (RFC 2132) */
74 uint8_t data
[MAX_CLIENT_ID_LEN
];
77 /* 1: Ethernet Link-Layer (RFC 2132) */
78 uint8_t haddr
[ETH_ALEN
];
81 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
85 /* 255: Node-specific (RFC 4361) */
90 uint8_t data
[MAX_CLIENT_ID_LEN
];
96 char *vendor_class_identifier
;
100 unsigned int attempt
;
102 sd_event_source
*timeout_t1
;
103 sd_event_source
*timeout_t2
;
104 sd_event_source
*timeout_expire
;
105 sd_dhcp_client_callback_t callback
;
107 sd_dhcp_lease
*lease
;
111 static const uint8_t default_req_opts
[] = {
112 SD_DHCP_OPTION_SUBNET_MASK
,
113 SD_DHCP_OPTION_ROUTER
,
114 SD_DHCP_OPTION_HOST_NAME
,
115 SD_DHCP_OPTION_DOMAIN_NAME
,
116 SD_DHCP_OPTION_DOMAIN_NAME_SERVER
,
119 static int client_receive_message_raw(
124 static int client_receive_message_udp(
129 static void client_stop(sd_dhcp_client
*client
, int error
);
131 int sd_dhcp_client_set_callback(
132 sd_dhcp_client
*client
,
133 sd_dhcp_client_callback_t cb
,
136 assert_return(client
, -EINVAL
);
138 client
->callback
= cb
;
139 client
->userdata
= userdata
;
144 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client
*client
, int broadcast
) {
145 assert_return(client
, -EINVAL
);
147 client
->request_broadcast
= !!broadcast
;
152 int sd_dhcp_client_set_request_option(sd_dhcp_client
*client
, uint8_t option
) {
155 assert_return(client
, -EINVAL
);
156 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
160 case SD_DHCP_OPTION_PAD
:
161 case SD_DHCP_OPTION_OVERLOAD
:
162 case SD_DHCP_OPTION_MESSAGE_TYPE
:
163 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
:
164 case SD_DHCP_OPTION_END
:
171 for (i
= 0; i
< client
->req_opts_size
; i
++)
172 if (client
->req_opts
[i
] == option
)
175 if (!GREEDY_REALLOC(client
->req_opts
, client
->req_opts_allocated
,
176 client
->req_opts_size
+ 1))
179 client
->req_opts
[client
->req_opts_size
++] = option
;
184 int sd_dhcp_client_set_request_address(
185 sd_dhcp_client
*client
,
186 const struct in_addr
*last_addr
) {
188 assert_return(client
, -EINVAL
);
189 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
192 client
->last_addr
= last_addr
->s_addr
;
194 client
->last_addr
= INADDR_ANY
;
199 int sd_dhcp_client_set_ifindex(sd_dhcp_client
*client
, int ifindex
) {
201 assert_return(client
, -EINVAL
);
202 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
), -EBUSY
);
203 assert_return(ifindex
> 0, -EINVAL
);
205 client
->ifindex
= ifindex
;
209 int sd_dhcp_client_set_mac(
210 sd_dhcp_client
*client
,
215 DHCP_CLIENT_DONT_DESTROY(client
);
216 bool need_restart
= false;
218 assert_return(client
, -EINVAL
);
219 assert_return(addr
, -EINVAL
);
220 assert_return(addr_len
> 0 && addr_len
<= MAX_MAC_ADDR_LEN
, -EINVAL
);
221 assert_return(arp_type
> 0, -EINVAL
);
223 if (arp_type
== ARPHRD_ETHER
)
224 assert_return(addr_len
== ETH_ALEN
, -EINVAL
);
225 else if (arp_type
== ARPHRD_INFINIBAND
)
226 assert_return(addr_len
== INFINIBAND_ALEN
, -EINVAL
);
230 if (client
->mac_addr_len
== addr_len
&&
231 memcmp(&client
->mac_addr
, addr
, addr_len
) == 0)
234 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
235 log_dhcp_client(client
, "Changing MAC address on running DHCP client, restarting");
237 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
240 memcpy(&client
->mac_addr
, addr
, addr_len
);
241 client
->mac_addr_len
= addr_len
;
242 client
->arp_type
= arp_type
;
244 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
245 sd_dhcp_client_start(client
);
250 int sd_dhcp_client_get_client_id(
251 sd_dhcp_client
*client
,
253 const uint8_t **data
,
256 assert_return(client
, -EINVAL
);
257 assert_return(type
, -EINVAL
);
258 assert_return(data
, -EINVAL
);
259 assert_return(data_len
, -EINVAL
);
264 if (client
->client_id_len
) {
265 *type
= client
->client_id
.type
;
266 *data
= client
->client_id
.raw
.data
;
267 *data_len
= client
->client_id_len
- sizeof(client
->client_id
.type
);
273 int sd_dhcp_client_set_client_id(
274 sd_dhcp_client
*client
,
279 DHCP_CLIENT_DONT_DESTROY(client
);
280 bool need_restart
= false;
282 assert_return(client
, -EINVAL
);
283 assert_return(data
, -EINVAL
);
284 assert_return(data_len
> 0 && data_len
<= MAX_CLIENT_ID_LEN
, -EINVAL
);
289 if (data_len
!= ETH_ALEN
)
293 case ARPHRD_INFINIBAND
:
294 if (data_len
!= INFINIBAND_ALEN
)
302 if (client
->client_id_len
== data_len
+ sizeof(client
->client_id
.type
) &&
303 client
->client_id
.type
== type
&&
304 memcmp(&client
->client_id
.raw
.data
, data
, data_len
) == 0)
307 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
308 log_dhcp_client(client
, "Changing client ID on running DHCP "
309 "client, restarting");
311 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
314 client
->client_id
.type
= type
;
315 memcpy(&client
->client_id
.raw
.data
, data
, data_len
);
316 client
->client_id_len
= data_len
+ sizeof (client
->client_id
.type
);
318 if (need_restart
&& client
->state
!= DHCP_STATE_STOPPED
)
319 sd_dhcp_client_start(client
);
325 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
326 * without further modification. Otherwise, if duid_type is supported, DUID
327 * is set based on that type. Otherwise, an error is returned.
329 int sd_dhcp_client_set_iaid_duid(
330 sd_dhcp_client
*client
,
336 DHCP_CLIENT_DONT_DESTROY(client
);
340 assert_return(client
, -EINVAL
);
341 assert_return(duid_len
== 0 || duid
!= NULL
, -EINVAL
);
344 r
= dhcp_validate_duid_len(duid_type
, duid_len
);
349 zero(client
->client_id
);
350 client
->client_id
.type
= 255;
352 /* If IAID is not configured, generate it. */
354 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
,
355 client
->mac_addr_len
,
356 &client
->client_id
.ns
.iaid
);
360 client
->client_id
.ns
.iaid
= htobe32(iaid
);
363 client
->client_id
.ns
.duid
.type
= htobe16(duid_type
);
364 memcpy(&client
->client_id
.ns
.duid
.raw
.data
, duid
, duid_len
);
365 len
= sizeof(client
->client_id
.ns
.duid
.type
) + duid_len
;
366 } else if (duid_type
== DUID_TYPE_EN
) {
367 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &len
);
373 client
->client_id_len
= sizeof(client
->client_id
.type
) + len
+
374 sizeof(client
->client_id
.ns
.iaid
);
376 if (!IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_STOPPED
)) {
377 log_dhcp_client(client
, "Configured IAID+DUID, restarting.");
378 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
379 sd_dhcp_client_start(client
);
385 int sd_dhcp_client_set_hostname(
386 sd_dhcp_client
*client
,
387 const char *hostname
) {
389 assert_return(client
, -EINVAL
);
391 /* Refuse hostnames that neither qualify as DNS nor as Linux hosntames */
393 !(hostname_is_valid(hostname
, false) || dns_name_is_valid(hostname
) > 0))
396 return free_and_strdup(&client
->hostname
, hostname
);
399 int sd_dhcp_client_set_vendor_class_identifier(
400 sd_dhcp_client
*client
,
403 assert_return(client
, -EINVAL
);
405 return free_and_strdup(&client
->vendor_class_identifier
, vci
);
408 int sd_dhcp_client_set_client_port(
409 sd_dhcp_client
*client
,
412 assert_return(client
, -EINVAL
);
419 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
420 assert_return(client
, -EINVAL
);
421 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
428 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
429 assert_return(client
, -EINVAL
);
431 if (client
->state
!= DHCP_STATE_BOUND
&&
432 client
->state
!= DHCP_STATE_RENEWING
&&
433 client
->state
!= DHCP_STATE_REBINDING
)
434 return -EADDRNOTAVAIL
;
437 *ret
= client
->lease
;
442 static void client_notify(sd_dhcp_client
*client
, int event
) {
445 if (client
->callback
)
446 client
->callback(client
, event
, client
->userdata
);
449 static int client_initialize(sd_dhcp_client
*client
) {
450 assert_return(client
, -EINVAL
);
452 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
454 client
->fd
= asynchronous_close(client
->fd
);
456 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
458 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
459 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
460 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
464 client
->state
= DHCP_STATE_INIT
;
467 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
472 static void client_stop(sd_dhcp_client
*client
, int error
) {
476 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
477 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
478 log_dhcp_client(client
, "STOPPED");
480 log_dhcp_client(client
, "STOPPED: Unknown event");
482 client_notify(client
, error
);
484 client_initialize(client
);
487 static int client_message_init(
488 sd_dhcp_client
*client
,
492 size_t *_optoffset
) {
494 _cleanup_free_ DHCPPacket
*packet
= NULL
;
495 size_t optlen
, optoffset
, size
;
502 assert(client
->start_time
);
506 assert(type
== DHCP_DISCOVER
|| type
== DHCP_REQUEST
);
508 optlen
= DHCP_MIN_OPTIONS_SIZE
;
509 size
= sizeof(DHCPPacket
) + optlen
;
511 packet
= malloc0(size
);
515 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
516 client
->arp_type
, optlen
, &optoffset
);
520 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
521 refuse to issue an DHCP lease if 'secs' is set to zero */
522 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
525 assert(time_now
>= client
->start_time
);
527 /* seconds between sending first and last DISCOVER
528 * must always be strictly positive to deal with broken servers */
529 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
530 packet
->dhcp
.secs
= htobe16(secs
);
532 /* RFC2132 section 4.1
533 A client that cannot receive unicast IP datagrams until its protocol
534 software has been configured with an IP address SHOULD set the
535 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
536 DHCPREQUEST messages that client sends. The BROADCAST bit will
537 provide a hint to the DHCP server and BOOTP relay agent to broadcast
538 any messages to the client on the client's subnet.
540 Note: some interfaces needs this to be enabled, but some networks
541 needs this to be disabled as broadcasts are filteretd, so this
542 needs to be configurable */
543 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
544 packet
->dhcp
.flags
= htobe16(0x8000);
546 /* RFC2132 section 4.1.1:
547 The client MUST include its hardware address in the ’chaddr’ field, if
548 necessary for delivery of DHCP reply messages. Non-Ethernet
549 interfaces will leave 'chaddr' empty and use the client identifier
550 instead (eg, RFC 4390 section 2.1).
552 if (client
->arp_type
== ARPHRD_ETHER
)
553 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
555 /* If no client identifier exists, construct an RFC 4361-compliant one */
556 if (client
->client_id_len
== 0) {
559 client
->client_id
.type
= 255;
561 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
, &client
->client_id
.ns
.iaid
);
565 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
569 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
572 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
573 Identifier option is not set */
574 if (client
->client_id_len
) {
575 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
576 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
577 client
->client_id_len
,
583 /* RFC2131 section 3.5:
584 in its initial DHCPDISCOVER or DHCPREQUEST message, a
585 client may provide the server with a list of specific
586 parameters the client is interested in. If the client
587 includes a list of parameters in a DHCPDISCOVER message,
588 it MUST include that list in any subsequent DHCPREQUEST
591 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
592 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
593 client
->req_opts_size
, client
->req_opts
);
597 /* RFC2131 section 3.5:
598 The client SHOULD include the ’maximum DHCP message size’ option to
599 let the server know how large the server may make its DHCP messages.
601 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
602 than the defined default size unless the Maximum Messge Size option
605 RFC3442 "Requirements to Avoid Sizing Constraints":
606 Because a full routing table can be quite large, the standard 576
607 octet maximum size for a DHCP message may be too short to contain
608 some legitimate Classless Static Route options. Because of this,
609 clients implementing the Classless Static Route option SHOULD send a
610 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
611 stack is capable of receiving larger IP datagrams. In this case, the
612 client SHOULD set the value of this option to at least the MTU of the
613 interface that the client is configuring. The client MAY set the
614 value of this option higher, up to the size of the largest UDP packet
615 it is prepared to accept. (Note that the value specified in the
616 Maximum DHCP Message Size option is the total maximum packet size,
617 including IP and UDP headers.)
619 max_size
= htobe16(size
);
620 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
621 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
627 *_optoffset
= optoffset
;
634 static int client_append_fqdn_option(
635 DHCPMessage
*message
,
640 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
643 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
644 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
645 buffer
[1] = 0; /* RCODE1 (deprecated) */
646 buffer
[2] = 0; /* RCODE2 (deprecated) */
648 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
650 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
651 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
656 static int dhcp_client_send_raw(
657 sd_dhcp_client
*client
,
661 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
662 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
664 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
668 static int client_send_discover(sd_dhcp_client
*client
) {
669 _cleanup_free_ DHCPPacket
*discover
= NULL
;
670 size_t optoffset
, optlen
;
674 assert(client
->state
== DHCP_STATE_INIT
||
675 client
->state
== DHCP_STATE_SELECTING
);
677 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
678 &optlen
, &optoffset
);
682 /* the client may suggest values for the network address
683 and lease time in the DHCPDISCOVER message. The client may include
684 the ’requested IP address’ option to suggest that a particular IP
685 address be assigned, and may include the ’IP address lease time’
686 option to suggest the lease time it would like.
688 if (client
->last_addr
!= INADDR_ANY
) {
689 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
690 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
691 4, &client
->last_addr
);
696 if (client
->hostname
) {
697 /* According to RFC 4702 "clients that send the Client FQDN option in
698 their messages MUST NOT also send the Host Name option". Just send
699 one of the two depending on the hostname type.
701 if (dns_name_is_single_label(client
->hostname
)) {
702 /* it is unclear from RFC 2131 if client should send hostname in
703 DHCPDISCOVER but dhclient does and so we do as well
705 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
706 SD_DHCP_OPTION_HOST_NAME
,
707 strlen(client
->hostname
), client
->hostname
);
709 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
715 if (client
->vendor_class_identifier
) {
716 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
717 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
718 strlen(client
->vendor_class_identifier
),
719 client
->vendor_class_identifier
);
724 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
725 SD_DHCP_OPTION_END
, 0, NULL
);
729 /* We currently ignore:
730 The client SHOULD wait a random time between one and ten seconds to
731 desynchronize the use of DHCP at startup.
733 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
737 log_dhcp_client(client
, "DISCOVER");
742 static int client_send_request(sd_dhcp_client
*client
) {
743 _cleanup_free_ DHCPPacket
*request
= NULL
;
744 size_t optoffset
, optlen
;
749 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
753 switch (client
->state
) {
754 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
755 SELECTING should be REQUESTING)
758 case DHCP_STATE_REQUESTING
:
759 /* Client inserts the address of the selected server in ’server
760 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
761 filled in with the yiaddr value from the chosen DHCPOFFER.
764 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
765 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
766 4, &client
->lease
->server_address
);
770 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
771 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
772 4, &client
->lease
->address
);
778 case DHCP_STATE_INIT_REBOOT
:
779 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
780 option MUST be filled in with client’s notion of its previously
781 assigned address. ’ciaddr’ MUST be zero.
783 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
784 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
785 4, &client
->last_addr
);
790 case DHCP_STATE_RENEWING
:
791 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
792 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
793 client’s IP address.
797 case DHCP_STATE_REBINDING
:
798 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
799 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
800 client’s IP address.
802 This message MUST be broadcast to the 0xffffffff IP broadcast address.
804 request
->dhcp
.ciaddr
= client
->lease
->address
;
808 case DHCP_STATE_INIT
:
809 case DHCP_STATE_SELECTING
:
810 case DHCP_STATE_REBOOTING
:
811 case DHCP_STATE_BOUND
:
812 case DHCP_STATE_STOPPED
:
816 if (client
->hostname
) {
817 if (dns_name_is_single_label(client
->hostname
))
818 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
819 SD_DHCP_OPTION_HOST_NAME
,
820 strlen(client
->hostname
), client
->hostname
);
822 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
828 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
829 SD_DHCP_OPTION_END
, 0, NULL
);
833 if (client
->state
== DHCP_STATE_RENEWING
) {
834 r
= dhcp_network_send_udp_socket(client
->fd
,
835 client
->lease
->server_address
,
838 sizeof(DHCPMessage
) + optoffset
);
840 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
845 switch (client
->state
) {
847 case DHCP_STATE_REQUESTING
:
848 log_dhcp_client(client
, "REQUEST (requesting)");
851 case DHCP_STATE_INIT_REBOOT
:
852 log_dhcp_client(client
, "REQUEST (init-reboot)");
855 case DHCP_STATE_RENEWING
:
856 log_dhcp_client(client
, "REQUEST (renewing)");
859 case DHCP_STATE_REBINDING
:
860 log_dhcp_client(client
, "REQUEST (rebinding)");
864 log_dhcp_client(client
, "REQUEST (invalid)");
871 static int client_start(sd_dhcp_client
*client
);
873 static int client_timeout_resend(
878 sd_dhcp_client
*client
= userdata
;
879 DHCP_CLIENT_DONT_DESTROY(client
);
880 usec_t next_timeout
= 0;
887 assert(client
->event
);
889 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
893 switch (client
->state
) {
895 case DHCP_STATE_RENEWING
:
897 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
901 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
905 case DHCP_STATE_REBINDING
:
907 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
911 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
914 case DHCP_STATE_REBOOTING
:
915 /* start over as we did not receive a timely ack or nak */
916 r
= client_initialize(client
);
920 r
= client_start(client
);
924 log_dhcp_client(client
, "REBOOTED");
928 case DHCP_STATE_INIT
:
929 case DHCP_STATE_INIT_REBOOT
:
930 case DHCP_STATE_SELECTING
:
931 case DHCP_STATE_REQUESTING
:
932 case DHCP_STATE_BOUND
:
934 if (client
->attempt
< 64)
935 client
->attempt
*= 2;
937 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
941 case DHCP_STATE_STOPPED
:
946 next_timeout
+= (random_u32() & 0x1fffff);
948 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
950 r
= sd_event_add_time(client
->event
,
951 &client
->timeout_resend
,
952 clock_boottime_or_monotonic(),
953 next_timeout
, 10 * USEC_PER_MSEC
,
954 client_timeout_resend
, client
);
958 r
= sd_event_source_set_priority(client
->timeout_resend
,
959 client
->event_priority
);
963 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
967 switch (client
->state
) {
968 case DHCP_STATE_INIT
:
969 r
= client_send_discover(client
);
971 client
->state
= DHCP_STATE_SELECTING
;
974 if (client
->attempt
>= 64)
980 case DHCP_STATE_SELECTING
:
981 r
= client_send_discover(client
);
982 if (r
< 0 && client
->attempt
>= 64)
987 case DHCP_STATE_INIT_REBOOT
:
988 case DHCP_STATE_REQUESTING
:
989 case DHCP_STATE_RENEWING
:
990 case DHCP_STATE_REBINDING
:
991 r
= client_send_request(client
);
992 if (r
< 0 && client
->attempt
>= 64)
995 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
996 client
->state
= DHCP_STATE_REBOOTING
;
998 client
->request_sent
= time_now
;
1002 case DHCP_STATE_REBOOTING
:
1003 case DHCP_STATE_BOUND
:
1007 case DHCP_STATE_STOPPED
:
1015 client_stop(client
, r
);
1017 /* Errors were dealt with when stopping the client, don't spill
1018 errors into the event loop handler */
1022 static int client_initialize_io_events(
1023 sd_dhcp_client
*client
,
1024 sd_event_io_handler_t io_callback
) {
1029 assert(client
->event
);
1031 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1032 client
->fd
, EPOLLIN
, io_callback
,
1037 r
= sd_event_source_set_priority(client
->receive_message
,
1038 client
->event_priority
);
1042 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1048 client_stop(client
, r
);
1053 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1058 assert(client
->event
);
1060 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1062 if (client
->start_delay
) {
1063 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1064 usec
+= client
->start_delay
;
1067 r
= sd_event_add_time(client
->event
,
1068 &client
->timeout_resend
,
1069 clock_boottime_or_monotonic(),
1071 client_timeout_resend
, client
);
1075 r
= sd_event_source_set_priority(client
->timeout_resend
,
1076 client
->event_priority
);
1080 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1086 client_stop(client
, r
);
1092 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1093 client_initialize_io_events(client
, io_callback
);
1094 client_initialize_time_events(client
);
1099 static int client_start_delayed(sd_dhcp_client
*client
) {
1102 assert_return(client
, -EINVAL
);
1103 assert_return(client
->event
, -EINVAL
);
1104 assert_return(client
->ifindex
> 0, -EINVAL
);
1105 assert_return(client
->fd
< 0, -EBUSY
);
1106 assert_return(client
->xid
== 0, -EINVAL
);
1107 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1109 client
->xid
= random_u32();
1111 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1112 client
->xid
, client
->mac_addr
,
1113 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1115 client_stop(client
, r
);
1120 if (client
->state
== DHCP_STATE_INIT
|| client
->state
== DHCP_STATE_INIT_REBOOT
)
1121 client
->start_time
= now(clock_boottime_or_monotonic());
1123 return client_initialize_events(client
, client_receive_message_raw
);
1126 static int client_start(sd_dhcp_client
*client
) {
1127 client
->start_delay
= 0;
1128 return client_start_delayed(client
);
1131 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1132 sd_dhcp_client
*client
= userdata
;
1133 DHCP_CLIENT_DONT_DESTROY(client
);
1135 log_dhcp_client(client
, "EXPIRED");
1137 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1139 /* lease was lost, start over if not freed or stopped in callback */
1140 if (client
->state
!= DHCP_STATE_STOPPED
) {
1141 client_initialize(client
);
1142 client_start(client
);
1148 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1149 sd_dhcp_client
*client
= userdata
;
1150 DHCP_CLIENT_DONT_DESTROY(client
);
1155 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1156 client
->fd
= asynchronous_close(client
->fd
);
1158 client
->state
= DHCP_STATE_REBINDING
;
1159 client
->attempt
= 1;
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
,
1166 client_stop(client
, r
);
1171 return client_initialize_events(client
, client_receive_message_raw
);
1174 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1175 sd_dhcp_client
*client
= userdata
;
1176 DHCP_CLIENT_DONT_DESTROY(client
);
1178 client
->state
= DHCP_STATE_RENEWING
;
1179 client
->attempt
= 1;
1181 return client_initialize_time_events(client
);
1184 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1185 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1188 r
= dhcp_lease_new(&lease
);
1192 if (client
->client_id_len
) {
1193 r
= dhcp_lease_set_client_id(lease
,
1194 (uint8_t *) &client
->client_id
,
1195 client
->client_id_len
);
1200 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1201 if (r
!= DHCP_OFFER
) {
1202 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1206 lease
->next_server
= offer
->siaddr
;
1207 lease
->address
= offer
->yiaddr
;
1209 if (lease
->address
== 0 ||
1210 lease
->server_address
== 0 ||
1211 lease
->lifetime
== 0) {
1212 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1216 if (!lease
->have_subnet_mask
) {
1217 r
= dhcp_lease_set_default_subnet_mask(lease
);
1219 log_dhcp_client(client
, "received lease lacks subnet "
1220 "mask, and a fallback one can not be "
1221 "generated, ignoring");
1226 sd_dhcp_lease_unref(client
->lease
);
1227 client
->lease
= lease
;
1230 log_dhcp_client(client
, "OFFER");
1235 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1238 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1239 if (r
!= DHCP_FORCERENEW
)
1242 log_dhcp_client(client
, "FORCERENEW");
1247 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1248 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1249 _cleanup_free_
char *error_message
= NULL
;
1252 r
= dhcp_lease_new(&lease
);
1256 if (client
->client_id_len
) {
1257 r
= dhcp_lease_set_client_id(lease
,
1258 (uint8_t *) &client
->client_id
,
1259 client
->client_id_len
);
1264 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1265 if (r
== DHCP_NAK
) {
1266 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1267 return -EADDRNOTAVAIL
;
1270 if (r
!= DHCP_ACK
) {
1271 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1275 lease
->next_server
= ack
->siaddr
;
1277 lease
->address
= ack
->yiaddr
;
1279 if (lease
->address
== INADDR_ANY
||
1280 lease
->server_address
== INADDR_ANY
||
1281 lease
->lifetime
== 0) {
1282 log_dhcp_client(client
, "received lease lacks address, server "
1283 "address or lease lifetime, ignoring");
1287 if (lease
->subnet_mask
== INADDR_ANY
) {
1288 r
= dhcp_lease_set_default_subnet_mask(lease
);
1290 log_dhcp_client(client
, "received lease lacks subnet "
1291 "mask, and a fallback one can not be "
1292 "generated, ignoring");
1297 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1298 if (client
->lease
) {
1299 if (client
->lease
->address
!= lease
->address
||
1300 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1301 client
->lease
->router
!= lease
->router
) {
1302 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1304 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1306 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1309 client
->lease
= lease
;
1312 log_dhcp_client(client
, "ACK");
1317 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1319 assert(client
->request_sent
);
1320 assert(lifetime
> 0);
1327 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1328 + (random_u32() & 0x1fffff);
1331 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1333 uint64_t lifetime_timeout
;
1334 uint64_t t2_timeout
;
1335 uint64_t t1_timeout
;
1336 char time_string
[FORMAT_TIMESPAN_MAX
];
1340 assert(client
->event
);
1341 assert(client
->lease
);
1342 assert(client
->lease
->lifetime
);
1344 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1345 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1346 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1348 /* don't set timers for infinite leases */
1349 if (client
->lease
->lifetime
== 0xffffffff)
1352 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1355 assert(client
->request_sent
<= time_now
);
1357 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1358 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1359 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1360 /* both T1 and T2 are given */
1361 if (client
->lease
->t1
< client
->lease
->t2
&&
1362 client
->lease
->t2
< client
->lease
->lifetime
) {
1363 /* they are both valid */
1364 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1365 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1368 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1369 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1370 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1371 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1373 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1374 /* only T2 is given, and it is valid */
1375 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1376 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1377 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1378 if (t2_timeout
<= t1_timeout
) {
1379 /* the computed T1 would be invalid, so discard T2 */
1380 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1381 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1383 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1384 /* only T1 is given, and it is valid */
1385 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1386 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1387 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1388 if (t2_timeout
<= t1_timeout
) {
1389 /* the computed T2 would be invalid, so discard T1 */
1390 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1391 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1394 /* fall back to the default timeouts */
1395 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1396 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1397 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1398 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1401 /* arm lifetime timeout */
1402 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1403 clock_boottime_or_monotonic(),
1404 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1405 client_timeout_expire
, client
);
1409 r
= sd_event_source_set_priority(client
->timeout_expire
,
1410 client
->event_priority
);
1414 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1418 log_dhcp_client(client
, "lease expires in %s",
1419 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1421 /* don't arm earlier timeouts if this has already expired */
1422 if (lifetime_timeout
<= time_now
)
1425 /* arm T2 timeout */
1426 r
= sd_event_add_time(client
->event
,
1427 &client
->timeout_t2
,
1428 clock_boottime_or_monotonic(),
1431 client_timeout_t2
, client
);
1435 r
= sd_event_source_set_priority(client
->timeout_t2
,
1436 client
->event_priority
);
1440 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1444 log_dhcp_client(client
, "T2 expires in %s",
1445 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1447 /* don't arm earlier timeout if this has already expired */
1448 if (t2_timeout
<= time_now
)
1451 /* arm T1 timeout */
1452 r
= sd_event_add_time(client
->event
,
1453 &client
->timeout_t1
,
1454 clock_boottime_or_monotonic(),
1455 t1_timeout
, 10 * USEC_PER_MSEC
,
1456 client_timeout_t1
, client
);
1460 r
= sd_event_source_set_priority(client
->timeout_t1
,
1461 client
->event_priority
);
1465 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1469 log_dhcp_client(client
, "T1 expires in %s",
1470 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1475 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1476 DHCP_CLIENT_DONT_DESTROY(client
);
1477 char time_string
[FORMAT_TIMESPAN_MAX
];
1478 int r
= 0, notify_event
= 0;
1481 assert(client
->event
);
1484 switch (client
->state
) {
1485 case DHCP_STATE_SELECTING
:
1487 r
= client_handle_offer(client
, message
, len
);
1490 client
->timeout_resend
=
1491 sd_event_source_unref(client
->timeout_resend
);
1493 client
->state
= DHCP_STATE_REQUESTING
;
1494 client
->attempt
= 1;
1496 r
= sd_event_add_time(client
->event
,
1497 &client
->timeout_resend
,
1498 clock_boottime_or_monotonic(),
1500 client_timeout_resend
, client
);
1504 r
= sd_event_source_set_priority(client
->timeout_resend
,
1505 client
->event_priority
);
1509 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1512 } else if (r
== -ENOMSG
)
1513 /* invalid message, let's ignore it */
1518 case DHCP_STATE_REBOOTING
:
1519 case DHCP_STATE_REQUESTING
:
1520 case DHCP_STATE_RENEWING
:
1521 case DHCP_STATE_REBINDING
:
1523 r
= client_handle_ack(client
, message
, len
);
1525 client
->start_delay
= 0;
1526 client
->timeout_resend
=
1527 sd_event_source_unref(client
->timeout_resend
);
1528 client
->receive_message
=
1529 sd_event_source_unref(client
->receive_message
);
1530 client
->fd
= asynchronous_close(client
->fd
);
1532 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1533 DHCP_STATE_REBOOTING
))
1534 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1535 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1538 client
->state
= DHCP_STATE_BOUND
;
1539 client
->attempt
= 1;
1541 client
->last_addr
= client
->lease
->address
;
1543 r
= client_set_lease_timeouts(client
);
1545 log_dhcp_client(client
, "could not set lease timeouts");
1549 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1551 log_dhcp_client(client
, "could not bind UDP socket");
1557 client_initialize_io_events(client
, client_receive_message_udp
);
1560 client_notify(client
, notify_event
);
1561 if (client
->state
== DHCP_STATE_STOPPED
)
1565 } else if (r
== -EADDRNOTAVAIL
) {
1566 /* got a NAK, let's restart the client */
1567 client
->timeout_resend
=
1568 sd_event_source_unref(client
->timeout_resend
);
1570 r
= client_initialize(client
);
1574 r
= client_start_delayed(client
);
1578 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1579 client
->start_delay
, USEC_PER_SEC
));
1581 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1582 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1585 } else if (r
== -ENOMSG
)
1586 /* invalid message, let's ignore it */
1591 case DHCP_STATE_BOUND
:
1592 r
= client_handle_forcerenew(client
, message
, len
);
1594 r
= client_timeout_t1(NULL
, 0, client
);
1597 } else if (r
== -ENOMSG
)
1598 /* invalid message, let's ignore it */
1603 case DHCP_STATE_INIT
:
1604 case DHCP_STATE_INIT_REBOOT
:
1608 case DHCP_STATE_STOPPED
:
1615 client_stop(client
, r
);
1620 static int client_receive_message_udp(
1626 sd_dhcp_client
*client
= userdata
;
1627 _cleanup_free_ DHCPMessage
*message
= NULL
;
1628 const struct ether_addr zero_mac
= {};
1629 const struct ether_addr
*expected_chaddr
= NULL
;
1630 uint8_t expected_hlen
= 0;
1631 ssize_t len
, buflen
;
1636 buflen
= next_datagram_size_fd(fd
);
1640 message
= malloc0(buflen
);
1644 len
= recv(fd
, message
, buflen
, 0);
1646 if (errno
== EAGAIN
|| errno
== EINTR
)
1649 return log_dhcp_client_errno(client
, errno
, "Could not receive message from UDP socket: %m");
1651 if ((size_t) len
< sizeof(DHCPMessage
)) {
1652 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1656 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1657 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1661 if (message
->op
!= BOOTREPLY
) {
1662 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1666 if (message
->htype
!= client
->arp_type
) {
1667 log_dhcp_client(client
, "Packet type does not match client type");
1671 if (client
->arp_type
== ARPHRD_ETHER
) {
1672 expected_hlen
= ETH_ALEN
;
1673 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1675 /* Non-Ethernet links expect zero chaddr */
1677 expected_chaddr
= &zero_mac
;
1680 if (message
->hlen
!= expected_hlen
) {
1681 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1685 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1686 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1690 if (client
->state
!= DHCP_STATE_BOUND
&&
1691 be32toh(message
->xid
) != client
->xid
) {
1692 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1693 so ignore the xid in this case */
1694 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1695 be32toh(message
->xid
), client
->xid
);
1699 return client_handle_message(client
, message
, len
);
1702 static int client_receive_message_raw(
1708 sd_dhcp_client
*client
= userdata
;
1709 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1710 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1711 struct iovec iov
= {};
1712 struct msghdr msg
= {
1715 .msg_control
= cmsgbuf
,
1716 .msg_controllen
= sizeof(cmsgbuf
),
1718 struct cmsghdr
*cmsg
;
1719 bool checksum
= true;
1720 ssize_t buflen
, len
;
1726 buflen
= next_datagram_size_fd(fd
);
1730 packet
= malloc0(buflen
);
1734 iov
.iov_base
= packet
;
1735 iov
.iov_len
= buflen
;
1737 len
= recvmsg(fd
, &msg
, 0);
1739 if (errno
== EAGAIN
|| errno
== EINTR
)
1742 log_dhcp_client(client
, "Could not receive message from raw socket: %m");
1745 } else if ((size_t)len
< sizeof(DHCPPacket
))
1748 CMSG_FOREACH(cmsg
, &msg
) {
1749 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1750 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1751 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1752 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1754 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1759 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1763 len
-= DHCP_IP_UDP_SIZE
;
1765 return client_handle_message(client
, &packet
->dhcp
, len
);
1768 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1771 assert_return(client
, -EINVAL
);
1773 r
= client_initialize(client
);
1777 if (client
->last_addr
)
1778 client
->state
= DHCP_STATE_INIT_REBOOT
;
1780 r
= client_start(client
);
1782 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1787 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1788 DHCP_CLIENT_DONT_DESTROY(client
);
1790 assert_return(client
, -EINVAL
);
1792 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1793 client
->state
= DHCP_STATE_STOPPED
;
1798 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1801 assert_return(client
, -EINVAL
);
1802 assert_return(!client
->event
, -EBUSY
);
1805 client
->event
= sd_event_ref(event
);
1807 r
= sd_event_default(&client
->event
);
1812 client
->event_priority
= priority
;
1817 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1818 assert_return(client
, -EINVAL
);
1820 client
->event
= sd_event_unref(client
->event
);
1825 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1826 assert_return(client
, NULL
);
1828 return client
->event
;
1831 sd_dhcp_client
*sd_dhcp_client_ref(sd_dhcp_client
*client
) {
1836 assert(client
->n_ref
>= 1);
1842 sd_dhcp_client
*sd_dhcp_client_unref(sd_dhcp_client
*client
) {
1847 assert(client
->n_ref
>= 1);
1850 if (client
->n_ref
> 0)
1853 log_dhcp_client(client
, "FREE");
1855 client_initialize(client
);
1857 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1859 sd_dhcp_client_detach_event(client
);
1861 sd_dhcp_lease_unref(client
->lease
);
1863 free(client
->req_opts
);
1864 free(client
->hostname
);
1865 free(client
->vendor_class_identifier
);
1866 return mfree(client
);
1869 int sd_dhcp_client_new(sd_dhcp_client
**ret
) {
1870 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1872 assert_return(ret
, -EINVAL
);
1874 client
= new0(sd_dhcp_client
, 1);
1879 client
->state
= DHCP_STATE_INIT
;
1880 client
->ifindex
= -1;
1882 client
->attempt
= 1;
1883 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1884 client
->port
= DHCP_PORT_CLIENT
;
1886 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1887 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1888 if (!client
->req_opts
)