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