source: rtems-libbsd/dhcpcd/dhcp.c @ 2017a6d

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 2017a6d was f2ed769, checked in by Sebastian Huber <sebastian.huber@…>, on 01/30/14 at 12:29:46

DHCPCD(8): Import

Import DHCPCD(8) from:

http://roy.marples.name/projects/dhcpcd/

The upstream sources can be obtained via:

fossil clone http://roy.marples.name/projects/dhcpcd

The imported version is 2014-01-29 19:46:44 [6b209507bb].

  • Property mode set to 100644
File size: 65.0 KB
Line 
1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/param.h>
29#include <sys/socket.h>
30#include <sys/stat.h>
31
32#ifdef __linux__
33#  include <asm/types.h> /* for systems with broken headers */
34#  include <linux/rtnetlink.h>
35#endif
36
37#include <arpa/inet.h>
38#include <net/route.h>
39
40#include <netinet/in_systm.h>
41#include <netinet/in.h>
42#include <netinet/ip.h>
43#define __FAVOR_BSD /* Nasty glibc hack so we can use BSD semantics for UDP */
44#include <netinet/udp.h>
45#undef __FAVOR_BSD
46
47#include <ctype.h>
48#include <errno.h>
49#include <fcntl.h>
50#include <inttypes.h>
51#include <stddef.h>
52#include <stdlib.h>
53#include <string.h>
54#include <syslog.h>
55#include <unistd.h>
56
57#include "config.h"
58#include "arp.h"
59#include "common.h"
60#include "dhcp.h"
61#include "dhcpcd.h"
62#include "dhcp-common.h"
63#include "duid.h"
64#include "eloop.h"
65#include "ipv4.h"
66#include "ipv4ll.h"
67#include "script.h"
68
69#define DAD             "Duplicate address detected"
70#define DHCP_MIN_LEASE  20
71
72static uint8_t *packet;
73
74/* Our aggregate option buffer.
75 * We ONLY use this when options are split, which for most purposes is
76 * practically never. See RFC3396 for details. */
77static uint8_t *opt_buffer;
78
79#define IPV4A           ADDRIPV4 | ARRAY
80#define IPV4R           ADDRIPV4 | REQUEST
81
82/* We should define a maximum for the NAK exponential backoff */
83#define NAKOFF_MAX              60
84
85/* Wait N nanoseconds between sending a RELEASE and dropping the address.
86 * This gives the kernel enough time to actually send it. */
87#define RELEASE_DELAY_S         0
88#define RELEASE_DELAY_NS        10000000
89
90struct dhcp_op {
91        uint8_t value;
92        const char *name;
93};
94
95static const struct dhcp_op dhcp_ops[] = {
96        { DHCP_DISCOVER, "DISCOVER" },
97        { DHCP_OFFER,    "OFFER" },
98        { DHCP_REQUEST,  "REQUEST" },
99        { DHCP_DECLINE,  "DECLINE" },
100        { DHCP_ACK,      "ACK" },
101        { DHCP_NAK,      "NAK" },
102        { DHCP_RELEASE,  "RELEASE" },
103        { DHCP_INFORM,   "INFORM" },
104        { 0, NULL }
105};
106
107static const char * const dhcp_params[] = {
108        "ip_address",
109        "subnet_cidr",
110        "network_number",
111        "filename",
112        "server_name",
113        NULL
114};
115
116struct udp_dhcp_packet
117{
118        struct ip ip;
119        struct udphdr udp;
120        struct dhcp_message dhcp;
121};
122
123struct dhcp_opt *dhcp_opts = NULL;
124size_t dhcp_opts_len = 0;
125
126static const size_t udp_dhcp_len = sizeof(struct udp_dhcp_packet);
127
128static int dhcp_open(struct interface *);
129
130void
131dhcp_printoptions(void)
132{
133        const char * const *p;
134        size_t i;
135        const struct dhcp_opt *opt;
136
137        for (p = dhcp_params; *p; p++)
138                printf("    %s\n", *p);
139
140        for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++)
141                printf("%03d %s\n", opt->option, opt->var);
142}
143
144#ifdef DEBUG_MEMORY
145static void
146dhcp_cleanup(void)
147{
148
149        free(packet);
150        free(opt_buffer);
151}
152#endif
153
154#define get_option_raw(dhcp, opt) get_option(dhcp, opt, NULL)
155static const uint8_t *
156get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len)
157{
158        const uint8_t *p = dhcp->options;
159        const uint8_t *e = p + sizeof(dhcp->options);
160        uint8_t l, ol = 0;
161        uint8_t o = 0;
162        uint8_t overl = 0;
163        uint8_t *bp = NULL;
164        const uint8_t *op = NULL;
165        int bl = 0;
166
167        while (p < e) {
168                o = *p++;
169                if (o == opt) {
170                        if (op) {
171                                if (!opt_buffer) {
172                                        opt_buffer = malloc(sizeof(*dhcp));
173                                        if (opt_buffer == NULL)
174                                                return NULL;
175                                }
176                                if (!bp)
177                                        bp = opt_buffer;
178                                memcpy(bp, op, ol);
179                                bp += ol;
180                        }
181                        ol = *p;
182                        if (p + ol > e) {
183                                errno = EINVAL;
184                                return NULL;
185                        }
186                        op = p + 1;
187                        bl += ol;
188                }
189                switch (o) {
190                case DHO_PAD:
191                        continue;
192                case DHO_END:
193                        if (overl & 1) {
194                                /* bit 1 set means parse boot file */
195                                overl &= ~1;
196                                p = dhcp->bootfile;
197                                e = p + sizeof(dhcp->bootfile);
198                        } else if (overl & 2) {
199                                /* bit 2 set means parse server name */
200                                overl &= ~2;
201                                p = dhcp->servername;
202                                e = p + sizeof(dhcp->servername);
203                        } else
204                                goto exit;
205                        break;
206                case DHO_OPTIONSOVERLOADED:
207                        /* Ensure we only get this option once */
208                        if (!overl)
209                                overl = p[1];
210                        break;
211                }
212                l = *p++;
213                p += l;
214        }
215
216exit:
217        if (len)
218                *len = bl;
219        if (bp) {
220                memcpy(bp, op, ol);
221                return (const uint8_t *)opt_buffer;
222        }
223        if (op)
224                return op;
225        errno = ENOENT;
226        return NULL;
227}
228
229int
230get_option_addr(struct in_addr *a, const struct dhcp_message *dhcp,
231    uint8_t option)
232{
233        const uint8_t *p;
234        int len;
235
236        p = get_option(dhcp, option, &len);
237        if (!p || len < (ssize_t)sizeof(a->s_addr))
238                return -1;
239        memcpy(&a->s_addr, p, sizeof(a->s_addr));
240        return 0;
241}
242
243static int
244get_option_uint32(uint32_t *i, const struct dhcp_message *dhcp, uint8_t option)
245{
246        const uint8_t *p;
247        int len;
248        uint32_t d;
249
250        p = get_option(dhcp, option, &len);
251        if (!p || len < (ssize_t)sizeof(d))
252                return -1;
253        memcpy(&d, p, sizeof(d));
254        if (i)
255                *i = ntohl(d);
256        return 0;
257}
258
259static int
260get_option_uint8(uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
261{
262        const uint8_t *p;
263        int len;
264
265        p = get_option(dhcp, option, &len);
266        if (!p || len < (ssize_t)sizeof(*p))
267                return -1;
268        if (i)
269                *i = *(p);
270        return 0;
271}
272
273ssize_t
274decode_rfc3442(char *out, ssize_t len, int pl, const uint8_t *p)
275{
276        const uint8_t *e;
277        ssize_t b, bytes = 0, ocets;
278        uint8_t cidr;
279        struct in_addr addr;
280        char *o = out;
281
282        /* Minimum is 5 -first is CIDR and a router length of 4 */
283        if (pl < 5) {
284                errno = EINVAL;
285                return -1;
286        }
287
288        e = p + pl;
289        while (p < e) {
290                cidr = *p++;
291                if (cidr > 32) {
292                        errno = EINVAL;
293                        return -1;
294                }
295                ocets = (cidr + 7) / 8;
296                if (!out) {
297                        p += 4 + ocets;
298                        bytes += ((4 * 4) * 2) + 4;
299                        continue;
300                }
301                if ((((4 * 4) * 2) + 4) > len) {
302                        errno = ENOBUFS;
303                        return -1;
304                }
305                if (o != out) {
306                        *o++ = ' ';
307                        len--;
308                }
309                /* If we have ocets then we have a destination and netmask */
310                if (ocets > 0) {
311                        addr.s_addr = 0;
312                        memcpy(&addr.s_addr, p, ocets);
313                        b = snprintf(o, len, "%s/%d", inet_ntoa(addr), cidr);
314                        p += ocets;
315                } else
316                        b = snprintf(o, len, "0.0.0.0/0");
317                o += b;
318                len -= b;
319
320                /* Finally, snag the router */
321                memcpy(&addr.s_addr, p, 4);
322                p += 4;
323                b = snprintf(o, len, " %s", inet_ntoa(addr));
324                o += b;
325                len -= b;
326        }
327
328        if (out)
329                return o - out;
330        return bytes;
331}
332
333static struct rt_head *
334decode_rfc3442_rt(int dl, const uint8_t *data)
335{
336        const uint8_t *p = data;
337        const uint8_t *e;
338        uint8_t cidr;
339        size_t ocets;
340        struct rt_head *routes;
341        struct rt *rt = NULL;
342
343        /* Minimum is 5 -first is CIDR and a router length of 4 */
344        if (dl < 5)
345                return NULL;
346
347        routes = malloc(sizeof(*routes));
348        TAILQ_INIT(routes);
349        e = p + dl;
350        while (p < e) {
351                cidr = *p++;
352                if (cidr > 32) {
353                        ipv4_freeroutes(routes);
354                        errno = EINVAL;
355                        return NULL;
356                }
357
358                rt = calloc(1, sizeof(*rt));
359                if (rt == NULL) {
360                        syslog(LOG_ERR, "%s: %m", __func__);
361                        ipv4_freeroutes(routes);
362                        return NULL;
363                }
364                TAILQ_INSERT_TAIL(routes, rt, next);
365
366                ocets = (cidr + 7) / 8;
367                /* If we have ocets then we have a destination and netmask */
368                if (ocets > 0) {
369                        memcpy(&rt->dest.s_addr, p, ocets);
370                        p += ocets;
371                        rt->net.s_addr = htonl(~0U << (32 - cidr));
372                }
373
374                /* Finally, snag the router */
375                memcpy(&rt->gate.s_addr, p, 4);
376                p += 4;
377        }
378        return routes;
379}
380
381char *
382decode_rfc3361(int dl, const uint8_t *data)
383{
384        uint8_t enc;
385        unsigned int l;
386        char *sip = NULL;
387        struct in_addr addr;
388        char *p;
389
390        if (dl < 2) {
391                errno = EINVAL;
392                return 0;
393        }
394
395        enc = *data++;
396        dl--;
397        switch (enc) {
398        case 0:
399                if ((l = decode_rfc3397(NULL, 0, dl, data)) > 0) {
400                        sip = malloc(l);
401                        if (sip == NULL)
402                                return 0;
403                        decode_rfc3397(sip, l, dl, data);
404                }
405                break;
406        case 1:
407                if (dl == 0 || dl % 4 != 0) {
408                        errno = EINVAL;
409                        break;
410                }
411                addr.s_addr = INADDR_BROADCAST;
412                l = ((dl / sizeof(addr.s_addr)) * ((4 * 4) + 1)) + 1;
413                sip = p = malloc(l);
414                if (sip == NULL)
415                        return 0;
416                while (dl != 0) {
417                        memcpy(&addr.s_addr, data, sizeof(addr.s_addr));
418                        data += sizeof(addr.s_addr);
419                        p += snprintf(p, l - (p - sip), "%s ", inet_ntoa(addr));
420                        dl -= sizeof(addr.s_addr);
421                }
422                *--p = '\0';
423                break;
424        default:
425                errno = EINVAL;
426                return 0;
427        }
428
429        return sip;
430}
431
432/* Decode an RFC5969 6rd order option into a space
433 * separated string. Returns length of string (including
434 * terminating zero) or zero on error. */
435ssize_t
436decode_rfc5969(char *out, ssize_t len, int pl, const uint8_t *p)
437{
438        uint8_t ipv4masklen, ipv6prefixlen;
439        uint8_t ipv6prefix[16];
440        uint8_t br[4];
441        int i;
442        ssize_t b, bytes = 0;
443
444        if (pl < 22) {
445                errno = EINVAL;
446                return 0;
447        }
448
449        ipv4masklen = *p++;
450        pl--;
451        ipv6prefixlen = *p++;
452        pl--;
453
454        for (i = 0; i < 16; i++) {
455                ipv6prefix[i] = *p++;
456                pl--;
457        }
458        if (out) {
459                b= snprintf(out, len,
460                    "%d %d "
461                    "%02x%02x:%02x%02x:"
462                    "%02x%02x:%02x%02x:"
463                    "%02x%02x:%02x%02x:"
464                    "%02x%02x:%02x%02x",
465                    ipv4masklen, ipv6prefixlen,
466                    ipv6prefix[0], ipv6prefix[1], ipv6prefix[2], ipv6prefix[3],
467                    ipv6prefix[4], ipv6prefix[5], ipv6prefix[6], ipv6prefix[7],
468                    ipv6prefix[8], ipv6prefix[9], ipv6prefix[10],ipv6prefix[11],
469                    ipv6prefix[12],ipv6prefix[13],ipv6prefix[14], ipv6prefix[15]
470                );
471
472                len -= b;
473                out += b;
474                bytes += b;
475        } else {
476                bytes += 16 * 2 + 8 + 2 + 1 + 2;
477        }
478
479        while (pl >= 4) {
480                br[0] = *p++;
481                br[1] = *p++;
482                br[2] = *p++;
483                br[3] = *p++;
484                pl -= 4;
485
486                if (out) {
487                        b= snprintf(out, len, " %d.%d.%d.%d",
488                            br[0], br[1], br[2], br[3]);
489                        len -= b;
490                        out += b;
491                        bytes += b;
492                } else {
493                        bytes += (4 * 4);
494                }
495        }
496
497        return bytes;
498}
499
500char *
501get_option_string(const struct dhcp_message *dhcp, uint8_t option)
502{
503        int len;
504        const uint8_t *p;
505        char *s;
506
507        p = get_option(dhcp, option, &len);
508        if (!p || len == 0 || *p == '\0')
509                return NULL;
510
511        s = malloc(sizeof(char) * (len + 1));
512        if (s) {
513                memcpy(s, p, len);
514                s[len] = '\0';
515        }
516        return s;
517}
518
519/* This calculates the netmask that we should use for static routes.
520 * This IS different from the calculation used to calculate the netmask
521 * for an interface address. */
522static uint32_t
523route_netmask(uint32_t ip_in)
524{
525        /* used to be unsigned long - check if error */
526        uint32_t p = ntohl(ip_in);
527        uint32_t t;
528
529        if (IN_CLASSA(p))
530                t = ~IN_CLASSA_NET;
531        else {
532                if (IN_CLASSB(p))
533                        t = ~IN_CLASSB_NET;
534                else {
535                        if (IN_CLASSC(p))
536                                t = ~IN_CLASSC_NET;
537                        else
538                                t = 0;
539                }
540        }
541
542        while (t & p)
543                t >>= 1;
544
545        return (htonl(~t));
546}
547
548/* We need to obey routing options.
549 * If we have a CSR then we only use that.
550 * Otherwise we add static routes and then routers. */
551struct rt_head *
552get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
553{
554        struct if_options *ifo = ifp->options;
555        const uint8_t *p;
556        const uint8_t *e;
557        struct rt_head *routes = NULL;
558        struct rt *route = NULL;
559        int len;
560        const char *csr = "";
561
562        /* If we have CSR's then we MUST use these only */
563        if (!has_option_mask(ifo->nomask, DHO_CSR))
564                p = get_option(dhcp, DHO_CSR, &len);
565        else
566                p = NULL;
567        /* Check for crappy MS option */
568        if (!p && !has_option_mask(ifo->nomask, DHO_MSCSR)) {
569                p = get_option(dhcp, DHO_MSCSR, &len);
570                if (p)
571                        csr = "MS ";
572        }
573        if (p) {
574                routes = decode_rfc3442_rt(len, p);
575                if (routes) {
576                        if (!(ifo->options & DHCPCD_CSR_WARNED)) {
577                                syslog(LOG_DEBUG,
578                                    "%s: using %sClassless Static Routes",
579                                    ifp->name, csr);
580                                ifo->options |= DHCPCD_CSR_WARNED;
581                        }
582                        return routes;
583                }
584        }
585
586        /* OK, get our static routes first. */
587        routes = malloc(sizeof(*routes));
588        if (routes == NULL) {
589                syslog(LOG_ERR, "%s: %m", __func__);
590                return NULL;
591        }
592        TAILQ_INIT(routes);
593        if (!has_option_mask(ifo->nomask, DHO_STATICROUTE))
594                p = get_option(dhcp, DHO_STATICROUTE, &len);
595        else
596                p = NULL;
597        if (p) {
598                e = p + len;
599                while (p < e) {
600                        route = calloc(1, sizeof(*route));
601                        if (route == NULL) {
602                                syslog(LOG_ERR, "%s: %m", __func__);
603                                ipv4_freeroutes(routes);
604                                return NULL;
605                        }
606                        memcpy(&route->dest.s_addr, p, 4);
607                        p += 4;
608                        memcpy(&route->gate.s_addr, p, 4);
609                        p += 4;
610                        route->net.s_addr = route_netmask(route->dest.s_addr);
611                        TAILQ_INSERT_TAIL(routes, route, next);
612                }
613        }
614
615        /* Now grab our routers */
616        if (!has_option_mask(ifo->nomask, DHO_ROUTER))
617                p = get_option(dhcp, DHO_ROUTER, &len);
618        else
619                p = NULL;
620        if (p) {
621                e = p + len;
622                while (p < e) {
623                        route = calloc(1, sizeof(*route));
624                        if (route == NULL) {
625                                syslog(LOG_ERR, "%s: %m", __func__);
626                                ipv4_freeroutes(routes);
627                                return NULL;
628                        }
629                        memcpy(&route->gate.s_addr, p, 4);
630                        p += 4;
631                        TAILQ_INSERT_TAIL(routes, route, next);
632                }
633        }
634
635        return routes;
636}
637
638#define PUTADDR(_type, _val)                                                  \
639        {                                                                     \
640                *p++ = _type;                                                 \
641                *p++ = 4;                                                     \
642                memcpy(p, &_val.s_addr, 4);                                   \
643                p += 4;                                                       \
644        }
645
646int
647dhcp_message_add_addr(struct dhcp_message *dhcp,
648    uint8_t type, struct in_addr addr)
649{
650        uint8_t *p;
651        size_t len;
652
653        p = dhcp->options;
654        while (*p != DHO_END) {
655                p++;
656                p += *p + 1;
657        }
658
659        len = p - (uint8_t *)dhcp;
660        if (len + 6 > sizeof(*dhcp)) {
661                errno = ENOMEM;
662                return -1;
663        }
664
665        PUTADDR(type, addr);
666        *p = DHO_END;
667        return 0;
668}
669
670ssize_t
671make_message(struct dhcp_message **message,
672    const struct interface *iface,
673    uint8_t type)
674{
675        struct dhcp_message *dhcp;
676        uint8_t *m, *lp, *p, *auth;
677        uint8_t *n_params = NULL;
678        uint32_t ul;
679        uint16_t sz;
680        size_t len, i;
681        int auth_len;
682        const struct dhcp_opt *opt;
683        const struct if_options *ifo = iface->options;
684        const struct dhcp_state *state = D_CSTATE(iface);
685        const struct dhcp_lease *lease = &state->lease;
686        time_t up = uptime() - state->start_uptime;
687        const char *hostname;
688        const struct vivco *vivco;
689
690        dhcp = calloc(1, sizeof (*dhcp));
691        if (dhcp == NULL)
692                return -1;
693        m = (uint8_t *)dhcp;
694        p = dhcp->options;
695
696        if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
697                (type == DHCP_REQUEST &&
698                    state->net.s_addr == lease->net.s_addr &&
699                    (state->new == NULL ||
700                        state->new->cookie == htonl(MAGIC_COOKIE)))))
701        {
702                dhcp->ciaddr = state->addr.s_addr;
703                /* In-case we haven't actually configured the address yet */
704                if (type == DHCP_INFORM && state->addr.s_addr == 0)
705                        dhcp->ciaddr = lease->addr.s_addr;
706        }
707
708        dhcp->op = DHCP_BOOTREQUEST;
709        dhcp->hwtype = iface->family;
710        switch (iface->family) {
711        case ARPHRD_ETHER:
712        case ARPHRD_IEEE802:
713                dhcp->hwlen = iface->hwlen;
714                memcpy(&dhcp->chaddr, &iface->hwaddr, iface->hwlen);
715                break;
716        }
717
718        if (ifo->options & DHCPCD_BROADCAST &&
719            dhcp->ciaddr == 0 &&
720            type != DHCP_DECLINE &&
721            type != DHCP_RELEASE)
722                dhcp->flags = htons(BROADCAST_FLAG);
723
724        if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
725                if (up < 0 || up > (time_t)UINT16_MAX)
726                        dhcp->secs = htons((uint16_t)UINT16_MAX);
727                else
728                        dhcp->secs = htons(up);
729        }
730        dhcp->xid = htonl(state->xid);
731        dhcp->cookie = htonl(MAGIC_COOKIE);
732
733        *p++ = DHO_MESSAGETYPE;
734        *p++ = 1;
735        *p++ = type;
736
737        if (state->clientid) {
738                *p++ = DHO_CLIENTID;
739                memcpy(p, state->clientid, state->clientid[0] + 1);
740                p += state->clientid[0] + 1;
741        }
742
743        if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
744                if (type == DHCP_DECLINE ||
745                    (type == DHCP_REQUEST &&
746                        lease->addr.s_addr != state->addr.s_addr))
747                {
748                        PUTADDR(DHO_IPADDRESS, lease->addr);
749                        if (lease->server.s_addr)
750                                PUTADDR(DHO_SERVERID, lease->server);
751                }
752
753                if (type == DHCP_RELEASE) {
754                        if (lease->server.s_addr)
755                                PUTADDR(DHO_SERVERID, lease->server);
756                }
757        }
758
759        if (type == DHCP_DECLINE) {
760                *p++ = DHO_MESSAGE;
761                len = strlen(DAD);
762                *p++ = len;
763                memcpy(p, DAD, len);
764                p += len;
765        }
766
767        if (type == DHCP_DISCOVER &&
768            !(options & DHCPCD_TEST) &&
769            has_option_mask(ifo->requestmask, DHO_RAPIDCOMMIT))
770        {
771                /* RFC 4039 Section 3 */
772                *p++ = DHO_RAPIDCOMMIT;
773                *p++ = 0;
774        }
775
776        if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST)
777                PUTADDR(DHO_IPADDRESS, ifo->req_addr);
778
779        if (type == DHCP_DISCOVER ||
780            type == DHCP_INFORM ||
781            type == DHCP_REQUEST)
782        {
783                *p++ = DHO_MAXMESSAGESIZE;
784                *p++ = 2;
785                sz = get_mtu(iface->name);
786                if (sz < MTU_MIN) {
787                        if (set_mtu(iface->name, MTU_MIN) == 0)
788                                sz = MTU_MIN;
789                } else if (sz > MTU_MAX) {
790                        /* Even though our MTU could be greater than
791                         * MTU_MAX (1500) dhcpcd does not presently
792                         * handle DHCP packets any bigger. */
793                        sz = MTU_MAX;
794                }
795                sz = htons(sz);
796                memcpy(p, &sz, 2);
797                p += 2;
798
799                if (ifo->userclass[0]) {
800                        *p++ = DHO_USERCLASS;
801                        memcpy(p, ifo->userclass, ifo->userclass[0] + 1);
802                        p += ifo->userclass[0] + 1;
803                }
804
805                if (ifo->vendorclassid[0]) {
806                        *p++ = DHO_VENDORCLASSID;
807                        memcpy(p, ifo->vendorclassid,
808                            ifo->vendorclassid[0] + 1);
809                        p += ifo->vendorclassid[0] + 1;
810                }
811
812
813                if (type != DHCP_INFORM) {
814                        if (ifo->leasetime != 0) {
815                                *p++ = DHO_LEASETIME;
816                                *p++ = 4;
817                                ul = htonl(ifo->leasetime);
818                                memcpy(p, &ul, 4);
819                                p += 4;
820                        }
821                }
822
823                if (ifo->hostname[0] == '\0')
824                        hostname = get_hostname(ifo->options &
825                            DHCPCD_HOSTNAME_SHORT ? 1 : 0);
826                else
827                        hostname = ifo->hostname;
828                if (ifo->fqdn != FQDN_DISABLE) {
829                        /* IETF DHC-FQDN option (81), RFC4702 */
830                        *p++ = DHO_FQDN;
831                        lp = p;
832                        *p++ = 3;
833                        /*
834                         * Flags: 0000NEOS
835                         * S: 1 => Client requests Server to update
836                         *         a RR in DNS as well as PTR
837                         * O: 1 => Server indicates to client that
838                         *         DNS has been updated
839                         * E: 1 => Name data is DNS format
840                         * N: 1 => Client requests Server to not
841                         *         update DNS
842                         */
843                        if (hostname)
844                                *p++ = (ifo->fqdn & 0x09) | 0x04;
845                        else
846                                *p++ = (FQDN_NONE & 0x09) | 0x04;
847                        *p++ = 0; /* from server for PTR RR */
848                        *p++ = 0; /* from server for A RR if S=1 */
849                        if (hostname) {
850                                ul = encode_rfc1035(hostname, p);
851                                *lp += ul;
852                                p += ul;
853                        }
854                } else if (ifo->options & DHCPCD_HOSTNAME && hostname) {
855                        *p++ = DHO_HOSTNAME;
856                        len = strlen(hostname);
857                        *p++ = len;
858                        memcpy(p, hostname, len);
859                        p += len;
860                }
861
862                /* vendor is already encoded correctly, so just add it */
863                if (ifo->vendor[0]) {
864                        *p++ = DHO_VENDOR;
865                        memcpy(p, ifo->vendor, ifo->vendor[0] + 1);
866                        p += ifo->vendor[0] + 1;
867                }
868
869                if (ifo->vivco_len) {
870                        *p++ = DHO_VIVCO;
871                        lp = p++;
872                        *lp = sizeof(ul);
873                        ul = htonl(ifo->vivco_en);
874                        memcpy(p, &ul, sizeof(ul));
875                        p += sizeof(ul);
876                        for (i = 0, vivco = ifo->vivco;
877                            i < ifo->vivco_len;
878                            i++, vivco++)
879                        {
880                                len = (p - m) + vivco->len + 1;
881                                if (len > sizeof(*dhcp))
882                                        goto toobig;
883                                if (vivco->len + 2 + *lp > 255) {
884                                        syslog(LOG_ERR,
885                                            "%s: VIVCO option too big",
886                                            iface->name);
887                                        free(dhcp);
888                                        return -1;
889                                }
890                                *p++ = (uint8_t)vivco->len;
891                                memcpy(p, vivco->data, vivco->len);
892                                p += vivco->len;
893                                *lp += (uint8_t)vivco->len + 1;
894                        }
895                }
896
897                len = (p - m) + 3;
898                if (len > sizeof(*dhcp))
899                        goto toobig;
900                *p++ = DHO_PARAMETERREQUESTLIST;
901                n_params = p;
902                *p++ = 0;
903                for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++) {
904                        if (!(opt->type & REQUEST ||
905                                has_option_mask(ifo->requestmask, opt->option)))
906                                continue;
907                        if (opt->type & NOREQ)
908                                continue;
909                        if (type == DHCP_INFORM &&
910                            (opt->option == DHO_RENEWALTIME ||
911                                opt->option == DHO_REBINDTIME))
912                                continue;
913                        len = (p - m) + 2;
914                        if (len > sizeof(*dhcp))
915                                goto toobig;
916                        *p++ = opt->option;
917                }
918                *n_params = p - n_params - 1;
919        }
920
921        /* silence GCC */
922        auth_len = 0;
923        auth = NULL;
924
925        if (ifo->auth.options & DHCPCD_AUTH_SEND) {
926                auth_len = dhcp_auth_encode(&ifo->auth, state->auth.token,
927                    NULL, 0, 4, type, NULL, 0);
928                if (auth_len > 0) {
929                        len = (p + auth_len) - m;
930                        if (auth_len > 255 || len > sizeof(*dhcp))
931                                goto toobig;
932                        *p++ = DHO_AUTHENTICATION;
933                        *p++ = (uint8_t)auth_len;
934                        auth = p;
935                        p += auth_len;
936                } else if (auth_len == -1)
937                        syslog(LOG_ERR, "%s: dhcp_auth_encode: %m",
938                            iface->name);
939        }
940
941        *p++ = DHO_END;
942
943#ifdef BOOTP_MESSAGE_LENTH_MIN
944        /* Some crappy DHCP servers think they have to obey the BOOTP minimum
945         * message length.
946         * They are wrong, but we should still cater for them. */
947        while (p - m < BOOTP_MESSAGE_LENTH_MIN)
948                *p++ = DHO_PAD;
949#endif
950
951        len = p - m;
952        if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len > 0)
953                dhcp_auth_encode(&ifo->auth, state->auth.token,
954                    m, len, 4, type, auth, auth_len);
955
956        *message = dhcp;
957        return len;
958
959toobig:
960        syslog(LOG_ERR, "%s: DHCP messge too big", iface->name);
961        free(dhcp);
962        return -1;
963}
964
965ssize_t
966write_lease(const struct interface *ifp, const struct dhcp_message *dhcp)
967{
968        int fd;
969        ssize_t bytes = sizeof(*dhcp);
970        const uint8_t *p = dhcp->options;
971        const uint8_t *e = p + sizeof(dhcp->options);
972        uint8_t l;
973        uint8_t o = 0;
974        const struct dhcp_state *state = D_CSTATE(ifp);
975
976        /* We don't write BOOTP leases */
977        if (is_bootp(dhcp)) {
978                unlink(state->leasefile);
979                return 0;
980        }
981
982        syslog(LOG_DEBUG, "%s: writing lease `%s'",
983            ifp->name, state->leasefile);
984
985        fd = open(state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
986        if (fd == -1)
987                return -1;
988
989        /* Only write as much as we need */
990        while (p < e) {
991                o = *p;
992                if (o == DHO_END) {
993                        bytes = p - (const uint8_t *)dhcp;
994                        break;
995                }
996                p++;
997                if (o != DHO_PAD) {
998                        l = *p++;
999                        p += l;
1000                }
1001        }
1002        bytes = write(fd, dhcp, bytes);
1003        close(fd);
1004        return bytes;
1005}
1006
1007struct dhcp_message *
1008read_lease(struct interface *ifp)
1009{
1010        int fd;
1011        struct dhcp_message *dhcp;
1012        struct dhcp_state *state = D_STATE(ifp);
1013        ssize_t bytes;
1014        const uint8_t *auth;
1015        uint8_t type;
1016        int auth_len;
1017
1018        fd = open(state->leasefile, O_RDONLY);
1019        if (fd == -1) {
1020                if (errno != ENOENT)
1021                        syslog(LOG_ERR, "%s: open `%s': %m",
1022                            ifp->name, state->leasefile);
1023                return NULL;
1024        }
1025        syslog(LOG_DEBUG, "%s: reading lease `%s'",
1026            ifp->name, state->leasefile);
1027        dhcp = calloc(1, sizeof(*dhcp));
1028        if (dhcp == NULL) {
1029                close(fd);
1030                return NULL;
1031        }
1032        bytes = read(fd, dhcp, sizeof(*dhcp));
1033        close(fd);
1034        if (bytes < 0) {
1035                free(dhcp);
1036                return NULL;
1037        }
1038
1039        /* We may have found a BOOTP server */
1040        if (get_option_uint8(&type, dhcp, DHO_MESSAGETYPE) == -1)
1041                type = 0;
1042        /* Authenticate the message */
1043        auth = get_option(dhcp, DHO_AUTHENTICATION, &auth_len);
1044        if (auth) {
1045                if (dhcp_auth_validate(&state->auth, &ifp->options->auth,
1046                    (uint8_t *)dhcp, sizeof(*dhcp), 4, type,
1047                    auth, auth_len) == NULL)
1048                {
1049                        syslog(LOG_DEBUG, "%s: dhcp_auth_validate: %m",
1050                            ifp->name);
1051                        free(dhcp);
1052                        return NULL;
1053                }
1054                syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
1055                    ifp->name, state->auth.token->secretid);
1056        }
1057
1058        return dhcp;
1059}
1060
1061static const struct dhcp_opt *
1062dhcp_getoverride(const struct if_options *ifo, uint16_t o)
1063{
1064        size_t i;
1065        const struct dhcp_opt *opt;
1066
1067        for (i = 0, opt = ifo->dhcp_override;
1068            i < ifo->dhcp_override_len;
1069            i++, opt++)
1070        {
1071                if (opt->option == o)
1072                        return opt;
1073        }
1074        return NULL;
1075}
1076
1077static const uint8_t *
1078dhcp_getoption(unsigned int *os, unsigned int *code, unsigned int *len,
1079    const uint8_t *od, unsigned int ol, struct dhcp_opt **oopt)
1080{
1081        size_t i;
1082        struct dhcp_opt *opt;
1083
1084        if (od) {
1085                if (ol < 2) {
1086                        errno = EINVAL;
1087                        return NULL;
1088                }
1089                *os = 2; /* code + len */
1090                *code = (int)*od++;
1091                *len = (int)*od++;
1092                if (*len > ol) {
1093                        errno = EINVAL;
1094                        return NULL;
1095                }
1096        }
1097
1098        for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++) {
1099                if (opt->option == *code) {
1100                        *oopt = opt;
1101                        break;
1102                }
1103        }
1104
1105        return od;
1106}
1107
1108ssize_t
1109dhcp_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
1110    const struct interface *ifp)
1111{
1112        const struct if_options *ifo;
1113        const uint8_t *p;
1114        int pl;
1115        struct in_addr addr;
1116        struct in_addr net;
1117        struct in_addr brd;
1118        struct dhcp_opt *opt, *vo;
1119        ssize_t e = 0;
1120        char **ep;
1121        char cidr[4];
1122        uint8_t overl = 0;
1123        size_t i;
1124        uint32_t en;
1125
1126        ifo = ifp->options;
1127        get_option_uint8(&overl, dhcp, DHO_OPTIONSOVERLOADED);
1128
1129        if (!env) {
1130                if (dhcp->yiaddr || dhcp->ciaddr)
1131                        e += 5;
1132                if (*dhcp->bootfile && !(overl & 1))
1133                        e++;
1134                if (*dhcp->servername && !(overl & 2))
1135                        e++;
1136                for (i = 0, opt = dhcp_opts;
1137                    i < dhcp_opts_len;
1138                    i++, opt++)
1139                {
1140                        if (has_option_mask(ifo->nomask, opt->option))
1141                                continue;
1142                        if (dhcp_getoverride(ifo, opt->option))
1143                                continue;
1144                        p = get_option(dhcp, opt->option, &pl);
1145                        if (!p)
1146                                continue;
1147                        e += dhcp_envoption(NULL, NULL, ifp->name,
1148                            opt, dhcp_getoption, p, pl);
1149                }
1150                for (i = 0, opt = ifo->dhcp_override;
1151                    i < ifo->dhcp_override_len;
1152                    i++, opt++)
1153                {
1154                        if (has_option_mask(ifo->nomask, opt->option))
1155                                continue;
1156                        p = get_option(dhcp, opt->option, &pl);
1157                        if (!p)
1158                                continue;
1159                        e += dhcp_envoption(NULL, NULL, ifp->name,
1160                            opt, dhcp_getoption, p, pl);
1161                }
1162                return e;
1163        }
1164
1165        ep = env;
1166        if (dhcp->yiaddr || dhcp->ciaddr) {
1167                /* Set some useful variables that we derive from the DHCP
1168                 * message but are not necessarily in the options */
1169                addr.s_addr = dhcp->yiaddr ? dhcp->yiaddr : dhcp->ciaddr;
1170                setvar(&ep, prefix, "ip_address", inet_ntoa(addr));
1171                if (get_option_addr(&net, dhcp, DHO_SUBNETMASK) == -1) {
1172                        net.s_addr = ipv4_getnetmask(addr.s_addr);
1173                        setvar(&ep, prefix, "subnet_mask", inet_ntoa(net));
1174                }
1175                snprintf(cidr, sizeof(cidr), "%d", inet_ntocidr(net));
1176                setvar(&ep, prefix, "subnet_cidr", cidr);
1177                if (get_option_addr(&brd, dhcp, DHO_BROADCAST) == -1) {
1178                        brd.s_addr = addr.s_addr | ~net.s_addr;
1179                        setvar(&ep, prefix, "broadcast_address",
1180                            inet_ntoa(brd));
1181                }
1182                addr.s_addr = dhcp->yiaddr & net.s_addr;
1183                setvar(&ep, prefix, "network_number", inet_ntoa(addr));
1184        }
1185
1186        if (*dhcp->bootfile && !(overl & 1))
1187                setvar(&ep, prefix, "filename", (const char *)dhcp->bootfile);
1188        if (*dhcp->servername && !(overl & 2))
1189                setvar(&ep, prefix, "server_name",
1190                    (const char *)dhcp->servername);
1191
1192        /* Zero our indexes */
1193        if (env) {
1194                for (i = 0, opt = dhcp_opts; i < dhcp_opts_len; i++, opt++)
1195                        dhcp_zero_index(opt);
1196                for (i = 0, opt = ifp->options->dhcp_override;
1197                    i < ifp->options->dhcp_override_len;
1198                    i++, opt++)
1199                        dhcp_zero_index(opt);
1200                for (i = 0, opt = vivso; i < vivso_len; i++, opt++)
1201                        dhcp_zero_index(opt);
1202        }
1203
1204        for (i = 0, opt = dhcp_opts;
1205            i < dhcp_opts_len;
1206            i++, opt++)
1207        {
1208                if (has_option_mask(ifo->nomask, opt->option))
1209                        continue;
1210                if (dhcp_getoverride(ifo, opt->option))
1211                        continue;
1212                if ((p = get_option(dhcp, opt->option, &pl))) {
1213                        ep += dhcp_envoption(ep, prefix, ifp->name,
1214                            opt, dhcp_getoption, p, pl);
1215                        if (opt->option == DHO_VIVSO &&
1216                            pl > (int)sizeof(uint32_t))
1217                        {
1218                                memcpy(&en, p, sizeof(en));
1219                                en = ntohl(en);
1220                                vo = vivso_find(en, ifp);
1221                                if (vo) {
1222                                        /* Skip over en + total size */
1223                                        p += sizeof(en) + 1;
1224                                        pl -= sizeof(en) + 1;
1225                                        ep += dhcp_envoption(ep, prefix,
1226                                            ifp->name,
1227                                            vo, dhcp_getoption, p, pl);
1228                                }
1229                        }
1230                }
1231        }
1232
1233        for (i = 0, opt = ifo->dhcp_override;
1234            i < ifo->dhcp_override_len;
1235            i++, opt++)
1236        {
1237                if (has_option_mask(ifo->nomask, opt->option))
1238                        continue;
1239                if ((p = get_option(dhcp, opt->option, &pl)))
1240                        ep += dhcp_envoption(ep, prefix, ifp->name,
1241                            opt, dhcp_getoption, p, pl);
1242        }
1243
1244        return ep - env;
1245}
1246
1247void
1248get_lease(struct dhcp_lease *lease, const struct dhcp_message *dhcp)
1249{
1250        struct timeval now;
1251
1252        lease->cookie = dhcp->cookie;
1253        /* BOOTP does not set yiaddr for replies when ciaddr is set. */
1254        if (dhcp->yiaddr)
1255                lease->addr.s_addr = dhcp->yiaddr;
1256        else
1257                lease->addr.s_addr = dhcp->ciaddr;
1258        if (get_option_addr(&lease->net, dhcp, DHO_SUBNETMASK) == -1)
1259                lease->net.s_addr = ipv4_getnetmask(lease->addr.s_addr);
1260        if (get_option_addr(&lease->brd, dhcp, DHO_BROADCAST) == -1)
1261                lease->brd.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
1262        if (get_option_uint32(&lease->leasetime, dhcp, DHO_LEASETIME) == 0) {
1263                /* Ensure that we can use the lease */
1264                get_monotonic(&now);
1265                if (now.tv_sec + (time_t)lease->leasetime < now.tv_sec)
1266                        lease->leasetime = ~0U; /* Infinite lease */
1267        } else
1268                lease->leasetime = ~0U; /* Default to infinite lease */
1269        if (get_option_uint32(&lease->renewaltime, dhcp, DHO_RENEWALTIME) != 0)
1270                lease->renewaltime = 0;
1271        if (get_option_uint32(&lease->rebindtime, dhcp, DHO_REBINDTIME) != 0)
1272                lease->rebindtime = 0;
1273        if (get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
1274                lease->server.s_addr = INADDR_ANY;
1275}
1276
1277static const char *
1278get_dhcp_op(uint8_t type)
1279{
1280        const struct dhcp_op *d;
1281
1282        for (d = dhcp_ops; d->name; d++)
1283                if (d->value == type)
1284                        return d->name;
1285        return NULL;
1286}
1287
1288static void
1289dhcp_fallback(void *arg)
1290{
1291        struct interface *iface;
1292
1293        iface = (struct interface *)arg;
1294        select_profile(iface, iface->options->fallback);
1295        start_interface(iface);
1296}
1297
1298uint32_t
1299dhcp_xid(const struct interface *ifp)
1300{
1301        uint32_t xid;
1302
1303        if (ifp->options->options & DHCPCD_XID_HWADDR &&
1304            ifp->hwlen >= sizeof(xid))
1305                /* The lower bits are probably more unique on the network */
1306                memcpy(&xid, (ifp->hwaddr + ifp->hwlen) - sizeof(xid),
1307                    sizeof(xid));
1308        else
1309                xid = arc4random();
1310
1311        return xid;
1312}
1313
1314void
1315dhcp_close(struct interface *ifp)
1316{
1317        struct dhcp_state *state = D_STATE(ifp);
1318
1319        if (state == NULL)
1320                return;
1321
1322        if (state->arp_fd != -1) {
1323                eloop_event_delete(state->arp_fd);
1324                close(state->arp_fd);
1325                state->arp_fd = -1;
1326        }
1327        if (state->raw_fd != -1) {
1328                eloop_event_delete(state->raw_fd);
1329                close(state->raw_fd);
1330                state->raw_fd = -1;
1331        }
1332        if (state->udp_fd != -1) {
1333                /* we don't listen to events on the udp */
1334                close(state->udp_fd);
1335                state->udp_fd = -1;
1336        }
1337
1338        state->interval = 0;
1339}
1340
1341static int
1342dhcp_openudp(struct interface *iface)
1343{
1344        int s;
1345        struct sockaddr_in sin;
1346        int n;
1347        struct dhcp_state *state;
1348#ifdef SO_BINDTODEVICE
1349        struct ifreq ifr;
1350        char *p;
1351#endif
1352
1353        if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
1354                return -1;
1355
1356        n = 1;
1357        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
1358                goto eexit;
1359#ifdef SO_BINDTODEVICE
1360        memset(&ifr, 0, sizeof(ifr));
1361        strlcpy(ifr.ifr_name, iface->name, sizeof(ifr.ifr_name));
1362        /* We can only bind to the real device */
1363        p = strchr(ifr.ifr_name, ':');
1364        if (p)
1365            *p = '\0';
1366        if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, &ifr,
1367                    sizeof(ifr)) == -1)
1368                goto eexit;
1369#endif
1370        /* As we don't use this socket for receiving, set the
1371         * receive buffer to 1 */
1372        n = 1;
1373        if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1)
1374                goto eexit;
1375        state = D_STATE(iface);
1376        memset(&sin, 0, sizeof(sin));
1377        sin.sin_family = AF_INET;
1378        sin.sin_port = htons(DHCP_CLIENT_PORT);
1379        sin.sin_addr.s_addr = state->addr.s_addr;
1380        if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
1381                goto eexit;
1382
1383        state->udp_fd = s;
1384        set_cloexec(s);
1385        return 0;
1386
1387eexit:
1388        close(s);
1389        return -1;
1390}
1391
1392static ssize_t
1393dhcp_sendpacket(const struct interface *iface, struct in_addr to,
1394    const uint8_t *data, ssize_t len)
1395{
1396        struct sockaddr_in sin;
1397
1398        memset(&sin, 0, sizeof(sin));
1399        sin.sin_family = AF_INET;
1400        sin.sin_addr.s_addr = to.s_addr;
1401        sin.sin_port = htons(DHCP_SERVER_PORT);
1402        return sendto(D_CSTATE(iface)->udp_fd, data, len, 0,
1403            (struct sockaddr *)&sin, sizeof(sin));
1404}
1405
1406static uint16_t
1407checksum(const void *data, uint16_t len)
1408{
1409        const uint8_t *addr = data;
1410        uint32_t sum = 0;
1411
1412        while (len > 1) {
1413                sum += addr[0] * 256 + addr[1];
1414                addr += 2;
1415                len -= 2;
1416        }
1417
1418        if (len == 1)
1419                sum += *addr * 256;
1420
1421        sum = (sum >> 16) + (sum & 0xffff);
1422        sum += (sum >> 16);
1423
1424        sum = htons(sum);
1425
1426        return ~sum;
1427}
1428
1429static ssize_t
1430dhcp_makeudppacket(uint8_t **p, const uint8_t *data, size_t length,
1431        struct in_addr source, struct in_addr dest)
1432{
1433        struct udp_dhcp_packet *udpp;
1434        struct ip *ip;
1435        struct udphdr *udp;
1436
1437        udpp = calloc(1, sizeof(*udpp));
1438        if (udpp == NULL)
1439                return -1;
1440        ip = &udpp->ip;
1441        udp = &udpp->udp;
1442
1443        /* OK, this is important :)
1444         * We copy the data to our packet and then create a small part of the
1445         * ip structure and an invalid ip_len (basically udp length).
1446         * We then fill the udp structure and put the checksum
1447         * of the whole packet into the udp checksum.
1448         * Finally we complete the ip structure and ip checksum.
1449         * If we don't do the ordering like so then the udp checksum will be
1450         * broken, so find another way of doing it! */
1451
1452        memcpy(&udpp->dhcp, data, length);
1453
1454        ip->ip_p = IPPROTO_UDP;
1455        ip->ip_src.s_addr = source.s_addr;
1456        if (dest.s_addr == 0)
1457                ip->ip_dst.s_addr = INADDR_BROADCAST;
1458        else
1459                ip->ip_dst.s_addr = dest.s_addr;
1460
1461        udp->uh_sport = htons(DHCP_CLIENT_PORT);
1462        udp->uh_dport = htons(DHCP_SERVER_PORT);
1463        udp->uh_ulen = htons(sizeof(*udp) + length);
1464        ip->ip_len = udp->uh_ulen;
1465        udp->uh_sum = checksum(udpp, sizeof(*udpp));
1466
1467        ip->ip_v = IPVERSION;
1468        ip->ip_hl = sizeof(*ip) >> 2;
1469        ip->ip_id = arc4random() & UINT16_MAX;
1470        ip->ip_ttl = IPDEFTTL;
1471        ip->ip_len = htons(sizeof(*ip) + sizeof(*udp) + length);
1472        ip->ip_sum = checksum(ip, sizeof(*ip));
1473
1474        *p = (uint8_t *)udpp;
1475        return sizeof(*ip) + sizeof(*udp) + length;
1476}
1477
1478static void
1479send_message(struct interface *iface, int type,
1480    void (*callback)(void *))
1481{
1482        struct dhcp_state *state = D_STATE(iface);
1483        struct if_options *ifo = iface->options;
1484        struct dhcp_message *dhcp;
1485        uint8_t *udp;
1486        ssize_t len, r;
1487        struct in_addr from, to;
1488        in_addr_t a = 0;
1489        struct timeval tv;
1490
1491        if (!callback)
1492                syslog(LOG_DEBUG, "%s: sending %s with xid 0x%x",
1493                    iface->name, get_dhcp_op(type), state->xid);
1494        else {
1495                if (state->interval == 0)
1496                        state->interval = 4;
1497                else {
1498                        state->interval *= 2;
1499                        if (state->interval > 64)
1500                                state->interval = 64;
1501                }
1502                tv.tv_sec = state->interval + DHCP_RAND_MIN;
1503                tv.tv_usec = arc4random() % (DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
1504                timernorm(&tv);
1505                syslog(LOG_DEBUG,
1506                    "%s: sending %s (xid 0x%x), next in %0.1f seconds",
1507                    iface->name, get_dhcp_op(type), state->xid,
1508                    timeval_to_double(&tv));
1509        }
1510
1511        /* Ensure sockets are open. */
1512        if (dhcp_open(iface) == -1) {
1513                if (!(options & DHCPCD_TEST))
1514                        dhcp_drop(iface, "FAIL");
1515                return;
1516        }
1517
1518        /* If we couldn't open a UDP port for our IP address
1519         * then we cannot renew.
1520         * This could happen if our IP was pulled out from underneath us.
1521         * Also, we should not unicast from a BOOTP lease. */
1522        if (state->udp_fd == -1 ||
1523            (!(ifo->options & DHCPCD_INFORM) && is_bootp(state->new)))
1524        {
1525                a = state->addr.s_addr;
1526                state->addr.s_addr = 0;
1527        }
1528        len = make_message(&dhcp, iface, type);
1529        if (a)
1530                state->addr.s_addr = a;
1531        from.s_addr = dhcp->ciaddr;
1532        if (from.s_addr)
1533                to.s_addr = state->lease.server.s_addr;
1534        else
1535                to.s_addr = 0;
1536        if (to.s_addr && to.s_addr != INADDR_BROADCAST) {
1537                r = dhcp_sendpacket(iface, to, (uint8_t *)dhcp, len);
1538                if (r == -1) {
1539                        syslog(LOG_ERR, "%s: dhcp_sendpacket: %m", iface->name);
1540                        dhcp_close(iface);
1541                }
1542        } else {
1543                len = dhcp_makeudppacket(&udp, (uint8_t *)dhcp, len, from, to);
1544                if (len == -1)
1545                        return;
1546                r = ipv4_sendrawpacket(iface, ETHERTYPE_IP, udp, len);
1547                free(udp);
1548                /* If we failed to send a raw packet this normally means
1549                 * we don't have the ability to work beneath the IP layer
1550                 * for this interface.
1551                 * As such we remove it from consideration without actually
1552                 * stopping the interface. */
1553                if (r == -1) {
1554                        syslog(LOG_ERR, "%s: ipv4_sendrawpacket: %m",
1555                            iface->name);
1556                        if (!(options & DHCPCD_TEST))
1557                                dhcp_drop(iface, "FAIL");
1558                        dhcp_close(iface);
1559                        eloop_timeout_delete(NULL, iface);
1560                        callback = NULL;
1561                }
1562        }
1563        free(dhcp);
1564
1565        /* Even if we fail to send a packet we should continue as we are
1566         * as our failure timeouts will change out codepath when needed. */
1567        if (callback)
1568                eloop_timeout_add_tv(&tv, callback, iface);
1569}
1570
1571static void
1572send_inform(void *arg)
1573{
1574
1575        send_message((struct interface *)arg, DHCP_INFORM, send_inform);
1576}
1577
1578static void
1579send_discover(void *arg)
1580{
1581
1582        send_message((struct interface *)arg, DHCP_DISCOVER, send_discover);
1583}
1584
1585static void
1586send_request(void *arg)
1587{
1588
1589        send_message((struct interface *)arg, DHCP_REQUEST, send_request);
1590}
1591
1592static void
1593send_renew(void *arg)
1594{
1595
1596        send_message((struct interface *)arg, DHCP_REQUEST, send_renew);
1597}
1598
1599static void
1600send_rebind(void *arg)
1601{
1602
1603        send_message((struct interface *)arg, DHCP_REQUEST, send_rebind);
1604}
1605
1606void
1607dhcp_discover(void *arg)
1608{
1609        struct interface *iface = arg;
1610        struct dhcp_state *state = D_STATE(iface);
1611        struct if_options *ifo = iface->options;
1612        int timeout = ifo->timeout;
1613
1614        /* If we're rebooting and we're not daemonised then we need
1615         * to shorten the normal timeout to ensure we try correctly
1616         * for a fallback or IPv4LL address. */
1617        if (state->state == DHS_REBOOT && !(options & DHCPCD_DAEMONISED)) {
1618                timeout -= ifo->reboot;
1619                if (timeout <= 0)
1620                        timeout = 2;
1621        }
1622
1623        state->state = DHS_DISCOVER;
1624        state->xid = dhcp_xid(iface);
1625        eloop_timeout_delete(NULL, iface);
1626        if (ifo->fallback)
1627                eloop_timeout_add_sec(timeout, dhcp_fallback, iface);
1628        else if (ifo->options & DHCPCD_IPV4LL &&
1629            !IN_LINKLOCAL(htonl(state->addr.s_addr)))
1630        {
1631                if (IN_LINKLOCAL(htonl(state->fail.s_addr)))
1632                        eloop_timeout_add_sec(RATE_LIMIT_INTERVAL,
1633                            ipv4ll_start, iface);
1634                else
1635                        eloop_timeout_add_sec(timeout, ipv4ll_start, iface);
1636        }
1637        if (ifo->options & DHCPCD_REQUEST)
1638                syslog(LOG_INFO, "%s: soliciting a DHCP lease (requesting %s)",
1639                    iface->name, inet_ntoa(ifo->req_addr));
1640        else
1641                syslog(LOG_INFO, "%s: soliciting a DHCP lease", iface->name);
1642        send_discover(iface);
1643}
1644
1645static void
1646dhcp_request(void *arg)
1647{
1648        struct interface *ifp = arg;
1649        struct dhcp_state *state = D_STATE(ifp);
1650
1651        state->state = DHS_REQUEST;
1652        send_request(ifp);
1653}
1654
1655static void
1656dhcp_expire(void *arg)
1657{
1658        struct interface *ifp = arg;
1659        struct dhcp_state *state = D_STATE(ifp);
1660
1661        syslog(LOG_ERR, "%s: DHCP lease expired", ifp->name);
1662        eloop_timeout_delete(NULL, ifp);
1663        dhcp_drop(ifp, "EXPIRE");
1664        unlink(state->leasefile);
1665
1666        state->interval = 0;
1667        dhcp_discover(ifp);
1668}
1669
1670void
1671dhcp_decline(struct interface *ifp)
1672{
1673
1674        send_message(ifp, DHCP_DECLINE, NULL);
1675}
1676
1677static void
1678dhcp_renew(void *arg)
1679{
1680        struct interface *ifp = arg;
1681        struct dhcp_state *state = D_STATE(ifp);
1682        struct dhcp_lease *lease = &state->lease;
1683
1684        syslog(LOG_DEBUG, "%s: renewing lease of %s",
1685            ifp->name, inet_ntoa(lease->addr));
1686        syslog(LOG_DEBUG, "%s: rebind in %"PRIu32" seconds,"
1687            " expire in %"PRIu32" seconds",
1688            ifp->name, lease->rebindtime - lease->renewaltime,
1689            lease->leasetime - lease->renewaltime);
1690        state->state = DHS_RENEW;
1691        state->xid = dhcp_xid(ifp);
1692        send_renew(ifp);
1693}
1694
1695static void
1696dhcp_rebind(void *arg)
1697{
1698        struct interface *ifp = arg;
1699        struct dhcp_state *state = D_STATE(ifp);
1700        struct dhcp_lease *lease = &state->lease;
1701
1702        syslog(LOG_WARNING, "%s: failed to renew DHCP, rebinding",
1703            ifp->name);
1704        syslog(LOG_DEBUG, "%s: expire in %"PRIu32" seconds",
1705            ifp->name, lease->leasetime - lease->rebindtime);
1706        state->state = DHS_REBIND;
1707        eloop_timeout_delete(send_renew, ifp);
1708        state->lease.server.s_addr = 0;
1709        ifp->options->options &= ~ DHCPCD_CSR_WARNED;
1710        send_rebind(ifp);
1711}
1712
1713void
1714dhcp_bind(void *arg)
1715{
1716        struct interface *iface = arg;
1717        struct dhcp_state *state = D_STATE(iface);
1718        struct if_options *ifo = iface->options;
1719        struct dhcp_lease *lease = &state->lease;
1720        struct timeval tv;
1721
1722        /* We're binding an address now - ensure that sockets are closed */
1723        dhcp_close(iface);
1724        state->reason = NULL;
1725        if (clock_monotonic)
1726                get_monotonic(&lease->boundtime);
1727        state->xid = 0;
1728        free(state->old);
1729        state->old = state->new;
1730        state->new = state->offer;
1731        state->offer = NULL;
1732        get_lease(lease, state->new);
1733        if (ifo->options & DHCPCD_STATIC) {
1734                syslog(LOG_INFO, "%s: using static address %s/%d",
1735                    iface->name, inet_ntoa(lease->addr),
1736                    inet_ntocidr(lease->net));
1737                lease->leasetime = ~0U;
1738                state->reason = "STATIC";
1739        } else if (state->new->cookie != htonl(MAGIC_COOKIE)) {
1740                syslog(LOG_INFO, "%s: using IPv4LL address %s",
1741                    iface->name, inet_ntoa(lease->addr));
1742                lease->leasetime = ~0U;
1743                state->reason = "IPV4LL";
1744        } else if (ifo->options & DHCPCD_INFORM) {
1745                if (ifo->req_addr.s_addr != 0)
1746                        lease->addr.s_addr = ifo->req_addr.s_addr;
1747                else
1748                        lease->addr.s_addr = state->addr.s_addr;
1749                syslog(LOG_INFO, "%s: received approval for %s", iface->name,
1750                    inet_ntoa(lease->addr));
1751                lease->leasetime = ~0U;
1752                state->reason = "INFORM";
1753        } else {
1754                if (gettimeofday(&tv, NULL) == 0)
1755                        lease->leasedfrom = tv.tv_sec;
1756                else if (lease->frominfo)
1757                        state->reason = "TIMEOUT";
1758                if (lease->leasetime == ~0U) {
1759                        lease->renewaltime =
1760                            lease->rebindtime =
1761                            lease->leasetime;
1762                        syslog(LOG_INFO, "%s: leased %s for infinity",
1763                            iface->name, inet_ntoa(lease->addr));
1764                } else {
1765                        if (lease->leasetime < DHCP_MIN_LEASE) {
1766                                syslog(LOG_WARNING,
1767                                    "%s: minimum lease is %d seconds",
1768                                    iface->name, DHCP_MIN_LEASE);
1769                                lease->leasetime = DHCP_MIN_LEASE;
1770                        }
1771                        if (lease->rebindtime == 0)
1772                                lease->rebindtime = lease->leasetime * T2;
1773                        else if (lease->rebindtime >= lease->leasetime) {
1774                                lease->rebindtime = lease->leasetime * T2;
1775                                syslog(LOG_WARNING,
1776                                    "%s: rebind time greater than lease "
1777                                    "time, forcing to %"PRIu32" seconds",
1778                                    iface->name, lease->rebindtime);
1779                        }
1780                        if (lease->renewaltime == 0)
1781                                lease->renewaltime = lease->leasetime * T1;
1782                        else if (lease->renewaltime > lease->rebindtime) {
1783                                lease->renewaltime = lease->leasetime * T1;
1784                                syslog(LOG_WARNING,
1785                                    "%s: renewal time greater than rebind "
1786                                    "time, forcing to %"PRIu32" seconds",
1787                                    iface->name, lease->renewaltime);
1788                        }
1789                        syslog(lease->addr.s_addr == state->addr.s_addr ?
1790                            LOG_DEBUG : LOG_INFO,
1791                            "%s: leased %s for %"PRIu32" seconds", iface->name,
1792                            inet_ntoa(lease->addr), lease->leasetime);
1793                }
1794        }
1795        if (options & DHCPCD_TEST) {
1796                state->reason = "TEST";
1797                script_runreason(iface, state->reason);
1798                exit(EXIT_SUCCESS);
1799        }
1800        if (state->reason == NULL) {
1801                if (state->old) {
1802                        if (state->old->yiaddr == state->new->yiaddr &&
1803                            lease->server.s_addr)
1804                                state->reason = "RENEW";
1805                        else
1806                                state->reason = "REBIND";
1807                } else if (state->state == DHS_REBOOT)
1808                        state->reason = "REBOOT";
1809                else
1810                        state->reason = "BOUND";
1811        }
1812        if (lease->leasetime == ~0U)
1813                lease->renewaltime = lease->rebindtime = lease->leasetime;
1814        else {
1815                eloop_timeout_add_sec(lease->renewaltime, dhcp_renew, iface);
1816                eloop_timeout_add_sec(lease->rebindtime, dhcp_rebind, iface);
1817                eloop_timeout_add_sec(lease->leasetime, dhcp_expire, iface);
1818                syslog(LOG_DEBUG,
1819                    "%s: renew in %"PRIu32" seconds, rebind in %"PRIu32
1820                    " seconds",
1821                    iface->name, lease->renewaltime, lease->rebindtime);
1822        }
1823        ipv4_applyaddr(iface);
1824        daemonise();
1825        state->state = DHS_BOUND;
1826        if (ifo->options & DHCPCD_ARP) {
1827                state->claims = 0;
1828                arp_announce(iface);
1829        }
1830}
1831
1832static void
1833dhcp_timeout(void *arg)
1834{
1835        struct interface *ifp = arg;
1836        struct dhcp_state *state = D_STATE(ifp);
1837
1838        dhcp_bind(ifp);
1839        state->interval = 0;
1840        dhcp_discover(ifp);
1841}
1842
1843struct dhcp_message *
1844dhcp_message_new(const struct in_addr *addr, const struct in_addr *mask)
1845{
1846        struct dhcp_message *dhcp;
1847        uint8_t *p;
1848
1849        dhcp = calloc(1, sizeof(*dhcp));
1850        if (dhcp == NULL)
1851                return NULL;
1852        dhcp->yiaddr = addr->s_addr;
1853        p = dhcp->options;
1854        if (mask && mask->s_addr != INADDR_ANY) {
1855                *p++ = DHO_SUBNETMASK;
1856                *p++ = sizeof(mask->s_addr);
1857                memcpy(p, &mask->s_addr, sizeof(mask->s_addr));
1858                p+= sizeof(mask->s_addr);
1859        }
1860        *p++ = DHO_END;
1861        return dhcp;
1862}
1863
1864static void
1865dhcp_static(struct interface *ifp)
1866{
1867        struct if_options *ifo;
1868        struct dhcp_state *state;
1869
1870        state = D_STATE(ifp);
1871        ifo = ifp->options;
1872        if (ifo->req_addr.s_addr == INADDR_ANY) {
1873                syslog(LOG_INFO,
1874                    "%s: waiting for 3rd party to "
1875                    "configure IP address",
1876                    ifp->name);
1877                state->reason = "3RDPARTY";
1878                script_runreason(ifp, state->reason);
1879                return;
1880        }
1881        state->offer = dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
1882        if (state->offer) {
1883                eloop_timeout_delete(NULL, ifp);
1884                dhcp_bind(ifp);
1885        }
1886}
1887
1888void
1889dhcp_inform(struct interface *ifp)
1890{
1891        struct dhcp_state *state;
1892        struct if_options *ifo;
1893        struct ipv4_addr *ap;
1894
1895        state = D_STATE(ifp);
1896        ifo = ifp->options;
1897        if (options & DHCPCD_TEST) {
1898                state->addr.s_addr = ifo->req_addr.s_addr;
1899                state->net.s_addr = ifo->req_mask.s_addr;
1900        } else {
1901                if (ifo->req_addr.s_addr == INADDR_ANY) {
1902                        state = D_STATE(ifp);
1903                        ap = ipv4_findaddr(ifp, NULL, NULL);
1904                        if (ap == NULL) {
1905                                syslog(LOG_INFO,
1906                                        "%s: waiting for 3rd party to "
1907                                        "configure IP address",
1908                                        ifp->name);
1909                                state->reason = "3RDPARTY";
1910                                script_runreason(ifp, state->reason);
1911                                return;
1912                        }
1913                        state->offer =
1914                            dhcp_message_new(&ap->addr, &ap->net);
1915                } else
1916                        state->offer =
1917                            dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
1918                if (state->offer) {
1919                        ifo->options |= DHCPCD_STATIC;
1920                        dhcp_bind(ifp);
1921                        ifo->options &= ~DHCPCD_STATIC;
1922                }
1923        }
1924
1925        state->state = DHS_INFORM;
1926        state->xid = dhcp_xid(ifp);
1927        send_inform(ifp);
1928}
1929
1930void
1931dhcp_reboot_newopts(struct interface *ifp, int oldopts)
1932{
1933        struct if_options *ifo;
1934        struct dhcp_state *state = D_STATE(ifp);
1935
1936        if (state == NULL)
1937                return;
1938        ifo = ifp->options;
1939        if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
1940                state->addr.s_addr != ifo->req_addr.s_addr) ||
1941            (oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) &&
1942                !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
1943        {
1944                dhcp_drop(ifp, "EXPIRE");
1945        }
1946}
1947
1948static void
1949dhcp_reboot(struct interface *ifp)
1950{
1951        struct if_options *ifo;
1952        struct dhcp_state *state = D_STATE(ifp);
1953
1954        if (state == NULL)
1955                return;
1956        ifo = ifp->options;
1957        state->interval = 0;
1958
1959        if (ifo->options & DHCPCD_LINK && ifp->carrier == LINK_DOWN) {
1960                syslog(LOG_INFO, "%s: waiting for carrier", ifp->name);
1961                return;
1962        }
1963        if (ifo->options & DHCPCD_STATIC) {
1964                dhcp_static(ifp);
1965                return;
1966        }
1967        if (ifo->reboot == 0 || state->offer == NULL) {
1968                dhcp_discover(ifp);
1969                return;
1970        }
1971        if (ifo->options & DHCPCD_INFORM) {
1972                syslog(LOG_INFO, "%s: informing address of %s",
1973                    ifp->name, inet_ntoa(state->lease.addr));
1974        } else if (state->offer->cookie == 0) {
1975                if (ifo->options & DHCPCD_IPV4LL) {
1976                        state->claims = 0;
1977                        arp_announce(ifp);
1978                } else
1979                        dhcp_discover(ifp);
1980                return;
1981        } else {
1982                syslog(LOG_INFO, "%s: rebinding lease of %s",
1983                    ifp->name, inet_ntoa(state->lease.addr));
1984        }
1985        state->state = DHS_REBOOT;
1986        state->xid = dhcp_xid(ifp);
1987        state->lease.server.s_addr = 0;
1988        eloop_timeout_delete(NULL, ifp);
1989        if (ifo->fallback)
1990                eloop_timeout_add_sec(ifo->reboot, dhcp_fallback, ifp);
1991        else if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo)
1992                eloop_timeout_add_sec(ifo->reboot, dhcp_timeout, ifp);
1993        else if (!(ifo->options & DHCPCD_INFORM &&
1994            options & (DHCPCD_MASTER | DHCPCD_DAEMONISED)))
1995                eloop_timeout_add_sec(ifo->reboot, dhcp_expire, ifp);
1996        /* Don't bother ARP checking as the server could NAK us first. */
1997        if (ifo->options & DHCPCD_INFORM)
1998                dhcp_inform(ifp);
1999        else
2000                dhcp_request(ifp);
2001}
2002
2003void
2004dhcp_drop(struct interface *ifp, const char *reason)
2005{
2006        struct dhcp_state *state;
2007#ifdef RELEASE_SLOW
2008        struct timespec ts;
2009#endif
2010
2011        state = D_STATE(ifp);
2012        if (state == NULL)
2013                return;
2014        eloop_timeouts_delete(ifp, dhcp_expire, NULL);
2015        if (ifp->options->options & DHCPCD_RELEASE) {
2016                unlink(state->leasefile);
2017                if (ifp->carrier != LINK_DOWN &&
2018                    state->new != NULL &&
2019                    state->new->cookie == htonl(MAGIC_COOKIE))
2020                {
2021                        syslog(LOG_INFO, "%s: releasing lease of %s",
2022                            ifp->name, inet_ntoa(state->lease.addr));
2023                        state->xid = dhcp_xid(ifp);
2024                        send_message(ifp, DHCP_RELEASE, NULL);
2025#ifdef RELEASE_SLOW
2026                        /* Give the packet a chance to go */
2027                        ts.tv_sec = RELEASE_DELAY_S;
2028                        ts.tv_nsec = RELEASE_DELAY_NS;
2029                        nanosleep(&ts, NULL);
2030#endif
2031                }
2032        }
2033        free(state->old);
2034        state->old = state->new;
2035        state->new = NULL;
2036        state->reason = reason;
2037        ipv4_applyaddr(ifp);
2038        free(state->old);
2039        state->old = NULL;
2040        state->lease.addr.s_addr = 0;
2041        ifp->options->options &= ~ DHCPCD_CSR_WARNED;
2042        state->auth.token = NULL;
2043        state->auth.replay = 0;
2044        free(state->auth.reconf);
2045        state->auth.reconf = NULL;
2046}
2047
2048static void
2049log_dhcp(int lvl, const char *msg,
2050    const struct interface *iface, const struct dhcp_message *dhcp,
2051    const struct in_addr *from)
2052{
2053        const char *tfrom;
2054        char *a;
2055        struct in_addr addr;
2056        int r;
2057
2058        if (strcmp(msg, "NAK:") == 0)
2059                a = get_option_string(dhcp, DHO_MESSAGE);
2060        else if (dhcp->yiaddr != 0) {
2061                addr.s_addr = dhcp->yiaddr;
2062                a = strdup(inet_ntoa(addr));
2063                if (a == NULL) {
2064                        syslog(LOG_ERR, "%s: %m", __func__);
2065                        return;
2066                }
2067        } else
2068                a = NULL;
2069
2070        tfrom = "from";
2071        r = get_option_addr(&addr, dhcp, DHO_SERVERID);
2072        if (dhcp->servername[0] && r == 0)
2073                syslog(lvl, "%s: %s %s %s %s `%s'", iface->name, msg, a,
2074                    tfrom, inet_ntoa(addr), dhcp->servername);
2075        else {
2076                if (r != 0) {
2077                        tfrom = "via";
2078                        addr = *from;
2079                }
2080                if (a == NULL)
2081                        syslog(lvl, "%s: %s %s %s",
2082                            iface->name, msg, tfrom, inet_ntoa(addr));
2083                else
2084                        syslog(lvl, "%s: %s %s %s %s",
2085                            iface->name, msg, a, tfrom, inet_ntoa(addr));
2086        }
2087        free(a);
2088}
2089
2090static int
2091blacklisted_ip(const struct if_options *ifo, in_addr_t addr)
2092{
2093        size_t i;
2094
2095        for (i = 0; i < ifo->blacklist_len; i += 2)
2096                if (ifo->blacklist[i] == (addr & ifo->blacklist[i + 1]))
2097                        return 1;
2098        return 0;
2099}
2100
2101static int
2102whitelisted_ip(const struct if_options *ifo, in_addr_t addr)
2103{
2104        size_t i;
2105
2106        if (ifo->whitelist_len == 0)
2107                return -1;
2108        for (i = 0; i < ifo->whitelist_len; i += 2)
2109                if (ifo->whitelist[i] == (addr & ifo->whitelist[i + 1]))
2110                        return 1;
2111        return 0;
2112}
2113
2114static void
2115dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp,
2116    const struct in_addr *from)
2117{
2118        struct dhcp_state *state = D_STATE(iface);
2119        struct if_options *ifo = iface->options;
2120        struct dhcp_message *dhcp = *dhcpp;
2121        struct dhcp_lease *lease = &state->lease;
2122        uint8_t type, tmp;
2123        const uint8_t *auth;
2124        struct in_addr addr;
2125        size_t i;
2126        int auth_len;
2127
2128        /* We may have found a BOOTP server */
2129        if (get_option_uint8(&type, dhcp, DHO_MESSAGETYPE) == -1)
2130                type = 0;
2131
2132        /* Authenticate the message */
2133        auth = get_option(dhcp, DHO_AUTHENTICATION, &auth_len);
2134        if (auth) {
2135                if (dhcp_auth_validate(&state->auth, &ifo->auth,
2136                    (uint8_t *)*dhcpp, sizeof(**dhcpp), 4, type,
2137                    auth, auth_len) == NULL)
2138                {
2139                        syslog(LOG_DEBUG, "%s: dhcp_auth_validate: %m",
2140                            iface->name);
2141                        log_dhcp(LOG_ERR, "authentication failed",
2142                            iface, dhcp, from);
2143                        return;
2144                }
2145                syslog(LOG_DEBUG, "%s: validated using 0x%08" PRIu32,
2146                    iface->name, state->auth.token->secretid);
2147        } else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
2148                log_dhcp(LOG_ERR, "missing authentiation", iface, dhcp, from);
2149                return;
2150        }
2151
2152        /* reset the message counter */
2153        state->interval = 0;
2154
2155        if (type == DHCP_NAK) {
2156                /* For NAK, only check if we require the ServerID */
2157                if (has_option_mask(ifo->requiremask, DHO_SERVERID) &&
2158                    get_option_addr(&addr, dhcp, DHO_SERVERID) == -1)
2159                {
2160                        log_dhcp(LOG_WARNING, "reject NAK", iface, dhcp, from);
2161                        return;
2162                }
2163                /* We should restart on a NAK */
2164                log_dhcp(LOG_WARNING, "NAK:", iface, dhcp, from);
2165                if (!(options & DHCPCD_TEST)) {
2166                        dhcp_drop(iface, "NAK");
2167                        unlink(state->leasefile);
2168                }
2169                dhcp_close(iface);
2170                /* If we constantly get NAKS then we should slowly back off */
2171                eloop_timeout_add_sec(state->nakoff, dhcp_discover, iface);
2172                if (state->nakoff == 0)
2173                        state->nakoff = 1;
2174                else {
2175                        state->nakoff *= 2;
2176                        if (state->nakoff > NAKOFF_MAX)
2177                                state->nakoff = NAKOFF_MAX;
2178                }
2179                return;
2180        }
2181
2182        /* Ensure that all required options are present */
2183        for (i = 1; i < 255; i++) {
2184                if (has_option_mask(ifo->requiremask, i) &&
2185                    get_option_uint8(&tmp, dhcp, i) != 0)
2186                {
2187                        /* If we are bootp, then ignore the need for serverid.
2188                         * To ignore bootp, require dhcp_message_type. */
2189                        if (type == 0 && i == DHO_SERVERID)
2190                                continue;
2191                        log_dhcp(LOG_WARNING, "reject DHCP", iface, dhcp, from);
2192                        return;
2193                }
2194        }
2195
2196        /* Ensure that the address offered is valid */
2197        if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) &&
2198            (dhcp->ciaddr == INADDR_ANY || dhcp->ciaddr == INADDR_BROADCAST) &&
2199            (dhcp->yiaddr == INADDR_ANY || dhcp->yiaddr == INADDR_BROADCAST))
2200        {
2201                log_dhcp(LOG_WARNING, "reject invalid address",
2202                    iface, dhcp, from);
2203                return;
2204        }
2205
2206        if ((type == 0 || type == DHCP_OFFER) &&
2207            state->state == DHS_DISCOVER)
2208        {
2209                lease->frominfo = 0;
2210                lease->addr.s_addr = dhcp->yiaddr;
2211                lease->cookie = dhcp->cookie;
2212                if (type == 0 ||
2213                    get_option_addr(&lease->server, dhcp, DHO_SERVERID) != 0)
2214                        lease->server.s_addr = INADDR_ANY;
2215                log_dhcp(LOG_INFO, "offered", iface, dhcp, from);
2216                free(state->offer);
2217                state->offer = dhcp;
2218                *dhcpp = NULL;
2219                if (options & DHCPCD_TEST) {
2220                        free(state->old);
2221                        state->old = state->new;
2222                        state->new = state->offer;
2223                        state->offer = NULL;
2224                        state->reason = "TEST";
2225                        script_runreason(iface, state->reason);
2226                        exit(EXIT_SUCCESS);
2227                }
2228                eloop_timeout_delete(send_discover, iface);
2229                /* We don't request BOOTP addresses */
2230                if (type) {
2231                        /* We used to ARP check here, but that seems to be in
2232                         * violation of RFC2131 where it only describes
2233                         * DECLINE after REQUEST.
2234                         * It also seems that some MS DHCP servers actually
2235                         * ignore DECLINE if no REQUEST, ie we decline a
2236                         * DISCOVER. */
2237                        dhcp_request(iface);
2238                        return;
2239                }
2240        }
2241
2242        if (type) {
2243                if (type == DHCP_OFFER) {
2244                        log_dhcp(LOG_WARNING, "ignoring offer of",
2245                            iface, dhcp, from);
2246                        return;
2247                }
2248
2249                /* We should only be dealing with acks */
2250                if (type != DHCP_ACK) {
2251                        log_dhcp(LOG_ERR, "not ACK or OFFER",
2252                            iface, dhcp, from);
2253                        return;
2254                }
2255
2256                if (!(ifo->options & DHCPCD_INFORM))
2257                        log_dhcp(LOG_DEBUG, "acknowledged", iface, dhcp, from);
2258                else
2259                    ifo->options &= ~DHCPCD_STATIC;
2260        }
2261
2262
2263        /* No NAK, so reset the backoff
2264         * We don't reset on an OFFER message because the server could
2265         * potentially NAK the REQUEST. */
2266        state->nakoff = 0;
2267
2268        /* BOOTP could have already assigned this above, so check we still
2269         * have a pointer. */
2270        if (*dhcpp) {
2271                free(state->offer);
2272                state->offer = dhcp;
2273                *dhcpp = NULL;
2274        }
2275
2276        lease->frominfo = 0;
2277        eloop_timeout_delete(NULL, iface);
2278
2279        /* We now have an offer, so close the DHCP sockets.
2280         * This allows us to safely ARP when broken DHCP servers send an ACK
2281         * follows by an invalid NAK. */
2282        dhcp_close(iface);
2283
2284        if (ifo->options & DHCPCD_ARP &&
2285            state->addr.s_addr != state->offer->yiaddr)
2286        {
2287                /* If the interface already has the address configured
2288                 * then we can't ARP for duplicate detection. */
2289                addr.s_addr = state->offer->yiaddr;
2290                if (!ipv4_findaddr(iface, &addr, NULL)) {
2291                        state->claims = 0;
2292                        state->probes = 0;
2293                        state->conflicts = 0;
2294                        state->state = DHS_PROBE;
2295                        arp_probe(iface);
2296                        return;
2297                }
2298        }
2299
2300        dhcp_bind(iface);
2301}
2302
2303static ssize_t
2304get_udp_data(const uint8_t **data, const uint8_t *udp)
2305{
2306        struct udp_dhcp_packet p;
2307
2308        memcpy(&p, udp, sizeof(p));
2309        *data = udp + offsetof(struct udp_dhcp_packet, dhcp);
2310        return ntohs(p.ip.ip_len) - sizeof(p.ip) - sizeof(p.udp);
2311}
2312
2313static int
2314valid_udp_packet(const uint8_t *data, size_t data_len, struct in_addr *from,
2315    int noudpcsum)
2316{
2317        struct udp_dhcp_packet p;
2318        uint16_t bytes, udpsum;
2319
2320        if (data_len < sizeof(p.ip)) {
2321                if (from)
2322                        from->s_addr = INADDR_ANY;
2323                errno = EINVAL;
2324                return -1;
2325        }
2326        memcpy(&p, data, MIN(data_len, sizeof(p)));
2327        if (from)
2328                from->s_addr = p.ip.ip_src.s_addr;
2329        if (data_len > sizeof(p)) {
2330                errno = EINVAL;
2331                return -1;
2332        }
2333        if (checksum(&p.ip, sizeof(p.ip)) != 0) {
2334                errno = EINVAL;
2335                return -1;
2336        }
2337
2338        bytes = ntohs(p.ip.ip_len);
2339        if (data_len < bytes) {
2340                errno = EINVAL;
2341                return -1;
2342        }
2343
2344        if (noudpcsum == 0) {
2345                udpsum = p.udp.uh_sum;
2346                p.udp.uh_sum = 0;
2347                p.ip.ip_hl = 0;
2348                p.ip.ip_v = 0;
2349                p.ip.ip_tos = 0;
2350                p.ip.ip_len = p.udp.uh_ulen;
2351                p.ip.ip_id = 0;
2352                p.ip.ip_off = 0;
2353                p.ip.ip_ttl = 0;
2354                p.ip.ip_sum = 0;
2355                if (udpsum && checksum(&p, bytes) != udpsum) {
2356                        errno = EINVAL;
2357                        return -1;
2358                }
2359        }
2360
2361        return 0;
2362}
2363
2364static void
2365dhcp_handlepacket(void *arg)
2366{
2367        struct interface *iface = arg;
2368        struct dhcp_message *dhcp = NULL;
2369        const uint8_t *pp;
2370        ssize_t bytes;
2371        struct in_addr from;
2372        int i, partialcsum = 0;
2373        const struct dhcp_state *state = D_CSTATE(iface);
2374
2375        /* We loop through until our buffer is empty.
2376         * The benefit is that if we get >1 DHCP packet in our buffer and
2377         * the first one fails for any reason, we can use the next. */
2378        for(;;) {
2379                bytes = ipv4_getrawpacket(iface, ETHERTYPE_IP,
2380                    packet, udp_dhcp_len, &partialcsum);
2381                if (bytes == 0 || bytes == -1)
2382                        break;
2383                if (valid_udp_packet(packet, bytes, &from, partialcsum) == -1) {
2384                        syslog(LOG_ERR, "%s: invalid UDP packet from %s",
2385                            iface->name, inet_ntoa(from));
2386                        continue;
2387                }
2388                i = whitelisted_ip(iface->options, from.s_addr);
2389                if (i == 0) {
2390                        syslog(LOG_WARNING,
2391                            "%s: non whitelisted DHCP packet from %s",
2392                            iface->name, inet_ntoa(from));
2393                        continue;
2394                } else if (i != 1 &&
2395                    blacklisted_ip(iface->options, from.s_addr) == 1)
2396                {
2397                        syslog(LOG_WARNING,
2398                            "%s: blacklisted DHCP packet from %s",
2399                            iface->name, inet_ntoa(from));
2400                        continue;
2401                }
2402                if (iface->flags & IFF_POINTOPOINT &&
2403                    state->dst.s_addr != from.s_addr)
2404                {
2405                        syslog(LOG_WARNING,
2406                            "%s: server %s is not destination",
2407                            iface->name, inet_ntoa(from));
2408                }
2409                bytes = get_udp_data(&pp, packet);
2410                if ((size_t)bytes > sizeof(*dhcp)) {
2411                        syslog(LOG_ERR,
2412                            "%s: packet greater than DHCP size from %s",
2413                            iface->name, inet_ntoa(from));
2414                        continue;
2415                }
2416                if (dhcp == NULL) {
2417                        dhcp = calloc(1, sizeof(*dhcp));
2418                        if (dhcp == NULL) {
2419                                syslog(LOG_ERR, "%s: calloc: %m", __func__);
2420                                break;
2421                        }
2422                }
2423                memcpy(dhcp, pp, bytes);
2424                if (dhcp->cookie != htonl(MAGIC_COOKIE)) {
2425                        syslog(LOG_DEBUG, "%s: bogus cookie from %s",
2426                            iface->name, inet_ntoa(from));
2427                        continue;
2428                }
2429                /* Ensure it's the right transaction */
2430                if (state->xid != ntohl(dhcp->xid)) {
2431                        syslog(LOG_DEBUG,
2432                            "%s: wrong xid 0x%x (expecting 0x%x) from %s",
2433                            iface->name, ntohl(dhcp->xid), state->xid,
2434                            inet_ntoa(from));
2435                        continue;
2436                }
2437                /* Ensure packet is for us */
2438                if (iface->hwlen <= sizeof(dhcp->chaddr) &&
2439                    memcmp(dhcp->chaddr, iface->hwaddr, iface->hwlen))
2440                {
2441                        syslog(LOG_DEBUG, "%s: xid 0x%x is not for hwaddr %s",
2442                            iface->name, ntohl(dhcp->xid),
2443                            hwaddr_ntoa(dhcp->chaddr, sizeof(dhcp->chaddr)));
2444                        continue;
2445                }
2446                dhcp_handledhcp(iface, &dhcp, &from);
2447                if (state->raw_fd == -1)
2448                        break;
2449        }
2450        free(dhcp);
2451}
2452
2453static int
2454dhcp_open(struct interface *ifp)
2455{
2456        struct dhcp_state *state;
2457
2458        if (packet == NULL) {
2459                packet = malloc(udp_dhcp_len);
2460                if (packet == NULL) {
2461                        syslog(LOG_ERR, "%s: %m", __func__);
2462                        return -1;
2463                }
2464#ifdef DEBUG_MEMORY
2465                atexit(dhcp_cleanup);
2466#endif
2467        }
2468
2469        state = D_STATE(ifp);
2470        if (state->raw_fd == -1) {
2471                state->raw_fd = ipv4_opensocket(ifp, ETHERTYPE_IP);
2472                if (state->raw_fd == -1) {
2473                        syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name);
2474                        return -1;
2475                }
2476                eloop_event_add(state->raw_fd, dhcp_handlepacket, ifp);
2477        }
2478        if (state->udp_fd == -1 &&
2479            state->addr.s_addr != 0 &&
2480            state->new != NULL &&
2481            (state->new->cookie == htonl(MAGIC_COOKIE) ||
2482            ifp->options->options & DHCPCD_INFORM))
2483        {
2484                if (dhcp_openudp(ifp) == -1 && errno != EADDRINUSE) {
2485                        syslog(LOG_ERR, "%s: dhcp_openudp: %m", ifp->name);
2486                        return -1;
2487                }
2488        }
2489        return 0;
2490}
2491
2492int
2493dhcp_dump(const char *ifname)
2494{
2495        struct interface *ifp;
2496        struct dhcp_state *state;
2497
2498        ifaces = malloc(sizeof(*ifaces));
2499        if (ifaces == NULL)
2500                goto eexit;
2501        TAILQ_INIT(ifaces);
2502        ifp = calloc(1, sizeof(*ifp));
2503        if (ifp == NULL)
2504                goto eexit;
2505        TAILQ_INSERT_HEAD(ifaces, ifp, next);
2506        ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
2507        if (state == NULL)
2508                goto eexit;
2509        ifp->options = calloc(1, sizeof(*ifp->options));
2510        if (ifp->options == NULL)
2511                goto eexit;
2512        strlcpy(ifp->name, ifname, sizeof(ifp->name));
2513        snprintf(state->leasefile, sizeof(state->leasefile),
2514            LEASEFILE, ifp->name);
2515        strlcpy(ifp->options->script, if_options->script,
2516            sizeof(ifp->options->script));
2517        state->new = read_lease(ifp);
2518        if (state->new == NULL && errno == ENOENT) {
2519                strlcpy(state->leasefile, ifname, sizeof(state->leasefile));
2520                state->new = read_lease(ifp);
2521        }
2522        if (state->new == NULL) {
2523                if (errno == ENOENT)
2524                        syslog(LOG_ERR, "%s: no lease to dump", ifname);
2525                return -1;
2526        }
2527        state->reason = "DUMP";
2528        return script_runreason(ifp, state->reason);
2529
2530eexit:
2531        syslog(LOG_ERR, "%s: %m", __func__);
2532        return -1;
2533}
2534
2535void
2536dhcp_free(struct interface *ifp)
2537{
2538        struct dhcp_state *state = D_STATE(ifp);
2539
2540        if (state) {
2541                free(state->old);
2542                free(state->new);
2543                free(state->offer);
2544                free(state->buffer);
2545                free(state->clientid);
2546                free(state);
2547                ifp->if_data[IF_DATA_DHCP] = NULL;
2548        }
2549}
2550
2551static int
2552dhcp_init(struct interface *ifp)
2553{
2554        struct dhcp_state *state;
2555        const struct if_options *ifo;
2556        size_t len;
2557
2558        state = D_STATE(ifp);
2559        if (state == NULL) {
2560                ifp->if_data[IF_DATA_DHCP] = calloc(1, sizeof(*state));
2561                state = D_STATE(ifp);
2562                if (state == NULL)
2563                        return -1;
2564                /* 0 is a valid fd, so init to -1 */
2565                state->raw_fd = state->udp_fd = state->arp_fd = -1;
2566        }
2567
2568        state->state = DHS_INIT;
2569        state->reason = "PREINIT";
2570        state->nakoff = 0;
2571        snprintf(state->leasefile, sizeof(state->leasefile),
2572            LEASEFILE, ifp->name);
2573
2574        ifo = ifp->options;
2575        /* We need to drop the leasefile so that start_interface
2576         * doesn't load it. */
2577        if (ifo->options & DHCPCD_REQUEST)
2578                unlink(state->leasefile);
2579
2580        free(state->clientid);
2581        state->clientid = NULL;
2582
2583        if (*ifo->clientid) {
2584                state->clientid = malloc(ifo->clientid[0] + 1);
2585                if (state->clientid == NULL)
2586                        goto eexit;
2587                memcpy(state->clientid, ifo->clientid, ifo->clientid[0] + 1);
2588        } else if (ifo->options & DHCPCD_CLIENTID) {
2589                if (ifo->options & DHCPCD_DUID) {
2590                        state->clientid = malloc(duid_len + 6);
2591                        if (state->clientid == NULL)
2592                                goto eexit;
2593                        state->clientid[0] = duid_len + 5;
2594                        state->clientid[1] = 255; /* RFC 4361 */
2595                        memcpy(state->clientid + 2, ifo->iaid, 4);
2596                        memcpy(state->clientid + 6, duid, duid_len);
2597                } else {
2598                        len = ifp->hwlen + 1;
2599                        state->clientid = malloc(len + 1);
2600                        if (state->clientid == NULL)
2601                                goto eexit;
2602                        state->clientid[0] = len;
2603                        state->clientid[1] = ifp->family;
2604                        memcpy(state->clientid + 2, ifp->hwaddr,
2605                            ifp->hwlen);
2606                }
2607        }
2608
2609        if (ifo->options & DHCPCD_DUID)
2610                /* Don't bother logging as DUID and IAID are reported
2611                 * at device start. */
2612                return 0;
2613
2614        if (ifo->options & DHCPCD_CLIENTID)
2615                syslog(LOG_DEBUG, "%s: using ClientID %s", ifp->name,
2616                    hwaddr_ntoa(state->clientid + 1, state->clientid[0]));
2617        else if (ifp->hwlen)
2618                syslog(LOG_DEBUG, "%s: using hwaddr %s", ifp->name,
2619                    hwaddr_ntoa(ifp->hwaddr, ifp->hwlen));
2620        return 0;
2621
2622eexit:
2623        syslog(LOG_ERR, "%s: Error making ClientID: %m", __func__);
2624        return -1;
2625}
2626
2627void
2628dhcp_start(struct interface *ifp)
2629{
2630        struct if_options *ifo = ifp->options;
2631        struct dhcp_state *state;
2632        struct stat st;
2633        struct timeval now;
2634        uint32_t l;
2635        int nolease;
2636
2637        if (!(ifo->options & DHCPCD_IPV4))
2638                return;
2639
2640        if (dhcp_init(ifp) == -1) {
2641                syslog(LOG_ERR, "%s: dhcp_init: %m", ifp->name);
2642                return;
2643        }
2644
2645        /* Close any pre-existing sockets as we're starting over */
2646        dhcp_close(ifp);
2647
2648        state = D_STATE(ifp);
2649        state->start_uptime = uptime();
2650        free(state->offer);
2651        state->offer = NULL;
2652
2653        if (state->arping_index < ifo->arping_len) {
2654                arp_start(ifp);
2655                return;
2656        }
2657
2658        if (ifo->options & DHCPCD_STATIC) {
2659                dhcp_static(ifp);
2660                return;
2661        }
2662
2663        if (ifo->options & DHCPCD_DHCP && dhcp_open(ifp) == -1)
2664                return;
2665
2666        if (ifo->options & DHCPCD_INFORM) {
2667                dhcp_inform(ifp);
2668                return;
2669        }
2670        if (ifp->hwlen == 0 && ifo->clientid[0] == '\0') {
2671                syslog(LOG_WARNING, "%s: needs a clientid to configure",
2672                    ifp->name);
2673                dhcp_drop(ifp, "FAIL");
2674                dhcp_close(ifp);
2675                eloop_timeout_delete(NULL, ifp);
2676                return;
2677        }
2678        /* We don't want to read the old lease if we NAK an old test */
2679        nolease = state->offer && options & DHCPCD_TEST;
2680        if (!nolease)
2681                state->offer = read_lease(ifp);
2682        if (state->offer) {
2683                get_lease(&state->lease, state->offer);
2684                state->lease.frominfo = 1;
2685                if (state->offer->cookie == 0) {
2686                        if (state->offer->yiaddr == state->addr.s_addr) {
2687                                free(state->offer);
2688                                state->offer = NULL;
2689                        }
2690                } else if (state->lease.leasetime != ~0U &&
2691                    stat(state->leasefile, &st) == 0)
2692                {
2693                        /* Offset lease times and check expiry */
2694                        gettimeofday(&now, NULL);
2695                        if ((time_t)state->lease.leasetime <
2696                            now.tv_sec - st.st_mtime)
2697                        {
2698                                syslog(LOG_DEBUG,
2699                                    "%s: discarding expired lease",
2700                                    ifp->name);
2701                                free(state->offer);
2702                                state->offer = NULL;
2703                                state->lease.addr.s_addr = 0;
2704                        } else {
2705                                l = now.tv_sec - st.st_mtime;
2706                                state->lease.leasetime -= l;
2707                                state->lease.renewaltime -= l;
2708                                state->lease.rebindtime -= l;
2709                        }
2710                }
2711        }
2712
2713        if (!(ifo->options & DHCPCD_DHCP)) {
2714                if (ifo->options & DHCPCD_IPV4LL) {
2715                        if (state->offer && state->offer->cookie != 0) {
2716                                free(state->offer);
2717                                state->offer = NULL;
2718                        }
2719                        ipv4ll_start(ifp);
2720                }
2721                return;
2722        }
2723
2724        if (state->offer == NULL)
2725                dhcp_discover(ifp);
2726        else if (state->offer->cookie == 0 && ifo->options & DHCPCD_IPV4LL)
2727                ipv4ll_start(ifp);
2728        else
2729                dhcp_reboot(ifp);
2730}
2731
2732void
2733dhcp_handleifa(int type, struct interface *ifp,
2734        const struct in_addr *addr,
2735        const struct in_addr *net,
2736        const struct in_addr *dst)
2737{
2738        struct dhcp_state *state;
2739        struct if_options *ifo;
2740        int i;
2741
2742        state = D_STATE(ifp);
2743        if (state == NULL)
2744                return;
2745
2746        if (type == RTM_DELADDR) {
2747                if (state->new &&
2748                    (state->new->yiaddr == addr->s_addr ||
2749                    (state->new->yiaddr == INADDR_ANY &&
2750                     state->new->ciaddr == addr->s_addr)))
2751                {
2752                        syslog(LOG_INFO, "%s: removing IP address %s/%d",
2753                            ifp->name, inet_ntoa(state->lease.addr),
2754                            inet_ntocidr(state->lease.net));
2755                        dhcp_drop(ifp, "EXPIRE");
2756                }
2757                return;
2758        }
2759
2760        if (type != RTM_NEWADDR)
2761                return;
2762
2763        ifo = ifp->options;
2764        if (ifo->options & DHCPCD_INFORM) {
2765                if (state->state != DHS_INFORM)
2766                        dhcp_inform(ifp);
2767                return;
2768        }
2769
2770        if (!(ifo->options & DHCPCD_STATIC))
2771                return;
2772        if (ifo->req_addr.s_addr != INADDR_ANY)
2773                return;
2774
2775        free(state->old);
2776        state->old = state->new;
2777        state->new = dhcp_message_new(addr, net);
2778        if (state->new == NULL)
2779                return;
2780        state->dst.s_addr = dst ? dst->s_addr : INADDR_ANY;
2781        if (dst) {
2782                for (i = 1; i < 255; i++)
2783                        if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i))
2784                                dhcp_message_add_addr(state->new, i, *dst);
2785        }
2786        state->reason = "STATIC";
2787        ipv4_buildroutes();
2788        script_runreason(ifp, state->reason);
2789        if (ifo->options & DHCPCD_INFORM) {
2790                state->state = DHS_INFORM;
2791                state->xid = dhcp_xid(ifp);
2792                state->lease.server.s_addr = dst ? dst->s_addr : INADDR_ANY;
2793                state->addr = *addr;
2794                state->net = *net;
2795                dhcp_inform(ifp);
2796        }
2797}
Note: See TracBrowser for help on using the repository browser.