chiark / gitweb /
networkd: dhcp add vendor class indentifier option 60
[elogind.git] / src / libsystemd-network / sd-dhcp-client.c
1 /***
2   This file is part of systemd.
3
4   Copyright (C) 2013 Intel Corporation. All rights reserved.
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <net/ethernet.h>
25 #include <net/if_arp.h>
26 #include <netinet/ether.h>
27 #include <sys/param.h>
28 #include <sys/ioctl.h>
29
30 #include "util.h"
31 #include "list.h"
32 #include "refcnt.h"
33 #include "async.h"
34
35 #include "dhcp-protocol.h"
36 #include "dhcp-internal.h"
37 #include "dhcp-lease-internal.h"
38 #include "sd-dhcp-client.h"
39
40 struct sd_dhcp_client {
41         RefCount n_ref;
42
43         DHCPState state;
44         sd_event *event;
45         int event_priority;
46         sd_event_source *timeout_resend;
47         int index;
48         int fd;
49         union sockaddr_union link;
50         sd_event_source *receive_message;
51         uint8_t *req_opts;
52         size_t req_opts_allocated;
53         size_t req_opts_size;
54         be32_t last_addr;
55         struct {
56                 uint8_t type;
57                 struct ether_addr mac_addr;
58         } _packed_ client_id;
59         char *hostname;
60         char *vendor_class_identifier;
61         uint32_t xid;
62         usec_t start_time;
63         uint16_t secs;
64         unsigned int attempt;
65         usec_t request_sent;
66         sd_event_source *timeout_t1;
67         sd_event_source *timeout_t2;
68         sd_event_source *timeout_expire;
69         sd_dhcp_client_cb_t cb;
70         void *userdata;
71         sd_dhcp_lease *lease;
72 };
73
74 static const uint8_t default_req_opts[] = {
75         DHCP_OPTION_SUBNET_MASK,
76         DHCP_OPTION_ROUTER,
77         DHCP_OPTION_HOST_NAME,
78         DHCP_OPTION_DOMAIN_NAME,
79         DHCP_OPTION_DOMAIN_NAME_SERVER,
80         DHCP_OPTION_NTP_SERVER,
81 };
82
83 static int client_receive_message_raw(sd_event_source *s, int fd,
84                                       uint32_t revents, void *userdata);
85 static int client_receive_message_udp(sd_event_source *s, int fd,
86                                       uint32_t revents, void *userdata);
87 static void client_stop(sd_dhcp_client *client, int error);
88
89 int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
90                                 void *userdata) {
91         assert_return(client, -EINVAL);
92
93         client->cb = cb;
94         client->userdata = userdata;
95
96         return 0;
97 }
98
99 int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
100         size_t i;
101
102         assert_return(client, -EINVAL);
103         assert_return (IN_SET(client->state, DHCP_STATE_INIT,
104                               DHCP_STATE_STOPPED), -EBUSY);
105
106         switch(option) {
107         case DHCP_OPTION_PAD:
108         case DHCP_OPTION_OVERLOAD:
109         case DHCP_OPTION_MESSAGE_TYPE:
110         case DHCP_OPTION_PARAMETER_REQUEST_LIST:
111         case DHCP_OPTION_END:
112                 return -EINVAL;
113
114         default:
115                 break;
116         }
117
118         for (i = 0; i < client->req_opts_size; i++)
119                 if (client->req_opts[i] == option)
120                         return -EEXIST;
121
122         if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
123                             client->req_opts_size + 1))
124                 return -ENOMEM;
125
126         client->req_opts[client->req_opts_size++] = option;
127
128         return 0;
129 }
130
131 int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
132                                        const struct in_addr *last_addr) {
133         assert_return(client, -EINVAL);
134         assert_return (IN_SET(client->state, DHCP_STATE_INIT,
135                               DHCP_STATE_STOPPED), -EBUSY);
136
137         if (last_addr)
138                 client->last_addr = last_addr->s_addr;
139         else
140                 client->last_addr = INADDR_ANY;
141
142         return 0;
143 }
144
145 int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
146         assert_return(client, -EINVAL);
147         assert_return (IN_SET(client->state, DHCP_STATE_INIT,
148                               DHCP_STATE_STOPPED), -EBUSY);
149         assert_return(interface_index > 0, -EINVAL);
150
151         client->index = interface_index;
152
153         return 0;
154 }
155
156 int sd_dhcp_client_set_mac(sd_dhcp_client *client,
157                            const struct ether_addr *addr) {
158         DHCP_CLIENT_DONT_DESTROY(client);
159         bool need_restart = false;
160
161         assert_return(client, -EINVAL);
162         assert_return(addr, -EINVAL);
163
164         if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0)
165                 return 0;
166
167         if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
168                 log_dhcp_client(client, "Changing MAC address on running DHCP "
169                                 "client, restarting");
170                 need_restart = true;
171                 client_stop(client, DHCP_EVENT_STOP);
172         }
173
174         memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
175         client->client_id.type = 0x01;
176
177         if (need_restart && client->state != DHCP_STATE_STOPPED)
178                 sd_dhcp_client_start(client);
179
180         return 0;
181 }
182
183 int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
184                                 const char *hostname) {
185         char *new_hostname = NULL;
186
187         assert_return(client, -EINVAL);
188
189         if (streq_ptr(client->hostname, hostname))
190                 return 0;
191
192         if (hostname) {
193                 new_hostname = strdup(hostname);
194                 if (!new_hostname)
195                         return -ENOMEM;
196         }
197
198         free(client->hostname);
199         client->hostname = new_hostname;
200
201         return 0;
202 }
203
204 int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
205                                                const char *vci) {
206         char *new_vci = NULL;
207
208         assert_return(client, -EINVAL);
209
210         new_vci = strdup(vci);
211         if (!new_vci)
212                 return -ENOMEM;
213
214         free(client->vendor_class_identifier);
215
216         client->vendor_class_identifier = new_vci;
217
218         return 0;
219 }
220
221 int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
222         assert_return(client, -EINVAL);
223         assert_return(ret, -EINVAL);
224
225         if (client->state != DHCP_STATE_BOUND &&
226             client->state != DHCP_STATE_RENEWING &&
227             client->state != DHCP_STATE_REBINDING)
228                 return -EADDRNOTAVAIL;
229
230         *ret = sd_dhcp_lease_ref(client->lease);
231
232         return 0;
233 }
234
235 static void client_notify(sd_dhcp_client *client, int event) {
236         if (client->cb)
237                 client->cb(client, event, client->userdata);
238 }
239
240 static int client_initialize(sd_dhcp_client *client) {
241         assert_return(client, -EINVAL);
242
243         client->receive_message =
244                 sd_event_source_unref(client->receive_message);
245
246         client->fd = asynchronous_close(client->fd);
247
248         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
249
250         client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
251         client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
252         client->timeout_expire = sd_event_source_unref(client->timeout_expire);
253
254         client->attempt = 1;
255
256         client->state = DHCP_STATE_INIT;
257         client->xid = 0;
258
259         if (client->lease)
260                 client->lease = sd_dhcp_lease_unref(client->lease);
261
262         return 0;
263 }
264
265 static void client_stop(sd_dhcp_client *client, int error) {
266         assert(client);
267
268         if (error < 0)
269                 log_dhcp_client(client, "STOPPED: %s", strerror(-error));
270         else {
271                 switch(error) {
272                 case DHCP_EVENT_STOP:
273                         log_dhcp_client(client, "STOPPED");
274                         break;
275                 case DHCP_EVENT_NO_LEASE:
276                         log_dhcp_client(client, "STOPPED: No lease");
277                         break;
278                 default:
279                         log_dhcp_client(client, "STOPPED: Unknown reason");
280                         break;
281                 }
282         }
283
284         client_notify(client, error);
285
286         client_initialize(client);
287 }
288
289 static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
290                                uint8_t type, size_t *_optlen, size_t *_optoffset) {
291         _cleanup_free_ DHCPPacket *packet;
292         size_t optlen, optoffset, size;
293         be16_t max_size;
294         int r;
295
296         assert(client);
297         assert(client->secs);
298         assert(ret);
299         assert(_optlen);
300         assert(_optoffset);
301         assert(type == DHCP_DISCOVER || type == DHCP_REQUEST);
302
303         optlen = DHCP_MIN_OPTIONS_SIZE;
304         size = sizeof(DHCPPacket) + optlen;
305
306         packet = malloc0(size);
307         if (!packet)
308                 return -ENOMEM;
309
310         r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type,
311                               optlen, &optoffset);
312         if (r < 0)
313                 return r;
314
315         /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP servers
316            refuse to issue an DHCP lease if 'secs' is set to zero */
317         packet->dhcp.secs = htobe16(client->secs);
318
319         /* RFC2132 section 4.1
320            A client that cannot receive unicast IP datagrams until its protocol
321            software has been configured with an IP address SHOULD set the
322            BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or
323            DHCPREQUEST messages that client sends.  The BROADCAST bit will
324            provide a hint to the DHCP server and BOOTP relay agent to broadcast
325            any messages to the client on the client's subnet. */
326         packet->dhcp.flags = htobe16(0x8000);
327
328         /* RFC2132 section 4.1.1:
329            The client MUST include its hardware address in the ’chaddr’ field, if
330            necessary for delivery of DHCP reply messages.
331          */
332         memcpy(&packet->dhcp.chaddr, &client->client_id.mac_addr, ETH_ALEN);
333
334         /* Some DHCP servers will refuse to issue an DHCP lease if the Client
335            Identifier option is not set */
336         r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
337                                DHCP_OPTION_CLIENT_IDENTIFIER,
338                                sizeof(client->client_id), &client->client_id);
339         if (r < 0)
340                 return r;
341
342
343         /* RFC2131 section 3.5:
344            in its initial DHCPDISCOVER or DHCPREQUEST message, a
345            client may provide the server with a list of specific
346            parameters the client is interested in. If the client
347            includes a list of parameters in a DHCPDISCOVER message,
348            it MUST include that list in any subsequent DHCPREQUEST
349            messages.
350          */
351         r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
352                                DHCP_OPTION_PARAMETER_REQUEST_LIST,
353                                client->req_opts_size, client->req_opts);
354         if (r < 0)
355                 return r;
356
357         /* RFC2131 section 3.5:
358            The client SHOULD include the ’maximum DHCP message size’ option to
359            let the server know how large the server may make its DHCP messages.
360
361            Note (from ConnMan): Some DHCP servers will send bigger DHCP packets
362            than the defined default size unless the Maximum Messge Size option
363            is explicitely set
364          */
365         max_size = htobe16(size);
366         r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
367                                DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
368                                2, &max_size);
369         if (r < 0)
370                 return r;
371
372         *_optlen = optlen;
373         *_optoffset = optoffset;
374         *ret = packet;
375         packet = NULL;
376
377         return 0;
378 }
379
380 static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
381                                 size_t len) {
382         dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
383                                       INADDR_BROADCAST, DHCP_PORT_SERVER, len);
384
385         return dhcp_network_send_raw_socket(client->fd, &client->link,
386                                             packet, len);
387 }
388
389 static int client_send_discover(sd_dhcp_client *client) {
390         _cleanup_free_ DHCPPacket *discover = NULL;
391         size_t optoffset, optlen;
392         usec_t time_now;
393         int r;
394
395         assert(client);
396         assert(client->state == DHCP_STATE_INIT ||
397                client->state == DHCP_STATE_SELECTING);
398
399         /* See RFC2131 section 4.4.1 */
400
401         r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now);
402         if (r < 0)
403                 return r;
404         assert(time_now >= client->start_time);
405
406         /* seconds between sending first and last DISCOVER
407          * must always be strictly positive to deal with broken servers */
408         client->secs = ((time_now - client->start_time) / USEC_PER_SEC) ? : 1;
409
410         r = client_message_init(client, &discover, DHCP_DISCOVER,
411                                 &optlen, &optoffset);
412         if (r < 0)
413                 return r;
414
415         /* the client may suggest values for the network address
416            and lease time in the DHCPDISCOVER message. The client may include
417            the ’requested IP address’ option to suggest that a particular IP
418            address be assigned, and may include the ’IP address lease time’
419            option to suggest the lease time it would like.
420          */
421         if (client->last_addr != INADDR_ANY) {
422                 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
423                                        DHCP_OPTION_REQUESTED_IP_ADDRESS,
424                                        4, &client->last_addr);
425                 if (r < 0)
426                         return r;
427         }
428
429         /* it is unclear from RFC 2131 if client should send hostname in
430            DHCPDISCOVER but dhclient does and so we do as well
431         */
432         if (client->hostname) {
433                 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
434                                        DHCP_OPTION_HOST_NAME,
435                                        strlen(client->hostname), client->hostname);
436                 if (r < 0)
437                         return r;
438         }
439
440         if (client->vendor_class_identifier) {
441                 r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
442                                        DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
443                                        strlen(client->vendor_class_identifier),
444                                        client->vendor_class_identifier);
445                 if (r < 0)
446                         return r;
447         }
448
449         r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
450                                DHCP_OPTION_END, 0, NULL);
451         if (r < 0)
452                 return r;
453
454         /* We currently ignore:
455            The client SHOULD wait a random time between one and ten seconds to
456            desynchronize the use of DHCP at startup.
457          */
458         r = dhcp_client_send_raw(client, discover, sizeof(DHCPPacket) + optoffset);
459         if (r < 0)
460                 return r;
461
462         log_dhcp_client(client, "DISCOVER");
463
464         return 0;
465 }
466
467 static int client_send_request(sd_dhcp_client *client) {
468         _cleanup_free_ DHCPPacket *request = NULL;
469         size_t optoffset, optlen;
470         int r;
471
472         r = client_message_init(client, &request, DHCP_REQUEST,
473                                 &optlen, &optoffset);
474         if (r < 0)
475                 return r;
476
477         switch (client->state) {
478         /* See RFC2131 section 4.3.2 (note that there is a typo in the RFC,
479            SELECTING should be REQUESTING)
480          */
481
482         case DHCP_STATE_REQUESTING:
483                 /* Client inserts the address of the selected server in ’server
484                    identifier’, ’ciaddr’ MUST be zero, ’requested IP address’ MUST be
485                    filled in with the yiaddr value from the chosen DHCPOFFER.
486                  */
487
488                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
489                                        DHCP_OPTION_SERVER_IDENTIFIER,
490                                        4, &client->lease->server_address);
491                 if (r < 0)
492                         return r;
493
494                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
495                                        DHCP_OPTION_REQUESTED_IP_ADDRESS,
496                                        4, &client->lease->address);
497                 if (r < 0)
498                         return r;
499
500                 break;
501
502         case DHCP_STATE_INIT_REBOOT:
503                 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
504                    option MUST be filled in with client’s notion of its previously
505                    assigned address. ’ciaddr’ MUST be zero.
506                  */
507                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
508                                        DHCP_OPTION_REQUESTED_IP_ADDRESS,
509                                        4, &client->last_addr);
510                 if (r < 0)
511                         return r;
512                 break;
513
514         case DHCP_STATE_RENEWING:
515                 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
516                    option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
517                    client’s IP address.
518                 */
519
520                 /* fall through */
521         case DHCP_STATE_REBINDING:
522                 /* ’server identifier’ MUST NOT be filled in, ’requested IP address’
523                    option MUST NOT be filled in, ’ciaddr’ MUST be filled in with
524                    client’s IP address.
525
526                    This message MUST be broadcast to the 0xffffffff IP broadcast address.
527                  */
528                 request->dhcp.ciaddr = client->lease->address;
529
530                 break;
531
532         case DHCP_STATE_INIT:
533         case DHCP_STATE_SELECTING:
534         case DHCP_STATE_REBOOTING:
535         case DHCP_STATE_BOUND:
536         case DHCP_STATE_STOPPED:
537                 return -EINVAL;
538         }
539
540         if (client->hostname) {
541                 r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
542                                        DHCP_OPTION_HOST_NAME,
543                                        strlen(client->hostname), client->hostname);
544                 if (r < 0)
545                         return r;
546         }
547
548         r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
549                                DHCP_OPTION_END, 0, NULL);
550         if (r < 0)
551                 return r;
552
553         if (client->state == DHCP_STATE_RENEWING) {
554                 r = dhcp_network_send_udp_socket(client->fd,
555                                                  client->lease->server_address,
556                                                  DHCP_PORT_SERVER,
557                                                  &request->dhcp,
558                                                  sizeof(DHCPMessage) + optoffset);
559         } else {
560                 r = dhcp_client_send_raw(client, request, sizeof(DHCPPacket) + optoffset);
561         }
562         if (r < 0)
563                 return r;
564
565         switch (client->state) {
566         case DHCP_STATE_REQUESTING:
567                 log_dhcp_client(client, "REQUEST (requesting)");
568                 break;
569         case DHCP_STATE_INIT_REBOOT:
570                 log_dhcp_client(client, "REQUEST (init-reboot)");
571                 break;
572         case DHCP_STATE_RENEWING:
573                 log_dhcp_client(client, "REQUEST (renewing)");
574                 break;
575         case DHCP_STATE_REBINDING:
576                 log_dhcp_client(client, "REQUEST (rebinding)");
577                 break;
578         default:
579                 log_dhcp_client(client, "REQUEST (invalid)");
580                 break;
581         }
582
583         return 0;
584 }
585
586 static int client_start(sd_dhcp_client *client);
587
588 static int client_timeout_resend(sd_event_source *s, uint64_t usec,
589                                  void *userdata) {
590         sd_dhcp_client *client = userdata;
591         DHCP_CLIENT_DONT_DESTROY(client);
592         usec_t next_timeout = 0;
593         uint64_t time_now;
594         uint32_t time_left;
595         int r;
596
597         assert(s);
598         assert(client);
599         assert(client->event);
600
601         r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now);
602         if (r < 0)
603                 goto error;
604
605         switch (client->state) {
606         case DHCP_STATE_RENEWING:
607
608                 time_left = (client->lease->t2 - client->lease->t1) / 2;
609                 if (time_left < 60)
610                         time_left = 60;
611
612                 next_timeout = time_now + time_left * USEC_PER_SEC;
613
614                 break;
615
616         case DHCP_STATE_REBINDING:
617
618                 time_left = (client->lease->lifetime - client->lease->t2) / 2;
619                 if (time_left < 60)
620                         time_left = 60;
621
622                 next_timeout = time_now + time_left * USEC_PER_SEC;
623                 break;
624
625         case DHCP_STATE_REBOOTING:
626                 /* start over as we did not receive a timely ack or nak */
627                 r = client_initialize(client);
628                 if (r < 0)
629                         goto error;
630
631                 r = client_start(client);
632                 if (r < 0)
633                         goto error;
634                 else {
635                         log_dhcp_client(client, "REBOOTED");
636                         return 0;
637                 }
638
639         case DHCP_STATE_INIT:
640         case DHCP_STATE_INIT_REBOOT:
641         case DHCP_STATE_SELECTING:
642         case DHCP_STATE_REQUESTING:
643         case DHCP_STATE_BOUND:
644
645                 if (client->attempt < 64)
646                         client->attempt *= 2;
647
648                 next_timeout = time_now + (client->attempt - 1) * USEC_PER_SEC;
649
650                 break;
651
652         case DHCP_STATE_STOPPED:
653                 r = -EINVAL;
654                 goto error;
655         }
656
657         next_timeout += (random_u32() & 0x1fffff);
658
659         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
660
661         r = sd_event_add_time(client->event,
662                               &client->timeout_resend,
663                               CLOCK_MONOTONIC,
664                               next_timeout, 10 * USEC_PER_MSEC,
665                               client_timeout_resend, client);
666         if (r < 0)
667                 goto error;
668
669         r = sd_event_source_set_priority(client->timeout_resend,
670                                          client->event_priority);
671         if (r < 0)
672                 goto error;
673
674         switch (client->state) {
675         case DHCP_STATE_INIT:
676                 r = client_send_discover(client);
677                 if (r >= 0) {
678                         client->state = DHCP_STATE_SELECTING;
679                         client->attempt = 1;
680                 } else {
681                         if (client->attempt >= 64)
682                                 goto error;
683                 }
684
685                 break;
686
687         case DHCP_STATE_SELECTING:
688                 r = client_send_discover(client);
689                 if (r < 0 && client->attempt >= 64)
690                         goto error;
691
692                 break;
693
694         case DHCP_STATE_INIT_REBOOT:
695         case DHCP_STATE_REQUESTING:
696         case DHCP_STATE_RENEWING:
697         case DHCP_STATE_REBINDING:
698                 r = client_send_request(client);
699                 if (r < 0 && client->attempt >= 64)
700                          goto error;
701
702                 if (client->state == DHCP_STATE_INIT_REBOOT)
703                         client->state = DHCP_STATE_REBOOTING;
704
705                 client->request_sent = time_now;
706
707                 break;
708
709         case DHCP_STATE_REBOOTING:
710         case DHCP_STATE_BOUND:
711
712                 break;
713
714         case DHCP_STATE_STOPPED:
715                 r = -EINVAL;
716                 goto error;
717         }
718
719         return 0;
720
721 error:
722         client_stop(client, r);
723
724         /* Errors were dealt with when stopping the client, don't spill
725            errors into the event loop handler */
726         return 0;
727 }
728
729 static int client_initialize_events(sd_dhcp_client *client,
730                                     sd_event_io_handler_t io_callback) {
731         int r;
732
733         assert(client);
734         assert(client->event);
735
736         r = sd_event_add_io(client->event, &client->receive_message,
737                             client->fd, EPOLLIN, io_callback,
738                             client);
739         if (r < 0)
740                 goto error;
741
742         r = sd_event_source_set_priority(client->receive_message,
743                                          client->event_priority);
744         if (r < 0)
745                 goto error;
746
747         client->timeout_resend = sd_event_source_unref(client->timeout_resend);
748
749         r = sd_event_add_time(client->event,
750                               &client->timeout_resend,
751                               CLOCK_MONOTONIC,
752                               0, 0,
753                               client_timeout_resend, client);
754         if (r < 0)
755                 goto error;
756
757         r = sd_event_source_set_priority(client->timeout_resend,
758                                          client->event_priority);
759
760 error:
761         if (r < 0)
762                 client_stop(client, r);
763
764         return 0;
765
766 }
767
768 static int client_start(sd_dhcp_client *client) {
769         int r;
770
771         assert_return(client, -EINVAL);
772         assert_return(client->event, -EINVAL);
773         assert_return(client->index > 0, -EINVAL);
774         assert_return(client->fd < 0, -EBUSY);
775         assert_return(client->xid == 0, -EINVAL);
776         assert_return(client->state == DHCP_STATE_INIT ||
777                       client->state == DHCP_STATE_INIT_REBOOT, -EBUSY);
778
779         client->xid = random_u32();
780
781         r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
782         if (r < 0) {
783                 client_stop(client, r);
784                 return r;
785         }
786         client->fd = r;
787
788         if (client->state == DHCP_STATE_INIT) {
789                 client->start_time = now(CLOCK_MONOTONIC);
790                 client->secs = 0;
791         }
792
793         return client_initialize_events(client, client_receive_message_raw);
794 }
795
796 static int client_timeout_expire(sd_event_source *s, uint64_t usec,
797                                  void *userdata) {
798         sd_dhcp_client *client = userdata;
799         DHCP_CLIENT_DONT_DESTROY(client);
800
801         log_dhcp_client(client, "EXPIRED");
802
803         client_notify(client, DHCP_EVENT_EXPIRED);
804
805         /* lease was lost, start over if not freed or stopped in callback */
806         if (client->state != DHCP_STATE_STOPPED) {
807                 client_initialize(client);
808                 client_start(client);
809         }
810
811         return 0;
812 }
813
814 static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
815         sd_dhcp_client *client = userdata;
816         DHCP_CLIENT_DONT_DESTROY(client);
817         int r;
818
819         client->receive_message = sd_event_source_unref(client->receive_message);
820         client->fd = asynchronous_close(client->fd);
821
822         client->state = DHCP_STATE_REBINDING;
823         client->attempt = 1;
824
825         r = dhcp_network_bind_raw_socket(client->index, &client->link, client->xid, client->client_id.mac_addr);
826         if (r < 0) {
827                 client_stop(client, r);
828                 return 0;
829         }
830         client->fd = r;
831
832         return client_initialize_events(client, client_receive_message_raw);
833 }
834
835 static int client_timeout_t1(sd_event_source *s, uint64_t usec,
836                              void *userdata) {
837         sd_dhcp_client *client = userdata;
838         DHCP_CLIENT_DONT_DESTROY(client);
839         int r;
840
841         client->state = DHCP_STATE_RENEWING;
842         client->attempt = 1;
843
844         r = dhcp_network_bind_udp_socket(client->lease->address,
845                                          DHCP_PORT_CLIENT);
846         if (r < 0) {
847                 log_dhcp_client(client, "could not bind UDP socket");
848                 return 0;
849         }
850
851         client->fd = r;
852
853         return client_initialize_events(client, client_receive_message_udp);
854 }
855
856 static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
857                                size_t len) {
858         _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
859         int r;
860
861         r = dhcp_lease_new(&lease);
862         if (r < 0)
863                 return r;
864
865         r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
866         if (r != DHCP_OFFER) {
867                 log_dhcp_client(client, "receieved message was not an OFFER, ignoring");
868                 return -ENOMSG;
869         }
870
871         lease->next_server = offer->siaddr;
872
873         lease->address = offer->yiaddr;
874
875         if (lease->address == INADDR_ANY ||
876             lease->server_address == INADDR_ANY ||
877             lease->lifetime == 0) {
878                 log_dhcp_client(client, "receieved lease lacks address, server "
879                                 "address or lease lifetime, ignoring");
880                 return -ENOMSG;
881         }
882
883         if (lease->subnet_mask == INADDR_ANY) {
884                 r = dhcp_lease_set_default_subnet_mask(lease);
885                 if (r < 0) {
886                         log_dhcp_client(client, "receieved lease lacks subnet "
887                                         "mask, and a fallback one can not be "
888                                         "generated, ignoring");
889                         return -ENOMSG;
890                 }
891         }
892
893         sd_dhcp_lease_unref(client->lease);
894         client->lease = lease;
895         lease = NULL;
896
897         log_dhcp_client(client, "OFFER");
898
899         return 0;
900 }
901
902 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
903                              size_t len) {
904         _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
905         int r;
906
907         r = dhcp_lease_new(&lease);
908         if (r < 0)
909                 return r;
910
911         r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
912         if (r == DHCP_NAK) {
913                 log_dhcp_client(client, "NAK");
914                 return DHCP_EVENT_NO_LEASE;
915         }
916
917         if (r != DHCP_ACK) {
918                 log_dhcp_client(client, "receieved message was not an ACK, ignoring");
919                 return -ENOMSG;
920         }
921
922         lease->next_server = ack->siaddr;
923
924         lease->address = ack->yiaddr;
925
926         if (lease->address == INADDR_ANY ||
927             lease->server_address == INADDR_ANY ||
928             lease->lifetime == 0) {
929                 log_dhcp_client(client, "receieved lease lacks address, server "
930                                 "address or lease lifetime, ignoring");
931                 return -ENOMSG;
932         }
933
934         if (lease->subnet_mask == INADDR_ANY) {
935                 r = dhcp_lease_set_default_subnet_mask(lease);
936                 if (r < 0) {
937                         log_dhcp_client(client, "receieved lease lacks subnet "
938                                         "mask, and a fallback one can not be "
939                                         "generated, ignoring");
940                         return -ENOMSG;
941                 }
942         }
943
944         r = DHCP_EVENT_IP_ACQUIRE;
945         if (client->lease) {
946                 if (client->lease->address != lease->address ||
947                     client->lease->subnet_mask != lease->subnet_mask ||
948                     client->lease->router != lease->router) {
949                         r = DHCP_EVENT_IP_CHANGE;
950                 } else
951                         r = DHCP_EVENT_RENEW;
952
953                 client->lease = sd_dhcp_lease_unref(client->lease);
954         }
955
956         client->lease = lease;
957         lease = NULL;
958
959         log_dhcp_client(client, "ACK");
960
961         return r;
962 }
963
964 static uint64_t client_compute_timeout(sd_dhcp_client *client,
965                                        uint32_t lifetime, double factor) {
966         assert(client);
967         assert(client->request_sent);
968         assert(lifetime);
969
970         return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) +
971                 + (random_u32() & 0x1fffff);
972 }
973
974 static int client_set_lease_timeouts(sd_dhcp_client *client) {
975         usec_t time_now;
976         uint64_t lifetime_timeout;
977         uint64_t t2_timeout;
978         uint64_t t1_timeout;
979         char time_string[FORMAT_TIMESPAN_MAX];
980         int r;
981
982         assert(client);
983         assert(client->event);
984         assert(client->lease);
985         assert(client->lease->lifetime);
986
987         client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
988         client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
989         client->timeout_expire = sd_event_source_unref(client->timeout_expire);
990
991         /* don't set timers for infinite leases */
992         if (client->lease->lifetime == 0xffffffff)
993                 return 0;
994
995         r = sd_event_now(client->event, CLOCK_MONOTONIC, &time_now);
996         if (r < 0)
997                 return r;
998         assert(client->request_sent <= time_now);
999
1000         /* convert the various timeouts from relative (secs) to absolute (usecs) */
1001         lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1002         if (client->lease->t1 && client->lease->t2) {
1003                 /* both T1 and T2 are given */
1004                 if (client->lease->t1 < client->lease->t2 &&
1005                     client->lease->t2 < client->lease->lifetime) {
1006                         /* they are both valid */
1007                         t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1008                         t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1009                 } else {
1010                         /* discard both */
1011                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1012                         client->lease->t2 = (client->lease->lifetime * 7) / 8;
1013                         t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1014                         client->lease->t1 = client->lease->lifetime / 2;
1015                 }
1016         } else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) {
1017                 /* only T2 is given, and it is valid */
1018                 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1019                 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1020                 client->lease->t1 = client->lease->lifetime / 2;
1021                 if (t2_timeout <= t1_timeout) {
1022                         /* the computed T1 would be invalid, so discard T2 */
1023                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1024                         client->lease->t2 = (client->lease->lifetime * 7) / 8;
1025                 }
1026         } else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) {
1027                 /* only T1 is given, and it is valid */
1028                 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1029                 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1030                 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1031                 if (t2_timeout <= t1_timeout) {
1032                         /* the computed T2 would be invalid, so discard T1 */
1033                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1034                         client->lease->t2 = client->lease->lifetime / 2;
1035                 }
1036         } else {
1037                 /* fall back to the default timeouts */
1038                 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1039                 client->lease->t1 = client->lease->lifetime / 2;
1040                 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1041                 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1042         }
1043
1044         /* arm lifetime timeout */
1045         r = sd_event_add_time(client->event, &client->timeout_expire,
1046                               CLOCK_MONOTONIC,
1047                               lifetime_timeout, 10 * USEC_PER_MSEC,
1048                               client_timeout_expire, client);
1049         if (r < 0)
1050                 return r;
1051
1052         r = sd_event_source_set_priority(client->timeout_expire,
1053                                          client->event_priority);
1054         if (r < 0)
1055                 return r;
1056
1057         log_dhcp_client(client, "lease expires in %s",
1058                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1059                         lifetime_timeout - time_now, 0));
1060
1061         /* don't arm earlier timeouts if this has already expired */
1062         if (lifetime_timeout <= time_now)
1063                 return 0;
1064
1065         /* arm T2 timeout */
1066         r = sd_event_add_time(client->event,
1067                               &client->timeout_t2,
1068                               CLOCK_MONOTONIC,
1069                               t2_timeout,
1070                               10 * USEC_PER_MSEC,
1071                               client_timeout_t2, client);
1072         if (r < 0)
1073                 return r;
1074
1075         r = sd_event_source_set_priority(client->timeout_t2,
1076                                          client->event_priority);
1077         if (r < 0)
1078                 return r;
1079
1080         log_dhcp_client(client, "T2 expires in %s",
1081                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1082                         t2_timeout - time_now, 0));
1083
1084         /* don't arm earlier timeout if this has already expired */
1085         if (t2_timeout <= time_now)
1086                 return 0;
1087
1088         /* arm T1 timeout */
1089         r = sd_event_add_time(client->event,
1090                               &client->timeout_t1,
1091                               CLOCK_MONOTONIC,
1092                               t1_timeout, 10 * USEC_PER_MSEC,
1093                               client_timeout_t1, client);
1094         if (r < 0)
1095                 return r;
1096
1097         r = sd_event_source_set_priority(client->timeout_t1,
1098                                          client->event_priority);
1099         if (r < 0)
1100                 return r;
1101
1102         log_dhcp_client(client, "T1 expires in %s",
1103                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1104                         t1_timeout - time_now, 0));
1105
1106         return 0;
1107 }
1108
1109 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
1110                                  int len) {
1111         DHCP_CLIENT_DONT_DESTROY(client);
1112         int r = 0, notify_event = 0;
1113
1114         assert(client);
1115         assert(client->event);
1116         assert(message);
1117
1118         if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1119                 log_dhcp_client(client, "not a DHCP message: ignoring");
1120                 return 0;
1121         }
1122
1123         if (message->op != BOOTREPLY) {
1124                 log_dhcp_client(client, "not a BOOTREPLY message: ignoring");
1125                 return 0;
1126         }
1127
1128         if (be32toh(message->xid) != client->xid) {
1129                 log_dhcp_client(client, "received xid (%u) does not match "
1130                                 "expected (%u): ignoring",
1131                                 be32toh(message->xid), client->xid);
1132                 return 0;
1133         }
1134
1135         if (message->htype != ARPHRD_ETHER || message->hlen != ETHER_ADDR_LEN) {
1136                 log_dhcp_client(client, "not an ethernet packet");
1137                 return 0;
1138         }
1139
1140         if (memcmp(&message->chaddr[0], &client->client_id.mac_addr,
1141                    ETH_ALEN)) {
1142                 log_dhcp_client(client, "received chaddr does not match "
1143                                 "expected: ignoring");
1144                 return 0;
1145         }
1146
1147         switch (client->state) {
1148         case DHCP_STATE_SELECTING:
1149
1150                 r = client_handle_offer(client, message, len);
1151                 if (r >= 0) {
1152
1153                         client->timeout_resend =
1154                                 sd_event_source_unref(client->timeout_resend);
1155
1156                         client->state = DHCP_STATE_REQUESTING;
1157                         client->attempt = 1;
1158
1159                         r = sd_event_add_time(client->event,
1160                                               &client->timeout_resend,
1161                                               CLOCK_MONOTONIC,
1162                                               0, 0,
1163                                               client_timeout_resend, client);
1164                         if (r < 0)
1165                                 goto error;
1166
1167                         r = sd_event_source_set_priority(client->timeout_resend,
1168                                                          client->event_priority);
1169                         if (r < 0)
1170                                 goto error;
1171                 } else if (r == -ENOMSG)
1172                         /* invalid message, let's ignore it */
1173                         return 0;
1174
1175                 break;
1176
1177         case DHCP_STATE_REBOOTING:
1178         case DHCP_STATE_REQUESTING:
1179         case DHCP_STATE_RENEWING:
1180         case DHCP_STATE_REBINDING:
1181
1182                 r = client_handle_ack(client, message, len);
1183                 if (r == DHCP_EVENT_NO_LEASE) {
1184
1185                         client->timeout_resend =
1186                                 sd_event_source_unref(client->timeout_resend);
1187
1188                         if (client->state == DHCP_STATE_REBOOTING) {
1189                                 r = client_initialize(client);
1190                                 if (r < 0)
1191                                         goto error;
1192
1193                                 r = client_start(client);
1194                                 if (r < 0)
1195                                         goto error;
1196
1197                                 log_dhcp_client(client, "REBOOTED");
1198                         }
1199
1200                         goto error;
1201                 } else if (r >= 0) {
1202                         client->timeout_resend =
1203                                 sd_event_source_unref(client->timeout_resend);
1204
1205                         if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1206                                    DHCP_STATE_REBOOTING))
1207                                 notify_event = DHCP_EVENT_IP_ACQUIRE;
1208                         else if (r != DHCP_EVENT_IP_ACQUIRE)
1209                                 notify_event = r;
1210
1211                         client->state = DHCP_STATE_BOUND;
1212                         client->attempt = 1;
1213
1214                         client->last_addr = client->lease->address;
1215
1216                         r = client_set_lease_timeouts(client);
1217                         if (r < 0)
1218                                 goto error;
1219
1220                         if (notify_event) {
1221                                 client_notify(client, notify_event);
1222                                 if (client->state == DHCP_STATE_STOPPED)
1223                                         return 0;
1224                         }
1225
1226                         client->receive_message =
1227                                 sd_event_source_unref(client->receive_message);
1228                         client->fd = asynchronous_close(client->fd);
1229                 } else if (r == -ENOMSG)
1230                         /* invalid message, let's ignore it */
1231                         return 0;
1232
1233                 break;
1234
1235         case DHCP_STATE_INIT:
1236         case DHCP_STATE_INIT_REBOOT:
1237         case DHCP_STATE_BOUND:
1238
1239                 break;
1240
1241         case DHCP_STATE_STOPPED:
1242                 r = -EINVAL;
1243                 goto error;
1244         }
1245
1246 error:
1247         if (r < 0 || r == DHCP_EVENT_NO_LEASE)
1248                 client_stop(client, r);
1249
1250         return r;
1251 }
1252
1253 static int client_receive_message_udp(sd_event_source *s, int fd,
1254                                       uint32_t revents, void *userdata) {
1255         sd_dhcp_client *client = userdata;
1256         _cleanup_free_ DHCPMessage *message = NULL;
1257         int buflen = 0, len, r;
1258
1259         assert(s);
1260         assert(client);
1261
1262         r = ioctl(fd, FIONREAD, &buflen);
1263         if (r < 0)
1264                 return r;
1265
1266         if (buflen < 0)
1267                 /* this can't be right */
1268                 return -EIO;
1269
1270         message = malloc0(buflen);
1271         if (!message)
1272                 return -ENOMEM;
1273
1274         len = read(fd, message, buflen);
1275         if (len < 0) {
1276                 log_dhcp_client(client, "could not receive message from UDP "
1277                                 "socket: %m");
1278                 return 0;
1279         } else if ((size_t)len < sizeof(DHCPMessage))
1280                 return 0;
1281
1282         return client_handle_message(client, message, len);
1283 }
1284
1285 static int client_receive_message_raw(sd_event_source *s, int fd,
1286                                       uint32_t revents, void *userdata) {
1287         sd_dhcp_client *client = userdata;
1288         _cleanup_free_ DHCPPacket *packet = NULL;
1289         uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1290         struct iovec iov = {};
1291         struct msghdr msg = {
1292                 .msg_iov = &iov,
1293                 .msg_iovlen = 1,
1294                 .msg_control = cmsgbuf,
1295                 .msg_controllen = sizeof(cmsgbuf),
1296         };
1297         struct cmsghdr *cmsg;
1298         bool checksum = true;
1299         int buflen = 0, len, r;
1300
1301         assert(s);
1302         assert(client);
1303
1304         r = ioctl(fd, FIONREAD, &buflen);
1305         if (r < 0)
1306                 return r;
1307
1308         if (buflen < 0)
1309                 /* this can't be right */
1310                 return -EIO;
1311
1312         packet = malloc0(buflen);
1313         if (!packet)
1314                 return -ENOMEM;
1315
1316         iov.iov_base = packet;
1317         iov.iov_len = buflen;
1318
1319         len = recvmsg(fd, &msg, 0);
1320         if (len < 0) {
1321                 log_dhcp_client(client, "could not receive message from raw "
1322                                 "socket: %m");
1323                 return 0;
1324         } else if ((size_t)len < sizeof(DHCPPacket))
1325                 return 0;
1326
1327         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1328                 if (cmsg->cmsg_level == SOL_PACKET &&
1329                     cmsg->cmsg_type == PACKET_AUXDATA &&
1330                     cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1331                         struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1332
1333                         checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1334                         break;
1335                 }
1336         }
1337
1338         r = dhcp_packet_verify_headers(packet, len, checksum);
1339         if (r < 0)
1340                 return 0;
1341
1342         len -= DHCP_IP_UDP_SIZE;
1343
1344         return client_handle_message(client, &packet->dhcp, len);
1345 }
1346
1347 int sd_dhcp_client_start(sd_dhcp_client *client) {
1348         int r;
1349
1350         assert_return(client, -EINVAL);
1351
1352         r = client_initialize(client);
1353         if (r < 0)
1354                 return r;
1355
1356         if (client->last_addr)
1357                 client->state = DHCP_STATE_INIT_REBOOT;
1358
1359         r = client_start(client);
1360         if (r >= 0)
1361                 log_dhcp_client(client, "STARTED on ifindex %u with address %s",
1362                                 client->index,
1363                                 ether_ntoa(&client->client_id.mac_addr));
1364
1365         return r;
1366 }
1367
1368 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1369         DHCP_CLIENT_DONT_DESTROY(client);
1370
1371         assert_return(client, -EINVAL);
1372
1373         client_stop(client, DHCP_EVENT_STOP);
1374         client->state = DHCP_STATE_STOPPED;
1375
1376         return 0;
1377 }
1378
1379 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
1380                                 int priority) {
1381         int r;
1382
1383         assert_return(client, -EINVAL);
1384         assert_return(!client->event, -EBUSY);
1385
1386         if (event)
1387                 client->event = sd_event_ref(event);
1388         else {
1389                 r = sd_event_default(&client->event);
1390                 if (r < 0)
1391                         return 0;
1392         }
1393
1394         client->event_priority = priority;
1395
1396         return 0;
1397 }
1398
1399 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1400         assert_return(client, -EINVAL);
1401
1402         client->event = sd_event_unref(client->event);
1403
1404         return 0;
1405 }
1406
1407 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1408         if (!client)
1409                 return NULL;
1410
1411         return client->event;
1412 }
1413
1414 sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
1415         if (client)
1416                 assert_se(REFCNT_INC(client->n_ref) >= 2);
1417
1418         return client;
1419 }
1420
1421 sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
1422         if (client && REFCNT_DEC(client->n_ref) <= 0) {
1423                 log_dhcp_client(client, "FREE");
1424
1425                 client_initialize(client);
1426
1427                 client->receive_message =
1428                         sd_event_source_unref(client->receive_message);
1429
1430                 sd_dhcp_client_detach_event(client);
1431
1432                 sd_dhcp_lease_unref(client->lease);
1433
1434                 free(client->req_opts);
1435                 free(client->hostname);
1436                 free(client->vendor_class_identifier);
1437                 free(client);
1438         }
1439
1440         return NULL;
1441 }
1442
1443 int sd_dhcp_client_new(sd_dhcp_client **ret) {
1444         _cleanup_dhcp_client_unref_ sd_dhcp_client *client = NULL;
1445
1446         assert_return(ret, -EINVAL);
1447
1448         client = new0(sd_dhcp_client, 1);
1449         if (!client)
1450                 return -ENOMEM;
1451
1452         client->n_ref = REFCNT_INIT;
1453         client->state = DHCP_STATE_INIT;
1454         client->index = -1;
1455         client->fd = -1;
1456         client->attempt = 1;
1457
1458         client->req_opts_size = ELEMENTSOF(default_req_opts);
1459
1460         client->req_opts = memdup(default_req_opts, client->req_opts_size);
1461         if (!client->req_opts)
1462                 return -ENOMEM;
1463
1464         *ret = client;
1465         client = NULL;
1466
1467         return 0;
1468 }