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