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