chiark / gitweb /
sd-dhcp-lease: load/save client ID
[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         if (client->client_id_len) {
1033                 r = dhcp_lease_set_client_id(lease,
1034                                              (uint8_t *) &client->client_id.raw,
1035                                              client->client_id_len);
1036                 if (r < 0)
1037                         return r;
1038         }
1039
1040         r = dhcp_option_parse(offer, len, dhcp_lease_parse_options, lease);
1041         if (r != DHCP_OFFER) {
1042                 log_dhcp_client(client, "received message was not an OFFER, ignoring");
1043                 return -ENOMSG;
1044         }
1045
1046         lease->next_server = offer->siaddr;
1047
1048         lease->address = offer->yiaddr;
1049
1050         if (lease->address == INADDR_ANY ||
1051             lease->server_address == INADDR_ANY ||
1052             lease->lifetime == 0) {
1053                 log_dhcp_client(client, "received lease lacks address, server "
1054                                 "address or lease lifetime, ignoring");
1055                 return -ENOMSG;
1056         }
1057
1058         if (lease->subnet_mask == INADDR_ANY) {
1059                 r = dhcp_lease_set_default_subnet_mask(lease);
1060                 if (r < 0) {
1061                         log_dhcp_client(client, "received lease lacks subnet "
1062                                         "mask, and a fallback one can not be "
1063                                         "generated, ignoring");
1064                         return -ENOMSG;
1065                 }
1066         }
1067
1068         sd_dhcp_lease_unref(client->lease);
1069         client->lease = lease;
1070         lease = NULL;
1071
1072         log_dhcp_client(client, "OFFER");
1073
1074         return 0;
1075 }
1076
1077 static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
1078                                     size_t len) {
1079         int r;
1080
1081         r = dhcp_option_parse(force, len, NULL, NULL);
1082         if (r != DHCP_FORCERENEW)
1083                 return -ENOMSG;
1084
1085         log_dhcp_client(client, "FORCERENEW");
1086
1087         return 0;
1088 }
1089
1090 static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
1091                              size_t len) {
1092         _cleanup_dhcp_lease_unref_ sd_dhcp_lease *lease = NULL;
1093         int r;
1094
1095         r = dhcp_lease_new(&lease);
1096         if (r < 0)
1097                 return r;
1098
1099         if (client->client_id_len) {
1100                 r = dhcp_lease_set_client_id(lease,
1101                                              (uint8_t *) &client->client_id.raw,
1102                                              client->client_id_len);
1103                 if (r < 0)
1104                         return r;
1105         }
1106
1107         r = dhcp_option_parse(ack, len, dhcp_lease_parse_options, lease);
1108         if (r == DHCP_NAK) {
1109                 log_dhcp_client(client, "NAK");
1110                 return -EADDRNOTAVAIL;
1111         }
1112
1113         if (r != DHCP_ACK) {
1114                 log_dhcp_client(client, "received message was not an ACK, ignoring");
1115                 return -ENOMSG;
1116         }
1117
1118         lease->next_server = ack->siaddr;
1119
1120         lease->address = ack->yiaddr;
1121
1122         if (lease->address == INADDR_ANY ||
1123             lease->server_address == INADDR_ANY ||
1124             lease->lifetime == 0) {
1125                 log_dhcp_client(client, "received lease lacks address, server "
1126                                 "address or lease lifetime, ignoring");
1127                 return -ENOMSG;
1128         }
1129
1130         if (lease->subnet_mask == INADDR_ANY) {
1131                 r = dhcp_lease_set_default_subnet_mask(lease);
1132                 if (r < 0) {
1133                         log_dhcp_client(client, "received lease lacks subnet "
1134                                         "mask, and a fallback one can not be "
1135                                         "generated, ignoring");
1136                         return -ENOMSG;
1137                 }
1138         }
1139
1140         r = DHCP_EVENT_IP_ACQUIRE;
1141         if (client->lease) {
1142                 if (client->lease->address != lease->address ||
1143                     client->lease->subnet_mask != lease->subnet_mask ||
1144                     client->lease->router != lease->router) {
1145                         r = DHCP_EVENT_IP_CHANGE;
1146                 } else
1147                         r = DHCP_EVENT_RENEW;
1148
1149                 client->lease = sd_dhcp_lease_unref(client->lease);
1150         }
1151
1152         client->lease = lease;
1153         lease = NULL;
1154
1155         log_dhcp_client(client, "ACK");
1156
1157         return r;
1158 }
1159
1160 static uint64_t client_compute_timeout(sd_dhcp_client *client,
1161                                        uint32_t lifetime, double factor) {
1162         assert(client);
1163         assert(client->request_sent);
1164         assert(lifetime);
1165
1166         return client->request_sent + ((lifetime - 3) * USEC_PER_SEC * factor) +
1167                 + (random_u32() & 0x1fffff);
1168 }
1169
1170 static int client_set_lease_timeouts(sd_dhcp_client *client) {
1171         usec_t time_now;
1172         uint64_t lifetime_timeout;
1173         uint64_t t2_timeout;
1174         uint64_t t1_timeout;
1175         char time_string[FORMAT_TIMESPAN_MAX];
1176         int r;
1177
1178         assert(client);
1179         assert(client->event);
1180         assert(client->lease);
1181         assert(client->lease->lifetime);
1182
1183         client->timeout_t1 = sd_event_source_unref(client->timeout_t1);
1184         client->timeout_t2 = sd_event_source_unref(client->timeout_t2);
1185         client->timeout_expire = sd_event_source_unref(client->timeout_expire);
1186
1187         /* don't set timers for infinite leases */
1188         if (client->lease->lifetime == 0xffffffff)
1189                 return 0;
1190
1191         r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now);
1192         if (r < 0)
1193                 return r;
1194         assert(client->request_sent <= time_now);
1195
1196         /* convert the various timeouts from relative (secs) to absolute (usecs) */
1197         lifetime_timeout = client_compute_timeout(client, client->lease->lifetime, 1);
1198         if (client->lease->t1 && client->lease->t2) {
1199                 /* both T1 and T2 are given */
1200                 if (client->lease->t1 < client->lease->t2 &&
1201                     client->lease->t2 < client->lease->lifetime) {
1202                         /* they are both valid */
1203                         t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1204                         t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1205                 } else {
1206                         /* discard both */
1207                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1208                         client->lease->t2 = (client->lease->lifetime * 7) / 8;
1209                         t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1210                         client->lease->t1 = client->lease->lifetime / 2;
1211                 }
1212         } else if (client->lease->t2 && client->lease->t2 < client->lease->lifetime) {
1213                 /* only T2 is given, and it is valid */
1214                 t2_timeout = client_compute_timeout(client, client->lease->t2, 1);
1215                 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1216                 client->lease->t1 = client->lease->lifetime / 2;
1217                 if (t2_timeout <= t1_timeout) {
1218                         /* the computed T1 would be invalid, so discard T2 */
1219                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1220                         client->lease->t2 = (client->lease->lifetime * 7) / 8;
1221                 }
1222         } else if (client->lease->t1 && client->lease->t1 < client->lease->lifetime) {
1223                 /* only T1 is given, and it is valid */
1224                 t1_timeout = client_compute_timeout(client, client->lease->t1, 1);
1225                 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1226                 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1227                 if (t2_timeout <= t1_timeout) {
1228                         /* the computed T2 would be invalid, so discard T1 */
1229                         t2_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1230                         client->lease->t2 = client->lease->lifetime / 2;
1231                 }
1232         } else {
1233                 /* fall back to the default timeouts */
1234                 t1_timeout = client_compute_timeout(client, client->lease->lifetime, 0.5);
1235                 client->lease->t1 = client->lease->lifetime / 2;
1236                 t2_timeout = client_compute_timeout(client, client->lease->lifetime, 7.0 / 8.0);
1237                 client->lease->t2 = (client->lease->lifetime * 7) / 8;
1238         }
1239
1240         /* arm lifetime timeout */
1241         r = sd_event_add_time(client->event, &client->timeout_expire,
1242                               clock_boottime_or_monotonic(),
1243                               lifetime_timeout, 10 * USEC_PER_MSEC,
1244                               client_timeout_expire, client);
1245         if (r < 0)
1246                 return r;
1247
1248         r = sd_event_source_set_priority(client->timeout_expire,
1249                                          client->event_priority);
1250         if (r < 0)
1251                 return r;
1252
1253         r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime");
1254         if (r < 0)
1255                 return r;
1256
1257         log_dhcp_client(client, "lease expires in %s",
1258                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1259                         lifetime_timeout - time_now, 0));
1260
1261         /* don't arm earlier timeouts if this has already expired */
1262         if (lifetime_timeout <= time_now)
1263                 return 0;
1264
1265         /* arm T2 timeout */
1266         r = sd_event_add_time(client->event,
1267                               &client->timeout_t2,
1268                               clock_boottime_or_monotonic(),
1269                               t2_timeout,
1270                               10 * USEC_PER_MSEC,
1271                               client_timeout_t2, client);
1272         if (r < 0)
1273                 return r;
1274
1275         r = sd_event_source_set_priority(client->timeout_t2,
1276                                          client->event_priority);
1277         if (r < 0)
1278                 return r;
1279
1280         r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout");
1281         if (r < 0)
1282                 return r;
1283
1284         log_dhcp_client(client, "T2 expires in %s",
1285                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1286                         t2_timeout - time_now, 0));
1287
1288         /* don't arm earlier timeout if this has already expired */
1289         if (t2_timeout <= time_now)
1290                 return 0;
1291
1292         /* arm T1 timeout */
1293         r = sd_event_add_time(client->event,
1294                               &client->timeout_t1,
1295                               clock_boottime_or_monotonic(),
1296                               t1_timeout, 10 * USEC_PER_MSEC,
1297                               client_timeout_t1, client);
1298         if (r < 0)
1299                 return r;
1300
1301         r = sd_event_source_set_priority(client->timeout_t1,
1302                                          client->event_priority);
1303         if (r < 0)
1304                 return r;
1305
1306         r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer");
1307         if (r < 0)
1308                 return r;
1309
1310         log_dhcp_client(client, "T1 expires in %s",
1311                         format_timespan(time_string, FORMAT_TIMESPAN_MAX,
1312                         t1_timeout - time_now, 0));
1313
1314         return 0;
1315 }
1316
1317 static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
1318                                  int len) {
1319         DHCP_CLIENT_DONT_DESTROY(client);
1320         int r = 0, notify_event = 0;
1321
1322         assert(client);
1323         assert(client->event);
1324         assert(message);
1325
1326         switch (client->state) {
1327         case DHCP_STATE_SELECTING:
1328
1329                 r = client_handle_offer(client, message, len);
1330                 if (r >= 0) {
1331
1332                         client->timeout_resend =
1333                                 sd_event_source_unref(client->timeout_resend);
1334
1335                         client->state = DHCP_STATE_REQUESTING;
1336                         client->attempt = 1;
1337
1338                         r = sd_event_add_time(client->event,
1339                                               &client->timeout_resend,
1340                                               clock_boottime_or_monotonic(),
1341                                               0, 0,
1342                                               client_timeout_resend, client);
1343                         if (r < 0)
1344                                 goto error;
1345
1346                         r = sd_event_source_set_priority(client->timeout_resend,
1347                                                          client->event_priority);
1348                         if (r < 0)
1349                                 goto error;
1350
1351                         r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer");
1352                         if (r < 0)
1353                                 goto error;
1354                 } else if (r == -ENOMSG)
1355                         /* invalid message, let's ignore it */
1356                         return 0;
1357
1358                 break;
1359
1360         case DHCP_STATE_REBOOTING:
1361         case DHCP_STATE_REQUESTING:
1362         case DHCP_STATE_RENEWING:
1363         case DHCP_STATE_REBINDING:
1364
1365                 r = client_handle_ack(client, message, len);
1366                 if (r >= 0) {
1367                         client->timeout_resend =
1368                                 sd_event_source_unref(client->timeout_resend);
1369                         client->receive_message =
1370                                 sd_event_source_unref(client->receive_message);
1371                         client->fd = asynchronous_close(client->fd);
1372
1373                         if (IN_SET(client->state, DHCP_STATE_REQUESTING,
1374                                    DHCP_STATE_REBOOTING))
1375                                 notify_event = DHCP_EVENT_IP_ACQUIRE;
1376                         else if (r != DHCP_EVENT_IP_ACQUIRE)
1377                                 notify_event = r;
1378
1379                         client->state = DHCP_STATE_BOUND;
1380                         client->attempt = 1;
1381
1382                         client->last_addr = client->lease->address;
1383
1384                         r = client_set_lease_timeouts(client);
1385                         if (r < 0)
1386                                 goto error;
1387
1388                         r = dhcp_network_bind_udp_socket(client->lease->address,
1389                                                          DHCP_PORT_CLIENT);
1390                         if (r < 0) {
1391                                 log_dhcp_client(client, "could not bind UDP socket");
1392                                 goto error;
1393                         }
1394
1395                         client->fd = r;
1396
1397                         client_initialize_io_events(client, client_receive_message_udp);
1398
1399                         if (notify_event) {
1400                                 client_notify(client, notify_event);
1401                                 if (client->state == DHCP_STATE_STOPPED)
1402                                         return 0;
1403                         }
1404
1405                 } else if (r == -EADDRNOTAVAIL) {
1406                         /* got a NAK, let's restart the client */
1407                         client->timeout_resend =
1408                                 sd_event_source_unref(client->timeout_resend);
1409
1410                         r = client_initialize(client);
1411                         if (r < 0)
1412                                 goto error;
1413
1414                         r = client_start(client);
1415                         if (r < 0)
1416                                 goto error;
1417
1418                         log_dhcp_client(client, "REBOOTED");
1419
1420                         return 0;
1421                 } else if (r == -ENOMSG)
1422                         /* invalid message, let's ignore it */
1423                         return 0;
1424
1425                 break;
1426
1427         case DHCP_STATE_BOUND:
1428                 r = client_handle_forcerenew(client, message, len);
1429                 if (r >= 0) {
1430                         r = client_timeout_t1(NULL, 0, client);
1431                         if (r < 0)
1432                                 goto error;
1433                 } else if (r == -ENOMSG)
1434                         /* invalid message, let's ignore it */
1435                         return 0;
1436
1437                 break;
1438
1439         case DHCP_STATE_INIT:
1440         case DHCP_STATE_INIT_REBOOT:
1441
1442                 break;
1443
1444         case DHCP_STATE_STOPPED:
1445                 r = -EINVAL;
1446                 goto error;
1447         }
1448
1449 error:
1450         if (r < 0)
1451                 client_stop(client, r);
1452
1453         return r;
1454 }
1455
1456 static int client_receive_message_udp(sd_event_source *s, int fd,
1457                                       uint32_t revents, void *userdata) {
1458         sd_dhcp_client *client = userdata;
1459         _cleanup_free_ DHCPMessage *message = NULL;
1460         int buflen = 0, len, r;
1461         const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
1462         const struct ether_addr *expected_chaddr = NULL;
1463         uint8_t expected_hlen = 0;
1464
1465         assert(s);
1466         assert(client);
1467
1468         r = ioctl(fd, FIONREAD, &buflen);
1469         if (r < 0)
1470                 return r;
1471
1472         if (buflen < 0)
1473                 /* this can't be right */
1474                 return -EIO;
1475
1476         message = malloc0(buflen);
1477         if (!message)
1478                 return -ENOMEM;
1479
1480         len = read(fd, message, buflen);
1481         if (len < 0) {
1482                 log_dhcp_client(client, "could not receive message from UDP "
1483                                 "socket: %m");
1484                 return 0;
1485         } else if ((size_t)len < sizeof(DHCPMessage)) {
1486                 log_dhcp_client(client, "too small to be a DHCP message: ignoring");
1487                 return 0;
1488         }
1489
1490         if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
1491                 log_dhcp_client(client, "not a DHCP message: ignoring");
1492                 return 0;
1493         }
1494
1495         if (message->op != BOOTREPLY) {
1496                 log_dhcp_client(client, "not a BOOTREPLY message: ignoring");
1497                 return 0;
1498         }
1499
1500         if (message->htype != client->arp_type) {
1501                 log_dhcp_client(client, "packet type does not match client type");
1502                 return 0;
1503         }
1504
1505         if (client->arp_type == ARPHRD_ETHER) {
1506                 expected_hlen = ETH_ALEN;
1507                 expected_chaddr = (const struct ether_addr *) &client->mac_addr;
1508         } else {
1509                /* Non-ethernet links expect zero chaddr */
1510                expected_hlen = 0;
1511                expected_chaddr = &zero_mac;
1512         }
1513
1514         if (message->hlen != expected_hlen) {
1515                 log_dhcp_client(client, "unexpected packet hlen %d", message->hlen);
1516                 return 0;
1517         }
1518
1519         if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
1520                 log_dhcp_client(client, "received chaddr does not match "
1521                                 "expected: ignoring");
1522                 return 0;
1523         }
1524
1525         if (client->state != DHCP_STATE_BOUND &&
1526             be32toh(message->xid) != client->xid) {
1527                 /* in BOUND state, we may receive FORCERENEW with xid set by server,
1528                    so ignore the xid in this case */
1529                 log_dhcp_client(client, "received xid (%u) does not match "
1530                                 "expected (%u): ignoring",
1531                                 be32toh(message->xid), client->xid);
1532                 return 0;
1533         }
1534
1535         return client_handle_message(client, message, len);
1536 }
1537
1538 static int client_receive_message_raw(sd_event_source *s, int fd,
1539                                       uint32_t revents, void *userdata) {
1540         sd_dhcp_client *client = userdata;
1541         _cleanup_free_ DHCPPacket *packet = NULL;
1542         uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
1543         struct iovec iov = {};
1544         struct msghdr msg = {
1545                 .msg_iov = &iov,
1546                 .msg_iovlen = 1,
1547                 .msg_control = cmsgbuf,
1548                 .msg_controllen = sizeof(cmsgbuf),
1549         };
1550         struct cmsghdr *cmsg;
1551         bool checksum = true;
1552         int buflen = 0, len, r;
1553
1554         assert(s);
1555         assert(client);
1556
1557         r = ioctl(fd, FIONREAD, &buflen);
1558         if (r < 0)
1559                 return r;
1560
1561         if (buflen < 0)
1562                 /* this can't be right */
1563                 return -EIO;
1564
1565         packet = malloc0(buflen);
1566         if (!packet)
1567                 return -ENOMEM;
1568
1569         iov.iov_base = packet;
1570         iov.iov_len = buflen;
1571
1572         len = recvmsg(fd, &msg, 0);
1573         if (len < 0) {
1574                 log_dhcp_client(client, "could not receive message from raw "
1575                                 "socket: %m");
1576                 return 0;
1577         } else if ((size_t)len < sizeof(DHCPPacket))
1578                 return 0;
1579
1580         for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1581                 if (cmsg->cmsg_level == SOL_PACKET &&
1582                     cmsg->cmsg_type == PACKET_AUXDATA &&
1583                     cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
1584                         struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
1585
1586                         checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
1587                         break;
1588                 }
1589         }
1590
1591         r = dhcp_packet_verify_headers(packet, len, checksum);
1592         if (r < 0)
1593                 return 0;
1594
1595         len -= DHCP_IP_UDP_SIZE;
1596
1597         return client_handle_message(client, &packet->dhcp, len);
1598 }
1599
1600 int sd_dhcp_client_start(sd_dhcp_client *client) {
1601         int r;
1602
1603         assert_return(client, -EINVAL);
1604
1605         r = client_initialize(client);
1606         if (r < 0)
1607                 return r;
1608
1609         if (client->last_addr)
1610                 client->state = DHCP_STATE_INIT_REBOOT;
1611
1612         r = client_start(client);
1613         if (r >= 0)
1614                 log_dhcp_client(client, "STARTED on ifindex %u", client->index);
1615
1616         return r;
1617 }
1618
1619 int sd_dhcp_client_stop(sd_dhcp_client *client) {
1620         DHCP_CLIENT_DONT_DESTROY(client);
1621
1622         assert_return(client, -EINVAL);
1623
1624         client_stop(client, DHCP_EVENT_STOP);
1625         client->state = DHCP_STATE_STOPPED;
1626
1627         return 0;
1628 }
1629
1630 int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event,
1631                                 int priority) {
1632         int r;
1633
1634         assert_return(client, -EINVAL);
1635         assert_return(!client->event, -EBUSY);
1636
1637         if (event)
1638                 client->event = sd_event_ref(event);
1639         else {
1640                 r = sd_event_default(&client->event);
1641                 if (r < 0)
1642                         return 0;
1643         }
1644
1645         client->event_priority = priority;
1646
1647         return 0;
1648 }
1649
1650 int sd_dhcp_client_detach_event(sd_dhcp_client *client) {
1651         assert_return(client, -EINVAL);
1652
1653         client->event = sd_event_unref(client->event);
1654
1655         return 0;
1656 }
1657
1658 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
1659         if (!client)
1660                 return NULL;
1661
1662         return client->event;
1663 }
1664
1665 sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
1666         if (client)
1667                 assert_se(REFCNT_INC(client->n_ref) >= 2);
1668
1669         return client;
1670 }
1671
1672 sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
1673         if (client && REFCNT_DEC(client->n_ref) <= 0) {
1674                 log_dhcp_client(client, "FREE");
1675
1676                 client_initialize(client);
1677
1678                 client->receive_message =
1679                         sd_event_source_unref(client->receive_message);
1680
1681                 sd_dhcp_client_detach_event(client);
1682
1683                 sd_dhcp_lease_unref(client->lease);
1684
1685                 free(client->req_opts);
1686                 free(client->hostname);
1687                 free(client->vendor_class_identifier);
1688                 free(client);
1689         }
1690
1691         return NULL;
1692 }
1693
1694 int sd_dhcp_client_new(sd_dhcp_client **ret) {
1695         _cleanup_dhcp_client_unref_ sd_dhcp_client *client = NULL;
1696
1697         assert_return(ret, -EINVAL);
1698
1699         client = new0(sd_dhcp_client, 1);
1700         if (!client)
1701                 return -ENOMEM;
1702
1703         client->n_ref = REFCNT_INIT;
1704         client->state = DHCP_STATE_INIT;
1705         client->index = -1;
1706         client->fd = -1;
1707         client->attempt = 1;
1708         client->mtu = DHCP_DEFAULT_MIN_SIZE;
1709
1710         client->req_opts_size = ELEMENTSOF(default_req_opts);
1711
1712         client->req_opts = memdup(default_req_opts, client->req_opts_size);
1713         if (!client->req_opts)
1714                 return -ENOMEM;
1715
1716         *ret = client;
1717         client = NULL;
1718
1719         return 0;
1720 }