]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp-client.c
Merge pull request #13828 from keszybz/networkctl-print-wlan
[thirdparty/systemd.git] / src / libsystemd-network / sd-dhcp-client.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 Copyright © 2013 Intel Corporation. All rights reserved.
4 ***/
5
6 #include <errno.h>
7 #include <net/ethernet.h>
8 #include <net/if_arp.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/ioctl.h>
13 #include <linux/if_infiniband.h>
14
15 #include "sd-dhcp-client.h"
16
17 #include "alloc-util.h"
18 #include "async.h"
19 #include "dhcp-identifier.h"
20 #include "dhcp-internal.h"
21 #include "dhcp-lease-internal.h"
22 #include "dhcp-protocol.h"
23 #include "dns-domain.h"
24 #include "event-util.h"
25 #include "hostname-util.h"
26 #include "io-util.h"
27 #include "memory-util.h"
28 #include "random-util.h"
29 #include "string-util.h"
30 #include "strv.h"
31
32 #define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
33 #define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
34
35 #define RESTART_AFTER_NAK_MIN_USEC (1 * USEC_PER_SEC)
36 #define RESTART_AFTER_NAK_MAX_USEC (30 * USEC_PER_MINUTE)
37
38 struct sd_dhcp_option {
39 unsigned n_ref;
40
41 uint8_t option;
42 void *data;
43 size_t length;
44 };
45
46 struct sd_dhcp_client {
47 unsigned n_ref;
48
49 DHCPState state;
50 sd_event *event;
51 int event_priority;
52 sd_event_source *timeout_resend;
53 int ifindex;
54 int fd;
55 uint16_t port;
56 union sockaddr_union link;
57 sd_event_source *receive_message;
58 bool request_broadcast;
59 uint8_t *req_opts;
60 size_t req_opts_allocated;
61 size_t req_opts_size;
62 bool anonymize;
63 be32_t last_addr;
64 uint8_t mac_addr[MAX_MAC_ADDR_LEN];
65 size_t mac_addr_len;
66 uint16_t arp_type;
67 struct {
68 uint8_t type;
69 union {
70 struct {
71 /* 0: Generic (non-LL) (RFC 2132) */
72 uint8_t data[MAX_CLIENT_ID_LEN];
73 } _packed_ gen;
74 struct {
75 /* 1: Ethernet Link-Layer (RFC 2132) */
76 uint8_t haddr[ETH_ALEN];
77 } _packed_ eth;
78 struct {
79 /* 2 - 254: ARP/Link-Layer (RFC 2132) */
80 uint8_t haddr[0];
81 } _packed_ ll;
82 struct {
83 /* 255: Node-specific (RFC 4361) */
84 be32_t iaid;
85 struct duid duid;
86 } _packed_ ns;
87 struct {
88 uint8_t data[MAX_CLIENT_ID_LEN];
89 } _packed_ raw;
90 };
91 } _packed_ client_id;
92 size_t client_id_len;
93 char *hostname;
94 char *vendor_class_identifier;
95 char **user_class;
96 uint32_t mtu;
97 uint32_t xid;
98 usec_t start_time;
99 uint64_t attempt;
100 uint64_t max_attempts;
101 OrderedHashmap *options;
102 usec_t request_sent;
103 sd_event_source *timeout_t1;
104 sd_event_source *timeout_t2;
105 sd_event_source *timeout_expire;
106 sd_dhcp_client_callback_t callback;
107 void *userdata;
108 sd_dhcp_lease *lease;
109 usec_t start_delay;
110 int ip_service_type;
111 };
112
113 static const uint8_t default_req_opts[] = {
114 SD_DHCP_OPTION_SUBNET_MASK,
115 SD_DHCP_OPTION_ROUTER,
116 SD_DHCP_OPTION_HOST_NAME,
117 SD_DHCP_OPTION_DOMAIN_NAME,
118 SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
119 };
120
121 /* RFC7844 section 3:
122 MAY contain the Parameter Request List option.
123 RFC7844 section 3.6:
124 The client intending to protect its privacy SHOULD only request a
125 minimal number of options in the PRL and SHOULD also randomly shuffle
126 the ordering of option codes in the PRL. If this random ordering
127 cannot be implemented, the client MAY order the option codes in the
128 PRL by option code number (lowest to highest).
129 */
130 /* NOTE: using PRL options that Windows 10 RFC7844 implementation uses */
131 static const uint8_t default_req_opts_anonymize[] = {
132 SD_DHCP_OPTION_SUBNET_MASK, /* 1 */
133 SD_DHCP_OPTION_ROUTER, /* 3 */
134 SD_DHCP_OPTION_DOMAIN_NAME_SERVER, /* 6 */
135 SD_DHCP_OPTION_DOMAIN_NAME, /* 15 */
136 SD_DHCP_OPTION_ROUTER_DISCOVER, /* 31 */
137 SD_DHCP_OPTION_STATIC_ROUTE, /* 33 */
138 SD_DHCP_OPTION_VENDOR_SPECIFIC, /* 43 */
139 SD_DHCP_OPTION_NETBIOS_NAMESERVER, /* 44 */
140 SD_DHCP_OPTION_NETBIOS_NODETYPE, /* 46 */
141 SD_DHCP_OPTION_NETBIOS_SCOPE, /* 47 */
142 SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, /* 121 */
143 SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, /* 249 */
144 SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY, /* 252 */
145 };
146
147 static int client_receive_message_raw(
148 sd_event_source *s,
149 int fd,
150 uint32_t revents,
151 void *userdata);
152 static int client_receive_message_udp(
153 sd_event_source *s,
154 int fd,
155 uint32_t revents,
156 void *userdata);
157 static void client_stop(sd_dhcp_client *client, int error);
158
159 int sd_dhcp_client_set_callback(
160 sd_dhcp_client *client,
161 sd_dhcp_client_callback_t cb,
162 void *userdata) {
163
164 assert_return(client, -EINVAL);
165
166 client->callback = cb;
167 client->userdata = userdata;
168
169 return 0;
170 }
171
172 int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) {
173 assert_return(client, -EINVAL);
174
175 client->request_broadcast = !!broadcast;
176
177 return 0;
178 }
179
180 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
181 size_t i;
182
183 assert_return(client, -EINVAL);
184 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
185
186 switch(option) {
187
188 case SD_DHCP_OPTION_PAD:
189 case SD_DHCP_OPTION_OVERLOAD:
190 case SD_DHCP_OPTION_MESSAGE_TYPE:
191 case SD_DHCP_OPTION_PARAMETER_REQUEST_LIST:
192 case SD_DHCP_OPTION_END:
193 return -EINVAL;
194
195 default:
196 break;
197 }
198
199 for (i = 0; i < client->req_opts_size; i++)
200 if (client->req_opts[i] == option)
201 return -EEXIST;
202
203 if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
204 client->req_opts_size + 1))
205 return -ENOMEM;
206
207 client->req_opts[client->req_opts_size++] = option;
208
209 return 0;
210 }
211
212 int sd_dhcp_client_set_request_address(
213 sd_dhcp_client *client,
214 const struct in_addr *last_addr) {
215
216 assert_return(client, -EINVAL);
217 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
218
219 if (last_addr)
220 client->last_addr = last_addr->s_addr;
221 else
222 client->last_addr = INADDR_ANY;
223
224 return 0;
225 }
226
227 int sd_dhcp_client_set_ifindex(sd_dhcp_client *client, int ifindex) {
228
229 assert_return(client, -EINVAL);
230 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
231 assert_return(ifindex > 0, -EINVAL);
232
233 client->ifindex = ifindex;
234 return 0;
235 }
236
237 int sd_dhcp_client_set_mac(
238 sd_dhcp_client *client,
239 const uint8_t *addr,
240 size_t addr_len,
241 uint16_t arp_type) {
242
243 DHCP_CLIENT_DONT_DESTROY(client);
244 bool need_restart = false;
245
246 assert_return(client, -EINVAL);
247 assert_return(addr, -EINVAL);
248 assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL);
249 assert_return(arp_type > 0, -EINVAL);
250
251 if (arp_type == ARPHRD_ETHER)
252 assert_return(addr_len == ETH_ALEN, -EINVAL);
253 else if (arp_type == ARPHRD_INFINIBAND)
254 assert_return(addr_len == INFINIBAND_ALEN, -EINVAL);
255 else
256 return -EINVAL;
257
258 if (client->mac_addr_len == addr_len &&
259 memcmp(&client->mac_addr, addr, addr_len) == 0)
260 return 0;
261
262 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
263 log_dhcp_client(client, "Changing MAC address on running DHCP client, restarting");
264 need_restart = true;
265 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
266 }
267
268 memcpy(&client->mac_addr, addr, addr_len);
269 client->mac_addr_len = addr_len;
270 client->arp_type = arp_type;
271
272 if (need_restart && client->state != DHCP_STATE_STOPPED)
273 sd_dhcp_client_start(client);
274
275 return 0;
276 }
277
278 int sd_dhcp_client_get_client_id(
279 sd_dhcp_client *client,
280 uint8_t *type,
281 const uint8_t **data,
282 size_t *data_len) {
283
284 assert_return(client, -EINVAL);
285 assert_return(type, -EINVAL);
286 assert_return(data, -EINVAL);
287 assert_return(data_len, -EINVAL);
288
289 *type = 0;
290 *data = NULL;
291 *data_len = 0;
292 if (client->client_id_len) {
293 *type = client->client_id.type;
294 *data = client->client_id.raw.data;
295 *data_len = client->client_id_len - sizeof(client->client_id.type);
296 }
297
298 return 0;
299 }
300
301 int sd_dhcp_client_set_client_id(
302 sd_dhcp_client *client,
303 uint8_t type,
304 const uint8_t *data,
305 size_t data_len) {
306
307 DHCP_CLIENT_DONT_DESTROY(client);
308 bool need_restart = false;
309
310 assert_return(client, -EINVAL);
311 assert_return(data, -EINVAL);
312 assert_return(data_len > 0 && data_len <= MAX_CLIENT_ID_LEN, -EINVAL);
313
314 if (client->client_id_len == data_len + sizeof(client->client_id.type) &&
315 client->client_id.type == type &&
316 memcmp(&client->client_id.raw.data, data, data_len) == 0)
317 return 0;
318
319 /* For hardware types, log debug message about unexpected data length.
320 *
321 * Note that infiniband's INFINIBAND_ALEN is 20 bytes long, but only
322 * last last 8 bytes of the address are stable and suitable to put into
323 * the client-id. The caller is advised to account for that. */
324 if ((type == ARPHRD_ETHER && data_len != ETH_ALEN) ||
325 (type == ARPHRD_INFINIBAND && data_len != 8))
326 log_dhcp_client(client, "Changing client ID to hardware type %u with "
327 "unexpected address length %zu",
328 type, data_len);
329
330 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
331 log_dhcp_client(client, "Changing client ID on running DHCP "
332 "client, restarting");
333 need_restart = true;
334 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
335 }
336
337 client->client_id.type = type;
338 memcpy(&client->client_id.raw.data, data, data_len);
339 client->client_id_len = data_len + sizeof (client->client_id.type);
340
341 if (need_restart && client->state != DHCP_STATE_STOPPED)
342 sd_dhcp_client_start(client);
343
344 return 0;
345 }
346
347 /**
348 * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
349 * without further modification. Otherwise, if duid_type is supported, DUID
350 * is set based on that type. Otherwise, an error is returned.
351 */
352 static int dhcp_client_set_iaid_duid_internal(
353 sd_dhcp_client *client,
354 bool iaid_append,
355 bool iaid_set,
356 uint32_t iaid,
357 uint16_t duid_type,
358 const void *duid,
359 size_t duid_len,
360 usec_t llt_time) {
361
362 DHCP_CLIENT_DONT_DESTROY(client);
363 int r;
364 size_t len;
365
366 assert_return(client, -EINVAL);
367 assert_return(duid_len == 0 || duid, -EINVAL);
368
369 if (duid) {
370 r = dhcp_validate_duid_len(duid_type, duid_len, true);
371 if (r < 0)
372 return r;
373 }
374
375 zero(client->client_id);
376 client->client_id.type = 255;
377
378 if (iaid_append) {
379 if (iaid_set)
380 client->client_id.ns.iaid = htobe32(iaid);
381 else {
382 r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr,
383 client->mac_addr_len,
384 true,
385 &client->client_id.ns.iaid);
386 if (r < 0)
387 return r;
388 }
389 }
390
391 if (duid) {
392 client->client_id.ns.duid.type = htobe16(duid_type);
393 memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
394 len = sizeof(client->client_id.ns.duid.type) + duid_len;
395 } else
396 switch (duid_type) {
397 case DUID_TYPE_LLT:
398 if (client->mac_addr_len == 0)
399 return -EOPNOTSUPP;
400
401 r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
402 if (r < 0)
403 return r;
404 break;
405 case DUID_TYPE_EN:
406 r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
407 if (r < 0)
408 return r;
409 break;
410 case DUID_TYPE_LL:
411 if (client->mac_addr_len == 0)
412 return -EOPNOTSUPP;
413
414 r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len);
415 if (r < 0)
416 return r;
417 break;
418 case DUID_TYPE_UUID:
419 r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len);
420 if (r < 0)
421 return r;
422 break;
423 default:
424 return -EINVAL;
425 }
426
427 client->client_id_len = sizeof(client->client_id.type) + len +
428 (iaid_append ? sizeof(client->client_id.ns.iaid) : 0);
429
430 if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
431 log_dhcp_client(client, "Configured %sDUID, restarting.", iaid_append ? "IAID+" : "");
432 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
433 sd_dhcp_client_start(client);
434 }
435
436 return 0;
437 }
438
439 int sd_dhcp_client_set_iaid_duid(
440 sd_dhcp_client *client,
441 bool iaid_set,
442 uint32_t iaid,
443 uint16_t duid_type,
444 const void *duid,
445 size_t duid_len) {
446 return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, duid_type, duid, duid_len, 0);
447 }
448
449 int sd_dhcp_client_set_iaid_duid_llt(
450 sd_dhcp_client *client,
451 bool iaid_set,
452 uint32_t iaid,
453 usec_t llt_time) {
454 return dhcp_client_set_iaid_duid_internal(client, true, iaid_set, iaid, DUID_TYPE_LLT, NULL, 0, llt_time);
455 }
456
457 int sd_dhcp_client_set_duid(
458 sd_dhcp_client *client,
459 uint16_t duid_type,
460 const void *duid,
461 size_t duid_len) {
462 return dhcp_client_set_iaid_duid_internal(client, false, false, 0, duid_type, duid, duid_len, 0);
463 }
464
465 int sd_dhcp_client_set_duid_llt(
466 sd_dhcp_client *client,
467 usec_t llt_time) {
468 return dhcp_client_set_iaid_duid_internal(client, false, false, 0, DUID_TYPE_LLT, NULL, 0, llt_time);
469 }
470
471 int sd_dhcp_client_set_hostname(
472 sd_dhcp_client *client,
473 const char *hostname) {
474
475 assert_return(client, -EINVAL);
476
477 /* Make sure hostnames qualify as DNS and as Linux hostnames */
478 if (hostname &&
479 !(hostname_is_valid(hostname, false) && dns_name_is_valid(hostname) > 0))
480 return -EINVAL;
481
482 return free_and_strdup(&client->hostname, hostname);
483 }
484
485 int sd_dhcp_client_set_vendor_class_identifier(
486 sd_dhcp_client *client,
487 const char *vci) {
488
489 assert_return(client, -EINVAL);
490
491 return free_and_strdup(&client->vendor_class_identifier, vci);
492 }
493
494 int sd_dhcp_client_set_user_class(
495 sd_dhcp_client *client,
496 const char* const* user_class) {
497
498 _cleanup_strv_free_ char **s = NULL;
499 char **p;
500
501 STRV_FOREACH(p, (char **) user_class)
502 if (strlen(*p) > 255)
503 return -ENAMETOOLONG;
504
505 s = strv_copy((char **) user_class);
506 if (!s)
507 return -ENOMEM;
508
509 client->user_class = TAKE_PTR(s);
510
511 return 0;
512 }
513
514 int sd_dhcp_client_set_client_port(
515 sd_dhcp_client *client,
516 uint16_t port) {
517
518 assert_return(client, -EINVAL);
519
520 client->port = port;
521
522 return 0;
523 }
524
525 int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu) {
526 assert_return(client, -EINVAL);
527 assert_return(mtu >= DHCP_DEFAULT_MIN_SIZE, -ERANGE);
528
529 client->mtu = mtu;
530
531 return 0;
532 }
533
534 int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempts) {
535 assert_return(client, -EINVAL);
536
537 client->max_attempts = max_attempts;
538
539 return 0;
540 }
541
542 static sd_dhcp_option* dhcp_option_free(sd_dhcp_option *i) {
543 if (!i)
544 return NULL;
545
546 free(i->data);
547 return mfree(i);
548 }
549
550 int sd_dhcp_option_new(uint8_t option, void *data, size_t length, sd_dhcp_option **ret) {
551 _cleanup_(sd_dhcp_option_unrefp) sd_dhcp_option *p = NULL;
552 _cleanup_free_ void *q = NULL;
553
554 assert(ret);
555
556 q = memdup(data, length);
557 if (!q)
558 return -ENOMEM;
559
560 p = new(sd_dhcp_option, 1);
561 if (!p)
562 return -ENOMEM;
563
564 *p = (sd_dhcp_option) {
565 .n_ref = 1,
566 .option = option,
567 .length = length,
568 .data = TAKE_PTR(q),
569 };
570
571 *ret = TAKE_PTR(p);
572 return 0;
573 }
574
575 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free);
576 DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
577 dhcp_option_hash_ops,
578 void,
579 trivial_hash_func,
580 trivial_compare_func,
581 sd_dhcp_option,
582 sd_dhcp_option_unref);
583
584 int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
585 int r;
586
587 assert_return(client, -EINVAL);
588 assert_return(v, -EINVAL);
589
590 r = ordered_hashmap_ensure_allocated(&client->options, &dhcp_option_hash_ops);
591 if (r < 0)
592 return r;
593
594 r = ordered_hashmap_put(client->options, UINT_TO_PTR(v->option), v);
595 if (r < 0)
596 return r;
597
598 sd_dhcp_option_ref(v);
599 return 0;
600 }
601
602 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
603 assert_return(client, -EINVAL);
604
605 if (!IN_SET(client->state, DHCP_STATE_SELECTING, DHCP_STATE_BOUND, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING))
606 return -EADDRNOTAVAIL;
607
608 if (ret)
609 *ret = client->lease;
610
611 return 0;
612 }
613
614 int sd_dhcp_client_set_service_type(sd_dhcp_client *client, int type) {
615 assert_return(client, -EINVAL);
616
617 client->ip_service_type = type;
618
619 return 0;
620 }
621
622 static int client_notify(sd_dhcp_client *client, int event) {
623 assert(client);
624
625 if (client->callback)
626 return client->callback(client, event, client->userdata);
627
628 return 0;
629 }
630
631 static int client_initialize(sd_dhcp_client *client) {
632 assert_return(client, -EINVAL);
633
634 client->receive_message = sd_event_source_unref(client->receive_message);
635
636 client->fd = asynchronous_close(client->fd);
637
638 (void) event_source_disable(client->timeout_resend);
639 (void) event_source_disable(client->timeout_t1);
640 (void) event_source_disable(client->timeout_t2);
641 (void) event_source_disable(client->timeout_expire);
642
643 client->attempt = 0;
644
645 client->state = DHCP_STATE_INIT;
646 client->xid = 0;
647
648 client->lease = sd_dhcp_lease_unref(client->lease);
649
650 return 0;
651 }
652
653 static void client_stop(sd_dhcp_client *client, int error) {
654 assert(client);
655
656 if (error < 0)
657 log_dhcp_client_errno(client, error, "STOPPED: %m");
658 else if (error == SD_DHCP_CLIENT_EVENT_STOP)
659 log_dhcp_client(client, "STOPPED");
660 else
661 log_dhcp_client(client, "STOPPED: Unknown event");
662
663 client_notify(client, error);
664
665 client_initialize(client);
666 }
667
668 static int client_message_init(
669 sd_dhcp_client *client,
670 DHCPPacket **ret,
671 uint8_t type,
672 size_t *_optlen,
673 size_t *_optoffset) {
674
675 _cleanup_free_ DHCPPacket *packet = NULL;
676 size_t optlen, optoffset, size;
677 be16_t max_size;
678 usec_t time_now;
679 uint16_t secs;
680 int r;
681
682 assert(client);
683 assert(client->start_time);
684 assert(ret);
685 assert(_optlen);
686 assert(_optoffset);
687 assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST, DHCP_RELEASE));
688
689 optlen = DHCP_MIN_OPTIONS_SIZE;
690 size = sizeof(DHCPPacket) + optlen;
691
692 packet = malloc0(size);
693 if (!packet)
694 return -ENOMEM;
695
696 r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
697 client->arp_type, optlen, &optoffset);
698 if (r < 0)
699 return r;
700
701 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
702 refuse to issue an DHCP lease if 'secs' is set to zero */
703 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
704 if (r < 0)
705 return r;
706 assert(time_now >= client->start_time);
707
708 /* seconds between sending first and last DISCOVER
709 * must always be strictly positive to deal with broken servers */
710 secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
711 packet->dhcp.secs = htobe16(secs);
712
713 /* RFC2132 section 4.1
714 A client that cannot receive unicast IP datagrams until its protocol
715 software has been configured with an IP address SHOULD set the
716 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
717 DHCPREQUEST messages that client sends. The BROADCAST bit will
718 provide a hint to the DHCP server and BOOTP relay agent to broadcast
719 any messages to the client on the client's subnet.
720
721 Note: some interfaces needs this to be enabled, but some networks
722 needs this to be disabled as broadcasts are filteretd, so this
723 needs to be configurable */
724 if (client->request_broadcast || client->arp_type != ARPHRD_ETHER)
725 packet->dhcp.flags = htobe16(0x8000);
726
727 /* RFC2132 section 4.1.1:
728 The client MUST include its hardware address in the ’chaddr’ field, if
729 necessary for delivery of DHCP reply messages. Non-Ethernet
730 interfaces will leave 'chaddr' empty and use the client identifier
731 instead (eg, RFC 4390 section 2.1).
732 */
733 if (client->arp_type == ARPHRD_ETHER)
734 memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
735
736 /* If no client identifier exists, construct an RFC 4361-compliant one */
737 if (client->client_id_len == 0) {
738 size_t duid_len;
739
740 client->client_id.type = 255;
741
742 r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len,
743 true, &client->client_id.ns.iaid);
744 if (r < 0)
745 return r;
746
747 r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &duid_len);
748 if (r < 0)
749 return r;
750
751 client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid_len;
752 }
753
754 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
755 Identifier option is not set */
756 if (client->client_id_len) {
757 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
758 SD_DHCP_OPTION_CLIENT_IDENTIFIER,
759 client->client_id_len,
760 &client->client_id);
761 if (r < 0)
762 return r;
763 }
764
765 /* RFC2131 section 3.5:
766 in its initial DHCPDISCOVER or DHCPREQUEST message, a
767 client may provide the server with a list of specific
768 parameters the client is interested in. If the client
769 includes a list of parameters in a DHCPDISCOVER message,
770 it MUST include that list in any subsequent DHCPREQUEST
771 messages.
772 */
773
774 /* RFC7844 section 3:
775 MAY contain the Parameter Request List option. */
776 /* NOTE: in case that there would be an option to do not send
777 * any PRL at all, the size should be checked before sending */
778 if (client->req_opts_size > 0 && type != DHCP_RELEASE) {
779 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
780 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
781 client->req_opts_size, client->req_opts);
782 if (r < 0)
783 return r;
784 }
785
786 /* RFC2131 section 3.5:
787 The client SHOULD include the ’maximum DHCP message size’ option to
788 let the server know how large the server may make its DHCP messages.
789
790 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
791 than the defined default size unless the Maximum Message Size option
792 is explicitly set
793
794 RFC3442 "Requirements to Avoid Sizing Constraints":
795 Because a full routing table can be quite large, the standard 576
796 octet maximum size for a DHCP message may be too short to contain
797 some legitimate Classless Static Route options. Because of this,
798 clients implementing the Classless Static Route option SHOULD send a
799 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
800 stack is capable of receiving larger IP datagrams. In this case, the
801 client SHOULD set the value of this option to at least the MTU of the
802 interface that the client is configuring. The client MAY set the
803 value of this option higher, up to the size of the largest UDP packet
804 it is prepared to accept. (Note that the value specified in the
805 Maximum DHCP Message Size option is the total maximum packet size,
806 including IP and UDP headers.)
807 */
808 /* RFC7844 section 3:
809 SHOULD NOT contain any other option. */
810 if (!client->anonymize && type != DHCP_RELEASE) {
811 max_size = htobe16(size);
812 r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
813 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
814 2, &max_size);
815 if (r < 0)
816 return r;
817 }
818
819 *_optlen = optlen;
820 *_optoffset = optoffset;
821 *ret = TAKE_PTR(packet);
822
823 return 0;
824 }
825
826 static int client_append_fqdn_option(
827 DHCPMessage *message,
828 size_t optlen,
829 size_t *optoffset,
830 const char *fqdn) {
831
832 uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH];
833 int r;
834
835 buffer[0] = DHCP_FQDN_FLAG_S | /* Request server to perform A RR DNS updates */
836 DHCP_FQDN_FLAG_E; /* Canonical wire format */
837 buffer[1] = 0; /* RCODE1 (deprecated) */
838 buffer[2] = 0; /* RCODE2 (deprecated) */
839
840 r = dns_name_to_wire_format(fqdn, buffer + 3, sizeof(buffer) - 3, false);
841 if (r > 0)
842 r = dhcp_option_append(message, optlen, optoffset, 0,
843 SD_DHCP_OPTION_FQDN, 3 + r, buffer);
844
845 return r;
846 }
847
848 static int dhcp_client_send_raw(
849 sd_dhcp_client *client,
850 DHCPPacket *packet,
851 size_t len) {
852
853 dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
854 INADDR_BROADCAST, DHCP_PORT_SERVER, len, client->ip_service_type);
855
856 return dhcp_network_send_raw_socket(client->fd, &client->link,
857 packet, len);
858 }
859
860 static int client_send_discover(sd_dhcp_client *client) {
861 _cleanup_free_ DHCPPacket *discover = NULL;
862 size_t optoffset, optlen;
863 sd_dhcp_option *j;
864 Iterator i;
865 int r;
866
867 assert(client);
868 assert(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_SELECTING));
869
870 r = client_message_init(client, &discover, DHCP_DISCOVER,
871 &optlen, &optoffset);
872 if (r < 0)
873 return r;
874
875 /* the client may suggest values for the network address
876 and lease time in the DHCPDISCOVER message. The client may include
877 the ’requested IP address’ option to suggest that a particular IP
878 address be assigned, and may include the ’IP address lease time’
879 option to suggest the lease time it would like.
880 */
881 if (client->last_addr != INADDR_ANY) {
882 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
883 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
884 4, &client->last_addr);
885 if (r < 0)
886 return r;
887 }
888
889 if (client->hostname) {
890 /* According to RFC 4702 "clients that send the Client FQDN option in
891 their messages MUST NOT also send the Host Name option". Just send
892 one of the two depending on the hostname type.
893 */
894 if (dns_name_is_single_label(client->hostname)) {
895 /* it is unclear from RFC 2131 if client should send hostname in
896 DHCPDISCOVER but dhclient does and so we do as well
897 */
898 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
899 SD_DHCP_OPTION_HOST_NAME,
900 strlen(client->hostname), client->hostname);
901 } else
902 r = client_append_fqdn_option(&discover->dhcp, optlen, &optoffset,
903 client->hostname);
904 if (r < 0)
905 return r;
906 }
907
908 if (client->vendor_class_identifier) {
909 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
910 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
911 strlen(client->vendor_class_identifier),
912 client->vendor_class_identifier);
913 if (r < 0)
914 return r;
915 }
916
917 if (client->user_class) {
918 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
919 SD_DHCP_OPTION_USER_CLASS,
920 strv_length(client->user_class),
921 client->user_class);
922 if (r < 0)
923 return r;
924 }
925
926 ORDERED_HASHMAP_FOREACH(j, client->options, i) {
927 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
928 j->option, j->length, j->data);
929 if (r < 0)
930 return r;
931 }
932
933 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
934 SD_DHCP_OPTION_END, 0, NULL);
935 if (r < 0)
936 return r;
937
938 /* We currently ignore:
939 The client SHOULD wait a random time between one and ten seconds to
940 desynchronize the use of DHCP at startup.
941 */
942 r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
943 if (r < 0)
944 return r;
945
946 log_dhcp_client(client, "DISCOVER");
947
948 return 0;
949 }
950
951 static int client_send_request(sd_dhcp_client *client) {
952 _cleanup_free_ DHCPPacket *request = NULL;
953 size_t optoffset, optlen;
954 int r;
955
956 assert(client);
957
958 r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset);
959 if (r < 0)
960 return r;
961
962 switch (client->state) {
963 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
964 SELECTING should be REQUESTING)
965 */
966
967 case DHCP_STATE_REQUESTING:
968 /* Client inserts the address of the selected server in ’server
969 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
970 filled in with the yiaddr value from the chosen DHCPOFFER.
971 */
972
973 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
974 SD_DHCP_OPTION_SERVER_IDENTIFIER,
975 4, &client->lease->server_address);
976 if (r < 0)
977 return r;
978
979 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
980 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
981 4, &client->lease->address);
982 if (r < 0)
983 return r;
984
985 break;
986
987 case DHCP_STATE_INIT_REBOOT:
988 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
989 option MUST be filled in with client’s notion of its previously
990 assigned address. ’ciaddr’ MUST be zero.
991 */
992 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
993 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
994 4, &client->last_addr);
995 if (r < 0)
996 return r;
997 break;
998
999 case DHCP_STATE_RENEWING:
1000 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1001 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1002 client’s IP address.
1003 */
1004
1005 case DHCP_STATE_REBINDING:
1006 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1007 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1008 client’s IP address.
1009
1010 This message MUST be broadcast to the 0xffffffff IP broadcast address.
1011 */
1012 request->dhcp.ciaddr = client->lease->address;
1013
1014 break;
1015
1016 case DHCP_STATE_INIT:
1017 case DHCP_STATE_SELECTING:
1018 case DHCP_STATE_REBOOTING:
1019 case DHCP_STATE_BOUND:
1020 case DHCP_STATE_STOPPED:
1021 return -EINVAL;
1022 }
1023
1024 if (client->hostname) {
1025 if (dns_name_is_single_label(client->hostname))
1026 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1027 SD_DHCP_OPTION_HOST_NAME,
1028 strlen(client->hostname), client->hostname);
1029 else
1030 r = client_append_fqdn_option(&request->dhcp, optlen, &optoffset,
1031 client->hostname);
1032 if (r < 0)
1033 return r;
1034 }
1035
1036 if (client->vendor_class_identifier) {
1037 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1038 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
1039 strlen(client->vendor_class_identifier),
1040 client->vendor_class_identifier);
1041 if (r < 0)
1042 return r;
1043 }
1044
1045 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1046 SD_DHCP_OPTION_END, 0, NULL);
1047 if (r < 0)
1048 return r;
1049
1050 if (client->state == DHCP_STATE_RENEWING)
1051 r = dhcp_network_send_udp_socket(client->fd,
1052 client->lease->server_address,
1053 DHCP_PORT_SERVER,
1054 &request->dhcp,
1055 sizeof(DHCPMessage) + optoffset);
1056 else
1057 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
1058 if (r < 0)
1059 return r;
1060
1061 switch (client->state) {
1062
1063 case DHCP_STATE_REQUESTING:
1064 log_dhcp_client(client, "REQUEST (requesting)");
1065 break;
1066
1067 case DHCP_STATE_INIT_REBOOT:
1068 log_dhcp_client(client, "REQUEST (init-reboot)");
1069 break;
1070
1071 case DHCP_STATE_RENEWING:
1072 log_dhcp_client(client, "REQUEST (renewing)");
1073 break;
1074
1075 case DHCP_STATE_REBINDING:
1076 log_dhcp_client(client, "REQUEST (rebinding)");
1077 break;
1078
1079 default:
1080 log_dhcp_client(client, "REQUEST (invalid)");
1081 break;
1082 }
1083
1084 return 0;
1085 }
1086
1087 static int client_start(sd_dhcp_client *client);
1088
1089 static int client_timeout_resend(
1090 sd_event_source *s,
1091 uint64_t usec,
1092 void *userdata) {
1093
1094 sd_dhcp_client *client = userdata;
1095 DHCP_CLIENT_DONT_DESTROY(client);
1096 usec_t next_timeout = 0;
1097 uint64_t time_now;
1098 uint32_t time_left;
1099 int r;
1100
1101 assert(s);
1102 assert(client);
1103 assert(client->event);
1104
1105 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1106 if (r < 0)
1107 goto error;
1108
1109 switch (client->state) {
1110
1111 case DHCP_STATE_RENEWING:
1112
1113 time_left = (client->lease->t2 - client->lease->t1) / 2;
1114 if (time_left < 60)
1115 time_left = 60;
1116
1117 next_timeout = time_now + time_left * USEC_PER_SEC;
1118
1119 break;
1120
1121 case DHCP_STATE_REBINDING:
1122
1123 time_left = (client->lease->lifetime - client->lease->t2) / 2;
1124 if (time_left < 60)
1125 time_left = 60;
1126
1127 next_timeout = time_now + time_left * USEC_PER_SEC;
1128 break;
1129
1130 case DHCP_STATE_REBOOTING:
1131 /* start over as we did not receive a timely ack or nak */
1132 r = client_initialize(client);
1133 if (r < 0)
1134 goto error;
1135
1136 r = client_start(client);
1137 if (r < 0)
1138 goto error;
1139 else {
1140 log_dhcp_client(client, "REBOOTED");
1141 return 0;
1142 }
1143
1144 case DHCP_STATE_INIT:
1145 case DHCP_STATE_INIT_REBOOT:
1146 case DHCP_STATE_SELECTING:
1147 case DHCP_STATE_REQUESTING:
1148 case DHCP_STATE_BOUND:
1149
1150 if (client->attempt < client->max_attempts)
1151 client->attempt++;
1152 else
1153 goto error;
1154
1155 next_timeout = time_now + ((UINT64_C(1) << MIN(client->attempt, (uint64_t) 6)) - 1) * USEC_PER_SEC;
1156
1157 break;
1158
1159 case DHCP_STATE_STOPPED:
1160 r = -EINVAL;
1161 goto error;
1162 }
1163
1164 next_timeout += (random_u32() & 0x1fffff);
1165
1166 r = event_reset_time(client->event, &client->timeout_resend,
1167 clock_boottime_or_monotonic(),
1168 next_timeout, 10 * USEC_PER_MSEC,
1169 client_timeout_resend, client,
1170 client->event_priority, "dhcp4-resend-timer", true);
1171 if (r < 0)
1172 goto error;
1173
1174 switch (client->state) {
1175 case DHCP_STATE_INIT:
1176 r = client_send_discover(client);
1177 if (r >= 0) {
1178 client->state = DHCP_STATE_SELECTING;
1179 client->attempt = 0;
1180 } else if (client->attempt >= client->max_attempts)
1181 goto error;
1182
1183 break;
1184
1185 case DHCP_STATE_SELECTING:
1186 r = client_send_discover(client);
1187 if (r < 0 && client->attempt >= client->max_attempts)
1188 goto error;
1189
1190 break;
1191
1192 case DHCP_STATE_INIT_REBOOT:
1193 case DHCP_STATE_REQUESTING:
1194 case DHCP_STATE_RENEWING:
1195 case DHCP_STATE_REBINDING:
1196 r = client_send_request(client);
1197 if (r < 0 && client->attempt >= client->max_attempts)
1198 goto error;
1199
1200 if (client->state == DHCP_STATE_INIT_REBOOT)
1201 client->state = DHCP_STATE_REBOOTING;
1202
1203 client->request_sent = time_now;
1204
1205 break;
1206
1207 case DHCP_STATE_REBOOTING:
1208 case DHCP_STATE_BOUND:
1209
1210 break;
1211
1212 case DHCP_STATE_STOPPED:
1213 r = -EINVAL;
1214 goto error;
1215 }
1216
1217 return 0;
1218
1219 error:
1220 client_stop(client, r);
1221
1222 /* Errors were dealt with when stopping the client, don't spill
1223 errors into the event loop handler */
1224 return 0;
1225 }
1226
1227 static int client_initialize_io_events(
1228 sd_dhcp_client *client,
1229 sd_event_io_handler_t io_callback) {
1230
1231 int r;
1232
1233 assert(client);
1234 assert(client->event);
1235
1236 r = sd_event_add_io(client->event, &client->receive_message,
1237 client->fd, EPOLLIN, io_callback,
1238 client);
1239 if (r < 0)
1240 goto error;
1241
1242 r = sd_event_source_set_priority(client->receive_message,
1243 client->event_priority);
1244 if (r < 0)
1245 goto error;
1246
1247 r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
1248 if (r < 0)
1249 goto error;
1250
1251 error:
1252 if (r < 0)
1253 client_stop(client, r);
1254
1255 return 0;
1256 }
1257
1258 static int client_initialize_time_events(sd_dhcp_client *client) {
1259 uint64_t usec = 0;
1260 int r;
1261
1262 assert(client);
1263 assert(client->event);
1264
1265 if (client->start_delay > 0) {
1266 assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
1267 usec += client->start_delay;
1268 }
1269
1270 r = event_reset_time(client->event, &client->timeout_resend,
1271 clock_boottime_or_monotonic(),
1272 usec, 0,
1273 client_timeout_resend, client,
1274 client->event_priority, "dhcp4-resend-timer", true);
1275 if (r < 0)
1276 client_stop(client, r);
1277
1278 return 0;
1279
1280 }
1281
1282 static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
1283 client_initialize_io_events(client, io_callback);
1284 client_initialize_time_events(client);
1285
1286 return 0;
1287 }
1288
1289 static int client_start_delayed(sd_dhcp_client *client) {
1290 int r;
1291
1292 assert_return(client, -EINVAL);
1293 assert_return(client->event, -EINVAL);
1294 assert_return(client->ifindex > 0, -EINVAL);
1295 assert_return(client->fd < 0, -EBUSY);
1296 assert_return(client->xid == 0, -EINVAL);
1297 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY);
1298
1299 client->xid = random_u32();
1300
1301 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1302 client->xid, client->mac_addr,
1303 client->mac_addr_len, client->arp_type, client->port);
1304 if (r < 0) {
1305 client_stop(client, r);
1306 return r;
1307 }
1308 client->fd = r;
1309
1310 if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT))
1311 client->start_time = now(clock_boottime_or_monotonic());
1312
1313 return client_initialize_events(client, client_receive_message_raw);
1314 }
1315
1316 static int client_start(sd_dhcp_client *client) {
1317 client->start_delay = 0;
1318 return client_start_delayed(client);
1319 }
1320
1321 static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
1322 sd_dhcp_client *client = userdata;
1323 DHCP_CLIENT_DONT_DESTROY(client);
1324
1325 log_dhcp_client(client, "EXPIRED");
1326
1327 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1328
1329 /* lease was lost, start over if not freed or stopped in callback */
1330 if (client->state != DHCP_STATE_STOPPED) {
1331 client_initialize(client);
1332 client_start(client);
1333 }
1334
1335 return 0;
1336 }
1337
1338 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
1339 sd_dhcp_client *client = userdata;
1340 DHCP_CLIENT_DONT_DESTROY(client);
1341 int r;
1342
1343 assert(client);
1344
1345 client->receive_message = sd_event_source_unref(client->receive_message);
1346 client->fd = asynchronous_close(client->fd);
1347
1348 client->state = DHCP_STATE_REBINDING;
1349 client->attempt = 0;
1350
1351 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1352 client->xid, client->mac_addr,
1353 client->mac_addr_len, client->arp_type,
1354 client->port);
1355 if (r < 0) {
1356 client_stop(client, r);
1357 return 0;
1358 }
1359 client->fd = r;
1360
1361 return client_initialize_events(client, client_receive_message_raw);
1362 }
1363
1364 static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
1365 sd_dhcp_client *client = userdata;
1366 DHCP_CLIENT_DONT_DESTROY(client);
1367
1368 client->state = DHCP_STATE_RENEWING;
1369 client->attempt = 0;
1370
1371 return client_initialize_time_events(client);
1372 }
1373
1374 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
1375 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1376 int r;
1377
1378 r = dhcp_lease_new(&lease);
1379 if (r < 0)
1380 return r;
1381
1382 if (client->client_id_len) {
1383 r = dhcp_lease_set_client_id(lease,
1384 (uint8_t *) &client->client_id,
1385 client->client_id_len);
1386 if (r < 0)
1387 return r;
1388 }
1389
1390 r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease, NULL);
1391 if (r != DHCP_OFFER) {
1392 log_dhcp_client(client, "received message was not an OFFER, ignoring");
1393 return -ENOMSG;
1394 }
1395
1396 lease->next_server = offer->siaddr;
1397 lease->address = offer->yiaddr;
1398
1399 if (lease->address == 0 ||
1400 lease->server_address == 0 ||
1401 lease->lifetime == 0) {
1402 log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
1403 return -ENOMSG;
1404 }
1405
1406 if (!lease->have_subnet_mask) {
1407 r = dhcp_lease_set_default_subnet_mask(lease);
1408 if (r < 0) {
1409 log_dhcp_client(client,
1410 "received lease lacks subnet mask, "
1411 "and a fallback one cannot be generated, ignoring");
1412 return -ENOMSG;
1413 }
1414 }
1415
1416 sd_dhcp_lease_unref(client->lease);
1417 client->lease = TAKE_PTR(lease);
1418
1419 if (client_notify(client, SD_DHCP_CLIENT_EVENT_SELECTING) < 0)
1420 return -ENOMSG;
1421
1422 log_dhcp_client(client, "OFFER");
1423
1424 return 0;
1425 }
1426
1427 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
1428 int r;
1429
1430 r = dhcp_option_parse(force, len, NULL, NULL, NULL);
1431 if (r != DHCP_FORCERENEW)
1432 return -ENOMSG;
1433
1434 log_dhcp_client(client, "FORCERENEW");
1435
1436 return 0;
1437 }
1438
1439 static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {
1440 if (a->address != b->address)
1441 return false;
1442
1443 if (a->subnet_mask != b->subnet_mask)
1444 return false;
1445
1446 if (a->router_size != b->router_size)
1447 return false;
1448
1449 for (size_t i = 0; i < a->router_size; i++)
1450 if (a->router[i].s_addr != b->router[i].s_addr)
1451 return false;
1452
1453 return true;
1454 }
1455
1456 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
1457 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1458 _cleanup_free_ char *error_message = NULL;
1459 int r;
1460
1461 r = dhcp_lease_new(&lease);
1462 if (r < 0)
1463 return r;
1464
1465 if (client->client_id_len) {
1466 r = dhcp_lease_set_client_id(lease,
1467 (uint8_t *) &client->client_id,
1468 client->client_id_len);
1469 if (r < 0)
1470 return r;
1471 }
1472
1473 r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease, &error_message);
1474 if (r == DHCP_NAK) {
1475 log_dhcp_client(client, "NAK: %s", strna(error_message));
1476 return -EADDRNOTAVAIL;
1477 }
1478
1479 if (r != DHCP_ACK) {
1480 log_dhcp_client(client, "received message was not an ACK, ignoring");
1481 return -ENOMSG;
1482 }
1483
1484 lease->next_server = ack->siaddr;
1485
1486 lease->address = ack->yiaddr;
1487
1488 if (lease->address == INADDR_ANY ||
1489 lease->server_address == INADDR_ANY ||
1490 lease->lifetime == 0) {
1491 log_dhcp_client(client, "received lease lacks address, server "
1492 "address or lease lifetime, ignoring");
1493 return -ENOMSG;
1494 }
1495
1496 if (lease->subnet_mask == INADDR_ANY) {
1497 r = dhcp_lease_set_default_subnet_mask(lease);
1498 if (r < 0) {
1499 log_dhcp_client(client,
1500 "received lease lacks subnet mask, "
1501 "and a fallback one cannot be generated, ignoring");
1502 return -ENOMSG;
1503 }
1504 }
1505
1506 r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1507 if (client->lease) {
1508 if (lease_equal(client->lease, lease))
1509 r = SD_DHCP_CLIENT_EVENT_RENEW;
1510 else
1511 r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
1512
1513 client->lease = sd_dhcp_lease_unref(client->lease);
1514 }
1515
1516 client->lease = TAKE_PTR(lease);
1517
1518 log_dhcp_client(client, "ACK");
1519
1520 return r;
1521 }
1522
1523 static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) {
1524 assert(client);
1525 assert(client->request_sent);
1526 assert(lifetime > 0);
1527
1528 if (lifetime > 3)
1529 lifetime -= 3;
1530 else
1531 lifetime = 0;
1532
1533 return client->request_sent + (lifetime * USEC_PER_SEC * factor) +
1534 + (random_u32() & 0x1fffff);
1535 }
1536
1537 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1538 usec_t time_now;
1539 uint64_t lifetime_timeout;
1540 uint64_t t2_timeout;
1541 uint64_t t1_timeout;
1542 char time_string[FORMAT_TIMESPAN_MAX];
1543 int r;
1544
1545 assert(client);
1546 assert(client->event);
1547 assert(client->lease);
1548 assert(client->lease->lifetime);
1549
1550 /* don't set timers for infinite leases */
1551 if (client->lease->lifetime == 0xffffffff) {
1552 (void) event_source_disable(client->timeout_t1);
1553 (void) event_source_disable(client->timeout_t2);
1554 (void) event_source_disable(client->timeout_expire);
1555
1556 return 0;
1557 }
1558
1559 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1560 if (r < 0)
1561 return r;
1562 assert(client->request_sent <= time_now);
1563
1564 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1565 lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1566 if (client->lease->t1 > 0 && client->lease->t2 > 0) {
1567 /* both T1 and T2 are given */
1568 if (client->lease->t1 < client->lease->t2 &&
1569 client->lease->t2 < client->lease->lifetime) {
1570 /* they are both valid */
1571 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1572 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1573 } else {
1574 /* discard both */
1575 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1576 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1577 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1578 client->lease->t1 = client->lease->lifetime / 2;
1579 }
1580 } else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) {
1581 /* only T2 is given, and it is valid */
1582 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1583 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1584 client->lease->t1 = client->lease->lifetime / 2;
1585 if (t2_timeout <= t1_timeout) {
1586 /* the computed T1 would be invalid, so discard T2 */
1587 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1588 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1589 }
1590 } else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) {
1591 /* only T1 is given, and it is valid */
1592 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1593 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1594 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1595 if (t2_timeout <= t1_timeout) {
1596 /* the computed T2 would be invalid, so discard T1 */
1597 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1598 client->lease->t2 = client->lease->lifetime / 2;
1599 }
1600 } else {
1601 /* fall back to the default timeouts */
1602 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1603 client->lease->t1 = client->lease->lifetime / 2;
1604 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1605 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1606 }
1607
1608 /* arm lifetime timeout */
1609 r = event_reset_time(client->event, &client->timeout_expire,
1610 clock_boottime_or_monotonic(),
1611 lifetime_timeout, 10 * USEC_PER_MSEC,
1612 client_timeout_expire, client,
1613 client->event_priority, "dhcp4-lifetime", true);
1614 if (r < 0)
1615 return r;
1616
1617 log_dhcp_client(client, "lease expires in %s",
1618 format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime_timeout - time_now, USEC_PER_SEC));
1619
1620 /* don't arm earlier timeouts if this has already expired */
1621 if (lifetime_timeout <= time_now)
1622 return 0;
1623
1624 /* arm T2 timeout */
1625 r = event_reset_time(client->event, &client->timeout_t2,
1626 clock_boottime_or_monotonic(),
1627 t2_timeout, 10 * USEC_PER_MSEC,
1628 client_timeout_t2, client,
1629 client->event_priority, "dhcp4-t2-timeout", true);
1630 if (r < 0)
1631 return r;
1632
1633 log_dhcp_client(client, "T2 expires in %s",
1634 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t2_timeout - time_now, USEC_PER_SEC));
1635
1636 /* don't arm earlier timeout if this has already expired */
1637 if (t2_timeout <= time_now)
1638 return 0;
1639
1640 /* arm T1 timeout */
1641 r = event_reset_time(client->event, &client->timeout_t1,
1642 clock_boottime_or_monotonic(),
1643 t1_timeout, 10 * USEC_PER_MSEC,
1644 client_timeout_t1, client,
1645 client->event_priority, "dhcp4-t1-timer", true);
1646 if (r < 0)
1647 return r;
1648
1649 log_dhcp_client(client, "T1 expires in %s",
1650 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t1_timeout - time_now, USEC_PER_SEC));
1651
1652 return 0;
1653 }
1654
1655 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
1656 DHCP_CLIENT_DONT_DESTROY(client);
1657 char time_string[FORMAT_TIMESPAN_MAX];
1658 int r = 0, notify_event = 0;
1659
1660 assert(client);
1661 assert(client->event);
1662 assert(message);
1663
1664 switch (client->state) {
1665 case DHCP_STATE_SELECTING:
1666
1667 r = client_handle_offer(client, message, len);
1668 if (r >= 0) {
1669
1670 client->state = DHCP_STATE_REQUESTING;
1671 client->attempt = 0;
1672
1673 r = event_reset_time(client->event, &client->timeout_resend,
1674 clock_boottime_or_monotonic(),
1675 0, 0,
1676 client_timeout_resend, client,
1677 client->event_priority, "dhcp4-resend-timer", true);
1678 if (r < 0)
1679 goto error;
1680 } else if (r == -ENOMSG)
1681 /* invalid message, let's ignore it */
1682 return 0;
1683
1684 break;
1685
1686 case DHCP_STATE_REBOOTING:
1687 case DHCP_STATE_REQUESTING:
1688 case DHCP_STATE_RENEWING:
1689 case DHCP_STATE_REBINDING:
1690
1691 r = client_handle_ack(client, message, len);
1692 if (r >= 0) {
1693 client->start_delay = 0;
1694 (void) event_source_disable(client->timeout_resend);
1695 client->receive_message =
1696 sd_event_source_unref(client->receive_message);
1697 client->fd = asynchronous_close(client->fd);
1698
1699 if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1700 DHCP_STATE_REBOOTING))
1701 notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1702 else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
1703 notify_event = r;
1704
1705 client->state = DHCP_STATE_BOUND;
1706 client->attempt = 0;
1707
1708 client->last_addr = client->lease->address;
1709
1710 r = client_set_lease_timeouts(client);
1711 if (r < 0) {
1712 log_dhcp_client(client, "could not set lease timeouts");
1713 goto error;
1714 }
1715
1716 r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port, client->ip_service_type);
1717 if (r < 0) {
1718 log_dhcp_client(client, "could not bind UDP socket");
1719 goto error;
1720 }
1721
1722 client->fd = r;
1723
1724 client_initialize_io_events(client, client_receive_message_udp);
1725
1726 if (notify_event) {
1727 client_notify(client, notify_event);
1728 if (client->state == DHCP_STATE_STOPPED)
1729 return 0;
1730 }
1731
1732 } else if (r == -EADDRNOTAVAIL) {
1733 /* got a NAK, let's restart the client */
1734 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1735
1736 r = client_initialize(client);
1737 if (r < 0)
1738 goto error;
1739
1740 r = client_start_delayed(client);
1741 if (r < 0)
1742 goto error;
1743
1744 log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1745 client->start_delay, USEC_PER_SEC));
1746
1747 client->start_delay = CLAMP(client->start_delay * 2,
1748 RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
1749
1750 return 0;
1751 } else if (r == -ENOMSG)
1752 /* invalid message, let's ignore it */
1753 return 0;
1754
1755 break;
1756
1757 case DHCP_STATE_BOUND:
1758 r = client_handle_forcerenew(client, message, len);
1759 if (r >= 0) {
1760 r = client_timeout_t1(NULL, 0, client);
1761 if (r < 0)
1762 goto error;
1763 } else if (r == -ENOMSG)
1764 /* invalid message, let's ignore it */
1765 return 0;
1766
1767 break;
1768
1769 case DHCP_STATE_INIT:
1770 case DHCP_STATE_INIT_REBOOT:
1771
1772 break;
1773
1774 case DHCP_STATE_STOPPED:
1775 r = -EINVAL;
1776 goto error;
1777 }
1778
1779 error:
1780 if (r < 0)
1781 client_stop(client, r);
1782
1783 return r;
1784 }
1785
1786 static int client_receive_message_udp(
1787 sd_event_source *s,
1788 int fd,
1789 uint32_t revents,
1790 void *userdata) {
1791
1792 sd_dhcp_client *client = userdata;
1793 _cleanup_free_ DHCPMessage *message = NULL;
1794 const uint8_t *expected_chaddr = NULL;
1795 uint8_t expected_hlen = 0;
1796 ssize_t len, buflen;
1797
1798 assert(s);
1799 assert(client);
1800
1801 buflen = next_datagram_size_fd(fd);
1802 if (buflen == -ENETDOWN) {
1803 /* the link is down. Don't return an error or the I/O event
1804 source will be disconnected and we won't be able to receive
1805 packets again when the link comes back. */
1806 return 0;
1807 }
1808 if (buflen < 0)
1809 return buflen;
1810
1811 message = malloc0(buflen);
1812 if (!message)
1813 return -ENOMEM;
1814
1815 len = recv(fd, message, buflen, 0);
1816 if (len < 0) {
1817 /* see comment above for why we shouldn't error out on ENETDOWN. */
1818 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1819 return 0;
1820
1821 return log_dhcp_client_errno(client, errno,
1822 "Could not receive message from UDP socket: %m");
1823 }
1824 if ((size_t) len < sizeof(DHCPMessage)) {
1825 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
1826 return 0;
1827 }
1828
1829 if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1830 log_dhcp_client(client, "Not a DHCP message: ignoring");
1831 return 0;
1832 }
1833
1834 if (message->op != BOOTREPLY) {
1835 log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
1836 return 0;
1837 }
1838
1839 if (message->htype != client->arp_type) {
1840 log_dhcp_client(client, "Packet type does not match client type");
1841 return 0;
1842 }
1843
1844 if (client->arp_type == ARPHRD_ETHER) {
1845 expected_hlen = ETH_ALEN;
1846 expected_chaddr = &client->mac_addr[0];
1847 }
1848
1849 if (message->hlen != expected_hlen) {
1850 log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
1851 return 0;
1852 }
1853
1854 if (expected_hlen > 0 && memcmp(&message->chaddr[0], expected_chaddr, expected_hlen)) {
1855 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
1856 return 0;
1857 }
1858
1859 if (client->state != DHCP_STATE_BOUND &&
1860 be32toh(message->xid) != client->xid) {
1861 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1862 so ignore the xid in this case */
1863 log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
1864 be32toh(message->xid), client->xid);
1865 return 0;
1866 }
1867
1868 return client_handle_message(client, message, len);
1869 }
1870
1871 static int client_receive_message_raw(
1872 sd_event_source *s,
1873 int fd,
1874 uint32_t revents,
1875 void *userdata) {
1876
1877 sd_dhcp_client *client = userdata;
1878 _cleanup_free_ DHCPPacket *packet = NULL;
1879 uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1880 struct iovec iov = {};
1881 struct msghdr msg = {
1882 .msg_iov = &iov,
1883 .msg_iovlen = 1,
1884 .msg_control = cmsgbuf,
1885 .msg_controllen = sizeof(cmsgbuf),
1886 };
1887 struct cmsghdr *cmsg;
1888 bool checksum = true;
1889 ssize_t buflen, len;
1890 int r;
1891
1892 assert(s);
1893 assert(client);
1894
1895 buflen = next_datagram_size_fd(fd);
1896 if (buflen == -ENETDOWN)
1897 return 0;
1898 if (buflen < 0)
1899 return buflen;
1900
1901 packet = malloc0(buflen);
1902 if (!packet)
1903 return -ENOMEM;
1904
1905 iov = IOVEC_MAKE(packet, buflen);
1906
1907 len = recvmsg(fd, &msg, 0);
1908 if (len < 0) {
1909 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1910 return 0;
1911
1912 return log_dhcp_client_errno(client, errno,
1913 "Could not receive message from raw socket: %m");
1914 } else if ((size_t)len < sizeof(DHCPPacket))
1915 return 0;
1916
1917 CMSG_FOREACH(cmsg, &msg)
1918 if (cmsg->cmsg_level == SOL_PACKET &&
1919 cmsg->cmsg_type == PACKET_AUXDATA &&
1920 cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1921 struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1922
1923 checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1924 break;
1925 }
1926
1927 r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
1928 if (r < 0)
1929 return 0;
1930
1931 len -= DHCP_IP_UDP_SIZE;
1932
1933 return client_handle_message(client, &packet->dhcp, len);
1934 }
1935
1936 int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
1937 assert_return(client, -EINVAL);
1938 assert_return(client->fd >= 0, -EINVAL);
1939
1940 client->start_delay = 0;
1941 client->attempt = 1;
1942 client->state = DHCP_STATE_RENEWING;
1943
1944 return client_initialize_time_events(client);
1945 }
1946
1947 int sd_dhcp_client_start(sd_dhcp_client *client) {
1948 int r;
1949
1950 assert_return(client, -EINVAL);
1951
1952 r = client_initialize(client);
1953 if (r < 0)
1954 return r;
1955
1956 /* RFC7844 section 3.3:
1957 SHOULD perform a complete four-way handshake, starting with a
1958 DHCPDISCOVER, to obtain a new address lease. If the client can
1959 ascertain that this is exactly the same network to which it was
1960 previously connected, and if the link-layer address did not change,
1961 the client MAY issue a DHCPREQUEST to try to reclaim the current
1962 address. */
1963 if (client->last_addr && !client->anonymize)
1964 client->state = DHCP_STATE_INIT_REBOOT;
1965
1966 r = client_start(client);
1967 if (r >= 0)
1968 log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
1969
1970 return r;
1971 }
1972
1973 int sd_dhcp_client_send_release(sd_dhcp_client *client) {
1974 assert_return(client, -EINVAL);
1975 assert_return(client->state != DHCP_STATE_STOPPED, -ESTALE);
1976 assert_return(client->lease, -EUNATCH);
1977
1978 _cleanup_free_ DHCPPacket *release = NULL;
1979 size_t optoffset, optlen;
1980 int r;
1981
1982 r = client_message_init(client, &release, DHCP_RELEASE, &optlen, &optoffset);
1983 if (r < 0)
1984 return r;
1985
1986 /* Fill up release IP and MAC */
1987 release->dhcp.ciaddr = client->lease->address;
1988 memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
1989
1990 r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
1991 SD_DHCP_OPTION_END, 0, NULL);
1992 if (r < 0)
1993 return r;
1994
1995 r = dhcp_network_send_udp_socket(client->fd,
1996 client->lease->server_address,
1997 DHCP_PORT_SERVER,
1998 &release->dhcp,
1999 sizeof(DHCPMessage) + optoffset);
2000 if (r < 0)
2001 return r;
2002
2003 log_dhcp_client(client, "RELEASE");
2004
2005 return 0;
2006 }
2007
2008 int sd_dhcp_client_stop(sd_dhcp_client *client) {
2009 DHCP_CLIENT_DONT_DESTROY(client);
2010
2011 assert_return(client, -EINVAL);
2012
2013 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
2014 client->state = DHCP_STATE_STOPPED;
2015
2016 return 0;
2017 }
2018
2019 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
2020 int r;
2021
2022 assert_return(client, -EINVAL);
2023 assert_return(!client->event, -EBUSY);
2024
2025 if (event)
2026 client->event = sd_event_ref(event);
2027 else {
2028 r = sd_event_default(&client->event);
2029 if (r < 0)
2030 return 0;
2031 }
2032
2033 client->event_priority = priority;
2034
2035 return 0;
2036 }
2037
2038 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
2039 assert_return(client, -EINVAL);
2040
2041 client->event = sd_event_unref(client->event);
2042
2043 return 0;
2044 }
2045
2046 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
2047 assert_return(client, NULL);
2048
2049 return client->event;
2050 }
2051
2052 static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
2053 assert(client);
2054
2055 log_dhcp_client(client, "FREE");
2056
2057 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
2058 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
2059 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
2060 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
2061
2062 client_initialize(client);
2063
2064 sd_dhcp_client_detach_event(client);
2065
2066 sd_dhcp_lease_unref(client->lease);
2067
2068 free(client->req_opts);
2069 free(client->hostname);
2070 free(client->vendor_class_identifier);
2071 client->user_class = strv_free(client->user_class);
2072 ordered_hashmap_free(client->options);
2073 return mfree(client);
2074 }
2075
2076 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
2077
2078 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
2079 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = NULL;
2080
2081 assert_return(ret, -EINVAL);
2082
2083 client = new(sd_dhcp_client, 1);
2084 if (!client)
2085 return -ENOMEM;
2086
2087 *client = (sd_dhcp_client) {
2088 .n_ref = 1,
2089 .state = DHCP_STATE_INIT,
2090 .ifindex = -1,
2091 .fd = -1,
2092 .mtu = DHCP_DEFAULT_MIN_SIZE,
2093 .port = DHCP_PORT_CLIENT,
2094 .anonymize = !!anonymize,
2095 .max_attempts = (uint64_t) -1,
2096 .ip_service_type = -1,
2097 };
2098 /* NOTE: this could be moved to a function. */
2099 if (anonymize) {
2100 client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
2101 client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
2102 } else {
2103 client->req_opts_size = ELEMENTSOF(default_req_opts);
2104 client->req_opts = memdup(default_req_opts, client->req_opts_size);
2105 }
2106 if (!client->req_opts)
2107 return -ENOMEM;
2108
2109 *ret = TAKE_PTR(client);
2110
2111 return 0;
2112 }