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