xref: /dragonfly/contrib/dhcpcd/src/ipv4ll.c (revision 0ffa96a2)
1 /*
2  * dhcpcd - DHCP client daemon
3  * Copyright (c) 2006-2018 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 <arpa/inet.h>
29 
30 #include <assert.h>
31 #include <errno.h>
32 #include <stdbool.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 #define ELOOP_QUEUE 6
38 #include "config.h"
39 #include "arp.h"
40 #include "common.h"
41 #include "eloop.h"
42 #include "if.h"
43 #include "if-options.h"
44 #include "ipv4.h"
45 #include "ipv4ll.h"
46 #include "logerr.h"
47 #include "sa.h"
48 #include "script.h"
49 
50 #ifdef IPV4LL
51 static const struct in_addr inaddr_llmask = {
52 	.s_addr = HTONL(LINKLOCAL_MASK)
53 };
54 static const struct in_addr inaddr_llbcast = {
55 	.s_addr = HTONL(LINKLOCAL_BCAST)
56 };
57 
58 static in_addr_t
59 ipv4ll_pickaddr(struct arp_state *astate)
60 {
61 	struct in_addr addr;
62 	struct ipv4ll_state *istate;
63 
64 	istate = IPV4LL_STATE(astate->iface);
65 	setstate(istate->randomstate);
66 
67 	do {
68 		long r;
69 
70 		/* RFC 3927 Section 2.1 states that the first 256 and
71 		 * last 256 addresses are reserved for future use.
72 		 * See ipv4ll_start for why we don't use arc4random. */
73 		/* coverity[dont_call] */
74 		r = random();
75 		addr.s_addr = ntohl(LINKLOCAL_ADDR |
76 		    ((uint32_t)(r % 0xFD00) + 0x0100));
77 
78 		/* No point using a failed address */
79 		if (addr.s_addr == astate->failed.s_addr)
80 			continue;
81 		/* Ensure we don't have the address on another interface */
82 	} while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL);
83 
84 	/* Restore the original random state */
85 	setstate(istate->arp->iface->ctx->randomstate);
86 	return addr.s_addr;
87 }
88 
89 int
90 ipv4ll_subnetroute(struct rt_head *routes, struct interface *ifp)
91 {
92 	struct ipv4ll_state *state;
93 	struct rt *rt;
94 	struct in_addr in;
95 
96 	assert(ifp != NULL);
97 	if ((state = IPV4LL_STATE(ifp)) == NULL ||
98 	    state->addr == NULL)
99 		return 0;
100 
101 	if ((rt = rt_new(ifp)) == NULL)
102 		return -1;
103 
104 	in.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
105 	sa_in_init(&rt->rt_dest, &in);
106 	in.s_addr = state->addr->mask.s_addr;
107 	sa_in_init(&rt->rt_netmask, &in);
108 	in.s_addr = INADDR_ANY;
109 	sa_in_init(&rt->rt_gateway, &in);
110 	sa_in_init(&rt->rt_ifa, &state->addr->addr);
111 	TAILQ_INSERT_TAIL(routes, rt, rt_next);
112 	return 1;
113 }
114 
115 int
116 ipv4ll_defaultroute(struct rt_head *routes, struct interface *ifp)
117 {
118 	struct ipv4ll_state *state;
119 	struct rt *rt;
120 	struct in_addr in;
121 
122 	assert(ifp != NULL);
123 	if ((state = IPV4LL_STATE(ifp)) == NULL ||
124 	    state->addr == NULL)
125 		return 0;
126 
127 	if ((rt = rt_new(ifp)) == NULL)
128 		return -1;
129 
130 	in.s_addr = INADDR_ANY;
131 	sa_in_init(&rt->rt_dest, &in);
132 	sa_in_init(&rt->rt_netmask, &in);
133 	sa_in_init(&rt->rt_gateway, &in);
134 	sa_in_init(&rt->rt_ifa, &state->addr->addr);
135 	TAILQ_INSERT_TAIL(routes, rt, rt_next);
136 	return 1;
137 }
138 
139 ssize_t
140 ipv4ll_env(char **env, const char *prefix, const struct interface *ifp)
141 {
142 	const struct ipv4ll_state *state;
143 	const char *pf = prefix == NULL ? "" : "_";
144 	struct in_addr netnum;
145 
146 	assert(ifp != NULL);
147 	if ((state = IPV4LL_CSTATE(ifp)) == NULL || state->addr == NULL)
148 		return 0;
149 
150 	if (env == NULL)
151 		return 5;
152 
153 	/* Emulate a DHCP environment */
154 	if (asprintf(&env[0], "%s%sip_address=%s",
155 	    prefix, pf, inet_ntoa(state->addr->addr)) == -1)
156 		return -1;
157 	if (asprintf(&env[1], "%s%ssubnet_mask=%s",
158 	    prefix, pf, inet_ntoa(state->addr->mask)) == -1)
159 		return -1;
160 	if (asprintf(&env[2], "%s%ssubnet_cidr=%d",
161 	    prefix, pf, inet_ntocidr(state->addr->mask)) == -1)
162 		return -1;
163 	if (asprintf(&env[3], "%s%sbroadcast_address=%s",
164 	    prefix, pf, inet_ntoa(state->addr->brd)) == -1)
165 		return -1;
166 	netnum.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr;
167 	if (asprintf(&env[4], "%s%snetwork_number=%s",
168 	    prefix, pf, inet_ntoa(netnum)) == -1)
169 		return -1;
170 	return 5;
171 }
172 
173 static void
174 ipv4ll_probed(struct arp_state *astate)
175 {
176 	struct interface *ifp;
177 	struct ipv4ll_state *state;
178 	struct ipv4_addr *ia;
179 
180 	assert(astate != NULL);
181 	assert(astate->iface != NULL);
182 
183 	ifp = astate->iface;
184 	state = IPV4LL_STATE(ifp);
185 	assert(state != NULL);
186 
187 	ia = ipv4_iffindaddr(ifp, &astate->addr, &inaddr_llmask);
188 #ifdef IN_IFF_NOTREADY
189 	if (ia == NULL || ia->addr_flags & IN_IFF_NOTREADY)
190 #endif
191 		loginfox("%s: using IPv4LL address %s",
192 		  ifp->name, inet_ntoa(astate->addr));
193 	if (ia == NULL) {
194 		if (ifp->ctx->options & DHCPCD_TEST)
195 			goto test;
196 		ia = ipv4_addaddr(ifp, &astate->addr,
197 		    &inaddr_llmask, &inaddr_llbcast);
198 	}
199 	if (ia == NULL)
200 		return;
201 #ifdef IN_IFF_NOTREADY
202 	if (ia->addr_flags & IN_IFF_NOTREADY)
203 		return;
204 	logdebugx("%s: DAD completed for %s",
205 	    ifp->name, inet_ntoa(astate->addr));
206 #endif
207 test:
208 	state->addr = ia;
209 	if (ifp->ctx->options & DHCPCD_TEST) {
210 		script_runreason(ifp, "TEST");
211 		eloop_exit(ifp->ctx->eloop, EXIT_SUCCESS);
212 		return;
213 	}
214 	timespecclear(&state->defend);
215 	if_initrt(ifp->ctx, AF_INET);
216 	rt_build(ifp->ctx, AF_INET);
217 	arp_announce(astate);
218 	script_runreason(ifp, "IPV4LL");
219 	dhcpcd_daemonise(ifp->ctx);
220 }
221 
222 static void
223 ipv4ll_announced(struct arp_state *astate)
224 {
225 	struct ipv4ll_state *state = IPV4LL_STATE(astate->iface);
226 
227 	state->conflicts = 0;
228 	/* Need to keep the arp state so we can defend our IP. */
229 }
230 
231 static void
232 ipv4ll_probe(void *arg)
233 {
234 
235 #ifdef IN_IFF_TENTATIVE
236 	ipv4ll_probed(arg);
237 #else
238 	arp_probe(arg);
239 #endif
240 }
241 
242 static void
243 ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg)
244 {
245 	struct interface *ifp;
246 	struct ipv4ll_state *state;
247 #ifdef IN_IFF_DUPLICATED
248 	struct ipv4_addr *ia;
249 #endif
250 
251 	assert(astate != NULL);
252 	assert(astate->iface != NULL);
253 	ifp = astate->iface;
254 	state = IPV4LL_STATE(ifp);
255 	assert(state != NULL);
256 
257 	/*
258 	 * NULL amsg means kernel detected DAD.
259 	 * We always fail on matching sip.
260 	 * We only fail on matching tip and we haven't added that address yet.
261 	 */
262 	if (amsg == NULL ||
263 	    amsg->sip.s_addr == astate->addr.s_addr ||
264 	    (amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr
265 	     && ipv4_iffindaddr(ifp, &amsg->tip, NULL) == NULL))
266 		astate->failed = astate->addr;
267 	else
268 		return;
269 
270 	arp_report_conflicted(astate, amsg);
271 
272 	if (state->addr != NULL &&
273 	    astate->failed.s_addr == state->addr->addr.s_addr)
274 	{
275 #ifdef KERNEL_RFC5227
276 		logwarnx("%s: IPv4LL defence failed for %s",
277 		    ifp->name, state->addr->saddr);
278 #else
279 		struct timespec now, defend;
280 
281 		/* RFC 3927 Section 2.5 says a defence should
282 		 * broadcast an ARP announcement.
283 		 * Because the kernel will also unicast a reply to the
284 		 * hardware address which requested the IP address
285 		 * the other IPv4LL client will receieve two ARP
286 		 * messages.
287 		 * If another conflict happens within DEFEND_INTERVAL
288 		 * then we must drop our address and negotiate a new one. */
289 		defend.tv_sec = state->defend.tv_sec + DEFEND_INTERVAL;
290 		defend.tv_nsec = state->defend.tv_nsec;
291 		clock_gettime(CLOCK_MONOTONIC, &now);
292 		if (timespeccmp(&defend, &now, >))
293 			logwarnx("%s: IPv4LL %d second defence failed for %s",
294 			    ifp->name, DEFEND_INTERVAL, state->addr->saddr);
295 		else if (arp_request(ifp,
296 		    state->addr->addr.s_addr, state->addr->addr.s_addr) == -1)
297 			logerr(__func__);
298 		else {
299 			logdebugx("%s: defended IPv4LL address %s",
300 			    ifp->name, state->addr->saddr);
301 			state->defend = now;
302 			return;
303 		}
304 #endif
305 		ipv4_deladdr(state->addr, 1);
306 		state->down = 1;
307 		state->addr = NULL;
308 		script_runreason(ifp, "IPV4LL");
309 	}
310 
311 #ifdef IN_IFF_DUPLICATED
312 	ia = ipv4_iffindaddr(ifp, &astate->addr, NULL);
313 	if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED)
314 		ipv4_deladdr(ia, 1);
315 #endif
316 
317 	arp_cancel(astate);
318 	if (++state->conflicts == MAX_CONFLICTS)
319 		logerr("%s: failed to acquire an IPv4LL address",
320 		    ifp->name);
321 	astate->addr.s_addr = ipv4ll_pickaddr(astate);
322 	eloop_timeout_add_sec(ifp->ctx->eloop,
323 		state->conflicts >= MAX_CONFLICTS ?
324 		RATE_LIMIT_INTERVAL : PROBE_WAIT,
325 		ipv4ll_probe, astate);
326 }
327 
328 static void
329 ipv4ll_arpfree(struct arp_state *astate)
330 {
331 	struct ipv4ll_state *state;
332 
333 	state = IPV4LL_STATE(astate->iface);
334 	if (state->arp == astate)
335 		state->arp = NULL;
336 }
337 
338 void
339 ipv4ll_start(void *arg)
340 {
341 	struct interface *ifp;
342 	struct ipv4ll_state *state;
343 	struct arp_state *astate;
344 	struct ipv4_addr *ia;
345 
346 	assert(arg != NULL);
347 	ifp = arg;
348 	if ((state = IPV4LL_STATE(ifp)) == NULL) {
349 		ifp->if_data[IF_DATA_IPV4LL] = calloc(1, sizeof(*state));
350 		if ((state = IPV4LL_STATE(ifp)) == NULL) {
351 			logerr(__func__);
352 			return;
353 		}
354 	}
355 
356 	if (state->arp != NULL)
357 		return;
358 
359 	/* RFC 3927 Section 2.1 states that the random number generator
360 	 * SHOULD be seeded with a value derived from persistent information
361 	 * such as the IEEE 802 MAC address so that it usually picks
362 	 * the same address without persistent storage. */
363 	if (state->conflicts == 0) {
364 		unsigned int seed;
365 		char *orig;
366 
367 		if (sizeof(seed) > ifp->hwlen) {
368 			seed = 0;
369 			memcpy(&seed, ifp->hwaddr, ifp->hwlen);
370 		} else
371 			memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed),
372 			    sizeof(seed));
373 		/* coverity[dont_call] */
374 		orig = initstate(seed,
375 		    state->randomstate, sizeof(state->randomstate));
376 
377 		/* Save the original state. */
378 		if (ifp->ctx->randomstate == NULL)
379 			ifp->ctx->randomstate = orig;
380 
381 		/* Set back the original state until we need the seeded one. */
382 		setstate(ifp->ctx->randomstate);
383 	}
384 
385 	if ((astate = arp_new(ifp, NULL)) == NULL)
386 		return;
387 
388 	state->arp = astate;
389 	astate->probed_cb = ipv4ll_probed;
390 	astate->announced_cb = ipv4ll_announced;
391 	astate->conflicted_cb = ipv4ll_conflicted;
392 	astate->free_cb = ipv4ll_arpfree;
393 
394 	/* Find an existing IPv4LL address and ensure we can work with it. */
395 	ia = ipv4_iffindlladdr(ifp);
396 
397 #ifdef IN_IFF_TENTATIVE
398 	if (ia != NULL && ia->addr_flags & IN_IFF_DUPLICATED) {
399 		ipv4_deladdr(ia, 0);
400 		ia = NULL;
401 	}
402 #endif
403 
404 	if (ia != NULL) {
405 		astate->addr = ia->addr;
406 #ifdef IN_IFF_TENTATIVE
407 		if (ia->addr_flags & (IN_IFF_TENTATIVE | IN_IFF_DETACHED)) {
408 			loginfox("%s: waiting for DAD to complete on %s",
409 			    ifp->name, inet_ntoa(ia->addr));
410 			return;
411 		}
412 		loginfox("%s: using IPv4LL address %s", ifp->name, ia->saddr);
413 #endif
414 		ipv4ll_probed(astate);
415 		return;
416 	}
417 
418 	loginfox("%s: probing for an IPv4LL address", ifp->name);
419 	astate->addr.s_addr = ipv4ll_pickaddr(astate);
420 #ifdef IN_IFF_TENTATIVE
421 	ipv4ll_probed(astate);
422 #else
423 	arp_probe(astate);
424 #endif
425 }
426 
427 void
428 ipv4ll_freedrop(struct interface *ifp, int drop)
429 {
430 	struct ipv4ll_state *state;
431 	int dropped;
432 
433 	assert(ifp != NULL);
434 	state = IPV4LL_STATE(ifp);
435 	dropped = 0;
436 
437 	/* Free ARP state first because ipv4_deladdr might also ... */
438 	if (state && state->arp) {
439 		eloop_timeout_delete(ifp->ctx->eloop, NULL, state->arp);
440 		arp_free(state->arp);
441 		state->arp = NULL;
442 	}
443 
444 	if (drop && (ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) {
445 		struct ipv4_state *istate;
446 
447 		if (state && state->addr != NULL) {
448 			ipv4_deladdr(state->addr, 1);
449 			state->addr = NULL;
450 			dropped = 1;
451 		}
452 
453 		/* Free any other link local addresses that might exist. */
454 		if ((istate = IPV4_STATE(ifp)) != NULL) {
455 			struct ipv4_addr *ia, *ian;
456 
457 			TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) {
458 				if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) {
459 					ipv4_deladdr(ia, 0);
460 					dropped = 1;
461 				}
462 			}
463 		}
464 	}
465 
466 	if (state) {
467 		free(state);
468 		ifp->if_data[IF_DATA_IPV4LL] = NULL;
469 
470 		if (dropped) {
471 			rt_build(ifp->ctx, AF_INET);
472 			script_runreason(ifp, "IPV4LL");
473 		}
474 	}
475 }
476 
477 /* This may cause issues in BSD systems, where running as a single dhcpcd
478  * daemon would solve this issue easily. */
479 #ifdef HAVE_ROUTE_METRIC
480 int
481 ipv4ll_recvrt(__unused int cmd, const struct rt *rt)
482 {
483 	struct dhcpcd_ctx *ctx;
484 	struct interface *ifp;
485 
486 	/* Ignore route init. */
487 	if (rt->rt_dflags & RTDF_INIT)
488 		return 0;
489 
490 	/* Only interested in default route changes. */
491 	if (sa_is_unspecified(&rt->rt_dest))
492 		return 0;
493 
494 	/* If any interface is running IPv4LL, rebuild our routing table. */
495 	ctx = rt->rt_ifp->ctx;
496 	TAILQ_FOREACH(ifp, ctx->ifaces, next) {
497 		if (IPV4LL_STATE_RUNNING(ifp)) {
498 			if_initrt(ctx, AF_INET);
499 			rt_build(ctx, AF_INET);
500 			break;
501 		}
502 	}
503 
504 	return 0;
505 }
506 #endif
507 #endif
508