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