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