blob: f1cdc363e32e12ec861c68f04cd18c790f7b94f1 [file] [log] [blame]
Samuel Tand7ed8512015-08-13 16:11:35 -07001/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2015 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#include <arpa/inet.h>
33#include <net/if.h>
34#include <net/route.h>
35#include <netinet/if_ether.h>
36#include <netinet/in_systm.h>
37#include <netinet/in.h>
38#include <netinet/ip.h>
39#define __FAVOR_BSD /* Nasty glibc hack so we can use BSD semantics for UDP */
40#include <netinet/udp.h>
41#undef __FAVOR_BSD
42
43#include <ctype.h>
44#include <errno.h>
45#include <fcntl.h>
46#include <inttypes.h>
47#include <stddef.h>
48#include <stdlib.h>
49#include <string.h>
50#include <unistd.h>
51
52#define ELOOP_QUEUE 2
53#include "config.h"
54#include "arp.h"
55#include "common.h"
56#include "dhcp.h"
57#include "dhcpcd.h"
58#include "dhcp-common.h"
59#include "duid.h"
60#include "eloop.h"
61#include "if.h"
62#include "ipv4.h"
63#include "ipv4ll.h"
Samuel Tan23ff6ed2015-08-13 16:50:06 -070064#include "rpc-interface.h"
Samuel Tand7ed8512015-08-13 16:11:35 -070065#include "script.h"
66
67#define DAD "Duplicate address detected"
68#define DHCP_MIN_LEASE 20
69
70#define IPV4A ADDRIPV4 | ARRAY
71#define IPV4R ADDRIPV4 | REQUEST
72
73/* We should define a maximum for the NAK exponential backoff */
74#define NAKOFF_MAX 60
75
76/* Wait N nanoseconds between sending a RELEASE and dropping the address.
77 * This gives the kernel enough time to actually send it. */
78#define RELEASE_DELAY_S 0
79#define RELEASE_DELAY_NS 10000000
80
81#ifndef IPDEFTTL
82#define IPDEFTTL 64 /* RFC1340 */
83#endif
84
85struct dhcp_op {
86 uint8_t value;
87 const char *name;
88};
89
90static const struct dhcp_op dhcp_ops[] = {
91 { DHCP_DISCOVER, "DISCOVER" },
92 { DHCP_OFFER, "OFFER" },
93 { DHCP_REQUEST, "REQUEST" },
94 { DHCP_DECLINE, "DECLINE" },
95 { DHCP_ACK, "ACK" },
96 { DHCP_NAK, "NAK" },
97 { DHCP_RELEASE, "RELEASE" },
98 { DHCP_INFORM, "INFORM" },
99 { DHCP_FORCERENEW, "DHCP_FORCERENEW"},
100 { 0, NULL }
101};
102
103static const char * const dhcp_params[] = {
104 "ip_address",
105 "subnet_cidr",
106 "network_number",
107 "filename",
108 "server_name",
109 NULL
110};
111
112struct udp_dhcp_packet
113{
114 struct ip ip;
115 struct udphdr udp;
116 struct dhcp_message dhcp;
117};
118
119static const size_t udp_dhcp_len = sizeof(struct udp_dhcp_packet);
120
121static int dhcp_open(struct interface *ifp);
122
123void
124dhcp_printoptions(const struct dhcpcd_ctx *ctx,
125 const struct dhcp_opt *opts, size_t opts_len)
126{
127 const char * const *p;
128 size_t i, j;
129 const struct dhcp_opt *opt, *opt2;
130 int cols;
131
132 for (p = dhcp_params; *p; p++)
133 printf(" %s\n", *p);
134
135 for (i = 0, opt = ctx->dhcp_opts; i < ctx->dhcp_opts_len; i++, opt++) {
136 for (j = 0, opt2 = opts; j < opts_len; j++, opt2++)
137 if (opt->option == opt2->option)
138 break;
139 if (j == opts_len) {
140 cols = printf("%03d %s", opt->option, opt->var);
141 dhcp_print_option_encoding(opt, cols);
142 }
143 }
144 for (i = 0, opt = opts; i < opts_len; i++, opt++) {
145 cols = printf("%03d %s", opt->option, opt->var);
146 dhcp_print_option_encoding(opt, cols);
147 }
148}
149
150#define get_option_raw(ctx, dhcp, opt) get_option(ctx, dhcp, opt, NULL)
151static const uint8_t *
152get_option(struct dhcpcd_ctx *ctx,
153 const struct dhcp_message *dhcp, unsigned int opt, size_t *len)
154{
155 const uint8_t *p = dhcp->options;
156 const uint8_t *e = p + sizeof(dhcp->options);
157 uint8_t l, ol = 0;
158 uint8_t o = 0;
159 uint8_t overl = 0;
160 uint8_t *bp = NULL;
161 const uint8_t *op = NULL;
162 size_t bl = 0;
163
164 /* Check we have the magic cookie */
165 if (dhcp->cookie != htonl(MAGIC_COOKIE)) {
166 errno = ENOTSUP;
167 return NULL;
168 }
169
Samuel Tan9ae79b82015-08-13 16:46:52 -0700170 /* DHCP options are in TLV format with T and L each being a single
171 * bytes. In general, here we have p -> T, ol=p+1 -> L, op -> V.
172 * We must make sure there is enough room to read both T and L.
173 */
174 while (p + 1 < e) {
Samuel Tand7ed8512015-08-13 16:11:35 -0700175 o = *p++;
176 if (o == opt) {
177 if (op) {
178 if (!ctx->opt_buffer) {
179 ctx->opt_buffer =
180 malloc(DHCP_OPTION_LEN +
181 BOOTFILE_LEN + SERVERNAME_LEN);
182 if (ctx->opt_buffer == NULL)
183 return NULL;
184 }
185 if (!bp)
186 bp = ctx->opt_buffer;
187 memcpy(bp, op, ol);
188 bp += ol;
189 }
Samuel Tan9ae79b82015-08-13 16:46:52 -0700190 ol = (p + *p < e) ? *p : e - (p + 1);
Samuel Tand7ed8512015-08-13 16:11:35 -0700191 if (p + ol > e) {
192 errno = EINVAL;
193 return NULL;
194 }
195 op = p + 1;
196 bl += ol;
197 }
198 switch (o) {
199 case DHO_PAD:
200 continue;
201 case DHO_END:
202 if (overl & 1) {
203 /* bit 1 set means parse boot file */
204 overl = (uint8_t)(overl & ~1);
205 p = dhcp->bootfile;
206 e = p + sizeof(dhcp->bootfile);
207 } else if (overl & 2) {
208 /* bit 2 set means parse server name */
209 overl = (uint8_t)(overl & ~2);
210 p = dhcp->servername;
211 e = p + sizeof(dhcp->servername);
212 } else
213 goto exit;
214 break;
215 case DHO_OPTIONSOVERLOADED:
216 /* Ensure we only get this option once by setting
217 * the last bit as well as the value.
218 * This is valid because only the first two bits
219 * actually mean anything in RFC2132 Section 9.3 */
220 if (!overl)
221 overl = 0x80 | p[1];
222 break;
223 }
224 l = *p++;
225 p += l;
226 }
227
228exit:
229 if (len)
230 *len = bl;
231 if (bp) {
232 memcpy(bp, op, ol);
233 return (const uint8_t *)ctx->opt_buffer;
234 }
235 if (op)
236 return op;
237 errno = ENOENT;
238 return NULL;
239}
240
241int
242get_option_addr(struct dhcpcd_ctx *ctx,
243 struct in_addr *a, const struct dhcp_message *dhcp,
244 uint8_t option)
245{
246 const uint8_t *p;
247 size_t len;
248
249 p = get_option(ctx, dhcp, option, &len);
250 if (!p || len < (ssize_t)sizeof(a->s_addr))
251 return -1;
252 memcpy(&a->s_addr, p, sizeof(a->s_addr));
253 return 0;
254}
255
256static int
257get_option_uint32(struct dhcpcd_ctx *ctx,
258 uint32_t *i, const struct dhcp_message *dhcp, uint8_t option)
259{
260 const uint8_t *p;
261 size_t len;
262 uint32_t d;
263
264 p = get_option(ctx, dhcp, option, &len);
265 if (!p || len < (ssize_t)sizeof(d))
266 return -1;
267 memcpy(&d, p, sizeof(d));
268 if (i)
269 *i = ntohl(d);
270 return 0;
271}
272
273static int
274get_option_uint8(struct dhcpcd_ctx *ctx,
275 uint8_t *i, const struct dhcp_message *dhcp, uint8_t option)
276{
277 const uint8_t *p;
278 size_t len;
279
280 p = get_option(ctx, dhcp, option, &len);
281 if (!p || len < (ssize_t)sizeof(*p))
282 return -1;
283 if (i)
284 *i = *(p);
285 return 0;
286}
287
288ssize_t
289decode_rfc3442(char *out, size_t len, const uint8_t *p, size_t pl)
290{
291 const uint8_t *e;
292 size_t bytes = 0, ocets;
293 int b;
294 uint8_t cidr;
295 struct in_addr addr;
296 char *o = out;
297
298 /* Minimum is 5 -first is CIDR and a router length of 4 */
299 if (pl < 5) {
300 errno = EINVAL;
301 return -1;
302 }
303
304 e = p + pl;
305 while (p < e) {
306 cidr = *p++;
307 if (cidr > 32) {
308 errno = EINVAL;
309 return -1;
310 }
311 ocets = (size_t)(cidr + 7) / NBBY;
312 if (p + 4 + ocets > e) {
313 errno = ERANGE;
314 return -1;
315 }
316 if (!out) {
317 p += 4 + ocets;
318 bytes += ((4 * 4) * 2) + 4;
319 continue;
320 }
321 if ((((4 * 4) * 2) + 4) > len) {
322 errno = ENOBUFS;
323 return -1;
324 }
325 if (o != out) {
326 *o++ = ' ';
327 len--;
328 }
329 /* If we have ocets then we have a destination and netmask */
330 if (ocets > 0) {
331 addr.s_addr = 0;
332 memcpy(&addr.s_addr, p, ocets);
333 b = snprintf(o, len, "%s/%d", inet_ntoa(addr), cidr);
334 p += ocets;
335 } else
336 b = snprintf(o, len, "0.0.0.0/0");
337 o += b;
338 len -= (size_t)b;
339
340 /* Finally, snag the router */
341 memcpy(&addr.s_addr, p, 4);
342 p += 4;
343 b = snprintf(o, len, " %s", inet_ntoa(addr));
344 o += b;
345 len -= (size_t)b;
346 }
347
348 if (out)
349 return o - out;
350 return (ssize_t)bytes;
351}
352
353static struct rt_head *
354decode_rfc3442_rt(struct dhcpcd_ctx *ctx, const uint8_t *data, size_t dl)
355{
356 const uint8_t *p = data;
357 const uint8_t *e;
358 uint8_t cidr;
359 size_t ocets;
360 struct rt_head *routes;
361 struct rt *rt = NULL;
362
363 /* Minimum is 5 -first is CIDR and a router length of 4 */
364 if (dl < 5)
365 return NULL;
366
367 routes = malloc(sizeof(*routes));
368 TAILQ_INIT(routes);
369 e = p + dl;
370 while (p < e) {
371 cidr = *p++;
372 if (cidr > 32) {
373 ipv4_freeroutes(routes);
374 errno = EINVAL;
375 return NULL;
376 }
377
378 ocets = (size_t)(cidr + 7) / NBBY;
379 if (p + 4 + ocets > e) {
380 ipv4_freeroutes(routes);
381 errno = ERANGE;
382 return NULL;
383 }
384
385 rt = calloc(1, sizeof(*rt));
386 if (rt == NULL) {
387 logger(ctx, LOG_ERR, "%s: %m", __func__);
388 ipv4_freeroutes(routes);
389 return NULL;
390 }
391 TAILQ_INSERT_TAIL(routes, rt, next);
392
393 /* If we have ocets then we have a destination and netmask */
394 if (ocets > 0) {
395 memcpy(&rt->dest.s_addr, p, ocets);
396 p += ocets;
397 rt->net.s_addr = htonl(~0U << (32 - cidr));
398 }
399
400 /* Finally, snag the router */
401 memcpy(&rt->gate.s_addr, p, 4);
402 p += 4;
403 }
404 return routes;
405}
406
407char *
408decode_rfc3361(const uint8_t *data, size_t dl)
409{
410 uint8_t enc;
411 size_t l;
412 ssize_t r;
413 char *sip = NULL;
414 struct in_addr addr;
415 char *p;
416
417 if (dl < 2) {
418 errno = EINVAL;
419 return 0;
420 }
421
422 enc = *data++;
423 dl--;
424 switch (enc) {
425 case 0:
426 if ((r = decode_rfc3397(NULL, 0, data, dl)) > 0) {
427 l = (size_t)r;
428 sip = malloc(l);
429 if (sip == NULL)
430 return 0;
431 decode_rfc3397(sip, l, data, dl);
432 }
433 break;
434 case 1:
435 if (dl == 0 || dl % 4 != 0) {
436 errno = EINVAL;
437 break;
438 }
439 addr.s_addr = INADDR_BROADCAST;
440 l = ((dl / sizeof(addr.s_addr)) * ((4 * 4) + 1)) + 1;
441 sip = p = malloc(l);
442 if (sip == NULL)
443 return 0;
444 while (dl != 0) {
445 memcpy(&addr.s_addr, data, sizeof(addr.s_addr));
446 data += sizeof(addr.s_addr);
447 p += snprintf(p, l - (size_t)(p - sip),
448 "%s ", inet_ntoa(addr));
449 dl -= sizeof(addr.s_addr);
450 }
451 *--p = '\0';
452 break;
453 default:
454 errno = EINVAL;
455 return 0;
456 }
457
458 return sip;
459}
460
461/* Decode an RFC5969 6rd order option into a space
462 * separated string. Returns length of string (including
463 * terminating zero) or zero on error. */
464ssize_t
465decode_rfc5969(char *out, size_t len, const uint8_t *p, size_t pl)
466{
467 uint8_t ipv4masklen, ipv6prefixlen;
468 uint8_t ipv6prefix[16];
469 uint8_t br[4];
470 int i;
471 ssize_t b, bytes = 0;
472
473 if (pl < 22) {
474 errno = EINVAL;
475 return 0;
476 }
477
478 ipv4masklen = *p++;
479 pl--;
480 ipv6prefixlen = *p++;
481 pl--;
482
483 for (i = 0; i < 16; i++) {
484 ipv6prefix[i] = *p++;
485 pl--;
486 }
487 if (out) {
488 b= snprintf(out, len,
489 "%d %d "
490 "%02x%02x:%02x%02x:"
491 "%02x%02x:%02x%02x:"
492 "%02x%02x:%02x%02x:"
493 "%02x%02x:%02x%02x",
494 ipv4masklen, ipv6prefixlen,
495 ipv6prefix[0], ipv6prefix[1], ipv6prefix[2], ipv6prefix[3],
496 ipv6prefix[4], ipv6prefix[5], ipv6prefix[6], ipv6prefix[7],
497 ipv6prefix[8], ipv6prefix[9], ipv6prefix[10],ipv6prefix[11],
498 ipv6prefix[12],ipv6prefix[13],ipv6prefix[14], ipv6prefix[15]
499 );
500
501 len -= (size_t)b;
502 out += b;
503 bytes += b;
504 } else {
505 bytes += 16 * 2 + 8 + 2 + 1 + 2;
506 }
507
508 while (pl >= 4) {
509 br[0] = *p++;
510 br[1] = *p++;
511 br[2] = *p++;
512 br[3] = *p++;
513 pl -= 4;
514
515 if (out) {
516 b= snprintf(out, len, " %d.%d.%d.%d",
517 br[0], br[1], br[2], br[3]);
518 len -= (size_t)b;
519 out += b;
520 bytes += b;
521 } else {
522 bytes += (4 * 4);
523 }
524 }
525
526 return bytes;
527}
528
529static char *
530get_option_string(struct dhcpcd_ctx *ctx,
531 const struct dhcp_message *dhcp, uint8_t option)
532{
533 size_t len;
534 const uint8_t *p;
535 char *s;
536
537 p = get_option(ctx, dhcp, option, &len);
538 if (!p || len == 0 || *p == '\0')
539 return NULL;
540
541 s = malloc(sizeof(char) * (len + 1));
542 if (s) {
543 memcpy(s, p, len);
544 s[len] = '\0';
545 }
546 return s;
547}
548
549/* This calculates the netmask that we should use for static routes.
550 * This IS different from the calculation used to calculate the netmask
551 * for an interface address. */
552static uint32_t
553route_netmask(uint32_t ip_in)
554{
555 /* used to be unsigned long - check if error */
556 uint32_t p = ntohl(ip_in);
557 uint32_t t;
558
559 if (IN_CLASSA(p))
560 t = ~IN_CLASSA_NET;
561 else {
562 if (IN_CLASSB(p))
563 t = ~IN_CLASSB_NET;
564 else {
565 if (IN_CLASSC(p))
566 t = ~IN_CLASSC_NET;
567 else
568 t = 0;
569 }
570 }
571
572 while (t & p)
573 t >>= 1;
574
575 return (htonl(~t));
576}
577
578/* We need to obey routing options.
579 * If we have a CSR then we only use that.
580 * Otherwise we add static routes and then routers. */
581struct rt_head *
582get_option_routes(struct interface *ifp, const struct dhcp_message *dhcp)
583{
584 struct if_options *ifo = ifp->options;
585 const uint8_t *p;
586 const uint8_t *e;
587 struct rt_head *routes = NULL;
588 struct rt *route = NULL;
589 size_t len;
590 const char *csr = "";
591
592 /* If we have CSR's then we MUST use these only */
593 if (!has_option_mask(ifo->nomask, DHO_CSR))
594 p = get_option(ifp->ctx, dhcp, DHO_CSR, &len);
595 else
596 p = NULL;
597 /* Check for crappy MS option */
598 if (!p && !has_option_mask(ifo->nomask, DHO_MSCSR)) {
599 p = get_option(ifp->ctx, dhcp, DHO_MSCSR, &len);
600 if (p)
601 csr = "MS ";
602 }
603 if (p) {
604 routes = decode_rfc3442_rt(ifp->ctx, p, len);
605 if (routes) {
606 const struct dhcp_state *state;
607
608 state = D_CSTATE(ifp);
609 if (!(ifo->options & DHCPCD_CSR_WARNED) &&
610 !(state->added & STATE_FAKE))
611 {
612 logger(ifp->ctx, LOG_DEBUG,
613 "%s: using %sClassless Static Routes",
614 ifp->name, csr);
615 ifo->options |= DHCPCD_CSR_WARNED;
616 }
617 return routes;
618 }
619 }
620
621 /* OK, get our static routes first. */
622 routes = malloc(sizeof(*routes));
623 if (routes == NULL) {
624 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
625 return NULL;
626 }
627 TAILQ_INIT(routes);
628 if (!has_option_mask(ifo->nomask, DHO_STATICROUTE))
629 p = get_option(ifp->ctx, dhcp, DHO_STATICROUTE, &len);
630 else
631 p = NULL;
632 /* RFC 2131 Section 5.8 states length MUST be in multiples of 8 */
633 if (p && len % 8 == 0) {
634 e = p + len;
635 while (p < e) {
636 if ((route = calloc(1, sizeof(*route))) == NULL) {
637 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
638 ipv4_freeroutes(routes);
639 return NULL;
640 }
641 memcpy(&route->dest.s_addr, p, 4);
642 p += 4;
643 memcpy(&route->gate.s_addr, p, 4);
644 p += 4;
645 /* RFC 2131 Section 5.8 states default route is
646 * illegal */
647 if (route->dest.s_addr == htonl(INADDR_ANY)) {
648 errno = EINVAL;
649 free(route);
650 continue;
651 }
652 route->net.s_addr = route_netmask(route->dest.s_addr);
653 TAILQ_INSERT_TAIL(routes, route, next);
654 }
655 }
656
657 /* Now grab our routers */
658 if (!has_option_mask(ifo->nomask, DHO_ROUTER))
659 p = get_option(ifp->ctx, dhcp, DHO_ROUTER, &len);
660 else
661 p = NULL;
662 if (p) {
663 e = p + len;
664 while (p < e) {
665 if ((route = calloc(1, sizeof(*route))) == NULL) {
666 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
667 ipv4_freeroutes(routes);
668 return NULL;
669 }
670 memcpy(&route->gate.s_addr, p, 4);
671 p += 4;
672 TAILQ_INSERT_TAIL(routes, route, next);
673 }
674 }
675
676 return routes;
677}
678
679#define PUTADDR(_type, _val) \
680 { \
681 *p++ = _type; \
682 *p++ = 4; \
683 memcpy(p, &_val.s_addr, 4); \
684 p += 4; \
685 }
686
687int
688dhcp_message_add_addr(struct dhcp_message *dhcp,
689 uint8_t type, struct in_addr addr)
690{
691 uint8_t *p;
692 size_t len;
693
694 p = dhcp->options;
695 while (*p != DHO_END) {
696 p++;
697 p += *p + 1;
698 }
699
700 len = (size_t)(p - (uint8_t *)dhcp);
701 if (len + 6 > sizeof(*dhcp)) {
702 errno = ENOMEM;
703 return -1;
704 }
705
706 PUTADDR(type, addr);
707 *p = DHO_END;
708 return 0;
709}
710
711ssize_t
712make_message(struct dhcp_message **message,
713 const struct interface *ifp,
714 uint8_t type)
715{
716 struct dhcp_message *dhcp;
717 uint8_t *m, *lp, *p, *auth;
718 uint8_t *n_params = NULL, auth_len;
719 uint32_t ul;
720 uint16_t sz;
721 size_t len, i;
722 const struct dhcp_opt *opt;
723 struct if_options *ifo = ifp->options;
724 const struct dhcp_state *state = D_CSTATE(ifp);
725 const struct dhcp_lease *lease = &state->lease;
726 time_t up = uptime() - state->start_uptime;
727 char hbuf[HOSTNAME_MAX_LEN + 1];
728 const char *hostname;
729 const struct vivco *vivco;
730
731 dhcp = calloc(1, sizeof (*dhcp));
732 if (dhcp == NULL)
733 return -1;
734 m = (uint8_t *)dhcp;
735 p = dhcp->options;
736
737 if ((type == DHCP_INFORM || type == DHCP_RELEASE ||
738 (type == DHCP_REQUEST &&
739 state->net.s_addr == lease->net.s_addr &&
740 (state->new == NULL ||
741 state->new->cookie == htonl(MAGIC_COOKIE)))))
742 {
743 dhcp->ciaddr = state->addr.s_addr;
744 /* In-case we haven't actually configured the address yet */
745 if (type == DHCP_INFORM && state->addr.s_addr == 0)
746 dhcp->ciaddr = lease->addr.s_addr;
747 }
748
749 dhcp->op = DHCP_BOOTREQUEST;
750 dhcp->hwtype = (uint8_t)ifp->family;
751 switch (ifp->family) {
752 case ARPHRD_ETHER:
753 case ARPHRD_IEEE802:
754 dhcp->hwlen = (uint8_t)ifp->hwlen;
755 memcpy(&dhcp->chaddr, &ifp->hwaddr, ifp->hwlen);
756 break;
757 }
758
759 if (ifo->options & DHCPCD_BROADCAST &&
760 dhcp->ciaddr == 0 &&
761 type != DHCP_DECLINE &&
762 type != DHCP_RELEASE)
763 dhcp->flags = htons(BROADCAST_FLAG);
764
765 if (type != DHCP_DECLINE && type != DHCP_RELEASE) {
766 if (up < 0 || up > (time_t)UINT16_MAX)
767 dhcp->secs = htons((uint16_t)UINT16_MAX);
768 else
769 dhcp->secs = htons((uint16_t)up);
770 }
771 dhcp->xid = htonl(state->xid);
772 dhcp->cookie = htonl(MAGIC_COOKIE);
773
774 if (!(ifo->options & DHCPCD_BOOTP)) {
775 *p++ = DHO_MESSAGETYPE;
776 *p++ = 1;
777 *p++ = type;
778 }
779
780 if (state->clientid) {
781 *p++ = DHO_CLIENTID;
782 memcpy(p, state->clientid, (size_t)state->clientid[0] + 1);
783 p += state->clientid[0] + 1;
784 }
785
786 if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) {
787 if (type == DHCP_DECLINE ||
788 (type == DHCP_REQUEST &&
789 lease->addr.s_addr != state->addr.s_addr))
790 {
791 PUTADDR(DHO_IPADDRESS, lease->addr);
792 if (lease->server.s_addr)
793 PUTADDR(DHO_SERVERID, lease->server);
794 }
795
796 if (type == DHCP_RELEASE) {
797 if (lease->server.s_addr)
798 PUTADDR(DHO_SERVERID, lease->server);
799 }
800 }
801
802 if (type == DHCP_DECLINE) {
803 *p++ = DHO_MESSAGE;
804 len = strlen(DAD);
805 *p++ = (uint8_t)len;
806 memcpy(p, DAD, len);
807 p += len;
808 }
809
810 if (type == DHCP_DISCOVER &&
811 !(ifp->ctx->options & DHCPCD_TEST) &&
812 has_option_mask(ifo->requestmask, DHO_RAPIDCOMMIT))
813 {
814 /* RFC 4039 Section 3 */
815 *p++ = DHO_RAPIDCOMMIT;
816 *p++ = 0;
817 }
818
819 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_REQUEST)
820 PUTADDR(DHO_IPADDRESS, ifo->req_addr);
821
822 /* RFC 2563 Auto Configure */
823 if (type == DHCP_DISCOVER && ifo->options & DHCPCD_IPV4LL) {
824 *p++ = DHO_AUTOCONFIGURE;
825 *p++ = 1;
826 *p++ = 1;
827 }
828
829 if (type == DHCP_DISCOVER ||
830 type == DHCP_INFORM ||
831 type == DHCP_REQUEST)
832 {
833 if (!(ifo->options & DHCPCD_BOOTP)) {
834 int mtu;
835
836 *p++ = DHO_MAXMESSAGESIZE;
837 *p++ = 2;
838 mtu = if_getmtu(ifp->name);
839 if (mtu < MTU_MIN) {
840 if (if_setmtu(ifp->name, MTU_MIN) == 0)
841 sz = MTU_MIN;
842 } else if (mtu > MTU_MAX) {
843 /* Even though our MTU could be greater than
844 * MTU_MAX (1500) dhcpcd does not presently
845 * handle DHCP packets any bigger. */
846 mtu = MTU_MAX;
847 }
848 sz = htons((uint16_t)mtu);
849 memcpy(p, &sz, 2);
850 p += 2;
851 }
852
853 if (ifo->userclass[0]) {
854 *p++ = DHO_USERCLASS;
855 memcpy(p, ifo->userclass,
856 (size_t)ifo->userclass[0] + 1);
857 p += ifo->userclass[0] + 1;
858 }
859
860 if (ifo->vendorclassid[0]) {
861 *p++ = DHO_VENDORCLASSID;
862 memcpy(p, ifo->vendorclassid,
863 (size_t)ifo->vendorclassid[0] + 1);
864 p += ifo->vendorclassid[0] + 1;
865 }
866
867 if (type != DHCP_INFORM) {
868 if (ifo->leasetime != 0) {
869 *p++ = DHO_LEASETIME;
870 *p++ = 4;
871 ul = htonl(ifo->leasetime);
872 memcpy(p, &ul, 4);
873 p += 4;
874 }
875 }
876
877 if (ifo->hostname[0] == '\0')
878 hostname = get_hostname(hbuf, sizeof(hbuf),
879 ifo->options & DHCPCD_HOSTNAME_SHORT ? 1 : 0);
880 else
881 hostname = ifo->hostname;
882
883 /*
884 * RFC4702 3.1 States that if we send the Client FQDN option
885 * then we MUST NOT also send the Host Name option.
886 * Technically we could, but that is not RFC conformant and
887 * also seems to break some DHCP server implemetations such as
888 * Windows. On the other hand, ISC dhcpd is just as non RFC
889 * conformant by not accepting a partially qualified FQDN.
890 */
891 if (ifo->fqdn != FQDN_DISABLE) {
892 /* IETF DHC-FQDN option (81), RFC4702 */
893 *p++ = DHO_FQDN;
894 lp = p;
895 *p++ = 3;
896 /*
897 * Flags: 0000NEOS
898 * S: 1 => Client requests Server to update
899 * a RR in DNS as well as PTR
900 * O: 1 => Server indicates to client that
901 * DNS has been updated
902 * E: 1 => Name data is DNS format
903 * N: 1 => Client requests Server to not
904 * update DNS
905 */
906 if (hostname)
907 *p++ = (uint8_t)((ifo->fqdn & 0x09) | 0x04);
908 else
909 *p++ = (FQDN_NONE & 0x09) | 0x04;
910 *p++ = 0; /* from server for PTR RR */
911 *p++ = 0; /* from server for A RR if S=1 */
912 if (hostname) {
913 i = encode_rfc1035(hostname, p);
914 *lp = (uint8_t)(*lp + i);
915 p += i;
916 }
917 } else if (ifo->options & DHCPCD_HOSTNAME && hostname) {
918 *p++ = DHO_HOSTNAME;
919 len = strlen(hostname);
920 *p++ = (uint8_t)len;
921 memcpy(p, hostname, len);
922 p += len;
923 }
924
925 /* vendor is already encoded correctly, so just add it */
926 if (ifo->vendor[0]) {
927 *p++ = DHO_VENDOR;
928 memcpy(p, ifo->vendor, (size_t)ifo->vendor[0] + 1);
929 p += ifo->vendor[0] + 1;
930 }
931
932 if ((ifo->auth.options & DHCPCD_AUTH_SENDREQUIRE) !=
933 DHCPCD_AUTH_SENDREQUIRE)
934 {
935 /* We support HMAC-MD5 */
936 *p++ = DHO_FORCERENEW_NONCE;
937 *p++ = 1;
938 *p++ = AUTH_ALG_HMAC_MD5;
939 }
940
941 if (ifo->vivco_len) {
942 *p++ = DHO_VIVCO;
943 lp = p++;
944 *lp = sizeof(ul);
945 ul = htonl(ifo->vivco_en);
946 memcpy(p, &ul, sizeof(ul));
947 p += sizeof(ul);
948 for (i = 0, vivco = ifo->vivco;
949 i < ifo->vivco_len;
950 i++, vivco++)
951 {
952 len = (size_t)(p - m) + vivco->len + 1;
953 if (len > sizeof(*dhcp))
954 goto toobig;
955 if (vivco->len + 2 + *lp > 255) {
956 logger(ifp->ctx, LOG_ERR,
957 "%s: VIVCO option too big",
958 ifp->name);
959 free(dhcp);
960 return -1;
961 }
962 *p++ = (uint8_t)vivco->len;
963 memcpy(p, vivco->data, vivco->len);
964 p += vivco->len;
965 *lp = (uint8_t)(*lp + vivco->len + 1);
966 }
967 }
968
969 len = (size_t)((p - m) + 3);
970 if (len > sizeof(*dhcp))
971 goto toobig;
972 *p++ = DHO_PARAMETERREQUESTLIST;
973 n_params = p;
974 *p++ = 0;
975 for (i = 0, opt = ifp->ctx->dhcp_opts;
976 i < ifp->ctx->dhcp_opts_len;
977 i++, opt++)
978 {
979 if (!(opt->type & REQUEST ||
980 has_option_mask(ifo->requestmask, opt->option)))
981 continue;
982 if (opt->type & NOREQ)
983 continue;
984 if (type == DHCP_INFORM &&
985 (opt->option == DHO_RENEWALTIME ||
986 opt->option == DHO_REBINDTIME))
987 continue;
988 len = (size_t)((p - m) + 2);
989 if (len > sizeof(*dhcp))
990 goto toobig;
991 *p++ = (uint8_t)opt->option;
992 }
993 for (i = 0, opt = ifo->dhcp_override;
994 i < ifo->dhcp_override_len;
995 i++, opt++)
996 {
997 /* Check if added above */
998 for (lp = n_params + 1; lp < p; lp++)
999 if (*lp == (uint8_t)opt->option)
1000 break;
1001 if (lp < p)
1002 continue;
1003 if (!(opt->type & REQUEST ||
1004 has_option_mask(ifo->requestmask, opt->option)))
1005 continue;
1006 if (opt->type & NOREQ)
1007 continue;
1008 if (type == DHCP_INFORM &&
1009 (opt->option == DHO_RENEWALTIME ||
1010 opt->option == DHO_REBINDTIME))
1011 continue;
1012 len = (size_t)((p - m) + 2);
1013 if (len > sizeof(*dhcp))
1014 goto toobig;
1015 *p++ = (uint8_t)opt->option;
1016 }
1017 *n_params = (uint8_t)(p - n_params - 1);
1018 }
1019
1020 /* silence GCC */
1021 auth_len = 0;
1022 auth = NULL;
1023
1024 if (ifo->auth.options & DHCPCD_AUTH_SEND) {
1025 ssize_t alen = dhcp_auth_encode(&ifo->auth,
1026 state->auth.token,
1027 NULL, 0, 4, type, NULL, 0);
1028 if (alen != -1 && alen > UINT8_MAX) {
1029 errno = ERANGE;
1030 alen = -1;
1031 }
1032 if (alen == -1)
1033 logger(ifp->ctx, LOG_ERR,
1034 "%s: dhcp_auth_encode: %m", ifp->name);
1035 else if (alen != 0) {
1036 auth_len = (uint8_t)alen;
1037 len = (size_t)((p + alen) - m);
1038 if (len > sizeof(*dhcp))
1039 goto toobig;
1040 *p++ = DHO_AUTHENTICATION;
1041 *p++ = auth_len;
1042 auth = p;
1043 p += auth_len;
1044 }
1045 }
1046
1047 *p++ = DHO_END;
1048
1049 /* Pad out to the BOOTP minimum message length.
1050 * Some DHCP servers incorrectly require this. */
1051 while (p - m < BOOTP_MESSAGE_LENTH_MIN)
1052 *p++ = DHO_PAD;
1053
1054 len = (size_t)(p - m);
1055 if (ifo->auth.options & DHCPCD_AUTH_SEND && auth_len != 0)
1056 dhcp_auth_encode(&ifo->auth, state->auth.token,
1057 m, len, 4, type, auth, auth_len);
1058
1059 *message = dhcp;
1060 return (ssize_t)len;
1061
1062toobig:
1063 logger(ifp->ctx, LOG_ERR, "%s: DHCP messge too big", ifp->name);
1064 free(dhcp);
1065 return -1;
1066}
1067
1068static ssize_t
1069write_lease(const struct interface *ifp, const struct dhcp_message *dhcp)
1070{
1071 int fd;
1072 size_t len;
1073 ssize_t bytes;
1074 const uint8_t *e, *p;
1075 uint8_t l;
1076 uint8_t o = 0;
1077 const struct dhcp_state *state = D_CSTATE(ifp);
Samuel Tanf20514b2015-08-13 16:24:02 -07001078 uint8_t write_buffer[sizeof(*dhcp) + sizeof(state->server_info) + 1];
1079 uint8_t *w;
Samuel Tand7ed8512015-08-13 16:11:35 -07001080
1081 /* We don't write BOOTP leases */
1082 if (IS_BOOTP(ifp, dhcp)) {
1083 unlink(state->leasefile);
1084 return 0;
1085 }
1086
1087 logger(ifp->ctx, LOG_DEBUG, "%s: writing lease `%s'",
1088 ifp->name, state->leasefile);
1089
Samuel Tandd90b012015-08-13 16:27:29 -07001090 fd = open(state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
Samuel Tand7ed8512015-08-13 16:11:35 -07001091 if (fd == -1)
1092 return -1;
1093
1094 /* Only write as much as we need */
1095 p = dhcp->options;
1096 e = p + sizeof(dhcp->options);
1097 len = sizeof(*dhcp);
1098 while (p < e) {
1099 o = *p;
1100 if (o == DHO_END) {
1101 len = (size_t)(p - (const uint8_t *)dhcp);
1102 break;
1103 }
1104 p++;
1105 if (o != DHO_PAD) {
1106 l = *p++;
1107 p += l;
1108 }
1109 }
Samuel Tanf20514b2015-08-13 16:24:02 -07001110
1111 memcpy(write_buffer, dhcp, len);
1112 w = write_buffer + len;
1113
1114 /* Copy in server info if this is available. */
1115 if (state->server_info.gw_hwlen != 0) {
1116 *w++ = DHO_END;
1117 memcpy(w, &state->server_info, sizeof(state->server_info));
1118 len += sizeof(state->server_info) + 1;
1119 }
1120
1121 bytes = write(fd, write_buffer, len);
Samuel Tand7ed8512015-08-13 16:11:35 -07001122 close(fd);
1123 return bytes;
1124}
1125
1126static struct dhcp_message *
1127read_lease(struct interface *ifp)
1128{
1129 int fd;
1130 struct dhcp_message *dhcp;
1131 struct dhcp_state *state = D_STATE(ifp);
Samuel Tanf20514b2015-08-13 16:24:02 -07001132 uint8_t read_buffer[sizeof(*dhcp) + sizeof(state->server_info) + 1];
1133 const uint8_t *options_startp =
1134 read_buffer + offsetof(struct dhcp_message, options);
1135 const uint8_t *options_endp = options_startp + sizeof(dhcp->options);
1136 uint8_t option_len;
1137 uint8_t option_type = 0;
Samuel Tand7ed8512015-08-13 16:11:35 -07001138 ssize_t bytes;
1139 const uint8_t *auth;
1140 uint8_t type;
1141 size_t auth_len;
1142
Samuel Tanf20514b2015-08-13 16:24:02 -07001143 memset(&state->server_info, 0, sizeof(state->server_info));
Samuel Tand7ed8512015-08-13 16:11:35 -07001144 fd = open(state->leasefile, O_RDONLY);
1145 if (fd == -1) {
1146 if (errno != ENOENT)
1147 logger(ifp->ctx, LOG_ERR, "%s: open `%s': %m",
1148 ifp->name, state->leasefile);
1149 return NULL;
1150 }
1151 logger(ifp->ctx, LOG_DEBUG, "%s: reading lease `%s'",
1152 ifp->name, state->leasefile);
Samuel Tanf20514b2015-08-13 16:24:02 -07001153 bytes = read(fd, read_buffer, sizeof(read_buffer));
1154 close(fd);
1155
1156 /* Lease file should at minimum contain all fields before options. */
1157 if (read_buffer + bytes < options_startp)
1158 return NULL;
1159
Samuel Tand7ed8512015-08-13 16:11:35 -07001160 dhcp = calloc(1, sizeof(*dhcp));
1161 if (dhcp == NULL) {
Samuel Tand7ed8512015-08-13 16:11:35 -07001162 return NULL;
1163 }
Samuel Tanf20514b2015-08-13 16:24:02 -07001164
1165 if (options_endp > read_buffer + bytes)
1166 options_endp = read_buffer + bytes;
1167
1168 while (options_startp < options_endp) {
1169 option_type = *options_startp++;
1170 if (option_type == DHO_END)
1171 break;
1172 if (option_type != DHO_PAD) {
1173 option_len = *options_startp++;
1174 options_startp += option_len;
1175 }
Samuel Tand7ed8512015-08-13 16:11:35 -07001176 }
Samuel Tanf20514b2015-08-13 16:24:02 -07001177 memcpy(dhcp, read_buffer, options_startp - read_buffer);
Samuel Tand7ed8512015-08-13 16:11:35 -07001178
1179 /* We may have found a BOOTP server */
1180 if (get_option_uint8(ifp->ctx, &type, dhcp, DHO_MESSAGETYPE) == -1)
1181 type = 0;
1182
1183 /* Authenticate the message */
1184 auth = get_option(ifp->ctx, dhcp, DHO_AUTHENTICATION, &auth_len);
1185 if (auth) {
1186 if (dhcp_auth_validate(&state->auth, &ifp->options->auth,
1187 (uint8_t *)dhcp, sizeof(*dhcp), 4, type,
1188 auth, auth_len) == NULL)
1189 {
1190 logger(ifp->ctx, LOG_DEBUG,
1191 "%s: dhcp_auth_validate: %m", ifp->name);
1192 free(dhcp);
1193 return NULL;
1194 }
1195 if (state->auth.token)
1196 logger(ifp->ctx, LOG_DEBUG,
1197 "%s: validated using 0x%08" PRIu32,
1198 ifp->name, state->auth.token->secretid);
1199 else
1200 logger(ifp->ctx, LOG_DEBUG,
1201 "%s: accepted reconfigure key", ifp->name);
1202 }
1203
Samuel Tanf20514b2015-08-13 16:24:02 -07001204 /*
1205 * DHCP server information is stored after the DHO_END character
1206 * in the lease file. The first byte of the server information
1207 * is the length of the gateway hardware address.
1208 */
1209 options_endp = read_buffer + bytes;
1210 if (options_startp >= options_endp ||
1211 options_startp + sizeof(state->server_info) > options_endp)
1212 return dhcp;
1213
1214 logger(ifp->ctx, LOG_DEBUG, "%s: found server info in lease '%s'",
1215 ifp->name, state->leasefile);
1216
1217 memcpy(&state->server_info, options_startp, sizeof(state->server_info));
1218 if (state->server_info.gw_hwlen != ifp->hwlen) {
1219 logger(ifp->ctx, LOG_ERR, "%s: lease file %s has incompatible"
1220 "MAC address length %d (expected %zd)",
1221 ifp->name, state->leasefile,
1222 state->server_info.gw_hwlen, ifp->hwlen);
1223 memset(&state->server_info, 0, sizeof(state->server_info));
1224 }
Samuel Tand7ed8512015-08-13 16:11:35 -07001225 return dhcp;
1226}
1227
1228static const struct dhcp_opt *
1229dhcp_getoverride(const struct if_options *ifo, unsigned int o)
1230{
1231 size_t i;
1232 const struct dhcp_opt *opt;
1233
1234 for (i = 0, opt = ifo->dhcp_override;
1235 i < ifo->dhcp_override_len;
1236 i++, opt++)
1237 {
1238 if (opt->option == o)
1239 return opt;
1240 }
1241 return NULL;
1242}
1243
1244static const uint8_t *
1245dhcp_getoption(struct dhcpcd_ctx *ctx,
1246 size_t *os, unsigned int *code, size_t *len,
1247 const uint8_t *od, size_t ol, struct dhcp_opt **oopt)
1248{
1249 size_t i;
1250 struct dhcp_opt *opt;
1251
1252 if (od) {
1253 if (ol < 2) {
1254 errno = EINVAL;
1255 return NULL;
1256 }
1257 *os = 2; /* code + len */
1258 *code = (unsigned int)*od++;
1259 *len = (size_t)*od++;
Samuel Tanb745ca92016-01-08 09:46:36 -08001260 if (*len > ol - *os) {
Samuel Tand7ed8512015-08-13 16:11:35 -07001261 errno = EINVAL;
1262 return NULL;
1263 }
1264 }
1265
Samuel Tanb745ca92016-01-08 09:46:36 -08001266 *oopt = NULL;
Samuel Tand7ed8512015-08-13 16:11:35 -07001267 for (i = 0, opt = ctx->dhcp_opts; i < ctx->dhcp_opts_len; i++, opt++) {
1268 if (opt->option == *code) {
1269 *oopt = opt;
1270 break;
1271 }
1272 }
1273
1274 return od;
1275}
1276
1277ssize_t
1278dhcp_env(char **env, const char *prefix, const struct dhcp_message *dhcp,
1279 const struct interface *ifp)
1280{
1281 const struct if_options *ifo;
1282 const uint8_t *p;
1283 struct in_addr addr;
1284 struct in_addr net;
1285 struct in_addr brd;
1286 struct dhcp_opt *opt, *vo;
1287 size_t e, i, pl;
1288 char **ep;
1289 char cidr[4], safe[(BOOTFILE_LEN * 4) + 1];
1290 uint8_t overl = 0;
1291 uint32_t en;
1292
1293 e = 0;
1294 ifo = ifp->options;
1295 get_option_uint8(ifp->ctx, &overl, dhcp, DHO_OPTIONSOVERLOADED);
1296
1297 if (env == NULL) {
1298 if (dhcp->yiaddr || dhcp->ciaddr)
1299 e += 5;
1300 if (*dhcp->bootfile && !(overl & 1))
1301 e++;
1302 if (*dhcp->servername && !(overl & 2))
1303 e++;
1304 for (i = 0, opt = ifp->ctx->dhcp_opts;
1305 i < ifp->ctx->dhcp_opts_len;
1306 i++, opt++)
1307 {
1308 if (has_option_mask(ifo->nomask, opt->option))
1309 continue;
1310 if (dhcp_getoverride(ifo, opt->option))
1311 continue;
1312 p = get_option(ifp->ctx, dhcp, opt->option, &pl);
1313 if (!p)
1314 continue;
1315 e += dhcp_envoption(ifp->ctx, NULL, NULL, ifp->name,
1316 opt, dhcp_getoption, p, pl);
1317 }
1318 for (i = 0, opt = ifo->dhcp_override;
1319 i < ifo->dhcp_override_len;
1320 i++, opt++)
1321 {
1322 if (has_option_mask(ifo->nomask, opt->option))
1323 continue;
1324 p = get_option(ifp->ctx, dhcp, opt->option, &pl);
1325 if (!p)
1326 continue;
1327 e += dhcp_envoption(ifp->ctx, NULL, NULL, ifp->name,
1328 opt, dhcp_getoption, p, pl);
1329 }
1330 return (ssize_t)e;
1331 }
1332
1333 ep = env;
1334 if (dhcp->yiaddr || dhcp->ciaddr) {
1335 /* Set some useful variables that we derive from the DHCP
1336 * message but are not necessarily in the options */
1337 addr.s_addr = dhcp->yiaddr ? dhcp->yiaddr : dhcp->ciaddr;
1338 setvar(ifp->ctx, &ep, prefix, "ip_address", inet_ntoa(addr));
1339 if (get_option_addr(ifp->ctx, &net,
1340 dhcp, DHO_SUBNETMASK) == -1) {
1341 net.s_addr = ipv4_getnetmask(addr.s_addr);
1342 setvar(ifp->ctx, &ep, prefix,
1343 "subnet_mask", inet_ntoa(net));
1344 }
1345 snprintf(cidr, sizeof(cidr), "%d", inet_ntocidr(net));
1346 setvar(ifp->ctx, &ep, prefix, "subnet_cidr", cidr);
1347 if (get_option_addr(ifp->ctx, &brd,
1348 dhcp, DHO_BROADCAST) == -1) {
1349 brd.s_addr = addr.s_addr | ~net.s_addr;
1350 setvar(ifp->ctx, &ep, prefix,
1351 "broadcast_address", inet_ntoa(brd));
1352 }
1353 addr.s_addr = dhcp->yiaddr & net.s_addr;
1354 setvar(ifp->ctx, &ep, prefix,
1355 "network_number", inet_ntoa(addr));
1356 }
1357
1358 if (*dhcp->bootfile && !(overl & 1)) {
1359 print_string(safe, sizeof(safe), STRING,
1360 dhcp->bootfile, sizeof(dhcp->bootfile));
1361 setvar(ifp->ctx, &ep, prefix, "filename", safe);
1362 }
1363 if (*dhcp->servername && !(overl & 2)) {
1364 print_string(safe, sizeof(safe), STRING | DOMAIN,
1365 dhcp->servername, sizeof(dhcp->servername));
1366 setvar(ifp->ctx, &ep, prefix, "server_name", safe);
1367 }
1368
1369 /* Zero our indexes */
1370 if (env) {
1371 for (i = 0, opt = ifp->ctx->dhcp_opts;
1372 i < ifp->ctx->dhcp_opts_len;
1373 i++, opt++)
1374 dhcp_zero_index(opt);
1375 for (i = 0, opt = ifp->options->dhcp_override;
1376 i < ifp->options->dhcp_override_len;
1377 i++, opt++)
1378 dhcp_zero_index(opt);
1379 for (i = 0, opt = ifp->ctx->vivso;
1380 i < ifp->ctx->vivso_len;
1381 i++, opt++)
1382 dhcp_zero_index(opt);
1383 }
1384
1385 for (i = 0, opt = ifp->ctx->dhcp_opts;
1386 i < ifp->ctx->dhcp_opts_len;
1387 i++, opt++)
1388 {
1389 if (has_option_mask(ifo->nomask, opt->option))
1390 continue;
1391 if (dhcp_getoverride(ifo, opt->option))
1392 continue;
1393 if ((p = get_option(ifp->ctx, dhcp, opt->option, &pl))) {
1394 ep += dhcp_envoption(ifp->ctx, ep, prefix, ifp->name,
1395 opt, dhcp_getoption, p, pl);
1396 if (opt->option == DHO_VIVSO &&
1397 pl > (int)sizeof(uint32_t))
1398 {
1399 memcpy(&en, p, sizeof(en));
1400 en = ntohl(en);
1401 vo = vivso_find(en, ifp);
1402 if (vo) {
1403 /* Skip over en + total size */
1404 p += sizeof(en) + 1;
1405 pl -= sizeof(en) + 1;
1406 ep += dhcp_envoption(ifp->ctx,
1407 ep, prefix, ifp->name,
1408 vo, dhcp_getoption, p, pl);
1409 }
1410 }
1411 }
1412 }
1413
1414 for (i = 0, opt = ifo->dhcp_override;
1415 i < ifo->dhcp_override_len;
1416 i++, opt++)
1417 {
1418 if (has_option_mask(ifo->nomask, opt->option))
1419 continue;
1420 if ((p = get_option(ifp->ctx, dhcp, opt->option, &pl)))
1421 ep += dhcp_envoption(ifp->ctx, ep, prefix, ifp->name,
1422 opt, dhcp_getoption, p, pl);
1423 }
1424
1425 return ep - env;
1426}
1427
1428static void
1429get_lease(struct dhcpcd_ctx *ctx,
1430 struct dhcp_lease *lease, const struct dhcp_message *dhcp)
1431{
1432
1433 lease->cookie = dhcp->cookie;
1434 /* BOOTP does not set yiaddr for replies when ciaddr is set. */
1435 if (dhcp->yiaddr)
1436 lease->addr.s_addr = dhcp->yiaddr;
1437 else
1438 lease->addr.s_addr = dhcp->ciaddr;
1439 if (get_option_addr(ctx, &lease->net, dhcp, DHO_SUBNETMASK) == -1)
1440 lease->net.s_addr = ipv4_getnetmask(lease->addr.s_addr);
1441 if (get_option_addr(ctx, &lease->brd, dhcp, DHO_BROADCAST) == -1)
1442 lease->brd.s_addr = lease->addr.s_addr | ~lease->net.s_addr;
1443 if (get_option_uint32(ctx, &lease->leasetime, dhcp, DHO_LEASETIME) != 0)
1444 lease->leasetime = ~0U; /* Default to infinite lease */
1445 if (get_option_uint32(ctx, &lease->renewaltime,
1446 dhcp, DHO_RENEWALTIME) != 0)
1447 lease->renewaltime = 0;
1448 if (get_option_uint32(ctx, &lease->rebindtime,
1449 dhcp, DHO_REBINDTIME) != 0)
1450 lease->rebindtime = 0;
1451 if (get_option_addr(ctx, &lease->server, dhcp, DHO_SERVERID) != 0)
1452 lease->server.s_addr = INADDR_ANY;
1453}
1454
1455static const char *
1456get_dhcp_op(uint8_t type)
1457{
1458 const struct dhcp_op *d;
1459
1460 for (d = dhcp_ops; d->name; d++)
1461 if (d->value == type)
1462 return d->name;
1463 return NULL;
1464}
1465
1466static void
1467dhcp_fallback(void *arg)
1468{
1469 struct interface *iface;
1470
1471 iface = (struct interface *)arg;
1472 dhcpcd_selectprofile(iface, iface->options->fallback);
1473 dhcpcd_startinterface(iface);
1474}
1475
1476uint32_t
1477dhcp_xid(const struct interface *ifp)
1478{
1479 uint32_t xid;
1480
1481 if (ifp->options->options & DHCPCD_XID_HWADDR &&
1482 ifp->hwlen >= sizeof(xid))
1483 /* The lower bits are probably more unique on the network */
1484 memcpy(&xid, (ifp->hwaddr + ifp->hwlen) - sizeof(xid),
1485 sizeof(xid));
1486 else
1487 xid = arc4random();
1488
1489 return xid;
1490}
1491
1492void
1493dhcp_close(struct interface *ifp)
1494{
1495 struct dhcp_state *state = D_STATE(ifp);
1496
1497 if (state == NULL)
1498 return;
1499
1500 if (state->raw_fd != -1) {
1501 eloop_event_delete(ifp->ctx->eloop, state->raw_fd, 0);
1502 close(state->raw_fd);
1503 state->raw_fd = -1;
1504 }
1505
1506 state->interval = 0;
1507}
1508
1509static int
1510dhcp_openudp(struct interface *ifp)
1511{
1512 int s;
1513 struct sockaddr_in sin;
1514 int n;
1515 struct dhcp_state *state;
1516#ifdef SO_BINDTODEVICE
1517 struct ifreq ifr;
1518 char *p;
1519#endif
1520
1521#ifdef SOCK_CLOEXEC
1522 if ((s = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP)) == -1)
1523 return -1;
1524#else
1525 if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
1526 return -1;
1527 if ((n = fcntl(s, F_GETFD, 0)) == -1 ||
1528 fcntl(s, F_SETFD, n | FD_CLOEXEC) == -1)
1529 {
1530 close(s);
1531 return -1;
1532 }
1533#endif
1534
1535 n = 1;
1536 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)) == -1)
1537 goto eexit;
1538#ifdef SO_BINDTODEVICE
1539 if (ifp) {
1540 memset(&ifr, 0, sizeof(ifr));
1541 strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
1542 /* We can only bind to the real device */
1543 p = strchr(ifr.ifr_name, ':');
1544 if (p)
1545 *p = '\0';
1546 if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, &ifr,
1547 sizeof(ifr)) == -1)
1548 goto eexit;
1549 }
1550#endif
1551 memset(&sin, 0, sizeof(sin));
1552 sin.sin_family = AF_INET;
1553 sin.sin_port = htons(DHCP_CLIENT_PORT);
1554 if (ifp) {
1555 state = D_STATE(ifp);
1556 sin.sin_addr.s_addr = state->addr.s_addr;
1557 } else
1558 state = NULL; /* appease gcc */
1559 if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
1560 goto eexit;
1561
1562 return s;
1563
1564eexit:
1565 close(s);
1566 return -1;
1567}
1568
1569static uint16_t
1570checksum(const void *data, unsigned int len)
1571{
1572 const uint8_t *addr = data;
1573 uint32_t sum = 0;
1574
1575 while (len > 1) {
1576 sum += (uint32_t)(addr[0] * 256 + addr[1]);
1577 addr += 2;
1578 len -= 2;
1579 }
1580
1581 if (len == 1)
1582 sum += (uint32_t)(*addr * 256);
1583
1584 sum = (sum >> 16) + (sum & 0xffff);
1585 sum += (sum >> 16);
1586
1587 return (uint16_t)~htons((uint16_t)sum);
1588}
1589
1590static struct udp_dhcp_packet *
1591dhcp_makeudppacket(size_t *sz, const uint8_t *data, size_t length,
1592 struct in_addr source, struct in_addr dest)
1593{
1594 struct udp_dhcp_packet *udpp;
1595 struct ip *ip;
1596 struct udphdr *udp;
1597
1598 udpp = calloc(1, sizeof(*udpp));
1599 if (udpp == NULL)
1600 return NULL;
1601 ip = &udpp->ip;
1602 udp = &udpp->udp;
1603
1604 /* OK, this is important :)
1605 * We copy the data to our packet and then create a small part of the
1606 * ip structure and an invalid ip_len (basically udp length).
1607 * We then fill the udp structure and put the checksum
1608 * of the whole packet into the udp checksum.
1609 * Finally we complete the ip structure and ip checksum.
1610 * If we don't do the ordering like so then the udp checksum will be
1611 * broken, so find another way of doing it! */
1612
1613 memcpy(&udpp->dhcp, data, length);
1614
1615 ip->ip_p = IPPROTO_UDP;
1616 ip->ip_src.s_addr = source.s_addr;
1617 if (dest.s_addr == 0)
1618 ip->ip_dst.s_addr = INADDR_BROADCAST;
1619 else
1620 ip->ip_dst.s_addr = dest.s_addr;
1621
1622 udp->uh_sport = htons(DHCP_CLIENT_PORT);
1623 udp->uh_dport = htons(DHCP_SERVER_PORT);
1624 udp->uh_ulen = htons((uint16_t)(sizeof(*udp) + length));
1625 ip->ip_len = udp->uh_ulen;
1626 udp->uh_sum = checksum(udpp, sizeof(*udpp));
1627
1628 ip->ip_v = IPVERSION;
1629 ip->ip_hl = sizeof(*ip) >> 2;
1630 ip->ip_id = (uint16_t)arc4random_uniform(UINT16_MAX);
1631 ip->ip_ttl = IPDEFTTL;
1632 ip->ip_len = htons((uint16_t)(sizeof(*ip) + sizeof(*udp) + length));
1633 ip->ip_sum = checksum(ip, sizeof(*ip));
1634
1635 *sz = sizeof(*ip) + sizeof(*udp) + length;
1636 return udpp;
1637}
1638
1639static void
1640send_message(struct interface *ifp, uint8_t type,
1641 void (*callback)(void *))
1642{
1643 struct dhcp_state *state = D_STATE(ifp);
1644 struct if_options *ifo = ifp->options;
1645 struct dhcp_message *dhcp;
1646 struct udp_dhcp_packet *udp;
1647 size_t len;
1648 ssize_t r;
1649 struct in_addr from, to;
1650 in_addr_t a = INADDR_ANY;
1651 struct timespec tv;
1652 int s;
1653#ifdef IN_IFF_NOTUSEABLE
1654 struct ipv4_addr *ia;
1655#endif
1656
1657 if (!callback)
Samuel Tan24aa62e2015-08-13 17:12:30 -07001658 logger(ifp->ctx, LOG_INFO, "%s: sending %s with xid 0x%x",
Samuel Tand7ed8512015-08-13 16:11:35 -07001659 ifp->name,
1660 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
1661 state->xid);
1662 else {
1663 if (state->interval == 0)
Samuel Tane942e092015-08-13 17:14:37 -07001664 state->interval = DHCP_BASE;
Samuel Tand7ed8512015-08-13 16:11:35 -07001665 else {
1666 state->interval *= 2;
Samuel Tane942e092015-08-13 17:14:37 -07001667 if (state->interval > DHCP_MAX)
1668 state->interval = DHCP_MAX;
Samuel Tand7ed8512015-08-13 16:11:35 -07001669 }
1670 tv.tv_sec = state->interval + DHCP_RAND_MIN;
1671 tv.tv_nsec = (suseconds_t)arc4random_uniform(
1672 (DHCP_RAND_MAX - DHCP_RAND_MIN) * NSEC_PER_SEC);
1673 timespecnorm(&tv);
Samuel Tan24aa62e2015-08-13 17:12:30 -07001674 logger(ifp->ctx, LOG_INFO,
Samuel Tand7ed8512015-08-13 16:11:35 -07001675 "%s: sending %s (xid 0x%x), next in %0.1f seconds",
1676 ifp->name,
1677 ifo->options & DHCPCD_BOOTP ? "BOOTP" : get_dhcp_op(type),
1678 state->xid,
1679 timespec_to_double(&tv));
1680 }
1681
1682 if (dhcp_open(ifp) == -1)
1683 return;
1684
1685 if (state->added && !(state->added & STATE_FAKE) &&
1686 state->addr.s_addr != INADDR_ANY &&
1687 state->new != NULL &&
1688#ifdef IN_IFF_NOTUSEABLE
1689 ((ia = ipv4_iffindaddr(ifp, &state->addr, NULL)) &&
1690 !(ia->addr_flags & IN_IFF_NOTUSEABLE)) &&
1691#endif
1692 (state->new->cookie == htonl(MAGIC_COOKIE) ||
1693 ifp->options->options & DHCPCD_INFORM))
1694 {
1695 s = dhcp_openudp(ifp);
1696 if (s == -1 && errno != EADDRINUSE)
1697 logger(ifp->ctx, LOG_ERR,
1698 "%s: dhcp_openudp: %m", ifp->name);
1699 } else
1700 s = -1;
1701
1702 /* If we couldn't open a UDP port for our IP address
1703 * then we cannot renew.
1704 * This could happen if our IP was pulled out from underneath us.
1705 * Also, we should not unicast from a BOOTP lease. */
1706 if (s == -1 ||
1707 (!(ifo->options & DHCPCD_INFORM) &&
1708 IS_BOOTP(ifp, state->new)))
1709 {
1710 a = state->addr.s_addr;
1711 state->addr.s_addr = INADDR_ANY;
1712 }
1713 r = make_message(&dhcp, ifp, type);
1714 if (r == -1)
1715 goto fail;
1716 len = (size_t)r;
1717 if (a)
1718 state->addr.s_addr = a;
1719 from.s_addr = dhcp->ciaddr;
1720 if (from.s_addr)
1721 to.s_addr = state->lease.server.s_addr;
1722 else
1723 to.s_addr = INADDR_ANY;
1724 if (to.s_addr && to.s_addr != INADDR_BROADCAST) {
1725 struct sockaddr_in sin;
1726
1727 memset(&sin, 0, sizeof(sin));
1728 sin.sin_family = AF_INET;
1729 sin.sin_addr.s_addr = to.s_addr;
1730 sin.sin_port = htons(DHCP_SERVER_PORT);
1731 r = sendto(s, (uint8_t *)dhcp, len, 0,
1732 (struct sockaddr *)&sin, sizeof(sin));
1733 if (r == -1)
1734 logger(ifp->ctx, LOG_ERR,
1735 "%s: dhcp_sendpacket: %m", ifp->name);
1736 } else {
1737 size_t ulen;
1738
1739 r = 0;
1740 udp = dhcp_makeudppacket(&ulen, (uint8_t *)dhcp, len, from, to);
1741 if (udp == NULL) {
1742 logger(ifp->ctx, LOG_ERR, "dhcp_makeudppacket: %m");
1743 } else {
1744 r = if_sendrawpacket(ifp, ETHERTYPE_IP,
Samuel Tanf20514b2015-08-13 16:24:02 -07001745 (uint8_t *)udp, ulen, NULL);
Samuel Tand7ed8512015-08-13 16:11:35 -07001746 free(udp);
1747 }
1748 /* If we failed to send a raw packet this normally means
1749 * we don't have the ability to work beneath the IP layer
1750 * for this interface.
1751 * As such we remove it from consideration without actually
1752 * stopping the interface. */
1753 if (r == -1) {
1754 logger(ifp->ctx, LOG_ERR,
1755 "%s: if_sendrawpacket: %m", ifp->name);
1756 switch(errno) {
1757 case ENETDOWN:
1758 case ENETRESET:
1759 case ENETUNREACH:
1760 break;
1761 default:
1762 if (!(ifp->ctx->options & DHCPCD_TEST))
1763 dhcp_drop(ifp, "FAIL");
1764 dhcp_free(ifp);
1765 eloop_timeout_delete(ifp->ctx->eloop,
1766 NULL, ifp);
1767 callback = NULL;
1768 }
1769 }
1770 }
1771 free(dhcp);
1772
1773fail:
1774 if (s != -1)
1775 close(s);
1776
1777 /* Even if we fail to send a packet we should continue as we are
1778 * as our failure timeouts will change out codepath when needed. */
1779 if (callback)
1780 eloop_timeout_add_tv(ifp->ctx->eloop, &tv, callback, ifp);
1781}
1782
1783static void
1784send_inform(void *arg)
1785{
1786
1787 send_message((struct interface *)arg, DHCP_INFORM, send_inform);
1788}
1789
1790static void
1791send_discover(void *arg)
1792{
1793
1794 send_message((struct interface *)arg, DHCP_DISCOVER, send_discover);
1795}
1796
1797static void
1798send_request(void *arg)
1799{
1800
1801 send_message((struct interface *)arg, DHCP_REQUEST, send_request);
1802}
1803
1804static void
1805send_renew(void *arg)
1806{
1807
1808 send_message((struct interface *)arg, DHCP_REQUEST, send_renew);
1809}
1810
1811static void
1812send_rebind(void *arg)
1813{
1814
1815 send_message((struct interface *)arg, DHCP_REQUEST, send_rebind);
1816}
1817
1818void
1819dhcp_discover(void *arg)
1820{
1821 struct interface *ifp = arg;
1822 struct dhcp_state *state = D_STATE(ifp);
1823 struct if_options *ifo = ifp->options;
1824
Samuel Tan23ff6ed2015-08-13 16:50:06 -07001825 rpc_signal_status("Discover");
Samuel Tand7ed8512015-08-13 16:11:35 -07001826 state->state = DHS_DISCOVER;
1827 state->xid = dhcp_xid(ifp);
Samuel Tan5158c9d2015-08-13 18:09:30 -07001828 state->nak_receive_count = 0;
1829 state->failed_address_offer_count = 0;
Samuel Tand7ed8512015-08-13 16:11:35 -07001830 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1831 if (ifo->fallback)
1832 eloop_timeout_add_sec(ifp->ctx->eloop,
1833 ifo->reboot, dhcp_fallback, ifp);
1834 else if (ifo->options & DHCPCD_IPV4LL &&
1835 !IN_LINKLOCAL(htonl(state->addr.s_addr)))
1836 eloop_timeout_add_sec(ifp->ctx->eloop,
1837 ifo->reboot, ipv4ll_start, ifp);
1838 if (ifo->options & DHCPCD_REQUEST)
1839 logger(ifp->ctx, LOG_INFO,
1840 "%s: soliciting a DHCP lease (requesting %s)",
1841 ifp->name, inet_ntoa(ifo->req_addr));
1842 else
1843 logger(ifp->ctx, LOG_INFO,
1844 "%s: soliciting a %s lease",
1845 ifp->name, ifo->options & DHCPCD_BOOTP ? "BOOTP" : "DHCP");
1846 send_discover(ifp);
1847}
1848
1849static void
1850dhcp_request(void *arg)
1851{
1852 struct interface *ifp = arg;
1853 struct dhcp_state *state = D_STATE(ifp);
1854
Samuel Tan24aa62e2015-08-13 17:12:30 -07001855 logger(ifp->ctx, LOG_INFO, "%s: requesting lease of %s",
1856 ifp->name, inet_ntoa(state->lease.addr));
1857
Samuel Tan23ff6ed2015-08-13 16:50:06 -07001858 rpc_signal_status("Request");
Samuel Tand7ed8512015-08-13 16:11:35 -07001859 state->state = DHS_REQUEST;
Samuel Tan5158c9d2015-08-13 18:09:30 -07001860 state->nak_receive_count = 0;
Samuel Tand7ed8512015-08-13 16:11:35 -07001861 send_request(ifp);
1862}
1863
1864static void
1865dhcp_expire(void *arg)
1866{
1867 struct interface *ifp = arg;
1868 struct dhcp_state *state = D_STATE(ifp);
1869
1870 logger(ifp->ctx, LOG_ERR, "%s: DHCP lease expired", ifp->name);
1871 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
1872 dhcp_drop(ifp, "EXPIRE");
1873 unlink(state->leasefile);
1874 state->interval = 0;
1875 dhcp_discover(ifp);
1876}
1877
1878static void
1879dhcp_decline(struct interface *ifp)
1880{
1881
1882 send_message(ifp, DHCP_DECLINE, NULL);
1883}
1884
1885static void
1886dhcp_renew(void *arg)
1887{
1888 struct interface *ifp = arg;
1889 struct dhcp_state *state = D_STATE(ifp);
1890 struct dhcp_lease *lease = &state->lease;
1891
Samuel Tan23ff6ed2015-08-13 16:50:06 -07001892 rpc_signal_status("Renew");
Samuel Tan24aa62e2015-08-13 17:12:30 -07001893 logger(ifp->ctx, LOG_INFO, "%s: renewing lease of %s",
Samuel Tand7ed8512015-08-13 16:11:35 -07001894 ifp->name, inet_ntoa(lease->addr));
1895 logger(ifp->ctx, LOG_DEBUG, "%s: rebind in %"PRIu32" seconds,"
1896 " expire in %"PRIu32" seconds",
1897 ifp->name, lease->rebindtime - lease->renewaltime,
1898 lease->leasetime - lease->renewaltime);
1899 state->state = DHS_RENEW;
1900 state->xid = dhcp_xid(ifp);
Samuel Tan5158c9d2015-08-13 18:09:30 -07001901 state->nak_receive_count = 0;
Samuel Tand7ed8512015-08-13 16:11:35 -07001902 send_renew(ifp);
1903}
1904
1905#ifndef IN_IFF_TENTATIVE
1906static void
1907dhcp_arp_announced(struct arp_state *astate)
1908{
1909
1910 arp_close(astate->iface);
1911}
1912#endif
1913
1914static void
1915dhcp_rebind(void *arg)
1916{
1917 struct interface *ifp = arg;
1918 struct dhcp_state *state = D_STATE(ifp);
1919 struct dhcp_lease *lease = &state->lease;
1920
Samuel Tan23ff6ed2015-08-13 16:50:06 -07001921 rpc_signal_status("Rebind");
Samuel Tand7ed8512015-08-13 16:11:35 -07001922 logger(ifp->ctx, LOG_WARNING,
1923 "%s: failed to renew DHCP, rebinding", ifp->name);
1924 logger(ifp->ctx, LOG_DEBUG, "%s: expire in %"PRIu32" seconds",
1925 ifp->name, lease->leasetime - lease->rebindtime);
1926 state->state = DHS_REBIND;
1927 eloop_timeout_delete(ifp->ctx->eloop, send_renew, ifp);
1928 state->lease.server.s_addr = 0;
Samuel Tan5158c9d2015-08-13 18:09:30 -07001929 state->nak_receive_count = 0;
Samuel Tand7ed8512015-08-13 16:11:35 -07001930 ifp->options->options &= ~(DHCPCD_CSR_WARNED |
1931 DHCPCD_ROUTER_HOST_ROUTE_WARNED);
1932 send_rebind(ifp);
1933}
1934
Samuel Tan9177c6f2015-08-13 16:47:36 -07001935static void
1936init_option_iterator(const struct dhcp_message *message,
1937 struct dhcp_option_iterator *iterator)
1938{
1939 iterator->message = message;
1940 iterator->ptr = message->options;
1941 iterator->end = iterator->ptr + sizeof(message->options);
1942 iterator->extra_option_locations = 0;
1943 iterator->extra_option_locations_set = 0;
1944}
1945
1946static int
1947iterate_next_option(struct dhcp_option_iterator *iterator,
1948 uint8_t *option, uint8_t *length, const uint8_t **value)
1949{
1950 uint8_t option_code;
1951 uint8_t option_len;
1952
1953 /* Process special DHO_PAD and DHO_END opcodes. */
1954 while (iterator->ptr < iterator->end) {
1955 if (*iterator->ptr == DHO_PAD) {
1956 iterator->ptr++;
1957 continue;
1958 }
1959
1960 if (*iterator->ptr != DHO_END)
1961 break;
1962
1963 if (iterator->extra_option_locations &
1964 OPTION_OVERLOADED_BOOT_FILE) {
1965 iterator->extra_option_locations &=
1966 ~OPTION_OVERLOADED_BOOT_FILE;
1967 iterator->ptr = iterator->message->bootfile;
1968 iterator->end = iterator->ptr +
1969 sizeof(iterator->message->bootfile);
1970 } else if (iterator->extra_option_locations &
1971 OPTION_OVERLOADED_SERVER_NAME) {
1972 iterator->extra_option_locations &=
1973 ~OPTION_OVERLOADED_SERVER_NAME;
1974 iterator->ptr = iterator->message->servername;
1975 iterator->end = iterator->ptr +
1976 sizeof(iterator->message->servername);
1977 } else
1978 return 0;
1979 }
1980
1981 if (iterator->ptr + 2 > iterator->end)
1982 return 0;
1983
1984 option_code = *iterator->ptr++;
1985 option_len = *iterator->ptr++;
1986 if (iterator->ptr + option_len > iterator->end)
1987 return 0;
1988
1989 if (option_code == DHO_OPTIONSOVERLOADED && option_len > 0 &&
1990 !iterator->extra_option_locations_set) {
1991 iterator->extra_option_locations = *iterator->ptr;
1992 iterator->extra_option_locations_set = 1;
1993 }
1994
1995 if (option)
1996 *option = option_code;
1997 if (length)
1998 *length = option_len;
1999 if (value)
2000 *value = iterator->ptr;
2001
2002 iterator->ptr += option_len;
2003
2004 return 1;
2005}
2006
2007static void
2008merge_option_values(const struct dhcp_message *src,
2009 struct dhcp_message *dst, uint8_t *copy_options)
2010{
2011 uint8_t supplied_options[OPTION_MASK_SIZE];
2012 struct dhcp_option_iterator dst_iterator;
2013 struct dhcp_option_iterator src_iterator;
2014 uint8_t option;
2015 const uint8_t *option_value;
2016 uint8_t option_length;
2017 uint8_t *out;
2018 const uint8_t *out_end;
2019 int added_options = 0;
2020
2021 /* Traverse the destination message for options already supplied. */
2022 memset(&supplied_options, 0, sizeof(supplied_options));
2023 init_option_iterator(dst, &dst_iterator);
2024 while (iterate_next_option(&dst_iterator, &option, NULL, NULL)) {
2025 add_option_mask(supplied_options, option);
2026 }
2027
2028 /* We will start merging options at the end of the last block
2029 * the iterator traversed to. The const cast below is safe since
2030 * this points to data within the (non-const) dst message. */
2031 out = (uint8_t *) dst_iterator.ptr;
2032 out_end = dst_iterator.end;
2033
2034 init_option_iterator(src, &src_iterator);
2035 while (iterate_next_option(&src_iterator, &option, &option_length,
2036 &option_value)) {
2037 if (has_option_mask(supplied_options, option) ||
2038 !has_option_mask(copy_options, option))
2039 continue;
2040 /* We need space for this option, plus a trailing DHO_END. */
2041 if (out + option_length + 3 > out_end) {
2042 syslog(LOG_ERR,
2043 "%s: unable to fit option %d (length %d)",
2044 __func__, option, option_length);
2045 continue;
2046 }
2047 *out++ = option;
2048 *out++ = option_length;
2049 memcpy(out, option_value, option_length);
2050 out += option_length;
2051 added_options++;
2052 }
2053
2054 if (added_options) {
2055 *out++ = DHO_END;
2056 syslog(LOG_INFO, "carrying over %d options from original offer",
2057 added_options);
2058 }
2059}
2060
Samuel Tand7ed8512015-08-13 16:11:35 -07002061void
2062dhcp_bind(struct interface *ifp, struct arp_state *astate)
2063{
2064 struct dhcp_state *state = D_STATE(ifp);
2065 struct if_options *ifo = ifp->options;
2066 struct dhcp_lease *lease = &state->lease;
2067 uint8_t ipv4ll = 0;
2068
2069 if (state->state == DHS_BOUND)
2070 goto applyaddr;
2071 state->reason = NULL;
2072 free(state->old);
2073 state->old = state->new;
2074 state->new = state->offer;
2075 state->offer = NULL;
2076 get_lease(ifp->ctx, lease, state->new);
2077 if (ifo->options & DHCPCD_STATIC) {
2078 logger(ifp->ctx, LOG_INFO, "%s: using static address %s/%d",
2079 ifp->name, inet_ntoa(lease->addr),
2080 inet_ntocidr(lease->net));
2081 lease->leasetime = ~0U;
2082 state->reason = "STATIC";
2083 } else if (state->new->cookie != htonl(MAGIC_COOKIE)) {
2084 logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s",
2085 ifp->name, inet_ntoa(lease->addr));
2086 lease->leasetime = ~0U;
2087 state->reason = "IPV4LL";
2088 ipv4ll = 1;
2089 } else if (ifo->options & DHCPCD_INFORM) {
2090 if (ifo->req_addr.s_addr != 0)
2091 lease->addr.s_addr = ifo->req_addr.s_addr;
2092 else
2093 lease->addr.s_addr = state->addr.s_addr;
2094 logger(ifp->ctx, LOG_INFO, "%s: received approval for %s",
2095 ifp->name, inet_ntoa(lease->addr));
2096 lease->leasetime = ~0U;
2097 state->reason = "INFORM";
2098 } else {
2099 if (lease->frominfo)
2100 state->reason = "TIMEOUT";
2101 if (lease->leasetime == ~0U) {
2102 lease->renewaltime =
2103 lease->rebindtime =
2104 lease->leasetime;
2105 logger(ifp->ctx, LOG_INFO, "%s: leased %s for infinity",
2106 ifp->name, inet_ntoa(lease->addr));
2107 } else {
2108 if (lease->leasetime < DHCP_MIN_LEASE) {
2109 logger(ifp->ctx, LOG_WARNING,
2110 "%s: minimum lease is %d seconds",
2111 ifp->name, DHCP_MIN_LEASE);
2112 lease->leasetime = DHCP_MIN_LEASE;
2113 }
2114 if (lease->rebindtime == 0)
2115 lease->rebindtime =
2116 (uint32_t)(lease->leasetime * T2);
2117 else if (lease->rebindtime >= lease->leasetime) {
2118 lease->rebindtime =
2119 (uint32_t)(lease->leasetime * T2);
2120 logger(ifp->ctx, LOG_WARNING,
2121 "%s: rebind time greater than lease "
2122 "time, forcing to %"PRIu32" seconds",
2123 ifp->name, lease->rebindtime);
2124 }
2125 if (lease->renewaltime == 0)
2126 lease->renewaltime =
2127 (uint32_t)(lease->leasetime * T1);
2128 else if (lease->renewaltime > lease->rebindtime) {
2129 lease->renewaltime =
2130 (uint32_t)(lease->leasetime * T1);
2131 logger(ifp->ctx, LOG_WARNING,
2132 "%s: renewal time greater than rebind "
2133 "time, forcing to %"PRIu32" seconds",
2134 ifp->name, lease->renewaltime);
2135 }
2136 logger(ifp->ctx,
2137 lease->addr.s_addr == state->addr.s_addr &&
2138 !(state->added & STATE_FAKE) ?
2139 LOG_DEBUG : LOG_INFO,
2140 "%s: leased %s for %"PRIu32" seconds", ifp->name,
2141 inet_ntoa(lease->addr), lease->leasetime);
2142 }
2143 }
2144 if (ifp->ctx->options & DHCPCD_TEST) {
2145 state->reason = "TEST";
2146 script_runreason(ifp, state->reason);
2147 eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
2148 return;
2149 }
2150 if (state->reason == NULL) {
2151 if (state->old && !(state->added & STATE_FAKE)) {
2152 if (state->old->yiaddr == state->new->yiaddr &&
2153 lease->server.s_addr)
2154 state->reason = "RENEW";
2155 else
2156 state->reason = "REBIND";
2157 } else if (state->state == DHS_REBOOT)
2158 state->reason = "REBOOT";
2159 else
2160 state->reason = "BOUND";
2161 }
Samuel Tan9177c6f2015-08-13 16:47:36 -07002162
2163 if (state->old && state->old->yiaddr == state->new->yiaddr &&
2164 (state->state == DHS_REBOOT || state->state == DHS_RENEW ||
2165 state->state == DHS_REBIND)) {
2166 /* Some DHCP servers respond to REQUEST with a subset
2167 * of the original requested parameters. If they were not
2168 * supplied in the response to a renewal, we should assume
2169 * that it's reasonable to transfer them forward from the
2170 * original offer. */
2171 merge_option_values(state->old, state->new, ifo->requestmask);
2172 }
2173
Samuel Tand7ed8512015-08-13 16:11:35 -07002174 if (lease->leasetime == ~0U)
2175 lease->renewaltime = lease->rebindtime = lease->leasetime;
2176 else {
2177 eloop_timeout_add_sec(ifp->ctx->eloop,
2178 (time_t)lease->renewaltime, dhcp_renew, ifp);
2179 eloop_timeout_add_sec(ifp->ctx->eloop,
2180 (time_t)lease->rebindtime, dhcp_rebind, ifp);
2181 eloop_timeout_add_sec(ifp->ctx->eloop,
2182 (time_t)lease->leasetime, dhcp_expire, ifp);
2183 logger(ifp->ctx, LOG_DEBUG,
2184 "%s: renew in %"PRIu32" seconds, rebind in %"PRIu32
2185 " seconds",
2186 ifp->name, lease->renewaltime, lease->rebindtime);
2187 }
2188 if (!(ifo->options & DHCPCD_STATIC) &&
2189 state->new->cookie != htonl(MAGIC_COOKIE))
2190 state->state = DHS_IPV4LL_BOUND;
2191 else
2192 state->state = DHS_BOUND;
2193 if (!state->lease.frominfo &&
2194 !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))
2195 if (write_lease(ifp, state->new) == -1)
2196 logger(ifp->ctx, LOG_ERR,
2197 "%s: write_lease: %m", __func__);
2198
2199applyaddr:
2200 ipv4_applyaddr(ifp);
2201 if (ifo->options & DHCPCD_ARP &&
2202 !(ifp->ctx->options & DHCPCD_FORKED))
2203 {
2204#ifdef IN_IFF_TENTATIVE
2205 if (astate)
2206 arp_free_but(astate);
2207 else if (!ipv4ll)
2208 arp_close(ifp);
2209#else
2210 if (state->added) {
2211 if (astate == NULL) {
2212 astate = arp_new(ifp, &state->addr);
2213 astate->announced_cb =
2214 dhcp_arp_announced;
2215 }
2216 if (astate) {
2217 arp_announce(astate);
2218 if (!ipv4ll)
2219 arp_free_but(astate);
2220 }
2221 } else if (!ipv4ll)
2222 arp_close(ifp);
2223#endif
2224 }
2225}
2226
2227static void
2228dhcp_timeout(void *arg)
2229{
2230 struct interface *ifp = arg;
2231 struct dhcp_state *state = D_STATE(ifp);
2232
2233 dhcp_bind(ifp, NULL);
2234 state->interval = 0;
2235 dhcp_discover(ifp);
2236}
2237
2238struct dhcp_message *
2239dhcp_message_new(const struct in_addr *addr, const struct in_addr *mask)
2240{
2241 struct dhcp_message *dhcp;
2242 uint8_t *p;
2243
2244 dhcp = calloc(1, sizeof(*dhcp));
2245 if (dhcp == NULL)
2246 return NULL;
2247 dhcp->yiaddr = addr->s_addr;
2248 p = dhcp->options;
2249 if (mask && mask->s_addr != INADDR_ANY) {
2250 *p++ = DHO_SUBNETMASK;
2251 *p++ = sizeof(mask->s_addr);
2252 memcpy(p, &mask->s_addr, sizeof(mask->s_addr));
2253 p+= sizeof(mask->s_addr);
2254 }
2255 *p++ = DHO_END;
2256 return dhcp;
2257}
2258
2259static void
2260dhcp_static(struct interface *ifp)
2261{
2262 struct if_options *ifo;
2263 struct dhcp_state *state;
2264
2265 state = D_STATE(ifp);
2266 ifo = ifp->options;
2267 if (ifo->req_addr.s_addr == INADDR_ANY) {
2268 logger(ifp->ctx, LOG_INFO,
2269 "%s: waiting for 3rd party to "
2270 "configure IP address",
2271 ifp->name);
2272 state->reason = "3RDPARTY";
2273 script_runreason(ifp, state->reason);
2274 return;
2275 }
2276 state->offer = dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
2277 if (state->offer) {
2278 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2279 dhcp_bind(ifp, NULL);
2280 }
2281}
2282
2283void
2284dhcp_inform(struct interface *ifp)
2285{
2286 struct dhcp_state *state;
2287 struct if_options *ifo;
2288 struct ipv4_addr *ap;
2289
2290 state = D_STATE(ifp);
2291 ifo = ifp->options;
Samuel Tan24aa62e2015-08-13 17:12:30 -07002292 logger(ifp->ctx, LOG_INFO, "%s: informing peers of local address",
2293 ifp->name);
Samuel Tand7ed8512015-08-13 16:11:35 -07002294 if (ifp->ctx->options & DHCPCD_TEST) {
2295 state->addr.s_addr = ifo->req_addr.s_addr;
2296 state->net.s_addr = ifo->req_mask.s_addr;
2297 } else {
2298 if (ifo->req_addr.s_addr == INADDR_ANY) {
2299 state = D_STATE(ifp);
2300 ap = ipv4_iffindaddr(ifp, NULL, NULL);
2301 if (ap == NULL) {
2302 logger(ifp->ctx, LOG_INFO,
2303 "%s: waiting for 3rd party to "
2304 "configure IP address",
2305 ifp->name);
2306 state->reason = "3RDPARTY";
2307 script_runreason(ifp, state->reason);
2308 return;
2309 }
2310 state->offer =
2311 dhcp_message_new(&ap->addr, &ap->net);
2312 } else
2313 state->offer =
2314 dhcp_message_new(&ifo->req_addr, &ifo->req_mask);
2315 if (state->offer) {
2316 ifo->options |= DHCPCD_STATIC;
2317 dhcp_bind(ifp, NULL);
2318 ifo->options &= ~DHCPCD_STATIC;
2319 }
2320 }
2321
Samuel Tan23ff6ed2015-08-13 16:50:06 -07002322 rpc_signal_status("Inform");
Samuel Tand7ed8512015-08-13 16:11:35 -07002323 state->state = DHS_INFORM;
2324 state->xid = dhcp_xid(ifp);
2325 send_inform(ifp);
2326}
2327
2328void
2329dhcp_reboot_newopts(struct interface *ifp, unsigned long long oldopts)
2330{
2331 struct if_options *ifo;
2332 struct dhcp_state *state = D_STATE(ifp);
2333
2334 if (state == NULL)
2335 return;
2336 ifo = ifp->options;
2337 if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) &&
2338 state->addr.s_addr != ifo->req_addr.s_addr) ||
2339 (oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) &&
2340 !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))))
2341 {
2342 dhcp_drop(ifp, "EXPIRE");
2343 }
2344}
2345
Samuel Tanf20514b2015-08-13 16:24:02 -07002346static void start_unicast_arp(struct interface *ifp);
2347
Samuel Tand7ed8512015-08-13 16:11:35 -07002348static void
2349dhcp_reboot(struct interface *ifp)
2350{
2351 struct if_options *ifo;
2352 struct dhcp_state *state = D_STATE(ifp);
2353
2354 if (state == NULL)
2355 return;
Samuel Tan23ff6ed2015-08-13 16:50:06 -07002356 rpc_signal_status("Reboot");
Samuel Tand7ed8512015-08-13 16:11:35 -07002357 ifo = ifp->options;
2358 state->state = DHS_REBOOT;
2359 state->interval = 0;
2360
2361 if (ifo->options & DHCPCD_LINK && ifp->carrier == LINK_DOWN) {
2362 logger(ifp->ctx, LOG_INFO,
2363 "%s: waiting for carrier", ifp->name);
2364 return;
2365 }
2366 if (ifo->options & DHCPCD_STATIC) {
2367 dhcp_static(ifp);
2368 return;
2369 }
Samuel Tanf20514b2015-08-13 16:24:02 -07002370 if (ifo->options & DHCPCD_UNICAST_ARP) {
2371 start_unicast_arp(ifp);
2372 }
Samuel Tand7ed8512015-08-13 16:11:35 -07002373 if (ifo->options & DHCPCD_INFORM) {
2374 logger(ifp->ctx, LOG_INFO, "%s: informing address of %s",
2375 ifp->name, inet_ntoa(state->lease.addr));
2376 dhcp_inform(ifp);
2377 return;
2378 }
2379 if (ifo->reboot == 0 || state->offer == NULL) {
2380 dhcp_discover(ifp);
2381 return;
2382 }
2383 if (state->offer->cookie == 0)
2384 return;
2385
2386 logger(ifp->ctx, LOG_INFO, "%s: rebinding lease of %s",
2387 ifp->name, inet_ntoa(state->lease.addr));
2388 state->xid = dhcp_xid(ifp);
2389 state->lease.server.s_addr = 0;
2390 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2391
2392 /* Need to add this before dhcp_expire and friends. */
2393 if (!ifo->fallback && ifo->options & DHCPCD_IPV4LL &&
2394 !IN_LINKLOCAL(htonl(state->addr.s_addr)))
2395 eloop_timeout_add_sec(ifp->ctx->eloop,
2396 ifo->reboot, ipv4ll_start, ifp);
2397
2398 if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo)
2399 eloop_timeout_add_sec(ifp->ctx->eloop,
2400 ifo->reboot, dhcp_timeout, ifp);
2401 else if (!(ifo->options & DHCPCD_INFORM))
2402 eloop_timeout_add_sec(ifp->ctx->eloop,
2403 ifo->reboot, dhcp_expire, ifp);
2404
2405 /* Don't bother ARP checking as the server could NAK us first.
2406 * Don't call dhcp_request as that would change the state */
2407 send_request(ifp);
2408}
2409
2410void
2411dhcp_drop(struct interface *ifp, const char *reason)
2412{
2413 struct dhcp_state *state;
2414#ifdef RELEASE_SLOW
2415 struct timespec ts;
2416#endif
2417
2418 state = D_STATE(ifp);
2419 /* dhcp_start may just have been called and we don't yet have a state
2420 * but we do have a timeout, so punt it. */
2421 if (state == NULL) {
2422 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2423 return;
2424 }
2425 /* Don't reset DHCP state if we have an IPv4LL address and link is up,
2426 * unless the interface is departing. */
2427 if (state->state != DHS_IPV4LL_BOUND ||
2428 ifp->carrier != LINK_UP ||
2429 ifp->options->options & DHCPCD_DEPARTED)
2430 {
2431 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
2432 dhcp_auth_reset(&state->auth);
2433 dhcp_close(ifp);
2434 }
2435
Samuel Tane942e092015-08-13 17:14:37 -07002436 if (ifp->options->options & DHCPCD_RELEASE ||
2437 strcmp(reason, "RELEASE") == 0) {
Samuel Tand7ed8512015-08-13 16:11:35 -07002438 unlink(state->leasefile);
2439 if (ifp->carrier != LINK_DOWN &&
2440 state->new != NULL &&
2441 state->new->cookie == htonl(MAGIC_COOKIE))
2442 {
2443 logger(ifp->ctx, LOG_INFO, "%s: releasing lease of %s",
2444 ifp->name, inet_ntoa(state->lease.addr));
2445 state->xid = dhcp_xid(ifp);
2446 send_message(ifp, DHCP_RELEASE, NULL);
2447#ifdef RELEASE_SLOW
2448 /* Give the packet a chance to go */
2449 ts.tv_sec = RELEASE_DELAY_S;
2450 ts.tv_nsec = RELEASE_DELAY_NS;
2451 nanosleep(&ts, NULL);
2452#endif
2453 }
2454 }
2455
2456 free(state->old);
2457 state->old = state->new;
2458 state->new = NULL;
2459 state->reason = reason;
2460 ipv4_applyaddr(ifp);
2461 free(state->old);
2462 state->old = NULL;
2463 state->lease.addr.s_addr = 0;
2464 ifp->options->options &= ~(DHCPCD_CSR_WARNED |
2465 DHCPCD_ROUTER_HOST_ROUTE_WARNED);
2466}
2467
2468static void
2469log_dhcp1(int lvl, const char *msg,
2470 const struct interface *ifp, const struct dhcp_message *dhcp,
2471 const struct in_addr *from, int ad)
2472{
2473 const char *tfrom;
2474 char *a, sname[sizeof(dhcp->servername) * 4];
2475 struct in_addr addr;
2476 int r;
2477
2478 if (strcmp(msg, "NAK:") == 0) {
2479 a = get_option_string(ifp->ctx, dhcp, DHO_MESSAGE);
2480 if (a) {
2481 char *tmp;
2482 size_t al, tmpl;
2483
2484 al = strlen(a);
2485 tmpl = (al * 4) + 1;
2486 tmp = malloc(tmpl);
2487 if (tmp == NULL) {
2488 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
2489 free(a);
2490 return;
2491 }
2492 print_string(tmp, tmpl, STRING, (uint8_t *)a, al);
2493 free(a);
2494 a = tmp;
2495 }
2496 } else if (ad && dhcp->yiaddr != 0) {
2497 addr.s_addr = dhcp->yiaddr;
2498 a = strdup(inet_ntoa(addr));
2499 if (a == NULL) {
2500 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
2501 return;
2502 }
2503 } else
2504 a = NULL;
2505
2506 tfrom = "from";
2507 r = get_option_addr(ifp->ctx, &addr, dhcp, DHO_SERVERID);
2508 if (dhcp->servername[0] && r == 0) {
2509 print_string(sname, sizeof(sname), STRING,
2510 dhcp->servername, strlen((const char *)dhcp->servername));
2511 if (a == NULL)
2512 logger(ifp->ctx, lvl, "%s: %s %s %s `%s'",
2513 ifp->name, msg, tfrom, inet_ntoa(addr), sname);
2514 else
2515 logger(ifp->ctx, lvl, "%s: %s %s %s %s `%s'",
2516 ifp->name, msg, a, tfrom, inet_ntoa(addr), sname);
2517 } else {
2518 if (r != 0) {
2519 tfrom = "via";
2520 addr = *from;
2521 }
2522 if (a == NULL)
2523 logger(ifp->ctx, lvl, "%s: %s %s %s",
2524 ifp->name, msg, tfrom, inet_ntoa(addr));
2525 else
2526 logger(ifp->ctx, lvl, "%s: %s %s %s %s",
2527 ifp->name, msg, a, tfrom, inet_ntoa(addr));
2528 }
2529 free(a);
2530}
2531
2532static void
2533log_dhcp(int lvl, const char *msg,
2534 const struct interface *ifp, const struct dhcp_message *dhcp,
2535 const struct in_addr *from)
2536{
2537
2538 log_dhcp1(lvl, msg, ifp, dhcp, from, 1);
2539}
2540
2541static int
2542blacklisted_ip(const struct if_options *ifo, in_addr_t addr)
2543{
2544 size_t i;
2545
2546 for (i = 0; i < ifo->blacklist_len; i += 2)
2547 if (ifo->blacklist[i] == (addr & ifo->blacklist[i + 1]))
2548 return 1;
2549 return 0;
2550}
2551
2552static int
2553whitelisted_ip(const struct if_options *ifo, in_addr_t addr)
2554{
2555 size_t i;
2556
2557 if (ifo->whitelist_len == 0)
2558 return -1;
2559 for (i = 0; i < ifo->whitelist_len; i += 2)
2560 if (ifo->whitelist[i] == (addr & ifo->whitelist[i + 1]))
2561 return 1;
2562 return 0;
2563}
2564
2565static void
Samuel Tanf20514b2015-08-13 16:24:02 -07002566save_gateway_addr(struct interface *ifp, const uint8_t *gw_hwaddr)
2567{
2568 struct dhcp_state *state = D_STATE(ifp);
2569 memcpy(state->server_info.gw_hwaddr, gw_hwaddr, ifp->hwlen);
2570 state->server_info.gw_hwlen = ifp->hwlen;
2571}
2572
2573static void
2574dhcp_probe_gw_timeout(struct arp_state *astate)
2575{
Samuel Tan1c4088e2015-08-13 16:18:58 -07002576 struct dhcp_state *state = D_STATE(astate->iface);
2577
Samuel Tanf20514b2015-08-13 16:24:02 -07002578 /* Ignore unicast ARP failures. */
2579 if (astate->dest_hwlen)
2580 return;
2581
2582 /* Probegw failure, allow ourselves to fail only once this way */
Samuel Tan1c4088e2015-08-13 16:18:58 -07002583 logger(astate->iface->ctx, LOG_ERR,
2584 "%s: Probe gateway %s timed out ",
2585 astate->iface->name, inet_ntoa(astate->addr));
2586 astate->iface->options->options &= ~DHCPCD_ARPGW;
2587
2588 unlink(state->leasefile);
2589 if (!state->lease.frominfo)
2590 dhcp_decline(astate->iface);
2591#ifdef IN_IFF_DUPLICATED
2592 ia = ipv4_iffindaddr(astate->iface, &astate->addr, NULL);
2593 if (ia)
2594 ipv4_deladdr(astate->iface, &ia->addr, &ia->net);
2595#endif
2596 eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
2597 astate->iface);
2598 eloop_timeout_add_sec(astate->iface->ctx->eloop,
2599 DHCP_RAND_MAX, dhcp_discover, astate->iface);
2600}
2601
2602static void
2603dhcp_probe_gw_response(struct arp_state *astate, const struct arp_msg *amsg)
2604{
2605 /* Verify this is a response for the gateway probe. */
2606 if (astate->src_addr.s_addr != 0 &&
2607 amsg &&
2608 amsg->tip.s_addr == astate->src_addr.s_addr &&
2609 amsg->sip.s_addr == astate->addr.s_addr) {
Samuel Tanf20514b2015-08-13 16:24:02 -07002610 if (astate->dest_hwlen) {
2611 /* Response to unicast ARP. */
Samuel Tan23ff6ed2015-08-13 16:50:06 -07002612 rpc_notify_unicast_arp(astate->iface);
Samuel Tanf20514b2015-08-13 16:24:02 -07002613 } else {
2614 /* Response to arpgw request. */
2615 save_gateway_addr(astate->iface, amsg->sha);
2616
2617 dhcp_close(astate->iface);
2618 eloop_timeout_delete(astate->iface->ctx->eloop,
2619 NULL, astate->iface);
2620 #ifdef IN_IFF_TENTATIVE
2621 ipv4_finaliseaddr(astate->iface);
2622 #else
2623 dhcp_bind(astate->iface, NULL);
2624 #endif
2625 }
Samuel Tan1c4088e2015-08-13 16:18:58 -07002626 arp_close(astate->iface);
2627 }
2628}
2629
2630static int
2631dhcp_probe_gw(struct interface *ifp)
2632{
2633 struct dhcp_state *state = D_STATE(ifp);
2634 struct arp_state *astate;
2635 struct in_addr gateway_addr;
2636
2637 if (get_option_addr(ifp->ctx, &gateway_addr,
2638 state->offer, DHO_ROUTER) == 0) {
2639 astate = arp_new(ifp, &gateway_addr);
2640 if (astate) {
2641 astate->src_addr.s_addr = state->offer->yiaddr;
2642 astate->probed_cb = dhcp_probe_gw_timeout;
2643 astate->conflicted_cb = dhcp_probe_gw_response;
2644 arp_probe(astate);
2645 return 1;
2646 }
2647 }
2648 return 0;
2649}
2650
2651static void
Samuel Tanf20514b2015-08-13 16:24:02 -07002652start_unicast_arp(struct interface *ifp)
2653{
2654 struct dhcp_state *state = D_STATE(ifp);
2655 struct in_addr gwa;
2656 struct in_addr src_addr;
2657 struct arp_state *astate;
2658
2659 if (!state->offer)
2660 return;
2661
2662 if (!state->lease.frominfo)
2663 return;
2664
2665 if (state->server_info.gw_hwlen != ifp->hwlen)
2666 return;
2667
2668 if (get_option_addr(ifp->ctx, &gwa, state->offer, DHO_ROUTER))
2669 return;
2670
2671 astate = arp_new(ifp, &gwa);
2672 if (!astate)
2673 return;
2674 if (state->offer->yiaddr)
2675 astate->src_addr.s_addr = state->offer->yiaddr;
2676 else
2677 astate->src_addr.s_addr = state->offer->ciaddr;
2678 astate->probed_cb = dhcp_probe_gw_timeout;
2679 astate->conflicted_cb = dhcp_probe_gw_response;
2680 astate->dest_hwlen = state->server_info.gw_hwlen;
2681 memcpy(astate->dest_hwaddr, state->server_info.gw_hwaddr,
2682 state->server_info.gw_hwlen);
2683
2684 arp_probe(astate);
2685
2686 /* Invalidate our gateway address until the next successful PROBEGW. */
2687 state->server_info.gw_hwlen = 0;
2688}
2689
2690static void
Samuel Tand7ed8512015-08-13 16:11:35 -07002691dhcp_arp_probed(struct arp_state *astate)
2692{
2693 struct dhcp_state *state;
2694 struct if_options *ifo;
2695
2696 /* We didn't find a profile for this
2697 * address or hwaddr, so move to the next
2698 * arping profile */
2699 state = D_STATE(astate->iface);
2700 ifo = astate->iface->options;
2701 if (state->arping_index < ifo->arping_len) {
2702 if (++state->arping_index < ifo->arping_len) {
2703 astate->addr.s_addr =
2704 ifo->arping[state->arping_index - 1];
2705 arp_probe(astate);
2706 }
2707 dhcpcd_startinterface(astate->iface);
2708 return;
2709 }
Samuel Tan1c4088e2015-08-13 16:18:58 -07002710
2711 /* Probe the gateway specified in the lease offer. */
2712 if ((ifo->options & DHCPCD_ARPGW) && (dhcp_probe_gw(astate->iface))) {
2713 return;
2714 }
2715
Samuel Tand7ed8512015-08-13 16:11:35 -07002716 dhcp_close(astate->iface);
2717 eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate->iface);
2718#ifdef IN_IFF_TENTATIVE
2719 ipv4_finaliseaddr(astate->iface);
2720 arp_close(astate->iface);
2721#else
2722 dhcp_bind(astate->iface, astate);
2723#endif
2724}
2725
2726static void
2727dhcp_arp_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
2728{
2729 struct dhcp_state *state;
2730 struct if_options *ifo;
2731
2732 state = D_STATE(astate->iface);
2733 ifo = astate->iface->options;
2734 if (state->arping_index &&
2735 state->arping_index <= ifo->arping_len &&
2736 amsg &&
2737 (amsg->sip.s_addr == ifo->arping[state->arping_index - 1] ||
2738 (amsg->sip.s_addr == 0 &&
2739 amsg->tip.s_addr == ifo->arping[state->arping_index - 1])))
2740 {
2741 char buf[HWADDR_LEN * 3];
2742
2743 astate->failed.s_addr = ifo->arping[state->arping_index - 1];
2744 arp_report_conflicted(astate, amsg);
2745 hwaddr_ntoa(amsg->sha, astate->iface->hwlen, buf, sizeof(buf));
2746 if (dhcpcd_selectprofile(astate->iface, buf) == -1 &&
2747 dhcpcd_selectprofile(astate->iface,
2748 inet_ntoa(astate->failed)) == -1)
2749 {
2750 /* We didn't find a profile for this
2751 * address or hwaddr, so move to the next
2752 * arping profile */
2753 dhcp_arp_probed(astate);
2754 return;
2755 }
2756 dhcp_close(astate->iface);
2757 arp_close(astate->iface);
2758 eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
2759 astate->iface);
2760 dhcpcd_startinterface(astate->iface);
2761 }
2762
2763 /* RFC 2131 3.1.5, Client-server interaction
2764 * NULL amsg means IN_IFF_DUPLICATED */
2765 if (amsg == NULL || (state->offer &&
2766 (amsg->sip.s_addr == state->offer->yiaddr ||
2767 (amsg->sip.s_addr == 0 &&
2768 amsg->tip.s_addr == state->offer->yiaddr))))
2769 {
2770#ifdef IN_IFF_DUPLICATED
2771 struct ipv4_addr *ia;
2772#endif
2773
Samuel Tan5158c9d2015-08-13 18:09:30 -07002774 if (amsg) {
Samuel Tand7ed8512015-08-13 16:11:35 -07002775 astate->failed.s_addr = state->offer->yiaddr;
Samuel Tan5158c9d2015-08-13 18:09:30 -07002776 state->failed.s_addr = state->offer->yiaddr;
2777 } else {
Samuel Tand7ed8512015-08-13 16:11:35 -07002778 astate->failed = astate->addr;
Samuel Tan5158c9d2015-08-13 18:09:30 -07002779 state->failed = astate->addr;
2780 }
2781
Samuel Tand7ed8512015-08-13 16:11:35 -07002782 arp_report_conflicted(astate, amsg);
2783 unlink(state->leasefile);
2784 if (!state->lease.frominfo)
2785 dhcp_decline(astate->iface);
2786#ifdef IN_IFF_DUPLICATED
2787 ia = ipv4_iffindaddr(astate->iface, &astate->addr, NULL);
2788 if (ia)
2789 ipv4_deladdr(astate->iface, &ia->addr, &ia->net);
2790#endif
Samuel Tan11464a52015-08-13 16:48:29 -07002791 arp_close(astate->iface);
Samuel Tand7ed8512015-08-13 16:11:35 -07002792 eloop_timeout_delete(astate->iface->ctx->eloop, NULL,
2793 astate->iface);
2794 eloop_timeout_add_sec(astate->iface->ctx->eloop,
2795 DHCP_RAND_MAX, dhcp_discover, astate->iface);
2796 }
2797}
2798
2799static void
Samuel Tanb2d21e62015-08-13 16:45:06 -07002800handle_nak(void *arg)
2801{
2802 struct interface *ifp = arg;
2803 struct dhcp_state *state = D_STATE(ifp);
2804
2805 logger(ifp->ctx, LOG_INFO, "%s: Handling deferred NAK", ifp->name);
2806 if (!(ifp->ctx->options & DHCPCD_TEST)) {
2807 dhcp_drop(ifp, "NAK");
2808 unlink(state->leasefile);
2809 }
2810
2811 /* If we constantly get NAKS then we should slowly back off */
2812 eloop_timeout_add_sec(ifp->ctx->eloop,
2813 state->nakoff, dhcp_discover, ifp);
2814 if (state->nakoff == 0)
2815 state->nakoff = 1;
2816 else {
2817 state->nakoff *= 2;
2818 if (state->nakoff > NAKOFF_MAX)
2819 state->nakoff = NAKOFF_MAX;
2820 }
2821}
2822
2823static void
Samuel Tand7ed8512015-08-13 16:11:35 -07002824dhcp_handledhcp(struct interface *ifp, struct dhcp_message **dhcpp,
2825 const struct in_addr *from)
2826{
2827 struct dhcp_state *state = D_STATE(ifp);
2828 struct if_options *ifo = ifp->options;
2829 struct dhcp_message *dhcp = *dhcpp;
2830 struct dhcp_lease *lease = &state->lease;
2831 uint8_t type, tmp;
2832 const uint8_t *auth;
2833 struct in_addr addr;
2834 unsigned int i;
2835 size_t auth_len;
2836 char *msg;
2837 struct arp_state *astate;
2838 struct ipv4_addr *ia;
2839
2840 /* We may have found a BOOTP server */
2841 if (get_option_uint8(ifp->ctx, &type, dhcp, DHO_MESSAGETYPE) == -1)
2842 type = 0;
2843 else if (ifo->options & DHCPCD_BOOTP) {
2844 logger(ifp->ctx, LOG_DEBUG,
2845 "%s: ignoring DHCP reply (excpecting BOOTP)",
2846 ifp->name);
2847 return;
2848 }
2849
Samuel Tan24aa62e2015-08-13 17:12:30 -07002850 logger(ifp->ctx, LOG_INFO, "%s: received %s with xid 0x%x",
2851 ifp->name, get_dhcp_op(type), state->xid);
2852
Samuel Tand7ed8512015-08-13 16:11:35 -07002853 /* Authenticate the message */
2854 auth = get_option(ifp->ctx, dhcp, DHO_AUTHENTICATION, &auth_len);
2855 if (auth) {
2856 if (dhcp_auth_validate(&state->auth, &ifo->auth,
2857 (uint8_t *)*dhcpp, sizeof(**dhcpp), 4, type,
2858 auth, auth_len) == NULL)
2859 {
2860 logger(ifp->ctx, LOG_DEBUG,
2861 "%s: dhcp_auth_validate: %m", ifp->name);
2862 log_dhcp1(LOG_ERR, "authentication failed",
2863 ifp, dhcp, from, 0);
2864 return;
2865 }
2866 if (state->auth.token)
2867 logger(ifp->ctx, LOG_DEBUG,
2868 "%s: validated using 0x%08" PRIu32,
2869 ifp->name, state->auth.token->secretid);
2870 else
2871 logger(ifp->ctx, LOG_DEBUG,
2872 "%s: accepted reconfigure key", ifp->name);
2873 } else if (ifo->auth.options & DHCPCD_AUTH_REQUIRE) {
2874 log_dhcp1(LOG_ERR, "no authentication", ifp, dhcp, from, 0);
2875 return;
2876 } else if (ifo->auth.options & DHCPCD_AUTH_SEND)
2877 log_dhcp1(LOG_WARNING, "no authentication",
2878 ifp, dhcp, from, 0);
2879
2880 /* RFC 3203 */
2881 if (type == DHCP_FORCERENEW) {
2882 if (from->s_addr == INADDR_ANY ||
2883 from->s_addr == INADDR_BROADCAST)
2884 {
2885 log_dhcp(LOG_ERR, "discarding Force Renew",
2886 ifp, dhcp, from);
2887 return;
2888 }
2889 if (auth == NULL) {
2890 log_dhcp(LOG_ERR, "unauthenticated Force Renew",
2891 ifp, dhcp, from);
2892 return;
2893 }
2894 if (state->state != DHS_BOUND && state->state != DHS_INFORM) {
2895 log_dhcp(LOG_DEBUG, "not bound, ignoring Force Renew",
2896 ifp, dhcp, from);
2897 return;
2898 }
2899 log_dhcp(LOG_ERR, "Force Renew from", ifp, dhcp, from);
2900 /* The rebind and expire timings are still the same, we just
2901 * enter the renew state early */
2902 if (state->state == DHS_BOUND) {
2903 eloop_timeout_delete(ifp->ctx->eloop,
2904 dhcp_renew, ifp);
2905 dhcp_renew(ifp);
2906 } else {
2907 eloop_timeout_delete(ifp->ctx->eloop,
2908 send_inform, ifp);
2909 dhcp_inform(ifp);
2910 }
2911 return;
2912 }
2913
2914 if (state->state == DHS_BOUND) {
2915 /* Before we supported FORCERENEW we closed off the raw
2916 * port so we effectively ignored all messages.
2917 * As such we'll not log by default here. */
2918 //log_dhcp(LOG_DEBUG, "bound, ignoring", iface, dhcp, from);
2919 return;
2920 }
2921
2922 /* Ensure it's the right transaction */
2923 if (state->xid != ntohl(dhcp->xid)) {
2924 logger(ifp->ctx, LOG_DEBUG,
2925 "%s: wrong xid 0x%x (expecting 0x%x) from %s",
2926 ifp->name, ntohl(dhcp->xid), state->xid,
2927 inet_ntoa(*from));
2928 return;
2929 }
2930 /* reset the message counter */
2931 state->interval = 0;
2932
2933 /* Ensure that no reject options are present */
2934 for (i = 1; i < 255; i++) {
2935 if (has_option_mask(ifo->rejectmask, i) &&
2936 get_option_uint8(ifp->ctx, &tmp, dhcp, (uint8_t)i) == 0)
2937 {
2938 log_dhcp(LOG_WARNING, "reject DHCP", ifp, dhcp, from);
2939 return;
2940 }
2941 }
2942
2943 if (type == DHCP_NAK) {
Samuel Tand7ed8512015-08-13 16:11:35 -07002944 if ((msg = get_option_string(ifp->ctx, dhcp, DHO_MESSAGE))) {
2945 logger(ifp->ctx, LOG_WARNING, "%s: message: %s",
2946 ifp->name, msg);
2947 free(msg);
2948 }
2949 if (state->state == DHS_INFORM) /* INFORM should not be NAKed */
2950 return;
Samuel Tand7ed8512015-08-13 16:11:35 -07002951
Samuel Tanb2d21e62015-08-13 16:45:06 -07002952 log_dhcp(LOG_WARNING, "NAK (deferred):", ifp, dhcp, from);
Samuel Tan23ff6ed2015-08-13 16:50:06 -07002953 rpc_signal_status("NakDefer");
Samuel Tan5158c9d2015-08-13 18:09:30 -07002954 if (state->nak_receive_count == 0)
2955 eloop_timeout_add_sec(ifp->ctx->eloop,
2956 DHCP_BASE, handle_nak, ifp);
2957 state->nak_receive_count++;
Samuel Tand7ed8512015-08-13 16:11:35 -07002958 return;
2959 }
2960
2961 /* Ensure that all required options are present */
2962 for (i = 1; i < 255; i++) {
2963 if (has_option_mask(ifo->requiremask, i) &&
2964 get_option_uint8(ifp->ctx, &tmp, dhcp, (uint8_t)i) != 0)
2965 {
2966 /* If we are BOOTP, then ignore the need for serverid.
2967 * To ignore BOOTP, require dhcp_message_type.
2968 * However, nothing really stops BOOTP from providing
2969 * DHCP style options as well so the above isn't
2970 * always true. */
2971 if (type == 0 && i == DHO_SERVERID)
2972 continue;
2973 log_dhcp(LOG_WARNING, "reject DHCP", ifp, dhcp, from);
2974 return;
2975 }
2976 }
2977
2978 /* DHCP Auto-Configure, RFC 2563 */
2979 if (type == DHCP_OFFER && dhcp->yiaddr == 0) {
2980 log_dhcp(LOG_WARNING, "no address given", ifp, dhcp, from);
2981 if ((msg = get_option_string(ifp->ctx, dhcp, DHO_MESSAGE))) {
2982 logger(ifp->ctx, LOG_WARNING,
2983 "%s: message: %s", ifp->name, msg);
2984 free(msg);
2985 }
2986 if ((state->state == DHS_DISCOVER ||
2987 state->state == DHS_IPV4LL_BOUND) &&
2988 get_option_uint8(ifp->ctx, &tmp, dhcp,
2989 DHO_AUTOCONFIGURE) == 0)
2990 {
2991 switch (tmp) {
2992 case 0:
2993 log_dhcp(LOG_WARNING, "IPv4LL disabled from",
2994 ifp, dhcp, from);
2995 dhcp_drop(ifp, "EXPIRE");
2996 arp_close(ifp);
2997 eloop_timeout_delete(ifp->ctx->eloop,
2998 NULL, ifp);
2999 eloop_timeout_add_sec(ifp->ctx->eloop,
3000 DHCP_MAX, dhcp_discover,
3001 ifp);
3002 break;
3003 case 1:
3004 log_dhcp(LOG_WARNING, "IPv4LL enabled from",
3005 ifp, dhcp, from);
3006 eloop_timeout_delete(ifp->ctx->eloop,
3007 NULL, ifp);
3008 if (IN_LINKLOCAL(htonl(state->addr.s_addr)))
3009 eloop_timeout_add_sec(ifp->ctx->eloop,
3010 DHCP_MAX, dhcp_discover, ifp);
3011 else
3012 ipv4ll_start(ifp);
3013 break;
3014 default:
3015 logger(ifp->ctx, LOG_ERR,
3016 "%s: unknown auto configuration option %d",
3017 ifp->name, tmp);
3018 break;
3019 }
3020 }
3021 return;
3022 }
3023
3024 /* Ensure that the address offered is valid */
3025 if ((type == 0 || type == DHCP_OFFER || type == DHCP_ACK) &&
3026 (dhcp->ciaddr == INADDR_ANY || dhcp->ciaddr == INADDR_BROADCAST) &&
3027 (dhcp->yiaddr == INADDR_ANY || dhcp->yiaddr == INADDR_BROADCAST))
3028 {
Samuel Tan23ff6ed2015-08-13 16:50:06 -07003029 rpc_signal_status("IgnoreInvalidOffer");
Samuel Tand7ed8512015-08-13 16:11:35 -07003030 log_dhcp(LOG_WARNING, "reject invalid address",
3031 ifp, dhcp, from);
3032 return;
3033 }
3034
3035#ifdef IN_IFF_DUPLICATED
3036 ia = ipv4_iffindaddr(ifp, &lease->addr, NULL);
3037 if (ia && ia->addr_flags & IN_IFF_DUPLICATED) {
3038 log_dhcp(LOG_WARNING, "declined duplicate address",
3039 ifp, dhcp, from);
3040 if (type)
3041 dhcp_decline(ifp);
3042 ipv4_deladdr(ifp, &ia->addr, &ia->net);
3043 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3044 eloop_timeout_add_sec(ifp->ctx->eloop,
3045 DHCP_RAND_MAX, dhcp_discover, ifp);
3046 return;
3047 }
3048#endif
3049
3050 if ((type == 0 || type == DHCP_OFFER) &&
3051 (state->state == DHS_DISCOVER || state->state == DHS_IPV4LL_BOUND))
3052 {
Samuel Tan5158c9d2015-08-13 18:09:30 -07003053 if (dhcp->yiaddr == state->failed.s_addr &&
3054 state->failed_address_offer_count == 0) {
3055 log_dhcp(LOG_WARNING,
3056 "reject previously declined address",
3057 ifp, dhcp, from);
Samuel Tan23ff6ed2015-08-13 16:50:06 -07003058 rpc_signal_status("IgnoreFailedOffer");
Samuel Tan5158c9d2015-08-13 18:09:30 -07003059 state->failed_address_offer_count++;
3060 return;
3061 }
Samuel Tand7ed8512015-08-13 16:11:35 -07003062 lease->frominfo = 0;
3063 lease->addr.s_addr = dhcp->yiaddr;
3064 lease->cookie = dhcp->cookie;
3065 if (type == 0 ||
3066 get_option_addr(ifp->ctx,
3067 &lease->server, dhcp, DHO_SERVERID) != 0)
3068 lease->server.s_addr = INADDR_ANY;
3069 log_dhcp(LOG_INFO, "offered", ifp, dhcp, from);
3070 free(state->offer);
3071 state->offer = dhcp;
3072 *dhcpp = NULL;
3073 if (ifp->ctx->options & DHCPCD_TEST) {
3074 free(state->old);
3075 state->old = state->new;
3076 state->new = state->offer;
3077 state->offer = NULL;
3078 state->reason = "TEST";
3079 script_runreason(ifp, state->reason);
3080 eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
3081 return;
3082 }
3083 eloop_timeout_delete(ifp->ctx->eloop, send_discover, ifp);
Samuel Tanb2d21e62015-08-13 16:45:06 -07003084 eloop_timeout_delete(ifp->ctx->eloop, handle_nak, ifp);
Samuel Tand7ed8512015-08-13 16:11:35 -07003085 /* We don't request BOOTP addresses */
3086 if (type) {
3087 /* We used to ARP check here, but that seems to be in
3088 * violation of RFC2131 where it only describes
3089 * DECLINE after REQUEST.
3090 * It also seems that some MS DHCP servers actually
3091 * ignore DECLINE if no REQUEST, ie we decline a
3092 * DISCOVER. */
3093 dhcp_request(ifp);
3094 return;
3095 }
3096 }
3097
3098 if (type) {
3099 if (type == DHCP_OFFER) {
3100 log_dhcp(LOG_WARNING, "ignoring offer of",
3101 ifp, dhcp, from);
Samuel Tan23ff6ed2015-08-13 16:50:06 -07003102 rpc_signal_status("IgnoreAdditionalOffer");
Samuel Tand7ed8512015-08-13 16:11:35 -07003103 return;
3104 }
3105
3106 /* We should only be dealing with acks */
3107 if (type != DHCP_ACK) {
3108 log_dhcp(LOG_ERR, "not ACK or OFFER",
3109 ifp, dhcp, from);
Samuel Tan23ff6ed2015-08-13 16:50:06 -07003110 rpc_signal_status("IgnoreNonOffer");
Samuel Tand7ed8512015-08-13 16:11:35 -07003111 return;
3112 }
3113
3114 if (!(ifo->options & DHCPCD_INFORM))
Samuel Tan24aa62e2015-08-13 17:12:30 -07003115 log_dhcp(LOG_INFO, "acknowledged", ifp, dhcp, from);
Samuel Tand7ed8512015-08-13 16:11:35 -07003116 else
3117 ifo->options &= ~DHCPCD_STATIC;
3118 }
3119
3120
3121 /* No NAK, so reset the backoff
3122 * We don't reset on an OFFER message because the server could
3123 * potentially NAK the REQUEST. */
3124 state->nakoff = 0;
3125
3126 /* BOOTP could have already assigned this above, so check we still
3127 * have a pointer. */
3128 if (*dhcpp) {
3129 free(state->offer);
3130 state->offer = dhcp;
3131 *dhcpp = NULL;
3132 }
3133
3134 lease->frominfo = 0;
3135 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3136 astate = NULL;
3137
Samuel Tan47d708b2015-08-13 16:51:04 -07003138#ifdef IN_IFF_TENTATIVE
3139 addr.s_addr = state->offer->yiaddr;
3140 astate = arp_new(ifp, &addr);
3141 if (astate) {
3142 astate->probed_cb = dhcp_arp_probed;
3143 astate->conflicted_cb = dhcp_arp_conflicted;
3144 /* No need to start the probe as we'll
3145 * listen to the kernel stating DAD or not and
3146 * that action look look for our ARP state for
3147 * what to do. */
3148 }
3149#else
Samuel Tan5158c9d2015-08-13 18:09:30 -07003150 if ((ifo->options & DHCPCD_ARP || state->nak_receive_count > 0 ||
3151 dhcp->yiaddr == state->failed.s_addr)
Samuel Tand7ed8512015-08-13 16:11:35 -07003152 && state->addr.s_addr != state->offer->yiaddr)
Samuel Tand7ed8512015-08-13 16:11:35 -07003153 {
3154 addr.s_addr = state->offer->yiaddr;
Samuel Tand7ed8512015-08-13 16:11:35 -07003155 /* If the interface already has the address configured
3156 * then we can't ARP for duplicate detection. */
3157 ia = ipv4_findaddr(ifp->ctx, &addr);
Samuel Tan47d708b2015-08-13 16:51:04 -07003158 if (ia == NULL) {
Samuel Tand7ed8512015-08-13 16:11:35 -07003159 astate = arp_new(ifp, &addr);
3160 if (astate) {
3161 astate->probed_cb = dhcp_arp_probed;
3162 astate->conflicted_cb = dhcp_arp_conflicted;
Samuel Tand7ed8512015-08-13 16:11:35 -07003163 arp_probe(astate);
Samuel Tan23ff6ed2015-08-13 16:50:06 -07003164 rpc_signal_status("ArpSelf");
Samuel Tand7ed8512015-08-13 16:11:35 -07003165 }
Samuel Tand7ed8512015-08-13 16:11:35 -07003166 return;
3167 }
Samuel Tand7ed8512015-08-13 16:11:35 -07003168 }
Samuel Tan47d708b2015-08-13 16:51:04 -07003169#endif
Samuel Tand7ed8512015-08-13 16:11:35 -07003170
Samuel Tan1c4088e2015-08-13 16:18:58 -07003171 if ((ifo->options & DHCPCD_ARPGW) && (dhcp_probe_gw(ifp))) {
Samuel Tan23ff6ed2015-08-13 16:50:06 -07003172 rpc_signal_status("ArpGateway");
Samuel Tan1c4088e2015-08-13 16:18:58 -07003173 return;
3174 }
3175
Samuel Tand7ed8512015-08-13 16:11:35 -07003176 dhcp_bind(ifp, astate);
3177}
3178
3179static size_t
3180get_udp_data(const uint8_t **data, const uint8_t *udp)
3181{
3182 struct udp_dhcp_packet p;
3183
3184 memcpy(&p, udp, sizeof(p));
3185 *data = udp + offsetof(struct udp_dhcp_packet, dhcp);
3186 return ntohs(p.ip.ip_len) - sizeof(p.ip) - sizeof(p.udp);
3187}
3188
3189static int
3190valid_udp_packet(const uint8_t *data, size_t data_len, struct in_addr *from,
3191 int noudpcsum)
3192{
3193 struct udp_dhcp_packet p;
3194 uint16_t bytes, udpsum;
3195
3196 if (data_len < sizeof(p.ip)) {
Samuel Tan24aa62e2015-08-13 17:12:30 -07003197 syslog(LOG_WARNING, "packet short than an ip header "
3198 "(len=%zd)", data_len);
Samuel Tand7ed8512015-08-13 16:11:35 -07003199 if (from)
3200 from->s_addr = INADDR_ANY;
3201 errno = EINVAL;
3202 return -1;
3203 }
3204 memcpy(&p, data, MIN(data_len, sizeof(p)));
3205 if (from)
3206 from->s_addr = p.ip.ip_src.s_addr;
3207 if (data_len > sizeof(p)) {
Samuel Tan24aa62e2015-08-13 17:12:30 -07003208 syslog(LOG_WARNING, "packet too long (%zd bytes)", data_len);
Samuel Tand7ed8512015-08-13 16:11:35 -07003209 errno = EINVAL;
3210 return -1;
3211 }
3212 if (checksum(&p.ip, sizeof(p.ip)) != 0) {
Samuel Tan24aa62e2015-08-13 17:12:30 -07003213 syslog(LOG_WARNING, "packet failed ip header checksum");
Samuel Tand7ed8512015-08-13 16:11:35 -07003214 errno = EINVAL;
3215 return -1;
3216 }
3217
3218 bytes = ntohs(p.ip.ip_len);
3219 if (data_len < bytes) {
Samuel Tan24aa62e2015-08-13 17:12:30 -07003220 syslog(LOG_WARNING, "packet appears truncated "
3221 "(len=%zd, ip_len=%zd)", data_len, bytes);
Samuel Tand7ed8512015-08-13 16:11:35 -07003222 errno = EINVAL;
3223 return -1;
3224 }
3225
3226 if (noudpcsum == 0) {
3227 udpsum = p.udp.uh_sum;
3228 p.udp.uh_sum = 0;
3229 p.ip.ip_hl = 0;
3230 p.ip.ip_v = 0;
3231 p.ip.ip_tos = 0;
3232 p.ip.ip_len = p.udp.uh_ulen;
3233 p.ip.ip_id = 0;
3234 p.ip.ip_off = 0;
3235 p.ip.ip_ttl = 0;
3236 p.ip.ip_sum = 0;
3237 if (udpsum && checksum(&p, bytes) != udpsum) {
Samuel Tan24aa62e2015-08-13 17:12:30 -07003238 syslog(LOG_WARNING, "packet failed udp checksum");
Samuel Tand7ed8512015-08-13 16:11:35 -07003239 errno = EINVAL;
3240 return -1;
3241 }
3242 }
3243
3244 return 0;
3245}
3246
3247static void
3248dhcp_handlepacket(void *arg)
3249{
3250 struct interface *ifp = arg;
3251 struct dhcp_message *dhcp = NULL;
3252 const uint8_t *pp;
3253 size_t bytes;
3254 struct in_addr from;
3255 int i, flags;
3256 const struct dhcp_state *state = D_CSTATE(ifp);
3257
3258 /* Need this API due to BPF */
3259 flags = 0;
3260 while (!(flags & RAW_EOF)) {
3261 bytes = (size_t)if_readrawpacket(ifp, ETHERTYPE_IP,
3262 ifp->ctx->packet, udp_dhcp_len, &flags);
3263 if ((ssize_t)bytes == -1) {
3264 logger(ifp->ctx, LOG_ERR,
3265 "%s: dhcp if_readrawpacket: %m", ifp->name);
3266 dhcp_close(ifp);
3267 arp_close(ifp);
3268 break;
3269 }
3270 if (valid_udp_packet(ifp->ctx->packet, bytes,
3271 &from, flags & RAW_PARTIALCSUM) == -1)
3272 {
3273 logger(ifp->ctx, LOG_ERR,
3274 "%s: invalid UDP packet from %s",
3275 ifp->name, inet_ntoa(from));
3276 continue;
3277 }
3278 i = whitelisted_ip(ifp->options, from.s_addr);
3279 if (i == 0) {
3280 logger(ifp->ctx, LOG_WARNING,
3281 "%s: non whitelisted DHCP packet from %s",
3282 ifp->name, inet_ntoa(from));
3283 continue;
3284 } else if (i != 1 &&
3285 blacklisted_ip(ifp->options, from.s_addr) == 1)
3286 {
3287 logger(ifp->ctx, LOG_WARNING,
3288 "%s: blacklisted DHCP packet from %s",
3289 ifp->name, inet_ntoa(from));
3290 continue;
3291 }
3292 if (ifp->flags & IFF_POINTOPOINT &&
3293 state->dst.s_addr != from.s_addr)
3294 {
3295 logger(ifp->ctx, LOG_WARNING,
3296 "%s: server %s is not destination",
3297 ifp->name, inet_ntoa(from));
3298 }
3299 bytes = get_udp_data(&pp, ifp->ctx->packet);
3300 if (bytes > sizeof(*dhcp)) {
3301 logger(ifp->ctx, LOG_ERR,
3302 "%s: packet greater than DHCP size from %s",
3303 ifp->name, inet_ntoa(from));
3304 continue;
3305 }
3306 if (dhcp == NULL) {
3307 dhcp = calloc(1, sizeof(*dhcp));
3308 if (dhcp == NULL) {
3309 logger(ifp->ctx, LOG_ERR,
3310 "%s: calloc: %m", __func__);
3311 break;
3312 }
3313 }
3314 memcpy(dhcp, pp, bytes);
3315 if (dhcp->cookie != htonl(MAGIC_COOKIE)) {
3316 logger(ifp->ctx, LOG_DEBUG, "%s: bogus cookie from %s",
3317 ifp->name, inet_ntoa(from));
3318 continue;
3319 }
3320 /* Ensure packet is for us */
3321 if (ifp->hwlen <= sizeof(dhcp->chaddr) &&
3322 memcmp(dhcp->chaddr, ifp->hwaddr, ifp->hwlen))
3323 {
3324 char buf[sizeof(dhcp->chaddr) * 3];
3325
3326 logger(ifp->ctx, LOG_DEBUG,
3327 "%s: xid 0x%x is for hwaddr %s",
3328 ifp->name, ntohl(dhcp->xid),
3329 hwaddr_ntoa(dhcp->chaddr, sizeof(dhcp->chaddr),
3330 buf, sizeof(buf)));
3331 continue;
3332 }
3333 dhcp_handledhcp(ifp, &dhcp, &from);
3334 if (state->raw_fd == -1)
3335 break;
3336 }
3337 free(dhcp);
3338}
3339
3340static void
3341dhcp_handleudp(void *arg)
3342{
3343 struct dhcpcd_ctx *ctx;
3344 uint8_t buffer[sizeof(struct dhcp_message)];
3345
3346 ctx = arg;
3347
3348 /* Just read what's in the UDP fd and discard it as we always read
3349 * from the raw fd */
3350 if (read(ctx->udp_fd, buffer, sizeof(buffer)) == -1) {
3351 logger(ctx, LOG_ERR, "%s: %m", __func__);
3352 eloop_event_delete(ctx->eloop, ctx->udp_fd, 0);
3353 close(ctx->udp_fd);
3354 ctx->udp_fd = -1;
3355 }
3356}
3357
3358static int
3359dhcp_open(struct interface *ifp)
3360{
3361 struct dhcp_state *state;
3362
3363 if (ifp->ctx->packet == NULL) {
3364 ifp->ctx->packet = malloc(udp_dhcp_len);
3365 if (ifp->ctx->packet == NULL) {
3366 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
3367 return -1;
3368 }
3369 }
3370
3371 state = D_STATE(ifp);
3372 if (state->raw_fd == -1) {
3373 state->raw_fd = if_openrawsocket(ifp, ETHERTYPE_IP);
3374 if (state->raw_fd == -1) {
3375 if (errno == ENOENT) {
3376 logger(ifp->ctx, LOG_ERR,
3377 "%s not found", if_pfname);
3378 /* May as well disable IPv4 entirely at
3379 * this point as we really need it. */
3380 ifp->options->options &= ~DHCPCD_IPV4;
3381 } else
3382 logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
3383 __func__, ifp->name);
3384 return -1;
3385 }
3386 eloop_event_add(ifp->ctx->eloop,
3387 state->raw_fd, dhcp_handlepacket, ifp, NULL, NULL);
3388 }
3389 return 0;
3390}
3391
3392int
3393dhcp_dump(struct interface *ifp)
3394{
3395 struct dhcp_state *state;
3396
3397 ifp->if_data[IF_DATA_DHCP] = state = calloc(1, sizeof(*state));
3398 if (state == NULL)
3399 goto eexit;
3400 state->raw_fd = state->arp_fd = -1;
3401 TAILQ_INIT(&state->arp_states);
3402 dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
3403 AF_INET, ifp, "");
3404 state->new = read_lease(ifp);
3405 if (state->new == NULL) {
3406 logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
3407 *ifp->name ? ifp->name : state->leasefile, __func__);
3408 return -1;
3409 }
3410 state->reason = "DUMP";
3411 return script_runreason(ifp, state->reason);
3412
3413eexit:
3414 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
3415 return -1;
3416}
3417
3418void
3419dhcp_free(struct interface *ifp)
3420{
3421 struct dhcp_state *state = D_STATE(ifp);
3422 struct dhcpcd_ctx *ctx;
3423
3424 dhcp_close(ifp);
3425 arp_close(ifp);
3426 if (state) {
3427 free(state->old);
3428 free(state->new);
3429 free(state->offer);
3430 free(state->buffer);
3431 free(state->clientid);
3432 free(state);
3433 ifp->if_data[IF_DATA_DHCP] = NULL;
3434 }
3435
3436 ctx = ifp->ctx;
3437 /* If we don't have any more DHCP enabled interfaces,
3438 * close the global socket and release resources */
3439 if (ctx->ifaces) {
3440 TAILQ_FOREACH(ifp, ctx->ifaces, next) {
3441 if (D_STATE(ifp))
3442 break;
3443 }
3444 }
3445 if (ifp == NULL) {
3446 if (ctx->udp_fd != -1) {
3447 eloop_event_delete(ctx->eloop, ctx->udp_fd, 0);
3448 close(ctx->udp_fd);
3449 ctx->udp_fd = -1;
3450 }
3451
3452 free(ctx->packet);
3453 free(ctx->opt_buffer);
3454 ctx->packet = NULL;
3455 ctx->opt_buffer = NULL;
3456 }
3457}
3458
3459static int
3460dhcp_init(struct interface *ifp)
3461{
3462 struct dhcp_state *state;
3463 const struct if_options *ifo;
3464 uint8_t len;
3465 char buf[(sizeof(ifo->clientid) - 1) * 3];
3466
3467 state = D_STATE(ifp);
3468 if (state == NULL) {
3469 ifp->if_data[IF_DATA_DHCP] = calloc(1, sizeof(*state));
3470 state = D_STATE(ifp);
3471 if (state == NULL)
3472 return -1;
3473 /* 0 is a valid fd, so init to -1 */
3474 state->raw_fd = state->arp_fd = -1;
3475 TAILQ_INIT(&state->arp_states);
3476
3477 /* Now is a good time to find IPv4 routes */
3478 if_initrt(ifp);
3479 }
3480
3481 state->state = DHS_INIT;
3482 state->reason = "PREINIT";
3483 state->nakoff = 0;
3484 dhcp_set_leasefile(state->leasefile, sizeof(state->leasefile),
3485 AF_INET, ifp, "");
3486
3487 ifo = ifp->options;
3488 /* We need to drop the leasefile so that dhcp_start
3489 * doesn't load it. */
3490 if (ifo->options & DHCPCD_REQUEST)
3491 unlink(state->leasefile);
3492
3493 free(state->clientid);
3494 state->clientid = NULL;
3495
3496 if (*ifo->clientid) {
3497 state->clientid = malloc((size_t)(ifo->clientid[0] + 1));
3498 if (state->clientid == NULL)
3499 goto eexit;
3500 memcpy(state->clientid, ifo->clientid,
3501 (size_t)(ifo->clientid[0]) + 1);
3502 } else if (ifo->options & DHCPCD_CLIENTID) {
3503 if (ifo->options & DHCPCD_DUID) {
3504 state->clientid = malloc(ifp->ctx->duid_len + 6);
3505 if (state->clientid == NULL)
3506 goto eexit;
3507 state->clientid[0] =(uint8_t)(ifp->ctx->duid_len + 5);
3508 state->clientid[1] = 255; /* RFC 4361 */
3509 memcpy(state->clientid + 2, ifo->iaid, 4);
3510 memcpy(state->clientid + 6, ifp->ctx->duid,
3511 ifp->ctx->duid_len);
3512 } else {
3513 len = (uint8_t)(ifp->hwlen + 1);
3514 state->clientid = malloc((size_t)len + 1);
3515 if (state->clientid == NULL)
3516 goto eexit;
3517 state->clientid[0] = len;
3518 state->clientid[1] = (uint8_t)ifp->family;
3519 memcpy(state->clientid + 2, ifp->hwaddr,
3520 ifp->hwlen);
3521 }
3522 }
3523
3524 if (ifo->options & DHCPCD_DUID)
3525 /* Don't bother logging as DUID and IAID are reported
3526 * at device start. */
3527 return 0;
3528
3529 if (ifo->options & DHCPCD_CLIENTID)
3530 logger(ifp->ctx, LOG_DEBUG, "%s: using ClientID %s", ifp->name,
3531 hwaddr_ntoa(state->clientid + 1, state->clientid[0],
3532 buf, sizeof(buf)));
3533 else if (ifp->hwlen)
3534 logger(ifp->ctx, LOG_DEBUG, "%s: using hwaddr %s", ifp->name,
3535 hwaddr_ntoa(ifp->hwaddr, ifp->hwlen, buf, sizeof(buf)));
3536 return 0;
3537
3538eexit:
3539 logger(ifp->ctx, LOG_ERR, "%s: error making ClientID: %m", __func__);
3540 return -1;
3541}
3542
3543static void
3544dhcp_start1(void *arg)
3545{
3546 struct interface *ifp = arg;
3547 struct if_options *ifo = ifp->options;
3548 struct dhcp_state *state;
3549 struct stat st;
3550 uint32_t l;
3551 int nolease;
3552
3553 if (!(ifo->options & DHCPCD_IPV4))
3554 return;
3555
3556 /* Listen on *.*.*.*:bootpc so that the kernel never sends an
3557 * ICMP port unreachable message back to the DHCP server */
3558 if (ifp->ctx->udp_fd == -1) {
3559 ifp->ctx->udp_fd = dhcp_openudp(NULL);
3560 if (ifp->ctx->udp_fd == -1) {
3561 /* Don't log an error if some other process
3562 * is handling this. */
3563 if (errno != EADDRINUSE)
3564 logger(ifp->ctx, LOG_ERR,
3565 "%s: dhcp_openudp: %m", __func__);
3566 } else
3567 eloop_event_add(ifp->ctx->eloop,
3568 ifp->ctx->udp_fd, dhcp_handleudp,
3569 ifp->ctx, NULL, NULL);
3570 }
3571
3572 if (dhcp_init(ifp) == -1) {
3573 logger(ifp->ctx, LOG_ERR, "%s: dhcp_init: %m", ifp->name);
3574 return;
3575 }
3576
3577 state = D_STATE(ifp);
3578 state->start_uptime = uptime();
3579 free(state->offer);
3580 state->offer = NULL;
3581
3582 if (state->arping_index < ifo->arping_len) {
3583 struct arp_state *astate;
3584
3585 astate = arp_new(ifp, NULL);
3586 if (astate) {
3587 astate->probed_cb = dhcp_arp_probed;
3588 astate->conflicted_cb = dhcp_arp_conflicted;
3589 dhcp_arp_probed(astate);
3590 }
3591 return;
3592 }
3593
3594 if (ifo->options & DHCPCD_STATIC) {
3595 dhcp_static(ifp);
3596 return;
3597 }
3598
3599 if (ifo->options & DHCPCD_DHCP && dhcp_open(ifp) == -1)
3600 return;
3601
3602 if (ifo->options & DHCPCD_INFORM) {
3603 dhcp_inform(ifp);
3604 return;
3605 }
3606 if (ifp->hwlen == 0 && ifo->clientid[0] == '\0') {
3607 logger(ifp->ctx, LOG_WARNING,
3608 "%s: needs a clientid to configure", ifp->name);
3609 dhcp_drop(ifp, "FAIL");
3610 eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp);
3611 return;
3612 }
3613 /* We don't want to read the old lease if we NAK an old test */
3614 nolease = state->offer && ifp->ctx->options & DHCPCD_TEST;
3615 if (!nolease) {
3616 state->offer = read_lease(ifp);
3617 /* Check the saved lease matches the type we want */
3618 if (state->offer) {
3619#ifdef IN_IFF_DUPLICATED
3620 struct in_addr addr;
3621 struct ipv4_addr *ia;
3622
3623 addr.s_addr = state->offer->yiaddr;
3624 ia = ipv4_iffindaddr(ifp, &addr, NULL);
3625#endif
3626
3627 if ((IS_BOOTP(ifp, state->offer) &&
3628 !(ifo->options & DHCPCD_BOOTP)) ||
3629#ifdef IN_IFF_DUPLICATED
3630 (ia && ia->addr_flags & IN_IFF_DUPLICATED) ||
3631#endif
3632 (!IS_BOOTP(ifp, state->offer) &&
3633 ifo->options & DHCPCD_BOOTP))
3634 {
3635 free(state->offer);
3636 state->offer = NULL;
3637 }
3638 }
3639 }
3640 if (state->offer) {
3641 get_lease(ifp->ctx, &state->lease, state->offer);
3642 state->lease.frominfo = 1;
3643 if (state->new == NULL &&
3644 ipv4_iffindaddr(ifp, &state->lease.addr, &state->lease.net))
3645 {
3646 /* We still have the IP address from the last lease.
3647 * Fake add the address and routes from it so the lease
3648 * can be cleaned up. */
3649 state->new = malloc(sizeof(*state->new));
3650 if (state->new) {
3651 memcpy(state->new, state->offer,
3652 sizeof(*state->new));
3653 state->addr = state->lease.addr;
3654 state->net = state->lease.net;
3655 state->added |= STATE_ADDED | STATE_FAKE;
3656 ipv4_buildroutes(ifp->ctx);
3657 } else
3658 logger(ifp->ctx, LOG_ERR, "%s: %m", __func__);
3659 }
3660 if (state->offer->cookie == 0) {
3661 if (state->offer->yiaddr == state->addr.s_addr) {
3662 free(state->offer);
3663 state->offer = NULL;
3664 }
3665 } else if (state->lease.leasetime != ~0U &&
3666 stat(state->leasefile, &st) == 0)
3667 {
3668 time_t now;
3669
3670 /* Offset lease times and check expiry */
3671 now = time(NULL);
3672 if (now == -1 ||
3673 (time_t)state->lease.leasetime < now - st.st_mtime)
3674 {
3675 logger(ifp->ctx, LOG_DEBUG,
3676 "%s: discarding expired lease", ifp->name);
3677 free(state->offer);
3678 state->offer = NULL;
3679 state->lease.addr.s_addr = 0;
3680 /* Technically we should discard the lease
3681 * as it's expired, just as DHCPv6 addresses
3682 * would be by the kernel.
3683 * However, this may violate POLA so
3684 * we currently leave it be.
3685 * If we get a totally different lease from
3686 * the DHCP server we'll drop it anyway, as
3687 * we will on any other event which would
3688 * trigger a lease drop.
3689 * This should only happen if dhcpcd stops
3690 * running and the lease expires before
3691 * dhcpcd starts again. */
3692#if 0
3693 if (state->new)
3694 dhcp_drop(ifp, "EXPIRE");
3695#endif
3696 } else {
3697 l = (uint32_t)(now - st.st_mtime);
3698 state->lease.leasetime -= l;
3699 state->lease.renewaltime -= l;
3700 state->lease.rebindtime -= l;
3701 }
3702 }
3703 }
3704
3705 if (!(ifo->options & DHCPCD_DHCP)) {
3706 if (ifo->options & DHCPCD_IPV4LL) {
3707 if (state->offer && state->offer->cookie != 0) {
3708 free(state->offer);
3709 state->offer = NULL;
3710 }
3711 ipv4ll_start(ifp);
3712 }
3713 return;
3714 }
3715
3716 if (state->offer == NULL || state->offer->cookie == 0)
3717 dhcp_discover(ifp);
3718 else
3719 dhcp_reboot(ifp);
3720}
3721
3722void
3723dhcp_start(struct interface *ifp)
3724{
3725 struct timespec tv;
3726
3727 if (!(ifp->options->options & DHCPCD_IPV4))
3728 return;
3729
3730 /* No point in delaying a static configuration */
3731 tv.tv_sec = DHCP_MIN_DELAY;
3732 tv.tv_nsec = (suseconds_t)arc4random_uniform(
3733 (DHCP_MAX_DELAY - DHCP_MIN_DELAY) * NSEC_PER_SEC);
3734 timespecnorm(&tv);
3735 logger(ifp->ctx, LOG_DEBUG,
3736 "%s: delaying IPv4 for %0.1f seconds",
3737 ifp->name, timespec_to_double(&tv));
3738
3739 eloop_timeout_add_tv(ifp->ctx->eloop, &tv, dhcp_start1, ifp);
3740}
3741
3742void
3743dhcp_handleifa(int cmd, struct interface *ifp,
3744 const struct in_addr *addr,
3745 const struct in_addr *net,
3746 const struct in_addr *dst,
3747 __unused int flags)
3748{
3749 struct dhcp_state *state;
3750 struct if_options *ifo;
3751 uint8_t i;
3752
3753 state = D_STATE(ifp);
3754 if (state == NULL)
3755 return;
3756
3757 if (cmd == RTM_DELADDR) {
3758 if (state->addr.s_addr == addr->s_addr &&
3759 state->net.s_addr == net->s_addr)
3760 {
3761 logger(ifp->ctx, LOG_INFO,
3762 "%s: removing IP address %s/%d",
3763 ifp->name, inet_ntoa(state->addr),
3764 inet_ntocidr(state->net));
3765 dhcp_drop(ifp, "EXPIRE");
3766 }
3767 return;
3768 }
3769
3770 if (cmd != RTM_NEWADDR)
3771 return;
3772
3773 ifo = ifp->options;
3774 if (ifo->options & DHCPCD_INFORM) {
3775 if (state->state != DHS_INFORM)
3776 dhcp_inform(ifp);
3777 return;
3778 }
3779
3780 if (!(ifo->options & DHCPCD_STATIC))
3781 return;
3782 if (ifo->req_addr.s_addr != INADDR_ANY)
3783 return;
3784
3785 free(state->old);
3786 state->old = state->new;
3787 state->new = dhcp_message_new(addr, net);
3788 if (state->new == NULL)
3789 return;
3790 state->dst.s_addr = dst ? dst->s_addr : INADDR_ANY;
3791 if (dst) {
3792 for (i = 1; i < 255; i++)
3793 if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i))
3794 dhcp_message_add_addr(state->new, i, *dst);
3795 }
3796 state->reason = "STATIC";
3797 ipv4_buildroutes(ifp->ctx);
3798 script_runreason(ifp, state->reason);
3799 if (ifo->options & DHCPCD_INFORM) {
3800 state->state = DHS_INFORM;
3801 state->xid = dhcp_xid(ifp);
3802 state->lease.server.s_addr = dst ? dst->s_addr : INADDR_ANY;
3803 state->addr = *addr;
3804 state->net = *net;
3805 dhcp_inform(ifp);
3806 }
3807}