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 if (client
->vendor_class_identifier
) {
829 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
830 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
831 strlen(client
->vendor_class_identifier
),
832 client
->vendor_class_identifier
);
837 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
838 SD_DHCP_OPTION_END
, 0, NULL
);
842 if (client
->state
== DHCP_STATE_RENEWING
) {
843 r
= dhcp_network_send_udp_socket(client
->fd
,
844 client
->lease
->server_address
,
847 sizeof(DHCPMessage
) + optoffset
);
849 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
854 switch (client
->state
) {
856 case DHCP_STATE_REQUESTING
:
857 log_dhcp_client(client
, "REQUEST (requesting)");
860 case DHCP_STATE_INIT_REBOOT
:
861 log_dhcp_client(client
, "REQUEST (init-reboot)");
864 case DHCP_STATE_RENEWING
:
865 log_dhcp_client(client
, "REQUEST (renewing)");
868 case DHCP_STATE_REBINDING
:
869 log_dhcp_client(client
, "REQUEST (rebinding)");
873 log_dhcp_client(client
, "REQUEST (invalid)");
880 static int client_start(sd_dhcp_client
*client
);
882 static int client_timeout_resend(
887 sd_dhcp_client
*client
= userdata
;
888 DHCP_CLIENT_DONT_DESTROY(client
);
889 usec_t next_timeout
= 0;
896 assert(client
->event
);
898 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
902 switch (client
->state
) {
904 case DHCP_STATE_RENEWING
:
906 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
910 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
914 case DHCP_STATE_REBINDING
:
916 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
920 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
923 case DHCP_STATE_REBOOTING
:
924 /* start over as we did not receive a timely ack or nak */
925 r
= client_initialize(client
);
929 r
= client_start(client
);
933 log_dhcp_client(client
, "REBOOTED");
937 case DHCP_STATE_INIT
:
938 case DHCP_STATE_INIT_REBOOT
:
939 case DHCP_STATE_SELECTING
:
940 case DHCP_STATE_REQUESTING
:
941 case DHCP_STATE_BOUND
:
943 if (client
->attempt
< 64)
944 client
->attempt
*= 2;
946 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
950 case DHCP_STATE_STOPPED
:
955 next_timeout
+= (random_u32() & 0x1fffff);
957 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
959 r
= sd_event_add_time(client
->event
,
960 &client
->timeout_resend
,
961 clock_boottime_or_monotonic(),
962 next_timeout
, 10 * USEC_PER_MSEC
,
963 client_timeout_resend
, client
);
967 r
= sd_event_source_set_priority(client
->timeout_resend
,
968 client
->event_priority
);
972 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
976 switch (client
->state
) {
977 case DHCP_STATE_INIT
:
978 r
= client_send_discover(client
);
980 client
->state
= DHCP_STATE_SELECTING
;
983 if (client
->attempt
>= 64)
989 case DHCP_STATE_SELECTING
:
990 r
= client_send_discover(client
);
991 if (r
< 0 && client
->attempt
>= 64)
996 case DHCP_STATE_INIT_REBOOT
:
997 case DHCP_STATE_REQUESTING
:
998 case DHCP_STATE_RENEWING
:
999 case DHCP_STATE_REBINDING
:
1000 r
= client_send_request(client
);
1001 if (r
< 0 && client
->attempt
>= 64)
1004 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1005 client
->state
= DHCP_STATE_REBOOTING
;
1007 client
->request_sent
= time_now
;
1011 case DHCP_STATE_REBOOTING
:
1012 case DHCP_STATE_BOUND
:
1016 case DHCP_STATE_STOPPED
:
1024 client_stop(client
, r
);
1026 /* Errors were dealt with when stopping the client, don't spill
1027 errors into the event loop handler */
1031 static int client_initialize_io_events(
1032 sd_dhcp_client
*client
,
1033 sd_event_io_handler_t io_callback
) {
1038 assert(client
->event
);
1040 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1041 client
->fd
, EPOLLIN
, io_callback
,
1046 r
= sd_event_source_set_priority(client
->receive_message
,
1047 client
->event_priority
);
1051 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1057 client_stop(client
, r
);
1062 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1067 assert(client
->event
);
1069 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1071 if (client
->start_delay
) {
1072 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1073 usec
+= client
->start_delay
;
1076 r
= sd_event_add_time(client
->event
,
1077 &client
->timeout_resend
,
1078 clock_boottime_or_monotonic(),
1080 client_timeout_resend
, client
);
1084 r
= sd_event_source_set_priority(client
->timeout_resend
,
1085 client
->event_priority
);
1089 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1095 client_stop(client
, r
);
1101 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1102 client_initialize_io_events(client
, io_callback
);
1103 client_initialize_time_events(client
);
1108 static int client_start_delayed(sd_dhcp_client
*client
) {
1111 assert_return(client
, -EINVAL
);
1112 assert_return(client
->event
, -EINVAL
);
1113 assert_return(client
->ifindex
> 0, -EINVAL
);
1114 assert_return(client
->fd
< 0, -EBUSY
);
1115 assert_return(client
->xid
== 0, -EINVAL
);
1116 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1118 client
->xid
= random_u32();
1120 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1121 client
->xid
, client
->mac_addr
,
1122 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1124 client_stop(client
, r
);
1129 if (client
->state
== DHCP_STATE_INIT
|| client
->state
== DHCP_STATE_INIT_REBOOT
)
1130 client
->start_time
= now(clock_boottime_or_monotonic());
1132 return client_initialize_events(client
, client_receive_message_raw
);
1135 static int client_start(sd_dhcp_client
*client
) {
1136 client
->start_delay
= 0;
1137 return client_start_delayed(client
);
1140 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1141 sd_dhcp_client
*client
= userdata
;
1142 DHCP_CLIENT_DONT_DESTROY(client
);
1144 log_dhcp_client(client
, "EXPIRED");
1146 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1148 /* lease was lost, start over if not freed or stopped in callback */
1149 if (client
->state
!= DHCP_STATE_STOPPED
) {
1150 client_initialize(client
);
1151 client_start(client
);
1157 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1158 sd_dhcp_client
*client
= userdata
;
1159 DHCP_CLIENT_DONT_DESTROY(client
);
1164 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1165 client
->fd
= asynchronous_close(client
->fd
);
1167 client
->state
= DHCP_STATE_REBINDING
;
1168 client
->attempt
= 1;
1170 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1171 client
->xid
, client
->mac_addr
,
1172 client
->mac_addr_len
, client
->arp_type
,
1175 client_stop(client
, r
);
1180 return client_initialize_events(client
, client_receive_message_raw
);
1183 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1184 sd_dhcp_client
*client
= userdata
;
1185 DHCP_CLIENT_DONT_DESTROY(client
);
1187 client
->state
= DHCP_STATE_RENEWING
;
1188 client
->attempt
= 1;
1190 return client_initialize_time_events(client
);
1193 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1194 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1197 r
= dhcp_lease_new(&lease
);
1201 if (client
->client_id_len
) {
1202 r
= dhcp_lease_set_client_id(lease
,
1203 (uint8_t *) &client
->client_id
,
1204 client
->client_id_len
);
1209 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1210 if (r
!= DHCP_OFFER
) {
1211 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1215 lease
->next_server
= offer
->siaddr
;
1216 lease
->address
= offer
->yiaddr
;
1218 if (lease
->address
== 0 ||
1219 lease
->server_address
== 0 ||
1220 lease
->lifetime
== 0) {
1221 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1225 if (!lease
->have_subnet_mask
) {
1226 r
= dhcp_lease_set_default_subnet_mask(lease
);
1228 log_dhcp_client(client
, "received lease lacks subnet "
1229 "mask, and a fallback one can not be "
1230 "generated, ignoring");
1235 sd_dhcp_lease_unref(client
->lease
);
1236 client
->lease
= lease
;
1239 log_dhcp_client(client
, "OFFER");
1244 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1247 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1248 if (r
!= DHCP_FORCERENEW
)
1251 log_dhcp_client(client
, "FORCERENEW");
1256 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1257 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1258 _cleanup_free_
char *error_message
= NULL
;
1261 r
= dhcp_lease_new(&lease
);
1265 if (client
->client_id_len
) {
1266 r
= dhcp_lease_set_client_id(lease
,
1267 (uint8_t *) &client
->client_id
,
1268 client
->client_id_len
);
1273 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1274 if (r
== DHCP_NAK
) {
1275 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1276 return -EADDRNOTAVAIL
;
1279 if (r
!= DHCP_ACK
) {
1280 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1284 lease
->next_server
= ack
->siaddr
;
1286 lease
->address
= ack
->yiaddr
;
1288 if (lease
->address
== INADDR_ANY
||
1289 lease
->server_address
== INADDR_ANY
||
1290 lease
->lifetime
== 0) {
1291 log_dhcp_client(client
, "received lease lacks address, server "
1292 "address or lease lifetime, ignoring");
1296 if (lease
->subnet_mask
== INADDR_ANY
) {
1297 r
= dhcp_lease_set_default_subnet_mask(lease
);
1299 log_dhcp_client(client
, "received lease lacks subnet "
1300 "mask, and a fallback one can not be "
1301 "generated, ignoring");
1306 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1307 if (client
->lease
) {
1308 if (client
->lease
->address
!= lease
->address
||
1309 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1310 client
->lease
->router
!= lease
->router
) {
1311 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1313 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1315 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1318 client
->lease
= lease
;
1321 log_dhcp_client(client
, "ACK");
1326 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1328 assert(client
->request_sent
);
1329 assert(lifetime
> 0);
1336 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1337 + (random_u32() & 0x1fffff);
1340 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1342 uint64_t lifetime_timeout
;
1343 uint64_t t2_timeout
;
1344 uint64_t t1_timeout
;
1345 char time_string
[FORMAT_TIMESPAN_MAX
];
1349 assert(client
->event
);
1350 assert(client
->lease
);
1351 assert(client
->lease
->lifetime
);
1353 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1354 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1355 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1357 /* don't set timers for infinite leases */
1358 if (client
->lease
->lifetime
== 0xffffffff)
1361 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1364 assert(client
->request_sent
<= time_now
);
1366 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1367 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1368 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1369 /* both T1 and T2 are given */
1370 if (client
->lease
->t1
< client
->lease
->t2
&&
1371 client
->lease
->t2
< client
->lease
->lifetime
) {
1372 /* they are both valid */
1373 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1374 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1377 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1378 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1379 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1380 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1382 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1383 /* only T2 is given, and it is valid */
1384 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1385 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1386 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1387 if (t2_timeout
<= t1_timeout
) {
1388 /* the computed T1 would be invalid, so discard T2 */
1389 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1390 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1392 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1393 /* only T1 is given, and it is valid */
1394 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1395 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1396 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1397 if (t2_timeout
<= t1_timeout
) {
1398 /* the computed T2 would be invalid, so discard T1 */
1399 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1400 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1403 /* fall back to the default timeouts */
1404 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1405 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1406 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1407 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1410 /* arm lifetime timeout */
1411 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1412 clock_boottime_or_monotonic(),
1413 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1414 client_timeout_expire
, client
);
1418 r
= sd_event_source_set_priority(client
->timeout_expire
,
1419 client
->event_priority
);
1423 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1427 log_dhcp_client(client
, "lease expires in %s",
1428 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1430 /* don't arm earlier timeouts if this has already expired */
1431 if (lifetime_timeout
<= time_now
)
1434 /* arm T2 timeout */
1435 r
= sd_event_add_time(client
->event
,
1436 &client
->timeout_t2
,
1437 clock_boottime_or_monotonic(),
1440 client_timeout_t2
, client
);
1444 r
= sd_event_source_set_priority(client
->timeout_t2
,
1445 client
->event_priority
);
1449 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1453 log_dhcp_client(client
, "T2 expires in %s",
1454 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1456 /* don't arm earlier timeout if this has already expired */
1457 if (t2_timeout
<= time_now
)
1460 /* arm T1 timeout */
1461 r
= sd_event_add_time(client
->event
,
1462 &client
->timeout_t1
,
1463 clock_boottime_or_monotonic(),
1464 t1_timeout
, 10 * USEC_PER_MSEC
,
1465 client_timeout_t1
, client
);
1469 r
= sd_event_source_set_priority(client
->timeout_t1
,
1470 client
->event_priority
);
1474 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1478 log_dhcp_client(client
, "T1 expires in %s",
1479 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1484 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1485 DHCP_CLIENT_DONT_DESTROY(client
);
1486 char time_string
[FORMAT_TIMESPAN_MAX
];
1487 int r
= 0, notify_event
= 0;
1490 assert(client
->event
);
1493 switch (client
->state
) {
1494 case DHCP_STATE_SELECTING
:
1496 r
= client_handle_offer(client
, message
, len
);
1499 client
->timeout_resend
=
1500 sd_event_source_unref(client
->timeout_resend
);
1502 client
->state
= DHCP_STATE_REQUESTING
;
1503 client
->attempt
= 1;
1505 r
= sd_event_add_time(client
->event
,
1506 &client
->timeout_resend
,
1507 clock_boottime_or_monotonic(),
1509 client_timeout_resend
, client
);
1513 r
= sd_event_source_set_priority(client
->timeout_resend
,
1514 client
->event_priority
);
1518 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1521 } else if (r
== -ENOMSG
)
1522 /* invalid message, let's ignore it */
1527 case DHCP_STATE_REBOOTING
:
1528 case DHCP_STATE_REQUESTING
:
1529 case DHCP_STATE_RENEWING
:
1530 case DHCP_STATE_REBINDING
:
1532 r
= client_handle_ack(client
, message
, len
);
1534 client
->start_delay
= 0;
1535 client
->timeout_resend
=
1536 sd_event_source_unref(client
->timeout_resend
);
1537 client
->receive_message
=
1538 sd_event_source_unref(client
->receive_message
);
1539 client
->fd
= asynchronous_close(client
->fd
);
1541 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1542 DHCP_STATE_REBOOTING
))
1543 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1544 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1547 client
->state
= DHCP_STATE_BOUND
;
1548 client
->attempt
= 1;
1550 client
->last_addr
= client
->lease
->address
;
1552 r
= client_set_lease_timeouts(client
);
1554 log_dhcp_client(client
, "could not set lease timeouts");
1558 r
= dhcp_network_bind_udp_socket(client
->ifindex
, client
->lease
->address
, client
->port
);
1560 log_dhcp_client(client
, "could not bind UDP socket");
1566 client_initialize_io_events(client
, client_receive_message_udp
);
1569 client_notify(client
, notify_event
);
1570 if (client
->state
== DHCP_STATE_STOPPED
)
1574 } else if (r
== -EADDRNOTAVAIL
) {
1575 /* got a NAK, let's restart the client */
1576 client
->timeout_resend
=
1577 sd_event_source_unref(client
->timeout_resend
);
1579 r
= client_initialize(client
);
1583 r
= client_start_delayed(client
);
1587 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1588 client
->start_delay
, USEC_PER_SEC
));
1590 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1591 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1594 } else if (r
== -ENOMSG
)
1595 /* invalid message, let's ignore it */
1600 case DHCP_STATE_BOUND
:
1601 r
= client_handle_forcerenew(client
, message
, len
);
1603 r
= client_timeout_t1(NULL
, 0, client
);
1606 } else if (r
== -ENOMSG
)
1607 /* invalid message, let's ignore it */
1612 case DHCP_STATE_INIT
:
1613 case DHCP_STATE_INIT_REBOOT
:
1617 case DHCP_STATE_STOPPED
:
1624 client_stop(client
, r
);
1629 static int client_receive_message_udp(
1635 sd_dhcp_client
*client
= userdata
;
1636 _cleanup_free_ DHCPMessage
*message
= NULL
;
1637 const struct ether_addr zero_mac
= {};
1638 const struct ether_addr
*expected_chaddr
= NULL
;
1639 uint8_t expected_hlen
= 0;
1640 ssize_t len
, buflen
;
1645 buflen
= next_datagram_size_fd(fd
);
1649 message
= malloc0(buflen
);
1653 len
= recv(fd
, message
, buflen
, 0);
1655 if (errno
== EAGAIN
|| errno
== EINTR
)
1658 return log_dhcp_client_errno(client
, errno
, "Could not receive message from UDP socket: %m");
1660 if ((size_t) len
< sizeof(DHCPMessage
)) {
1661 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1665 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1666 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1670 if (message
->op
!= BOOTREPLY
) {
1671 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1675 if (message
->htype
!= client
->arp_type
) {
1676 log_dhcp_client(client
, "Packet type does not match client type");
1680 if (client
->arp_type
== ARPHRD_ETHER
) {
1681 expected_hlen
= ETH_ALEN
;
1682 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1684 /* Non-Ethernet links expect zero chaddr */
1686 expected_chaddr
= &zero_mac
;
1689 if (message
->hlen
!= expected_hlen
) {
1690 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1694 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1695 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1699 if (client
->state
!= DHCP_STATE_BOUND
&&
1700 be32toh(message
->xid
) != client
->xid
) {
1701 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1702 so ignore the xid in this case */
1703 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1704 be32toh(message
->xid
), client
->xid
);
1708 return client_handle_message(client
, message
, len
);
1711 static int client_receive_message_raw(
1717 sd_dhcp_client
*client
= userdata
;
1718 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1719 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1720 struct iovec iov
= {};
1721 struct msghdr msg
= {
1724 .msg_control
= cmsgbuf
,
1725 .msg_controllen
= sizeof(cmsgbuf
),
1727 struct cmsghdr
*cmsg
;
1728 bool checksum
= true;
1729 ssize_t buflen
, len
;
1735 buflen
= next_datagram_size_fd(fd
);
1739 packet
= malloc0(buflen
);
1743 iov
.iov_base
= packet
;
1744 iov
.iov_len
= buflen
;
1746 len
= recvmsg(fd
, &msg
, 0);
1748 if (errno
== EAGAIN
|| errno
== EINTR
)
1751 log_dhcp_client(client
, "Could not receive message from raw socket: %m");
1754 } else if ((size_t)len
< sizeof(DHCPPacket
))
1757 CMSG_FOREACH(cmsg
, &msg
) {
1758 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1759 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1760 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1761 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1763 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1768 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1772 len
-= DHCP_IP_UDP_SIZE
;
1774 return client_handle_message(client
, &packet
->dhcp
, len
);
1777 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1780 assert_return(client
, -EINVAL
);
1782 r
= client_initialize(client
);
1786 if (client
->last_addr
)
1787 client
->state
= DHCP_STATE_INIT_REBOOT
;
1789 r
= client_start(client
);
1791 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1796 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1797 DHCP_CLIENT_DONT_DESTROY(client
);
1799 assert_return(client
, -EINVAL
);
1801 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1802 client
->state
= DHCP_STATE_STOPPED
;
1807 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1810 assert_return(client
, -EINVAL
);
1811 assert_return(!client
->event
, -EBUSY
);
1814 client
->event
= sd_event_ref(event
);
1816 r
= sd_event_default(&client
->event
);
1821 client
->event_priority
= priority
;
1826 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1827 assert_return(client
, -EINVAL
);
1829 client
->event
= sd_event_unref(client
->event
);
1834 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1835 assert_return(client
, NULL
);
1837 return client
->event
;
1840 sd_dhcp_client
*sd_dhcp_client_ref(sd_dhcp_client
*client
) {
1845 assert(client
->n_ref
>= 1);
1851 sd_dhcp_client
*sd_dhcp_client_unref(sd_dhcp_client
*client
) {
1856 assert(client
->n_ref
>= 1);
1859 if (client
->n_ref
> 0)
1862 log_dhcp_client(client
, "FREE");
1864 client_initialize(client
);
1866 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1868 sd_dhcp_client_detach_event(client
);
1870 sd_dhcp_lease_unref(client
->lease
);
1872 free(client
->req_opts
);
1873 free(client
->hostname
);
1874 free(client
->vendor_class_identifier
);
1875 return mfree(client
);
1878 int sd_dhcp_client_new(sd_dhcp_client
**ret
) {
1879 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1881 assert_return(ret
, -EINVAL
);
1883 client
= new0(sd_dhcp_client
, 1);
1888 client
->state
= DHCP_STATE_INIT
;
1889 client
->ifindex
= -1;
1891 client
->attempt
= 1;
1892 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1893 client
->port
= DHCP_PORT_CLIENT
;
1895 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1896 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1897 if (!client
->req_opts
)