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 char *new_hostname
= NULL
;
391 assert_return(client
, -EINVAL
);
393 if (!hostname_is_valid(hostname
, false) && !dns_name_is_valid(hostname
))
396 if (streq_ptr(client
->hostname
, hostname
))
400 new_hostname
= strdup(hostname
);
405 free(client
->hostname
);
406 client
->hostname
= new_hostname
;
411 int sd_dhcp_client_set_vendor_class_identifier(
412 sd_dhcp_client
*client
,
415 char *new_vci
= NULL
;
417 assert_return(client
, -EINVAL
);
419 new_vci
= strdup(vci
);
423 free(client
->vendor_class_identifier
);
425 client
->vendor_class_identifier
= new_vci
;
430 int sd_dhcp_client_set_client_port(
431 sd_dhcp_client
*client
,
434 assert_return(client
, -EINVAL
);
441 int sd_dhcp_client_set_mtu(sd_dhcp_client
*client
, uint32_t mtu
) {
442 assert_return(client
, -EINVAL
);
443 assert_return(mtu
>= DHCP_DEFAULT_MIN_SIZE
, -ERANGE
);
450 int sd_dhcp_client_get_lease(sd_dhcp_client
*client
, sd_dhcp_lease
**ret
) {
451 assert_return(client
, -EINVAL
);
453 if (client
->state
!= DHCP_STATE_BOUND
&&
454 client
->state
!= DHCP_STATE_RENEWING
&&
455 client
->state
!= DHCP_STATE_REBINDING
)
456 return -EADDRNOTAVAIL
;
459 *ret
= client
->lease
;
464 static void client_notify(sd_dhcp_client
*client
, int event
) {
467 if (client
->callback
)
468 client
->callback(client
, event
, client
->userdata
);
471 static int client_initialize(sd_dhcp_client
*client
) {
472 assert_return(client
, -EINVAL
);
474 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
476 client
->fd
= asynchronous_close(client
->fd
);
478 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
480 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
481 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
482 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
486 client
->state
= DHCP_STATE_INIT
;
489 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
494 static void client_stop(sd_dhcp_client
*client
, int error
) {
498 log_dhcp_client(client
, "STOPPED: %s", strerror(-error
));
499 else if (error
== SD_DHCP_CLIENT_EVENT_STOP
)
500 log_dhcp_client(client
, "STOPPED");
502 log_dhcp_client(client
, "STOPPED: Unknown event");
504 client_notify(client
, error
);
506 client_initialize(client
);
509 static int client_message_init(
510 sd_dhcp_client
*client
,
514 size_t *_optoffset
) {
516 _cleanup_free_ DHCPPacket
*packet
= NULL
;
517 size_t optlen
, optoffset
, size
;
524 assert(client
->start_time
);
528 assert(type
== DHCP_DISCOVER
|| type
== DHCP_REQUEST
);
530 optlen
= DHCP_MIN_OPTIONS_SIZE
;
531 size
= sizeof(DHCPPacket
) + optlen
;
533 packet
= malloc0(size
);
537 r
= dhcp_message_init(&packet
->dhcp
, BOOTREQUEST
, client
->xid
, type
,
538 client
->arp_type
, optlen
, &optoffset
);
542 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
543 refuse to issue an DHCP lease if 'secs' is set to zero */
544 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
547 assert(time_now
>= client
->start_time
);
549 /* seconds between sending first and last DISCOVER
550 * must always be strictly positive to deal with broken servers */
551 secs
= ((time_now
- client
->start_time
) / USEC_PER_SEC
) ? : 1;
552 packet
->dhcp
.secs
= htobe16(secs
);
554 /* RFC2132 section 4.1
555 A client that cannot receive unicast IP datagrams until its protocol
556 software has been configured with an IP address SHOULD set the
557 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
558 DHCPREQUEST messages that client sends. The BROADCAST bit will
559 provide a hint to the DHCP server and BOOTP relay agent to broadcast
560 any messages to the client on the client's subnet.
562 Note: some interfaces needs this to be enabled, but some networks
563 needs this to be disabled as broadcasts are filteretd, so this
564 needs to be configurable */
565 if (client
->request_broadcast
|| client
->arp_type
!= ARPHRD_ETHER
)
566 packet
->dhcp
.flags
= htobe16(0x8000);
568 /* RFC2132 section 4.1.1:
569 The client MUST include its hardware address in the ’chaddr’ field, if
570 necessary for delivery of DHCP reply messages. Non-Ethernet
571 interfaces will leave 'chaddr' empty and use the client identifier
572 instead (eg, RFC 4390 section 2.1).
574 if (client
->arp_type
== ARPHRD_ETHER
)
575 memcpy(&packet
->dhcp
.chaddr
, &client
->mac_addr
, ETH_ALEN
);
577 /* If no client identifier exists, construct an RFC 4361-compliant one */
578 if (client
->client_id_len
== 0) {
581 client
->client_id
.type
= 255;
583 r
= dhcp_identifier_set_iaid(client
->ifindex
, client
->mac_addr
, client
->mac_addr_len
, &client
->client_id
.ns
.iaid
);
587 r
= dhcp_identifier_set_duid_en(&client
->client_id
.ns
.duid
, &duid_len
);
591 client
->client_id_len
= sizeof(client
->client_id
.type
) + sizeof(client
->client_id
.ns
.iaid
) + duid_len
;
594 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
595 Identifier option is not set */
596 if (client
->client_id_len
) {
597 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
598 SD_DHCP_OPTION_CLIENT_IDENTIFIER
,
599 client
->client_id_len
,
605 /* RFC2131 section 3.5:
606 in its initial DHCPDISCOVER or DHCPREQUEST message, a
607 client may provide the server with a list of specific
608 parameters the client is interested in. If the client
609 includes a list of parameters in a DHCPDISCOVER message,
610 it MUST include that list in any subsequent DHCPREQUEST
613 r
= dhcp_option_append(&packet
->dhcp
, optlen
, &optoffset
, 0,
614 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST
,
615 client
->req_opts_size
, client
->req_opts
);
619 /* RFC2131 section 3.5:
620 The client SHOULD include the ’maximum DHCP message size’ option to
621 let the server know how large the server may make its DHCP messages.
623 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
624 than the defined default size unless the Maximum Messge Size option
627 RFC3442 "Requirements to Avoid Sizing Constraints":
628 Because a full routing table can be quite large, the standard 576
629 octet maximum size for a DHCP message may be too short to contain
630 some legitimate Classless Static Route options. Because of this,
631 clients implementing the Classless Static Route option SHOULD send a
632 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
633 stack is capable of receiving larger IP datagrams. In this case, the
634 client SHOULD set the value of this option to at least the MTU of the
635 interface that the client is configuring. The client MAY set the
636 value of this option higher, up to the size of the largest UDP packet
637 it is prepared to accept. (Note that the value specified in the
638 Maximum DHCP Message Size option is the total maximum packet size,
639 including IP and UDP headers.)
641 max_size
= htobe16(size
);
642 r
= dhcp_option_append(&packet
->dhcp
, client
->mtu
, &optoffset
, 0,
643 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE
,
649 *_optoffset
= optoffset
;
656 static int client_append_fqdn_option(
657 DHCPMessage
*message
,
662 uint8_t buffer
[3 + DHCP_MAX_FQDN_LENGTH
];
665 buffer
[0] = DHCP_FQDN_FLAG_S
| /* Request server to perform A RR DNS updates */
666 DHCP_FQDN_FLAG_E
; /* Canonical wire format */
667 buffer
[1] = 0; /* RCODE1 (deprecated) */
668 buffer
[2] = 0; /* RCODE2 (deprecated) */
670 r
= dns_name_to_wire_format(fqdn
, buffer
+ 3, sizeof(buffer
) - 3, false);
672 r
= dhcp_option_append(message
, optlen
, optoffset
, 0,
673 SD_DHCP_OPTION_FQDN
, 3 + r
, buffer
);
678 static int dhcp_client_send_raw(
679 sd_dhcp_client
*client
,
683 dhcp_packet_append_ip_headers(packet
, INADDR_ANY
, client
->port
,
684 INADDR_BROADCAST
, DHCP_PORT_SERVER
, len
);
686 return dhcp_network_send_raw_socket(client
->fd
, &client
->link
,
690 static int client_send_discover(sd_dhcp_client
*client
) {
691 _cleanup_free_ DHCPPacket
*discover
= NULL
;
692 size_t optoffset
, optlen
;
696 assert(client
->state
== DHCP_STATE_INIT
||
697 client
->state
== DHCP_STATE_SELECTING
);
699 r
= client_message_init(client
, &discover
, DHCP_DISCOVER
,
700 &optlen
, &optoffset
);
704 /* the client may suggest values for the network address
705 and lease time in the DHCPDISCOVER message. The client may include
706 the ’requested IP address’ option to suggest that a particular IP
707 address be assigned, and may include the ’IP address lease time’
708 option to suggest the lease time it would like.
710 if (client
->last_addr
!= INADDR_ANY
) {
711 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
712 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
713 4, &client
->last_addr
);
718 if (client
->hostname
) {
719 /* According to RFC 4702 "clients that send the Client FQDN option in
720 their messages MUST NOT also send the Host Name option". Just send
721 one of the two depending on the hostname type.
723 if (dns_name_is_single_label(client
->hostname
)) {
724 /* it is unclear from RFC 2131 if client should send hostname in
725 DHCPDISCOVER but dhclient does and so we do as well
727 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
728 SD_DHCP_OPTION_HOST_NAME
,
729 strlen(client
->hostname
), client
->hostname
);
731 r
= client_append_fqdn_option(&discover
->dhcp
, optlen
, &optoffset
,
737 if (client
->vendor_class_identifier
) {
738 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
739 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER
,
740 strlen(client
->vendor_class_identifier
),
741 client
->vendor_class_identifier
);
746 r
= dhcp_option_append(&discover
->dhcp
, optlen
, &optoffset
, 0,
747 SD_DHCP_OPTION_END
, 0, NULL
);
751 /* We currently ignore:
752 The client SHOULD wait a random time between one and ten seconds to
753 desynchronize the use of DHCP at startup.
755 r
= dhcp_client_send_raw(client
, discover
, sizeof(DHCPPacket
) + optoffset
);
759 log_dhcp_client(client
, "DISCOVER");
764 static int client_send_request(sd_dhcp_client
*client
) {
765 _cleanup_free_ DHCPPacket
*request
= NULL
;
766 size_t optoffset
, optlen
;
771 r
= client_message_init(client
, &request
, DHCP_REQUEST
, &optlen
, &optoffset
);
775 switch (client
->state
) {
776 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
777 SELECTING should be REQUESTING)
780 case DHCP_STATE_REQUESTING
:
781 /* Client inserts the address of the selected server in ’server
782 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
783 filled in with the yiaddr value from the chosen DHCPOFFER.
786 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
787 SD_DHCP_OPTION_SERVER_IDENTIFIER
,
788 4, &client
->lease
->server_address
);
792 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
793 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
794 4, &client
->lease
->address
);
800 case DHCP_STATE_INIT_REBOOT
:
801 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
802 option MUST be filled in with client’s notion of its previously
803 assigned address. ’ciaddr’ MUST be zero.
805 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
806 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS
,
807 4, &client
->last_addr
);
812 case DHCP_STATE_RENEWING
:
813 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
814 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
815 client’s IP address.
819 case DHCP_STATE_REBINDING
:
820 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
821 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
822 client’s IP address.
824 This message MUST be broadcast to the 0xffffffff IP broadcast address.
826 request
->dhcp
.ciaddr
= client
->lease
->address
;
830 case DHCP_STATE_INIT
:
831 case DHCP_STATE_SELECTING
:
832 case DHCP_STATE_REBOOTING
:
833 case DHCP_STATE_BOUND
:
834 case DHCP_STATE_STOPPED
:
838 if (client
->hostname
) {
839 if (dns_name_is_single_label(client
->hostname
))
840 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
841 SD_DHCP_OPTION_HOST_NAME
,
842 strlen(client
->hostname
), client
->hostname
);
844 r
= client_append_fqdn_option(&request
->dhcp
, optlen
, &optoffset
,
850 r
= dhcp_option_append(&request
->dhcp
, optlen
, &optoffset
, 0,
851 SD_DHCP_OPTION_END
, 0, NULL
);
855 if (client
->state
== DHCP_STATE_RENEWING
) {
856 r
= dhcp_network_send_udp_socket(client
->fd
,
857 client
->lease
->server_address
,
860 sizeof(DHCPMessage
) + optoffset
);
862 r
= dhcp_client_send_raw(client
, request
, sizeof(DHCPPacket
) + optoffset
);
867 switch (client
->state
) {
869 case DHCP_STATE_REQUESTING
:
870 log_dhcp_client(client
, "REQUEST (requesting)");
873 case DHCP_STATE_INIT_REBOOT
:
874 log_dhcp_client(client
, "REQUEST (init-reboot)");
877 case DHCP_STATE_RENEWING
:
878 log_dhcp_client(client
, "REQUEST (renewing)");
881 case DHCP_STATE_REBINDING
:
882 log_dhcp_client(client
, "REQUEST (rebinding)");
886 log_dhcp_client(client
, "REQUEST (invalid)");
893 static int client_start(sd_dhcp_client
*client
);
895 static int client_timeout_resend(
900 sd_dhcp_client
*client
= userdata
;
901 DHCP_CLIENT_DONT_DESTROY(client
);
902 usec_t next_timeout
= 0;
909 assert(client
->event
);
911 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
915 switch (client
->state
) {
917 case DHCP_STATE_RENEWING
:
919 time_left
= (client
->lease
->t2
- client
->lease
->t1
) / 2;
923 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
927 case DHCP_STATE_REBINDING
:
929 time_left
= (client
->lease
->lifetime
- client
->lease
->t2
) / 2;
933 next_timeout
= time_now
+ time_left
* USEC_PER_SEC
;
936 case DHCP_STATE_REBOOTING
:
937 /* start over as we did not receive a timely ack or nak */
938 r
= client_initialize(client
);
942 r
= client_start(client
);
946 log_dhcp_client(client
, "REBOOTED");
950 case DHCP_STATE_INIT
:
951 case DHCP_STATE_INIT_REBOOT
:
952 case DHCP_STATE_SELECTING
:
953 case DHCP_STATE_REQUESTING
:
954 case DHCP_STATE_BOUND
:
956 if (client
->attempt
< 64)
957 client
->attempt
*= 2;
959 next_timeout
= time_now
+ (client
->attempt
- 1) * USEC_PER_SEC
;
963 case DHCP_STATE_STOPPED
:
968 next_timeout
+= (random_u32() & 0x1fffff);
970 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
972 r
= sd_event_add_time(client
->event
,
973 &client
->timeout_resend
,
974 clock_boottime_or_monotonic(),
975 next_timeout
, 10 * USEC_PER_MSEC
,
976 client_timeout_resend
, client
);
980 r
= sd_event_source_set_priority(client
->timeout_resend
,
981 client
->event_priority
);
985 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
989 switch (client
->state
) {
990 case DHCP_STATE_INIT
:
991 r
= client_send_discover(client
);
993 client
->state
= DHCP_STATE_SELECTING
;
996 if (client
->attempt
>= 64)
1002 case DHCP_STATE_SELECTING
:
1003 r
= client_send_discover(client
);
1004 if (r
< 0 && client
->attempt
>= 64)
1009 case DHCP_STATE_INIT_REBOOT
:
1010 case DHCP_STATE_REQUESTING
:
1011 case DHCP_STATE_RENEWING
:
1012 case DHCP_STATE_REBINDING
:
1013 r
= client_send_request(client
);
1014 if (r
< 0 && client
->attempt
>= 64)
1017 if (client
->state
== DHCP_STATE_INIT_REBOOT
)
1018 client
->state
= DHCP_STATE_REBOOTING
;
1020 client
->request_sent
= time_now
;
1024 case DHCP_STATE_REBOOTING
:
1025 case DHCP_STATE_BOUND
:
1029 case DHCP_STATE_STOPPED
:
1037 client_stop(client
, r
);
1039 /* Errors were dealt with when stopping the client, don't spill
1040 errors into the event loop handler */
1044 static int client_initialize_io_events(
1045 sd_dhcp_client
*client
,
1046 sd_event_io_handler_t io_callback
) {
1051 assert(client
->event
);
1053 r
= sd_event_add_io(client
->event
, &client
->receive_message
,
1054 client
->fd
, EPOLLIN
, io_callback
,
1059 r
= sd_event_source_set_priority(client
->receive_message
,
1060 client
->event_priority
);
1064 r
= sd_event_source_set_description(client
->receive_message
, "dhcp4-receive-message");
1070 client_stop(client
, r
);
1075 static int client_initialize_time_events(sd_dhcp_client
*client
) {
1080 assert(client
->event
);
1082 client
->timeout_resend
= sd_event_source_unref(client
->timeout_resend
);
1084 if (client
->start_delay
) {
1085 assert_se(sd_event_now(client
->event
, clock_boottime_or_monotonic(), &usec
) >= 0);
1086 usec
+= client
->start_delay
;
1089 r
= sd_event_add_time(client
->event
,
1090 &client
->timeout_resend
,
1091 clock_boottime_or_monotonic(),
1093 client_timeout_resend
, client
);
1097 r
= sd_event_source_set_priority(client
->timeout_resend
,
1098 client
->event_priority
);
1102 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1108 client_stop(client
, r
);
1114 static int client_initialize_events(sd_dhcp_client
*client
, sd_event_io_handler_t io_callback
) {
1115 client_initialize_io_events(client
, io_callback
);
1116 client_initialize_time_events(client
);
1121 static int client_start_delayed(sd_dhcp_client
*client
) {
1124 assert_return(client
, -EINVAL
);
1125 assert_return(client
->event
, -EINVAL
);
1126 assert_return(client
->ifindex
> 0, -EINVAL
);
1127 assert_return(client
->fd
< 0, -EBUSY
);
1128 assert_return(client
->xid
== 0, -EINVAL
);
1129 assert_return(IN_SET(client
->state
, DHCP_STATE_INIT
, DHCP_STATE_INIT_REBOOT
), -EBUSY
);
1131 client
->xid
= random_u32();
1133 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1134 client
->xid
, client
->mac_addr
,
1135 client
->mac_addr_len
, client
->arp_type
, client
->port
);
1137 client_stop(client
, r
);
1142 if (client
->state
== DHCP_STATE_INIT
|| client
->state
== DHCP_STATE_INIT_REBOOT
)
1143 client
->start_time
= now(clock_boottime_or_monotonic());
1145 return client_initialize_events(client
, client_receive_message_raw
);
1148 static int client_start(sd_dhcp_client
*client
) {
1149 client
->start_delay
= 0;
1150 return client_start_delayed(client
);
1153 static int client_timeout_expire(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1154 sd_dhcp_client
*client
= userdata
;
1155 DHCP_CLIENT_DONT_DESTROY(client
);
1157 log_dhcp_client(client
, "EXPIRED");
1159 client_notify(client
, SD_DHCP_CLIENT_EVENT_EXPIRED
);
1161 /* lease was lost, start over if not freed or stopped in callback */
1162 if (client
->state
!= DHCP_STATE_STOPPED
) {
1163 client_initialize(client
);
1164 client_start(client
);
1170 static int client_timeout_t2(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1171 sd_dhcp_client
*client
= userdata
;
1172 DHCP_CLIENT_DONT_DESTROY(client
);
1177 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1178 client
->fd
= asynchronous_close(client
->fd
);
1180 client
->state
= DHCP_STATE_REBINDING
;
1181 client
->attempt
= 1;
1183 r
= dhcp_network_bind_raw_socket(client
->ifindex
, &client
->link
,
1184 client
->xid
, client
->mac_addr
,
1185 client
->mac_addr_len
, client
->arp_type
,
1188 client_stop(client
, r
);
1193 return client_initialize_events(client
, client_receive_message_raw
);
1196 static int client_timeout_t1(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
1197 sd_dhcp_client
*client
= userdata
;
1198 DHCP_CLIENT_DONT_DESTROY(client
);
1200 client
->state
= DHCP_STATE_RENEWING
;
1201 client
->attempt
= 1;
1203 return client_initialize_time_events(client
);
1206 static int client_handle_offer(sd_dhcp_client
*client
, DHCPMessage
*offer
, size_t len
) {
1207 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1210 r
= dhcp_lease_new(&lease
);
1214 if (client
->client_id_len
) {
1215 r
= dhcp_lease_set_client_id(lease
,
1216 (uint8_t *) &client
->client_id
,
1217 client
->client_id_len
);
1222 r
= dhcp_option_parse(offer
, len
, dhcp_lease_parse_options
, lease
, NULL
);
1223 if (r
!= DHCP_OFFER
) {
1224 log_dhcp_client(client
, "received message was not an OFFER, ignoring");
1228 lease
->next_server
= offer
->siaddr
;
1229 lease
->address
= offer
->yiaddr
;
1231 if (lease
->address
== 0 ||
1232 lease
->server_address
== 0 ||
1233 lease
->lifetime
== 0) {
1234 log_dhcp_client(client
, "received lease lacks address, server address or lease lifetime, ignoring");
1238 if (!lease
->have_subnet_mask
) {
1239 r
= dhcp_lease_set_default_subnet_mask(lease
);
1241 log_dhcp_client(client
, "received lease lacks subnet "
1242 "mask, and a fallback one can not be "
1243 "generated, ignoring");
1248 sd_dhcp_lease_unref(client
->lease
);
1249 client
->lease
= lease
;
1252 log_dhcp_client(client
, "OFFER");
1257 static int client_handle_forcerenew(sd_dhcp_client
*client
, DHCPMessage
*force
, size_t len
) {
1260 r
= dhcp_option_parse(force
, len
, NULL
, NULL
, NULL
);
1261 if (r
!= DHCP_FORCERENEW
)
1264 log_dhcp_client(client
, "FORCERENEW");
1269 static int client_handle_ack(sd_dhcp_client
*client
, DHCPMessage
*ack
, size_t len
) {
1270 _cleanup_(sd_dhcp_lease_unrefp
) sd_dhcp_lease
*lease
= NULL
;
1271 _cleanup_free_
char *error_message
= NULL
;
1274 r
= dhcp_lease_new(&lease
);
1278 if (client
->client_id_len
) {
1279 r
= dhcp_lease_set_client_id(lease
,
1280 (uint8_t *) &client
->client_id
,
1281 client
->client_id_len
);
1286 r
= dhcp_option_parse(ack
, len
, dhcp_lease_parse_options
, lease
, &error_message
);
1287 if (r
== DHCP_NAK
) {
1288 log_dhcp_client(client
, "NAK: %s", strna(error_message
));
1289 return -EADDRNOTAVAIL
;
1292 if (r
!= DHCP_ACK
) {
1293 log_dhcp_client(client
, "received message was not an ACK, ignoring");
1297 lease
->next_server
= ack
->siaddr
;
1299 lease
->address
= ack
->yiaddr
;
1301 if (lease
->address
== INADDR_ANY
||
1302 lease
->server_address
== INADDR_ANY
||
1303 lease
->lifetime
== 0) {
1304 log_dhcp_client(client
, "received lease lacks address, server "
1305 "address or lease lifetime, ignoring");
1309 if (lease
->subnet_mask
== INADDR_ANY
) {
1310 r
= dhcp_lease_set_default_subnet_mask(lease
);
1312 log_dhcp_client(client
, "received lease lacks subnet "
1313 "mask, and a fallback one can not be "
1314 "generated, ignoring");
1319 r
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1320 if (client
->lease
) {
1321 if (client
->lease
->address
!= lease
->address
||
1322 client
->lease
->subnet_mask
!= lease
->subnet_mask
||
1323 client
->lease
->router
!= lease
->router
) {
1324 r
= SD_DHCP_CLIENT_EVENT_IP_CHANGE
;
1326 r
= SD_DHCP_CLIENT_EVENT_RENEW
;
1328 client
->lease
= sd_dhcp_lease_unref(client
->lease
);
1331 client
->lease
= lease
;
1334 log_dhcp_client(client
, "ACK");
1339 static uint64_t client_compute_timeout(sd_dhcp_client
*client
, uint32_t lifetime
, double factor
) {
1341 assert(client
->request_sent
);
1342 assert(lifetime
> 0);
1349 return client
->request_sent
+ (lifetime
* USEC_PER_SEC
* factor
) +
1350 + (random_u32() & 0x1fffff);
1353 static int client_set_lease_timeouts(sd_dhcp_client
*client
) {
1355 uint64_t lifetime_timeout
;
1356 uint64_t t2_timeout
;
1357 uint64_t t1_timeout
;
1358 char time_string
[FORMAT_TIMESPAN_MAX
];
1362 assert(client
->event
);
1363 assert(client
->lease
);
1364 assert(client
->lease
->lifetime
);
1366 client
->timeout_t1
= sd_event_source_unref(client
->timeout_t1
);
1367 client
->timeout_t2
= sd_event_source_unref(client
->timeout_t2
);
1368 client
->timeout_expire
= sd_event_source_unref(client
->timeout_expire
);
1370 /* don't set timers for infinite leases */
1371 if (client
->lease
->lifetime
== 0xffffffff)
1374 r
= sd_event_now(client
->event
, clock_boottime_or_monotonic(), &time_now
);
1377 assert(client
->request_sent
<= time_now
);
1379 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1380 lifetime_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 1);
1381 if (client
->lease
->t1
> 0 && client
->lease
->t2
> 0) {
1382 /* both T1 and T2 are given */
1383 if (client
->lease
->t1
< client
->lease
->t2
&&
1384 client
->lease
->t2
< client
->lease
->lifetime
) {
1385 /* they are both valid */
1386 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1387 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1390 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1391 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1392 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1393 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1395 } else if (client
->lease
->t2
> 0 && client
->lease
->t2
< client
->lease
->lifetime
) {
1396 /* only T2 is given, and it is valid */
1397 t2_timeout
= client_compute_timeout(client
, client
->lease
->t2
, 1);
1398 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1399 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1400 if (t2_timeout
<= t1_timeout
) {
1401 /* the computed T1 would be invalid, so discard T2 */
1402 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1403 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1405 } else if (client
->lease
->t1
> 0 && client
->lease
->t1
< client
->lease
->lifetime
) {
1406 /* only T1 is given, and it is valid */
1407 t1_timeout
= client_compute_timeout(client
, client
->lease
->t1
, 1);
1408 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1409 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1410 if (t2_timeout
<= t1_timeout
) {
1411 /* the computed T2 would be invalid, so discard T1 */
1412 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1413 client
->lease
->t2
= client
->lease
->lifetime
/ 2;
1416 /* fall back to the default timeouts */
1417 t1_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 0.5);
1418 client
->lease
->t1
= client
->lease
->lifetime
/ 2;
1419 t2_timeout
= client_compute_timeout(client
, client
->lease
->lifetime
, 7.0 / 8.0);
1420 client
->lease
->t2
= (client
->lease
->lifetime
* 7) / 8;
1423 /* arm lifetime timeout */
1424 r
= sd_event_add_time(client
->event
, &client
->timeout_expire
,
1425 clock_boottime_or_monotonic(),
1426 lifetime_timeout
, 10 * USEC_PER_MSEC
,
1427 client_timeout_expire
, client
);
1431 r
= sd_event_source_set_priority(client
->timeout_expire
,
1432 client
->event_priority
);
1436 r
= sd_event_source_set_description(client
->timeout_expire
, "dhcp4-lifetime");
1440 log_dhcp_client(client
, "lease expires in %s",
1441 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, lifetime_timeout
- time_now
, USEC_PER_SEC
));
1443 /* don't arm earlier timeouts if this has already expired */
1444 if (lifetime_timeout
<= time_now
)
1447 /* arm T2 timeout */
1448 r
= sd_event_add_time(client
->event
,
1449 &client
->timeout_t2
,
1450 clock_boottime_or_monotonic(),
1453 client_timeout_t2
, client
);
1457 r
= sd_event_source_set_priority(client
->timeout_t2
,
1458 client
->event_priority
);
1462 r
= sd_event_source_set_description(client
->timeout_t2
, "dhcp4-t2-timeout");
1466 log_dhcp_client(client
, "T2 expires in %s",
1467 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t2_timeout
- time_now
, USEC_PER_SEC
));
1469 /* don't arm earlier timeout if this has already expired */
1470 if (t2_timeout
<= time_now
)
1473 /* arm T1 timeout */
1474 r
= sd_event_add_time(client
->event
,
1475 &client
->timeout_t1
,
1476 clock_boottime_or_monotonic(),
1477 t1_timeout
, 10 * USEC_PER_MSEC
,
1478 client_timeout_t1
, client
);
1482 r
= sd_event_source_set_priority(client
->timeout_t1
,
1483 client
->event_priority
);
1487 r
= sd_event_source_set_description(client
->timeout_t1
, "dhcp4-t1-timer");
1491 log_dhcp_client(client
, "T1 expires in %s",
1492 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, t1_timeout
- time_now
, USEC_PER_SEC
));
1497 static int client_handle_message(sd_dhcp_client
*client
, DHCPMessage
*message
, int len
) {
1498 DHCP_CLIENT_DONT_DESTROY(client
);
1499 char time_string
[FORMAT_TIMESPAN_MAX
];
1500 int r
= 0, notify_event
= 0;
1503 assert(client
->event
);
1506 switch (client
->state
) {
1507 case DHCP_STATE_SELECTING
:
1509 r
= client_handle_offer(client
, message
, len
);
1512 client
->timeout_resend
=
1513 sd_event_source_unref(client
->timeout_resend
);
1515 client
->state
= DHCP_STATE_REQUESTING
;
1516 client
->attempt
= 1;
1518 r
= sd_event_add_time(client
->event
,
1519 &client
->timeout_resend
,
1520 clock_boottime_or_monotonic(),
1522 client_timeout_resend
, client
);
1526 r
= sd_event_source_set_priority(client
->timeout_resend
,
1527 client
->event_priority
);
1531 r
= sd_event_source_set_description(client
->timeout_resend
, "dhcp4-resend-timer");
1534 } else if (r
== -ENOMSG
)
1535 /* invalid message, let's ignore it */
1540 case DHCP_STATE_REBOOTING
:
1541 case DHCP_STATE_REQUESTING
:
1542 case DHCP_STATE_RENEWING
:
1543 case DHCP_STATE_REBINDING
:
1545 r
= client_handle_ack(client
, message
, len
);
1547 client
->start_delay
= 0;
1548 client
->timeout_resend
=
1549 sd_event_source_unref(client
->timeout_resend
);
1550 client
->receive_message
=
1551 sd_event_source_unref(client
->receive_message
);
1552 client
->fd
= asynchronous_close(client
->fd
);
1554 if (IN_SET(client
->state
, DHCP_STATE_REQUESTING
,
1555 DHCP_STATE_REBOOTING
))
1556 notify_event
= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
;
1557 else if (r
!= SD_DHCP_CLIENT_EVENT_IP_ACQUIRE
)
1560 client
->state
= DHCP_STATE_BOUND
;
1561 client
->attempt
= 1;
1563 client
->last_addr
= client
->lease
->address
;
1565 r
= client_set_lease_timeouts(client
);
1567 log_dhcp_client(client
, "could not set lease timeouts");
1571 r
= dhcp_network_bind_udp_socket(client
->lease
->address
, client
->port
);
1573 log_dhcp_client(client
, "could not bind UDP socket");
1579 client_initialize_io_events(client
, client_receive_message_udp
);
1582 client_notify(client
, notify_event
);
1583 if (client
->state
== DHCP_STATE_STOPPED
)
1587 } else if (r
== -EADDRNOTAVAIL
) {
1588 /* got a NAK, let's restart the client */
1589 client
->timeout_resend
=
1590 sd_event_source_unref(client
->timeout_resend
);
1592 r
= client_initialize(client
);
1596 r
= client_start_delayed(client
);
1600 log_dhcp_client(client
, "REBOOT in %s", format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
1601 client
->start_delay
, USEC_PER_SEC
));
1603 client
->start_delay
= CLAMP(client
->start_delay
* 2,
1604 RESTART_AFTER_NAK_MIN_USEC
, RESTART_AFTER_NAK_MAX_USEC
);
1607 } else if (r
== -ENOMSG
)
1608 /* invalid message, let's ignore it */
1613 case DHCP_STATE_BOUND
:
1614 r
= client_handle_forcerenew(client
, message
, len
);
1616 r
= client_timeout_t1(NULL
, 0, client
);
1619 } else if (r
== -ENOMSG
)
1620 /* invalid message, let's ignore it */
1625 case DHCP_STATE_INIT
:
1626 case DHCP_STATE_INIT_REBOOT
:
1630 case DHCP_STATE_STOPPED
:
1637 client_stop(client
, r
);
1642 static int client_receive_message_udp(
1648 sd_dhcp_client
*client
= userdata
;
1649 _cleanup_free_ DHCPMessage
*message
= NULL
;
1650 const struct ether_addr zero_mac
= {};
1651 const struct ether_addr
*expected_chaddr
= NULL
;
1652 uint8_t expected_hlen
= 0;
1653 ssize_t len
, buflen
;
1658 buflen
= next_datagram_size_fd(fd
);
1662 message
= malloc0(buflen
);
1666 len
= recv(fd
, message
, buflen
, 0);
1668 if (errno
== EAGAIN
|| errno
== EINTR
)
1671 return log_dhcp_client_errno(client
, errno
, "Could not receive message from UDP socket: %m");
1673 if ((size_t) len
< sizeof(DHCPMessage
)) {
1674 log_dhcp_client(client
, "Too small to be a DHCP message: ignoring");
1678 if (be32toh(message
->magic
) != DHCP_MAGIC_COOKIE
) {
1679 log_dhcp_client(client
, "Not a DHCP message: ignoring");
1683 if (message
->op
!= BOOTREPLY
) {
1684 log_dhcp_client(client
, "Not a BOOTREPLY message: ignoring");
1688 if (message
->htype
!= client
->arp_type
) {
1689 log_dhcp_client(client
, "Packet type does not match client type");
1693 if (client
->arp_type
== ARPHRD_ETHER
) {
1694 expected_hlen
= ETH_ALEN
;
1695 expected_chaddr
= (const struct ether_addr
*) &client
->mac_addr
;
1697 /* Non-Ethernet links expect zero chaddr */
1699 expected_chaddr
= &zero_mac
;
1702 if (message
->hlen
!= expected_hlen
) {
1703 log_dhcp_client(client
, "Unexpected packet hlen %d", message
->hlen
);
1707 if (memcmp(&message
->chaddr
[0], expected_chaddr
, ETH_ALEN
)) {
1708 log_dhcp_client(client
, "Received chaddr does not match expected: ignoring");
1712 if (client
->state
!= DHCP_STATE_BOUND
&&
1713 be32toh(message
->xid
) != client
->xid
) {
1714 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1715 so ignore the xid in this case */
1716 log_dhcp_client(client
, "Received xid (%u) does not match expected (%u): ignoring",
1717 be32toh(message
->xid
), client
->xid
);
1721 return client_handle_message(client
, message
, len
);
1724 static int client_receive_message_raw(
1730 sd_dhcp_client
*client
= userdata
;
1731 _cleanup_free_ DHCPPacket
*packet
= NULL
;
1732 uint8_t cmsgbuf
[CMSG_LEN(sizeof(struct tpacket_auxdata
))];
1733 struct iovec iov
= {};
1734 struct msghdr msg
= {
1737 .msg_control
= cmsgbuf
,
1738 .msg_controllen
= sizeof(cmsgbuf
),
1740 struct cmsghdr
*cmsg
;
1741 bool checksum
= true;
1742 ssize_t buflen
, len
;
1748 buflen
= next_datagram_size_fd(fd
);
1752 packet
= malloc0(buflen
);
1756 iov
.iov_base
= packet
;
1757 iov
.iov_len
= buflen
;
1759 len
= recvmsg(fd
, &msg
, 0);
1761 if (errno
== EAGAIN
|| errno
== EINTR
)
1764 log_dhcp_client(client
, "Could not receive message from raw socket: %m");
1767 } else if ((size_t)len
< sizeof(DHCPPacket
))
1770 CMSG_FOREACH(cmsg
, &msg
) {
1771 if (cmsg
->cmsg_level
== SOL_PACKET
&&
1772 cmsg
->cmsg_type
== PACKET_AUXDATA
&&
1773 cmsg
->cmsg_len
== CMSG_LEN(sizeof(struct tpacket_auxdata
))) {
1774 struct tpacket_auxdata
*aux
= (struct tpacket_auxdata
*)CMSG_DATA(cmsg
);
1776 checksum
= !(aux
->tp_status
& TP_STATUS_CSUMNOTREADY
);
1781 r
= dhcp_packet_verify_headers(packet
, len
, checksum
, client
->port
);
1785 len
-= DHCP_IP_UDP_SIZE
;
1787 return client_handle_message(client
, &packet
->dhcp
, len
);
1790 int sd_dhcp_client_start(sd_dhcp_client
*client
) {
1793 assert_return(client
, -EINVAL
);
1795 r
= client_initialize(client
);
1799 if (client
->last_addr
)
1800 client
->state
= DHCP_STATE_INIT_REBOOT
;
1802 r
= client_start(client
);
1804 log_dhcp_client(client
, "STARTED on ifindex %i", client
->ifindex
);
1809 int sd_dhcp_client_stop(sd_dhcp_client
*client
) {
1810 DHCP_CLIENT_DONT_DESTROY(client
);
1812 assert_return(client
, -EINVAL
);
1814 client_stop(client
, SD_DHCP_CLIENT_EVENT_STOP
);
1815 client
->state
= DHCP_STATE_STOPPED
;
1820 int sd_dhcp_client_attach_event(sd_dhcp_client
*client
, sd_event
*event
, int64_t priority
) {
1823 assert_return(client
, -EINVAL
);
1824 assert_return(!client
->event
, -EBUSY
);
1827 client
->event
= sd_event_ref(event
);
1829 r
= sd_event_default(&client
->event
);
1834 client
->event_priority
= priority
;
1839 int sd_dhcp_client_detach_event(sd_dhcp_client
*client
) {
1840 assert_return(client
, -EINVAL
);
1842 client
->event
= sd_event_unref(client
->event
);
1847 sd_event
*sd_dhcp_client_get_event(sd_dhcp_client
*client
) {
1848 assert_return(client
, NULL
);
1850 return client
->event
;
1853 sd_dhcp_client
*sd_dhcp_client_ref(sd_dhcp_client
*client
) {
1858 assert(client
->n_ref
>= 1);
1864 sd_dhcp_client
*sd_dhcp_client_unref(sd_dhcp_client
*client
) {
1869 assert(client
->n_ref
>= 1);
1872 if (client
->n_ref
> 0)
1875 log_dhcp_client(client
, "FREE");
1877 client_initialize(client
);
1879 client
->receive_message
= sd_event_source_unref(client
->receive_message
);
1881 sd_dhcp_client_detach_event(client
);
1883 sd_dhcp_lease_unref(client
->lease
);
1885 free(client
->req_opts
);
1886 free(client
->hostname
);
1887 free(client
->vendor_class_identifier
);
1888 return mfree(client
);
1891 int sd_dhcp_client_new(sd_dhcp_client
**ret
) {
1892 _cleanup_(sd_dhcp_client_unrefp
) sd_dhcp_client
*client
= NULL
;
1894 assert_return(ret
, -EINVAL
);
1896 client
= new0(sd_dhcp_client
, 1);
1901 client
->state
= DHCP_STATE_INIT
;
1902 client
->ifindex
= -1;
1904 client
->attempt
= 1;
1905 client
->mtu
= DHCP_DEFAULT_MIN_SIZE
;
1906 client
->port
= DHCP_PORT_CLIENT
;
1908 client
->req_opts_size
= ELEMENTSOF(default_req_opts
);
1909 client
->req_opts
= memdup(default_req_opts
, client
->req_opts_size
);
1910 if (!client
->req_opts
)