]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/sd-dhcp-client.c
Merge pull request #13676 from ClydeByrdIII/service-result-patch
[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 assert_return(ret, -EINVAL);
552 assert_return(length == 0 || data, -EINVAL);
553
554 _cleanup_free_ void *q = memdup(data, length);
555 if (!q)
556 return -ENOMEM;
557
558 sd_dhcp_option *p = new(sd_dhcp_option, 1);
559 if (!p)
560 return -ENOMEM;
561
562 *p = (sd_dhcp_option) {
563 .n_ref = 1,
564 .option = option,
565 .length = length,
566 .data = TAKE_PTR(q),
567 };
568
569 *ret = TAKE_PTR(p);
570 return 0;
571 }
572
573 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_option, sd_dhcp_option, dhcp_option_free);
574 DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
575 dhcp_option_hash_ops,
576 void,
577 trivial_hash_func,
578 trivial_compare_func,
579 sd_dhcp_option,
580 sd_dhcp_option_unref);
581
582 int sd_dhcp_client_set_dhcp_option(sd_dhcp_client *client, sd_dhcp_option *v) {
583 int r;
584
585 assert_return(client, -EINVAL);
586 assert_return(v, -EINVAL);
587
588 r = ordered_hashmap_ensure_allocated(&client->options, &dhcp_option_hash_ops);
589 if (r < 0)
590 return r;
591
592 r = ordered_hashmap_put(client->options, UINT_TO_PTR(v->option), v);
593 if (r < 0)
594 return r;
595
596 sd_dhcp_option_ref(v);
597 return 0;
598 }
599
600 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
601 assert_return(client, -EINVAL);
602
603 if (!IN_SET(client->state, DHCP_STATE_SELECTING, DHCP_STATE_BOUND, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING))
604 return -EADDRNOTAVAIL;
605
606 if (ret)
607 *ret = client->lease;
608
609 return 0;
610 }
611
612 int sd_dhcp_client_set_service_type(sd_dhcp_client *client, int type) {
613 assert_return(client, -EINVAL);
614
615 client->ip_service_type = type;
616
617 return 0;
618 }
619
620 static int client_notify(sd_dhcp_client *client, int event) {
621 assert(client);
622
623 if (client->callback)
624 return client->callback(client, event, client->userdata);
625
626 return 0;
627 }
628
629 static int client_initialize(sd_dhcp_client *client) {
630 assert_return(client, -EINVAL);
631
632 client->receive_message = sd_event_source_unref(client->receive_message);
633
634 client->fd = asynchronous_close(client->fd);
635
636 (void) event_source_disable(client->timeout_resend);
637 (void) event_source_disable(client->timeout_t1);
638 (void) event_source_disable(client->timeout_t2);
639 (void) event_source_disable(client->timeout_expire);
640
641 client->attempt = 0;
642
643 client->state = DHCP_STATE_INIT;
644 client->xid = 0;
645
646 client->lease = sd_dhcp_lease_unref(client->lease);
647
648 return 0;
649 }
650
651 static void client_stop(sd_dhcp_client *client, int error) {
652 assert(client);
653
654 if (error < 0)
655 log_dhcp_client_errno(client, error, "STOPPED: %m");
656 else if (error == SD_DHCP_CLIENT_EVENT_STOP)
657 log_dhcp_client(client, "STOPPED");
658 else
659 log_dhcp_client(client, "STOPPED: Unknown event");
660
661 client_notify(client, error);
662
663 client_initialize(client);
664 }
665
666 static int client_message_init(
667 sd_dhcp_client *client,
668 DHCPPacket **ret,
669 uint8_t type,
670 size_t *_optlen,
671 size_t *_optoffset) {
672
673 _cleanup_free_ DHCPPacket *packet = NULL;
674 size_t optlen, optoffset, size;
675 be16_t max_size;
676 usec_t time_now;
677 uint16_t secs;
678 int r;
679
680 assert(client);
681 assert(client->start_time);
682 assert(ret);
683 assert(_optlen);
684 assert(_optoffset);
685 assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST, DHCP_RELEASE));
686
687 optlen = DHCP_MIN_OPTIONS_SIZE;
688 size = sizeof(DHCPPacket) + optlen;
689
690 packet = malloc0(size);
691 if (!packet)
692 return -ENOMEM;
693
694 r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
695 client->arp_type, optlen, &optoffset);
696 if (r < 0)
697 return r;
698
699 /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
700 refuse to issue an DHCP lease if 'secs' is set to zero */
701 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
702 if (r < 0)
703 return r;
704 assert(time_now >= client->start_time);
705
706 /* seconds between sending first and last DISCOVER
707 * must always be strictly positive to deal with broken servers */
708 secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
709 packet->dhcp.secs = htobe16(secs);
710
711 /* RFC2132 section 4.1
712 A client that cannot receive unicast IP datagrams until its protocol
713 software has been configured with an IP address SHOULD set the
714 BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
715 DHCPREQUEST messages that client sends. The BROADCAST bit will
716 provide a hint to the DHCP server and BOOTP relay agent to broadcast
717 any messages to the client on the client's subnet.
718
719 Note: some interfaces needs this to be enabled, but some networks
720 needs this to be disabled as broadcasts are filteretd, so this
721 needs to be configurable */
722 if (client->request_broadcast || client->arp_type != ARPHRD_ETHER)
723 packet->dhcp.flags = htobe16(0x8000);
724
725 /* RFC2132 section 4.1.1:
726 The client MUST include its hardware address in the ’chaddr’ field, if
727 necessary for delivery of DHCP reply messages. Non-Ethernet
728 interfaces will leave 'chaddr' empty and use the client identifier
729 instead (eg, RFC 4390 section 2.1).
730 */
731 if (client->arp_type == ARPHRD_ETHER)
732 memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN);
733
734 /* If no client identifier exists, construct an RFC 4361-compliant one */
735 if (client->client_id_len == 0) {
736 size_t duid_len;
737
738 client->client_id.type = 255;
739
740 r = dhcp_identifier_set_iaid(client->ifindex, client->mac_addr, client->mac_addr_len,
741 true, &client->client_id.ns.iaid);
742 if (r < 0)
743 return r;
744
745 r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &duid_len);
746 if (r < 0)
747 return r;
748
749 client->client_id_len = sizeof(client->client_id.type) + sizeof(client->client_id.ns.iaid) + duid_len;
750 }
751
752 /* Some DHCP servers will refuse to issue an DHCP lease if the Client
753 Identifier option is not set */
754 if (client->client_id_len) {
755 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
756 SD_DHCP_OPTION_CLIENT_IDENTIFIER,
757 client->client_id_len,
758 &client->client_id);
759 if (r < 0)
760 return r;
761 }
762
763 /* RFC2131 section 3.5:
764 in its initial DHCPDISCOVER or DHCPREQUEST message, a
765 client may provide the server with a list of specific
766 parameters the client is interested in. If the client
767 includes a list of parameters in a DHCPDISCOVER message,
768 it MUST include that list in any subsequent DHCPREQUEST
769 messages.
770 */
771
772 /* RFC7844 section 3:
773 MAY contain the Parameter Request List option. */
774 /* NOTE: in case that there would be an option to do not send
775 * any PRL at all, the size should be checked before sending */
776 if (client->req_opts_size > 0 && type != DHCP_RELEASE) {
777 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
778 SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
779 client->req_opts_size, client->req_opts);
780 if (r < 0)
781 return r;
782 }
783
784 /* RFC2131 section 3.5:
785 The client SHOULD include the ’maximum DHCP message size’ option to
786 let the server know how large the server may make its DHCP messages.
787
788 Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
789 than the defined default size unless the Maximum Message Size option
790 is explicitly set
791
792 RFC3442 "Requirements to Avoid Sizing Constraints":
793 Because a full routing table can be quite large, the standard 576
794 octet maximum size for a DHCP message may be too short to contain
795 some legitimate Classless Static Route options. Because of this,
796 clients implementing the Classless Static Route option SHOULD send a
797 Maximum DHCP Message Size [4] option if the DHCP client's TCP/IP
798 stack is capable of receiving larger IP datagrams. In this case, the
799 client SHOULD set the value of this option to at least the MTU of the
800 interface that the client is configuring. The client MAY set the
801 value of this option higher, up to the size of the largest UDP packet
802 it is prepared to accept. (Note that the value specified in the
803 Maximum DHCP Message Size option is the total maximum packet size,
804 including IP and UDP headers.)
805 */
806 /* RFC7844 section 3:
807 SHOULD NOT contain any other option. */
808 if (!client->anonymize && type != DHCP_RELEASE) {
809 max_size = htobe16(size);
810 r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
811 SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
812 2, &max_size);
813 if (r < 0)
814 return r;
815 }
816
817 *_optlen = optlen;
818 *_optoffset = optoffset;
819 *ret = TAKE_PTR(packet);
820
821 return 0;
822 }
823
824 static int client_append_fqdn_option(
825 DHCPMessage *message,
826 size_t optlen,
827 size_t *optoffset,
828 const char *fqdn) {
829
830 uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH];
831 int r;
832
833 buffer[0] = DHCP_FQDN_FLAG_S | /* Request server to perform A RR DNS updates */
834 DHCP_FQDN_FLAG_E; /* Canonical wire format */
835 buffer[1] = 0; /* RCODE1 (deprecated) */
836 buffer[2] = 0; /* RCODE2 (deprecated) */
837
838 r = dns_name_to_wire_format(fqdn, buffer + 3, sizeof(buffer) - 3, false);
839 if (r > 0)
840 r = dhcp_option_append(message, optlen, optoffset, 0,
841 SD_DHCP_OPTION_FQDN, 3 + r, buffer);
842
843 return r;
844 }
845
846 static int dhcp_client_send_raw(
847 sd_dhcp_client *client,
848 DHCPPacket *packet,
849 size_t len) {
850
851 dhcp_packet_append_ip_headers(packet, INADDR_ANY, client->port,
852 INADDR_BROADCAST, DHCP_PORT_SERVER, len, client->ip_service_type);
853
854 return dhcp_network_send_raw_socket(client->fd, &client->link,
855 packet, len);
856 }
857
858 static int client_send_discover(sd_dhcp_client *client) {
859 _cleanup_free_ DHCPPacket *discover = NULL;
860 size_t optoffset, optlen;
861 sd_dhcp_option *j;
862 Iterator i;
863 int r;
864
865 assert(client);
866 assert(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_SELECTING));
867
868 r = client_message_init(client, &discover, DHCP_DISCOVER,
869 &optlen, &optoffset);
870 if (r < 0)
871 return r;
872
873 /* the client may suggest values for the network address
874 and lease time in the DHCPDISCOVER message. The client may include
875 the ’requested IP address’ option to suggest that a particular IP
876 address be assigned, and may include the ’IP address lease time’
877 option to suggest the lease time it would like.
878 */
879 if (client->last_addr != INADDR_ANY) {
880 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
881 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
882 4, &client->last_addr);
883 if (r < 0)
884 return r;
885 }
886
887 if (client->hostname) {
888 /* According to RFC 4702 "clients that send the Client FQDN option in
889 their messages MUST NOT also send the Host Name option". Just send
890 one of the two depending on the hostname type.
891 */
892 if (dns_name_is_single_label(client->hostname)) {
893 /* it is unclear from RFC 2131 if client should send hostname in
894 DHCPDISCOVER but dhclient does and so we do as well
895 */
896 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
897 SD_DHCP_OPTION_HOST_NAME,
898 strlen(client->hostname), client->hostname);
899 } else
900 r = client_append_fqdn_option(&discover->dhcp, optlen, &optoffset,
901 client->hostname);
902 if (r < 0)
903 return r;
904 }
905
906 if (client->vendor_class_identifier) {
907 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
908 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
909 strlen(client->vendor_class_identifier),
910 client->vendor_class_identifier);
911 if (r < 0)
912 return r;
913 }
914
915 if (client->user_class) {
916 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
917 SD_DHCP_OPTION_USER_CLASS,
918 strv_length(client->user_class),
919 client->user_class);
920 if (r < 0)
921 return r;
922 }
923
924 ORDERED_HASHMAP_FOREACH(j, client->options, i) {
925 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
926 j->option, j->length, j->data);
927 if (r < 0)
928 return r;
929 }
930
931 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
932 SD_DHCP_OPTION_END, 0, NULL);
933 if (r < 0)
934 return r;
935
936 /* We currently ignore:
937 The client SHOULD wait a random time between one and ten seconds to
938 desynchronize the use of DHCP at startup.
939 */
940 r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
941 if (r < 0)
942 return r;
943
944 log_dhcp_client(client, "DISCOVER");
945
946 return 0;
947 }
948
949 static int client_send_request(sd_dhcp_client *client) {
950 _cleanup_free_ DHCPPacket *request = NULL;
951 size_t optoffset, optlen;
952 int r;
953
954 assert(client);
955
956 r = client_message_init(client, &request, DHCP_REQUEST, &optlen, &optoffset);
957 if (r < 0)
958 return r;
959
960 switch (client->state) {
961 /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
962 SELECTING should be REQUESTING)
963 */
964
965 case DHCP_STATE_REQUESTING:
966 /* Client inserts the address of the selected server in ’server
967 identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
968 filled in with the yiaddr value from the chosen DHCPOFFER.
969 */
970
971 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
972 SD_DHCP_OPTION_SERVER_IDENTIFIER,
973 4, &client->lease->server_address);
974 if (r < 0)
975 return r;
976
977 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
978 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
979 4, &client->lease->address);
980 if (r < 0)
981 return r;
982
983 break;
984
985 case DHCP_STATE_INIT_REBOOT:
986 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
987 option MUST be filled in with client’s notion of its previously
988 assigned address. ’ciaddr’ MUST be zero.
989 */
990 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
991 SD_DHCP_OPTION_REQUESTED_IP_ADDRESS,
992 4, &client->last_addr);
993 if (r < 0)
994 return r;
995 break;
996
997 case DHCP_STATE_RENEWING:
998 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
999 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1000 client’s IP address.
1001 */
1002
1003 case DHCP_STATE_REBINDING:
1004 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
1005 option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
1006 client’s IP address.
1007
1008 This message MUST be broadcast to the 0xffffffff IP broadcast address.
1009 */
1010 request->dhcp.ciaddr = client->lease->address;
1011
1012 break;
1013
1014 case DHCP_STATE_INIT:
1015 case DHCP_STATE_SELECTING:
1016 case DHCP_STATE_REBOOTING:
1017 case DHCP_STATE_BOUND:
1018 case DHCP_STATE_STOPPED:
1019 return -EINVAL;
1020 }
1021
1022 if (client->hostname) {
1023 if (dns_name_is_single_label(client->hostname))
1024 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1025 SD_DHCP_OPTION_HOST_NAME,
1026 strlen(client->hostname), client->hostname);
1027 else
1028 r = client_append_fqdn_option(&request->dhcp, optlen, &optoffset,
1029 client->hostname);
1030 if (r < 0)
1031 return r;
1032 }
1033
1034 if (client->vendor_class_identifier) {
1035 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1036 SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
1037 strlen(client->vendor_class_identifier),
1038 client->vendor_class_identifier);
1039 if (r < 0)
1040 return r;
1041 }
1042
1043 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
1044 SD_DHCP_OPTION_END, 0, NULL);
1045 if (r < 0)
1046 return r;
1047
1048 if (client->state == DHCP_STATE_RENEWING)
1049 r = dhcp_network_send_udp_socket(client->fd,
1050 client->lease->server_address,
1051 DHCP_PORT_SERVER,
1052 &request->dhcp,
1053 sizeof(DHCPMessage) + optoffset);
1054 else
1055 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
1056 if (r < 0)
1057 return r;
1058
1059 switch (client->state) {
1060
1061 case DHCP_STATE_REQUESTING:
1062 log_dhcp_client(client, "REQUEST (requesting)");
1063 break;
1064
1065 case DHCP_STATE_INIT_REBOOT:
1066 log_dhcp_client(client, "REQUEST (init-reboot)");
1067 break;
1068
1069 case DHCP_STATE_RENEWING:
1070 log_dhcp_client(client, "REQUEST (renewing)");
1071 break;
1072
1073 case DHCP_STATE_REBINDING:
1074 log_dhcp_client(client, "REQUEST (rebinding)");
1075 break;
1076
1077 default:
1078 log_dhcp_client(client, "REQUEST (invalid)");
1079 break;
1080 }
1081
1082 return 0;
1083 }
1084
1085 static int client_start(sd_dhcp_client *client);
1086
1087 static int client_timeout_resend(
1088 sd_event_source *s,
1089 uint64_t usec,
1090 void *userdata) {
1091
1092 sd_dhcp_client *client = userdata;
1093 DHCP_CLIENT_DONT_DESTROY(client);
1094 usec_t next_timeout = 0;
1095 uint64_t time_now;
1096 uint32_t time_left;
1097 int r;
1098
1099 assert(s);
1100 assert(client);
1101 assert(client->event);
1102
1103 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1104 if (r < 0)
1105 goto error;
1106
1107 switch (client->state) {
1108
1109 case DHCP_STATE_RENEWING:
1110
1111 time_left = (client->lease->t2 - client->lease->t1) / 2;
1112 if (time_left < 60)
1113 time_left = 60;
1114
1115 next_timeout = time_now + time_left * USEC_PER_SEC;
1116
1117 break;
1118
1119 case DHCP_STATE_REBINDING:
1120
1121 time_left = (client->lease->lifetime - client->lease->t2) / 2;
1122 if (time_left < 60)
1123 time_left = 60;
1124
1125 next_timeout = time_now + time_left * USEC_PER_SEC;
1126 break;
1127
1128 case DHCP_STATE_REBOOTING:
1129 /* start over as we did not receive a timely ack or nak */
1130 r = client_initialize(client);
1131 if (r < 0)
1132 goto error;
1133
1134 r = client_start(client);
1135 if (r < 0)
1136 goto error;
1137 else {
1138 log_dhcp_client(client, "REBOOTED");
1139 return 0;
1140 }
1141
1142 case DHCP_STATE_INIT:
1143 case DHCP_STATE_INIT_REBOOT:
1144 case DHCP_STATE_SELECTING:
1145 case DHCP_STATE_REQUESTING:
1146 case DHCP_STATE_BOUND:
1147
1148 if (client->attempt < client->max_attempts)
1149 client->attempt++;
1150 else
1151 goto error;
1152
1153 next_timeout = time_now + ((UINT64_C(1) << MIN(client->attempt, (uint64_t) 6)) - 1) * USEC_PER_SEC;
1154
1155 break;
1156
1157 case DHCP_STATE_STOPPED:
1158 r = -EINVAL;
1159 goto error;
1160 }
1161
1162 next_timeout += (random_u32() & 0x1fffff);
1163
1164 r = event_reset_time(client->event, &client->timeout_resend,
1165 clock_boottime_or_monotonic(),
1166 next_timeout, 10 * USEC_PER_MSEC,
1167 client_timeout_resend, client,
1168 client->event_priority, "dhcp4-resend-timer", true);
1169 if (r < 0)
1170 goto error;
1171
1172 switch (client->state) {
1173 case DHCP_STATE_INIT:
1174 r = client_send_discover(client);
1175 if (r >= 0) {
1176 client->state = DHCP_STATE_SELECTING;
1177 client->attempt = 0;
1178 } else if (client->attempt >= client->max_attempts)
1179 goto error;
1180
1181 break;
1182
1183 case DHCP_STATE_SELECTING:
1184 r = client_send_discover(client);
1185 if (r < 0 && client->attempt >= client->max_attempts)
1186 goto error;
1187
1188 break;
1189
1190 case DHCP_STATE_INIT_REBOOT:
1191 case DHCP_STATE_REQUESTING:
1192 case DHCP_STATE_RENEWING:
1193 case DHCP_STATE_REBINDING:
1194 r = client_send_request(client);
1195 if (r < 0 && client->attempt >= client->max_attempts)
1196 goto error;
1197
1198 if (client->state == DHCP_STATE_INIT_REBOOT)
1199 client->state = DHCP_STATE_REBOOTING;
1200
1201 client->request_sent = time_now;
1202
1203 break;
1204
1205 case DHCP_STATE_REBOOTING:
1206 case DHCP_STATE_BOUND:
1207
1208 break;
1209
1210 case DHCP_STATE_STOPPED:
1211 r = -EINVAL;
1212 goto error;
1213 }
1214
1215 return 0;
1216
1217 error:
1218 client_stop(client, r);
1219
1220 /* Errors were dealt with when stopping the client, don't spill
1221 errors into the event loop handler */
1222 return 0;
1223 }
1224
1225 static int client_initialize_io_events(
1226 sd_dhcp_client *client,
1227 sd_event_io_handler_t io_callback) {
1228
1229 int r;
1230
1231 assert(client);
1232 assert(client->event);
1233
1234 r = sd_event_add_io(client->event, &client->receive_message,
1235 client->fd, EPOLLIN, io_callback,
1236 client);
1237 if (r < 0)
1238 goto error;
1239
1240 r = sd_event_source_set_priority(client->receive_message,
1241 client->event_priority);
1242 if (r < 0)
1243 goto error;
1244
1245 r = sd_event_source_set_description(client->receive_message, "dhcp4-receive-message");
1246 if (r < 0)
1247 goto error;
1248
1249 error:
1250 if (r < 0)
1251 client_stop(client, r);
1252
1253 return 0;
1254 }
1255
1256 static int client_initialize_time_events(sd_dhcp_client *client) {
1257 uint64_t usec = 0;
1258 int r;
1259
1260 assert(client);
1261 assert(client->event);
1262
1263 if (client->start_delay > 0) {
1264 assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0);
1265 usec += client->start_delay;
1266 }
1267
1268 r = event_reset_time(client->event, &client->timeout_resend,
1269 clock_boottime_or_monotonic(),
1270 usec, 0,
1271 client_timeout_resend, client,
1272 client->event_priority, "dhcp4-resend-timer", true);
1273 if (r < 0)
1274 client_stop(client, r);
1275
1276 return 0;
1277
1278 }
1279
1280 static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
1281 client_initialize_io_events(client, io_callback);
1282 client_initialize_time_events(client);
1283
1284 return 0;
1285 }
1286
1287 static int client_start_delayed(sd_dhcp_client *client) {
1288 int r;
1289
1290 assert_return(client, -EINVAL);
1291 assert_return(client->event, -EINVAL);
1292 assert_return(client->ifindex > 0, -EINVAL);
1293 assert_return(client->fd < 0, -EBUSY);
1294 assert_return(client->xid == 0, -EINVAL);
1295 assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT), -EBUSY);
1296
1297 client->xid = random_u32();
1298
1299 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1300 client->xid, client->mac_addr,
1301 client->mac_addr_len, client->arp_type, client->port);
1302 if (r < 0) {
1303 client_stop(client, r);
1304 return r;
1305 }
1306 client->fd = r;
1307
1308 if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT))
1309 client->start_time = now(clock_boottime_or_monotonic());
1310
1311 return client_initialize_events(client, client_receive_message_raw);
1312 }
1313
1314 static int client_start(sd_dhcp_client *client) {
1315 client->start_delay = 0;
1316 return client_start_delayed(client);
1317 }
1318
1319 static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
1320 sd_dhcp_client *client = userdata;
1321 DHCP_CLIENT_DONT_DESTROY(client);
1322
1323 log_dhcp_client(client, "EXPIRED");
1324
1325 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1326
1327 /* lease was lost, start over if not freed or stopped in callback */
1328 if (client->state != DHCP_STATE_STOPPED) {
1329 client_initialize(client);
1330 client_start(client);
1331 }
1332
1333 return 0;
1334 }
1335
1336 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
1337 sd_dhcp_client *client = userdata;
1338 DHCP_CLIENT_DONT_DESTROY(client);
1339 int r;
1340
1341 assert(client);
1342
1343 client->receive_message = sd_event_source_unref(client->receive_message);
1344 client->fd = asynchronous_close(client->fd);
1345
1346 client->state = DHCP_STATE_REBINDING;
1347 client->attempt = 0;
1348
1349 r = dhcp_network_bind_raw_socket(client->ifindex, &client->link,
1350 client->xid, client->mac_addr,
1351 client->mac_addr_len, client->arp_type,
1352 client->port);
1353 if (r < 0) {
1354 client_stop(client, r);
1355 return 0;
1356 }
1357 client->fd = r;
1358
1359 return client_initialize_events(client, client_receive_message_raw);
1360 }
1361
1362 static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
1363 sd_dhcp_client *client = userdata;
1364 DHCP_CLIENT_DONT_DESTROY(client);
1365
1366 client->state = DHCP_STATE_RENEWING;
1367 client->attempt = 0;
1368
1369 return client_initialize_time_events(client);
1370 }
1371
1372 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
1373 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1374 int r;
1375
1376 r = dhcp_lease_new(&lease);
1377 if (r < 0)
1378 return r;
1379
1380 if (client->client_id_len) {
1381 r = dhcp_lease_set_client_id(lease,
1382 (uint8_t *) &client->client_id,
1383 client->client_id_len);
1384 if (r < 0)
1385 return r;
1386 }
1387
1388 r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease, NULL);
1389 if (r != DHCP_OFFER) {
1390 log_dhcp_client(client, "received message was not an OFFER, ignoring");
1391 return -ENOMSG;
1392 }
1393
1394 lease->next_server = offer->siaddr;
1395 lease->address = offer->yiaddr;
1396
1397 if (lease->address == 0 ||
1398 lease->server_address == 0 ||
1399 lease->lifetime == 0) {
1400 log_dhcp_client(client, "received lease lacks address, server address or lease lifetime, ignoring");
1401 return -ENOMSG;
1402 }
1403
1404 if (!lease->have_subnet_mask) {
1405 r = dhcp_lease_set_default_subnet_mask(lease);
1406 if (r < 0) {
1407 log_dhcp_client(client,
1408 "received lease lacks subnet mask, "
1409 "and a fallback one cannot be generated, ignoring");
1410 return -ENOMSG;
1411 }
1412 }
1413
1414 sd_dhcp_lease_unref(client->lease);
1415 client->lease = TAKE_PTR(lease);
1416
1417 if (client_notify(client, SD_DHCP_CLIENT_EVENT_SELECTING) < 0)
1418 return -ENOMSG;
1419
1420 log_dhcp_client(client, "OFFER");
1421
1422 return 0;
1423 }
1424
1425 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
1426 int r;
1427
1428 r = dhcp_option_parse(force, len, NULL, NULL, NULL);
1429 if (r != DHCP_FORCERENEW)
1430 return -ENOMSG;
1431
1432 log_dhcp_client(client, "FORCERENEW");
1433
1434 return 0;
1435 }
1436
1437 static bool lease_equal(const sd_dhcp_lease *a, const sd_dhcp_lease *b) {
1438 if (a->address != b->address)
1439 return false;
1440
1441 if (a->subnet_mask != b->subnet_mask)
1442 return false;
1443
1444 if (a->router_size != b->router_size)
1445 return false;
1446
1447 for (size_t i = 0; i < a->router_size; i++)
1448 if (a->router[i].s_addr != b->router[i].s_addr)
1449 return false;
1450
1451 return true;
1452 }
1453
1454 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
1455 _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
1456 _cleanup_free_ char *error_message = NULL;
1457 int r;
1458
1459 r = dhcp_lease_new(&lease);
1460 if (r < 0)
1461 return r;
1462
1463 if (client->client_id_len) {
1464 r = dhcp_lease_set_client_id(lease,
1465 (uint8_t *) &client->client_id,
1466 client->client_id_len);
1467 if (r < 0)
1468 return r;
1469 }
1470
1471 r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease, &error_message);
1472 if (r == DHCP_NAK) {
1473 log_dhcp_client(client, "NAK: %s", strna(error_message));
1474 return -EADDRNOTAVAIL;
1475 }
1476
1477 if (r != DHCP_ACK) {
1478 log_dhcp_client(client, "received message was not an ACK, ignoring");
1479 return -ENOMSG;
1480 }
1481
1482 lease->next_server = ack->siaddr;
1483
1484 lease->address = ack->yiaddr;
1485
1486 if (lease->address == INADDR_ANY ||
1487 lease->server_address == INADDR_ANY ||
1488 lease->lifetime == 0) {
1489 log_dhcp_client(client, "received lease lacks address, server "
1490 "address or lease lifetime, ignoring");
1491 return -ENOMSG;
1492 }
1493
1494 if (lease->subnet_mask == INADDR_ANY) {
1495 r = dhcp_lease_set_default_subnet_mask(lease);
1496 if (r < 0) {
1497 log_dhcp_client(client,
1498 "received lease lacks subnet mask, "
1499 "and a fallback one cannot be generated, ignoring");
1500 return -ENOMSG;
1501 }
1502 }
1503
1504 r = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1505 if (client->lease) {
1506 if (lease_equal(client->lease, lease))
1507 r = SD_DHCP_CLIENT_EVENT_RENEW;
1508 else
1509 r = SD_DHCP_CLIENT_EVENT_IP_CHANGE;
1510
1511 client->lease = sd_dhcp_lease_unref(client->lease);
1512 }
1513
1514 client->lease = TAKE_PTR(lease);
1515
1516 log_dhcp_client(client, "ACK");
1517
1518 return r;
1519 }
1520
1521 static uint64_t client_compute_timeout(sd_dhcp_client *client, uint32_t lifetime, double factor) {
1522 assert(client);
1523 assert(client->request_sent);
1524 assert(lifetime > 0);
1525
1526 if (lifetime > 3)
1527 lifetime -= 3;
1528 else
1529 lifetime = 0;
1530
1531 return client->request_sent + (lifetime * USEC_PER_SEC * factor) +
1532 + (random_u32() & 0x1fffff);
1533 }
1534
1535 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1536 usec_t time_now;
1537 uint64_t lifetime_timeout;
1538 uint64_t t2_timeout;
1539 uint64_t t1_timeout;
1540 char time_string[FORMAT_TIMESPAN_MAX];
1541 int r;
1542
1543 assert(client);
1544 assert(client->event);
1545 assert(client->lease);
1546 assert(client->lease->lifetime);
1547
1548 /* don't set timers for infinite leases */
1549 if (client->lease->lifetime == 0xffffffff) {
1550 (void) event_source_disable(client->timeout_t1);
1551 (void) event_source_disable(client->timeout_t2);
1552 (void) event_source_disable(client->timeout_expire);
1553
1554 return 0;
1555 }
1556
1557 r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1558 if (r < 0)
1559 return r;
1560 assert(client->request_sent <= time_now);
1561
1562 /* convert the various timeouts from relative (secs) to absolute (usecs) */
1563 lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1564 if (client->lease->t1 > 0 && client->lease->t2 > 0) {
1565 /* both T1 and T2 are given */
1566 if (client->lease->t1 < client->lease->t2 &&
1567 client->lease->t2 < client->lease->lifetime) {
1568 /* they are both valid */
1569 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1570 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1571 } else {
1572 /* discard both */
1573 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1574 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1575 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1576 client->lease->t1 = client->lease->lifetime / 2;
1577 }
1578 } else if (client->lease->t2 > 0 && client->lease->t2 < client->lease->lifetime) {
1579 /* only T2 is given, and it is valid */
1580 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1581 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1582 client->lease->t1 = client->lease->lifetime / 2;
1583 if (t2_timeout <= t1_timeout) {
1584 /* the computed T1 would be invalid, so discard T2 */
1585 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1586 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1587 }
1588 } else if (client->lease->t1 > 0 && client->lease->t1 < client->lease->lifetime) {
1589 /* only T1 is given, and it is valid */
1590 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1591 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1592 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1593 if (t2_timeout <= t1_timeout) {
1594 /* the computed T2 would be invalid, so discard T1 */
1595 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1596 client->lease->t2 = client->lease->lifetime / 2;
1597 }
1598 } else {
1599 /* fall back to the default timeouts */
1600 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1601 client->lease->t1 = client->lease->lifetime / 2;
1602 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1603 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1604 }
1605
1606 /* arm lifetime timeout */
1607 r = event_reset_time(client->event, &client->timeout_expire,
1608 clock_boottime_or_monotonic(),
1609 lifetime_timeout, 10 * USEC_PER_MSEC,
1610 client_timeout_expire, client,
1611 client->event_priority, "dhcp4-lifetime", true);
1612 if (r < 0)
1613 return r;
1614
1615 log_dhcp_client(client, "lease expires in %s",
1616 format_timespan(time_string, FORMAT_TIMESPAN_MAX, lifetime_timeout - time_now, USEC_PER_SEC));
1617
1618 /* don't arm earlier timeouts if this has already expired */
1619 if (lifetime_timeout <= time_now)
1620 return 0;
1621
1622 /* arm T2 timeout */
1623 r = event_reset_time(client->event, &client->timeout_t2,
1624 clock_boottime_or_monotonic(),
1625 t2_timeout, 10 * USEC_PER_MSEC,
1626 client_timeout_t2, client,
1627 client->event_priority, "dhcp4-t2-timeout", true);
1628 if (r < 0)
1629 return r;
1630
1631 log_dhcp_client(client, "T2 expires in %s",
1632 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t2_timeout - time_now, USEC_PER_SEC));
1633
1634 /* don't arm earlier timeout if this has already expired */
1635 if (t2_timeout <= time_now)
1636 return 0;
1637
1638 /* arm T1 timeout */
1639 r = event_reset_time(client->event, &client->timeout_t1,
1640 clock_boottime_or_monotonic(),
1641 t1_timeout, 10 * USEC_PER_MSEC,
1642 client_timeout_t1, client,
1643 client->event_priority, "dhcp4-t1-timer", true);
1644 if (r < 0)
1645 return r;
1646
1647 log_dhcp_client(client, "T1 expires in %s",
1648 format_timespan(time_string, FORMAT_TIMESPAN_MAX, t1_timeout - time_now, USEC_PER_SEC));
1649
1650 return 0;
1651 }
1652
1653 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
1654 DHCP_CLIENT_DONT_DESTROY(client);
1655 char time_string[FORMAT_TIMESPAN_MAX];
1656 int r = 0, notify_event = 0;
1657
1658 assert(client);
1659 assert(client->event);
1660 assert(message);
1661
1662 switch (client->state) {
1663 case DHCP_STATE_SELECTING:
1664
1665 r = client_handle_offer(client, message, len);
1666 if (r >= 0) {
1667
1668 client->state = DHCP_STATE_REQUESTING;
1669 client->attempt = 0;
1670
1671 r = event_reset_time(client->event, &client->timeout_resend,
1672 clock_boottime_or_monotonic(),
1673 0, 0,
1674 client_timeout_resend, client,
1675 client->event_priority, "dhcp4-resend-timer", true);
1676 if (r < 0)
1677 goto error;
1678 } else if (r == -ENOMSG)
1679 /* invalid message, let's ignore it */
1680 return 0;
1681
1682 break;
1683
1684 case DHCP_STATE_REBOOTING:
1685 case DHCP_STATE_REQUESTING:
1686 case DHCP_STATE_RENEWING:
1687 case DHCP_STATE_REBINDING:
1688
1689 r = client_handle_ack(client, message, len);
1690 if (r >= 0) {
1691 client->start_delay = 0;
1692 (void) event_source_disable(client->timeout_resend);
1693 client->receive_message =
1694 sd_event_source_unref(client->receive_message);
1695 client->fd = asynchronous_close(client->fd);
1696
1697 if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1698 DHCP_STATE_REBOOTING))
1699 notify_event = SD_DHCP_CLIENT_EVENT_IP_ACQUIRE;
1700 else if (r != SD_DHCP_CLIENT_EVENT_IP_ACQUIRE)
1701 notify_event = r;
1702
1703 client->state = DHCP_STATE_BOUND;
1704 client->attempt = 0;
1705
1706 client->last_addr = client->lease->address;
1707
1708 r = client_set_lease_timeouts(client);
1709 if (r < 0) {
1710 log_dhcp_client(client, "could not set lease timeouts");
1711 goto error;
1712 }
1713
1714 r = dhcp_network_bind_udp_socket(client->ifindex, client->lease->address, client->port, client->ip_service_type);
1715 if (r < 0) {
1716 log_dhcp_client(client, "could not bind UDP socket");
1717 goto error;
1718 }
1719
1720 client->fd = r;
1721
1722 client_initialize_io_events(client, client_receive_message_udp);
1723
1724 if (notify_event) {
1725 client_notify(client, notify_event);
1726 if (client->state == DHCP_STATE_STOPPED)
1727 return 0;
1728 }
1729
1730 } else if (r == -EADDRNOTAVAIL) {
1731 /* got a NAK, let's restart the client */
1732 client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED);
1733
1734 r = client_initialize(client);
1735 if (r < 0)
1736 goto error;
1737
1738 r = client_start_delayed(client);
1739 if (r < 0)
1740 goto error;
1741
1742 log_dhcp_client(client, "REBOOT in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1743 client->start_delay, USEC_PER_SEC));
1744
1745 client->start_delay = CLAMP(client->start_delay * 2,
1746 RESTART_AFTER_NAK_MIN_USEC, RESTART_AFTER_NAK_MAX_USEC);
1747
1748 return 0;
1749 } else if (r == -ENOMSG)
1750 /* invalid message, let's ignore it */
1751 return 0;
1752
1753 break;
1754
1755 case DHCP_STATE_BOUND:
1756 r = client_handle_forcerenew(client, message, len);
1757 if (r >= 0) {
1758 r = client_timeout_t1(NULL, 0, client);
1759 if (r < 0)
1760 goto error;
1761 } else if (r == -ENOMSG)
1762 /* invalid message, let's ignore it */
1763 return 0;
1764
1765 break;
1766
1767 case DHCP_STATE_INIT:
1768 case DHCP_STATE_INIT_REBOOT:
1769
1770 break;
1771
1772 case DHCP_STATE_STOPPED:
1773 r = -EINVAL;
1774 goto error;
1775 }
1776
1777 error:
1778 if (r < 0)
1779 client_stop(client, r);
1780
1781 return r;
1782 }
1783
1784 static int client_receive_message_udp(
1785 sd_event_source *s,
1786 int fd,
1787 uint32_t revents,
1788 void *userdata) {
1789
1790 sd_dhcp_client *client = userdata;
1791 _cleanup_free_ DHCPMessage *message = NULL;
1792 const uint8_t *expected_chaddr = NULL;
1793 uint8_t expected_hlen = 0;
1794 ssize_t len, buflen;
1795
1796 assert(s);
1797 assert(client);
1798
1799 buflen = next_datagram_size_fd(fd);
1800 if (buflen == -ENETDOWN) {
1801 /* the link is down. Don't return an error or the I/O event
1802 source will be disconnected and we won't be able to receive
1803 packets again when the link comes back. */
1804 return 0;
1805 }
1806 if (buflen < 0)
1807 return buflen;
1808
1809 message = malloc0(buflen);
1810 if (!message)
1811 return -ENOMEM;
1812
1813 len = recv(fd, message, buflen, 0);
1814 if (len < 0) {
1815 /* see comment above for why we shouldn't error out on ENETDOWN. */
1816 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1817 return 0;
1818
1819 return log_dhcp_client_errno(client, errno,
1820 "Could not receive message from UDP socket: %m");
1821 }
1822 if ((size_t) len < sizeof(DHCPMessage)) {
1823 log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
1824 return 0;
1825 }
1826
1827 if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1828 log_dhcp_client(client, "Not a DHCP message: ignoring");
1829 return 0;
1830 }
1831
1832 if (message->op != BOOTREPLY) {
1833 log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
1834 return 0;
1835 }
1836
1837 if (message->htype != client->arp_type) {
1838 log_dhcp_client(client, "Packet type does not match client type");
1839 return 0;
1840 }
1841
1842 if (client->arp_type == ARPHRD_ETHER) {
1843 expected_hlen = ETH_ALEN;
1844 expected_chaddr = &client->mac_addr[0];
1845 }
1846
1847 if (message->hlen != expected_hlen) {
1848 log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
1849 return 0;
1850 }
1851
1852 if (expected_hlen > 0 && memcmp(&message->chaddr[0], expected_chaddr, expected_hlen)) {
1853 log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
1854 return 0;
1855 }
1856
1857 if (client->state != DHCP_STATE_BOUND &&
1858 be32toh(message->xid) != client->xid) {
1859 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1860 so ignore the xid in this case */
1861 log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
1862 be32toh(message->xid), client->xid);
1863 return 0;
1864 }
1865
1866 return client_handle_message(client, message, len);
1867 }
1868
1869 static int client_receive_message_raw(
1870 sd_event_source *s,
1871 int fd,
1872 uint32_t revents,
1873 void *userdata) {
1874
1875 sd_dhcp_client *client = userdata;
1876 _cleanup_free_ DHCPPacket *packet = NULL;
1877 uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1878 struct iovec iov = {};
1879 struct msghdr msg = {
1880 .msg_iov = &iov,
1881 .msg_iovlen = 1,
1882 .msg_control = cmsgbuf,
1883 .msg_controllen = sizeof(cmsgbuf),
1884 };
1885 struct cmsghdr *cmsg;
1886 bool checksum = true;
1887 ssize_t buflen, len;
1888 int r;
1889
1890 assert(s);
1891 assert(client);
1892
1893 buflen = next_datagram_size_fd(fd);
1894 if (buflen == -ENETDOWN)
1895 return 0;
1896 if (buflen < 0)
1897 return buflen;
1898
1899 packet = malloc0(buflen);
1900 if (!packet)
1901 return -ENOMEM;
1902
1903 iov = IOVEC_MAKE(packet, buflen);
1904
1905 len = recvmsg(fd, &msg, 0);
1906 if (len < 0) {
1907 if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
1908 return 0;
1909
1910 return log_dhcp_client_errno(client, errno,
1911 "Could not receive message from raw socket: %m");
1912 } else if ((size_t)len < sizeof(DHCPPacket))
1913 return 0;
1914
1915 CMSG_FOREACH(cmsg, &msg)
1916 if (cmsg->cmsg_level == SOL_PACKET &&
1917 cmsg->cmsg_type == PACKET_AUXDATA &&
1918 cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1919 struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1920
1921 checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1922 break;
1923 }
1924
1925 r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
1926 if (r < 0)
1927 return 0;
1928
1929 len -= DHCP_IP_UDP_SIZE;
1930
1931 return client_handle_message(client, &packet->dhcp, len);
1932 }
1933
1934 int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
1935 assert_return(client, -EINVAL);
1936 assert_return(client->fd >= 0, -EINVAL);
1937
1938 client->start_delay = 0;
1939 client->attempt = 1;
1940 client->state = DHCP_STATE_RENEWING;
1941
1942 return client_initialize_time_events(client);
1943 }
1944
1945 int sd_dhcp_client_start(sd_dhcp_client *client) {
1946 int r;
1947
1948 assert_return(client, -EINVAL);
1949
1950 r = client_initialize(client);
1951 if (r < 0)
1952 return r;
1953
1954 /* RFC7844 section 3.3:
1955 SHOULD perform a complete four-way handshake, starting with a
1956 DHCPDISCOVER, to obtain a new address lease. If the client can
1957 ascertain that this is exactly the same network to which it was
1958 previously connected, and if the link-layer address did not change,
1959 the client MAY issue a DHCPREQUEST to try to reclaim the current
1960 address. */
1961 if (client->last_addr && !client->anonymize)
1962 client->state = DHCP_STATE_INIT_REBOOT;
1963
1964 r = client_start(client);
1965 if (r >= 0)
1966 log_dhcp_client(client, "STARTED on ifindex %i", client->ifindex);
1967
1968 return r;
1969 }
1970
1971 int sd_dhcp_client_send_release(sd_dhcp_client *client) {
1972 assert_return(client, -EINVAL);
1973 assert_return(client->state != DHCP_STATE_STOPPED, -ESTALE);
1974 assert_return(client->lease, -EUNATCH);
1975
1976 _cleanup_free_ DHCPPacket *release = NULL;
1977 size_t optoffset, optlen;
1978 int r;
1979
1980 r = client_message_init(client, &release, DHCP_RELEASE, &optlen, &optoffset);
1981 if (r < 0)
1982 return r;
1983
1984 /* Fill up release IP and MAC */
1985 release->dhcp.ciaddr = client->lease->address;
1986 memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
1987
1988 r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
1989 SD_DHCP_OPTION_END, 0, NULL);
1990 if (r < 0)
1991 return r;
1992
1993 r = dhcp_network_send_udp_socket(client->fd,
1994 client->lease->server_address,
1995 DHCP_PORT_SERVER,
1996 &release->dhcp,
1997 sizeof(DHCPMessage) + optoffset);
1998 if (r < 0)
1999 return r;
2000
2001 log_dhcp_client(client, "RELEASE");
2002
2003 return 0;
2004 }
2005
2006 int sd_dhcp_client_stop(sd_dhcp_client *client) {
2007 DHCP_CLIENT_DONT_DESTROY(client);
2008
2009 assert_return(client, -EINVAL);
2010
2011 client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
2012 client->state = DHCP_STATE_STOPPED;
2013
2014 return 0;
2015 }
2016
2017 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority) {
2018 int r;
2019
2020 assert_return(client, -EINVAL);
2021 assert_return(!client->event, -EBUSY);
2022
2023 if (event)
2024 client->event = sd_event_ref(event);
2025 else {
2026 r = sd_event_default(&client->event);
2027 if (r < 0)
2028 return 0;
2029 }
2030
2031 client->event_priority = priority;
2032
2033 return 0;
2034 }
2035
2036 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
2037 assert_return(client, -EINVAL);
2038
2039 client->event = sd_event_unref(client->event);
2040
2041 return 0;
2042 }
2043
2044 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
2045 assert_return(client, NULL);
2046
2047 return client->event;
2048 }
2049
2050 static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
2051 if (!client)
2052 return NULL;
2053
2054 log_dhcp_client(client, "FREE");
2055
2056 client->timeout_resend = sd_event_source_unref(client->timeout_resend);
2057 client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
2058 client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
2059 client->timeout_expire = sd_event_source_unref(client->timeout_expire);
2060
2061 client_initialize(client);
2062
2063 sd_dhcp_client_detach_event(client);
2064
2065 sd_dhcp_lease_unref(client->lease);
2066
2067 free(client->req_opts);
2068 free(client->hostname);
2069 free(client->vendor_class_identifier);
2070 client->user_class = strv_free(client->user_class);
2071 ordered_hashmap_free(client->options);
2072 return mfree(client);
2073 }
2074
2075 DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
2076
2077 int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
2078 assert_return(ret, -EINVAL);
2079
2080 _cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = new(sd_dhcp_client, 1);
2081 if (!client)
2082 return -ENOMEM;
2083
2084 *client = (sd_dhcp_client) {
2085 .n_ref = 1,
2086 .state = DHCP_STATE_INIT,
2087 .ifindex = -1,
2088 .fd = -1,
2089 .mtu = DHCP_DEFAULT_MIN_SIZE,
2090 .port = DHCP_PORT_CLIENT,
2091 .anonymize = !!anonymize,
2092 .max_attempts = (uint64_t) -1,
2093 .ip_service_type = -1,
2094 };
2095 /* NOTE: this could be moved to a function. */
2096 if (anonymize) {
2097 client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
2098 client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
2099 } else {
2100 client->req_opts_size = ELEMENTSOF(default_req_opts);
2101 client->req_opts = memdup(default_req_opts, client->req_opts_size);
2102 }
2103 if (!client->req_opts)
2104 return -ENOMEM;
2105
2106 *ret = TAKE_PTR(client);
2107
2108 return 0;
2109 }