2 __RCSID("$NetBSD: ipv4ll.c,v 1.12 2015/08/21 10:39:00 roy Exp $");
5 * dhcpcd - DHCP client daemon
6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <arpa/inet.h>
46 #include "if-options.h"
51 const struct in_addr inaddr_llmask
= { HTONL(LINKLOCAL_MASK
) };
52 const struct in_addr inaddr_llbcast
= { HTONL(LINKLOCAL_BRDC
) };
55 ipv4ll_pick_addr(const struct arp_state
*astate
)
58 struct ipv4ll_state
*istate
;
60 istate
= IPV4LL_STATE(astate
->iface
);
61 setstate(istate
->randomstate
);
64 /* RFC 3927 Section 2.1 states that the first 256 and
65 * last 256 addresses are reserved for future use.
66 * See ipv4ll_start for why we don't use arc4_random. */
67 addr
.s_addr
= ntohl(LINKLOCAL_ADDR
|
68 ((uint32_t)(random() % 0xFD00) + 0x0100));
70 /* No point using a failed address */
71 if (addr
.s_addr
== astate
->failed
.s_addr
)
73 /* Ensure we don't have the address on another interface */
74 } while (ipv4_findaddr(astate
->iface
->ctx
, &addr
) != NULL
);
76 /* Restore the original random state */
77 setstate(astate
->iface
->ctx
->randomstate
);
83 ipv4ll_subnet_route(const struct interface
*ifp
)
85 const struct ipv4ll_state
*state
;
89 if ((state
= IPV4LL_CSTATE(ifp
)) == NULL
||
90 state
->addr
.s_addr
== INADDR_ANY
)
93 if ((rt
= calloc(1, sizeof(*rt
))) == NULL
) {
94 logger(ifp
->ctx
, LOG_ERR
, "%s: malloc: %m", __func__
);
98 rt
->dest
.s_addr
= state
->addr
.s_addr
& inaddr_llmask
.s_addr
;
99 rt
->net
= inaddr_llmask
;
100 rt
->gate
.s_addr
= INADDR_ANY
;
101 rt
->src
= state
->addr
;
106 ipv4ll_default_route(const struct interface
*ifp
)
108 const struct ipv4ll_state
*state
;
112 if ((state
= IPV4LL_CSTATE(ifp
)) == NULL
||
113 state
->addr
.s_addr
== INADDR_ANY
)
116 if ((rt
= calloc(1, sizeof(*rt
))) == NULL
) {
117 logger(ifp
->ctx
, LOG_ERR
, "%s: malloc: %m", __func__
);
121 rt
->dest
.s_addr
= INADDR_ANY
;
122 rt
->net
.s_addr
= INADDR_ANY
;
123 rt
->gate
.s_addr
= INADDR_ANY
;
124 rt
->src
= state
->addr
;
129 ipv4ll_env(char **env
, const char *prefix
, const struct interface
*ifp
)
131 const struct ipv4ll_state
*state
;
132 const char *pf
= prefix
== NULL
? "" : "_";
133 struct in_addr netnum
;
136 if ((state
= IPV4LL_CSTATE(ifp
)) == NULL
)
142 /* Emulate a DHCP environment */
143 if (asprintf(&env
[0], "%s%sip_address=%s",
144 prefix
, pf
, inet_ntoa(state
->addr
)) == -1)
146 if (asprintf(&env
[1], "%s%ssubnet_mask=%s",
147 prefix
, pf
, inet_ntoa(inaddr_llmask
)) == -1)
149 if (asprintf(&env
[2], "%s%ssubnet_cidr=%d",
150 prefix
, pf
, inet_ntocidr(inaddr_llmask
)) == -1)
152 if (asprintf(&env
[3], "%s%sbroadcast_address=%s",
153 prefix
, pf
, inet_ntoa(inaddr_llbcast
)) == -1)
155 netnum
.s_addr
= state
->addr
.s_addr
& inaddr_llmask
.s_addr
;
156 if (asprintf(&env
[4], "%s%snetwork_number=%s",
157 prefix
, pf
, inet_ntoa(netnum
)) == -1)
163 ipv4ll_probed(struct arp_state
*astate
)
165 struct interface
*ifp
;
166 struct ipv4ll_state
*state
;
167 struct ipv4_addr
*ia
;
169 assert(astate
!= NULL
);
170 assert(astate
->iface
!= NULL
);
173 state
= IPV4LL_STATE(ifp
);
174 assert(state
!= NULL
);
176 ia
= ipv4_iffindaddr(ifp
, &astate
->addr
, &inaddr_llmask
);
177 #ifdef IN_IFF_NOTREADY
178 if (ia
== NULL
|| ia
->addr_flags
& IN_IFF_NOTREADY
)
180 logger(ifp
->ctx
, LOG_INFO
, "%s: using IPv4LL address %s",
181 ifp
->name
, inet_ntoa(astate
->addr
));
183 ia
= ipv4_addaddr(ifp
, &astate
->addr
,
184 &inaddr_llmask
, &inaddr_llbcast
);
187 #ifdef IN_IFF_NOTREADY
188 if (ia
->addr_flags
& IN_IFF_NOTREADY
)
190 logger(ifp
->ctx
, LOG_DEBUG
, "%s: DAD completed for %s",
191 ifp
->name
, inet_ntoa(astate
->addr
));
193 state
->addr
= astate
->addr
;
194 timespecclear(&state
->defend
);
196 ipv4_buildroutes(ifp
->ctx
);
197 arp_announce(astate
);
198 script_runreason(ifp
, "IPV4LL");
199 dhcpcd_daemonise(ifp
->ctx
);
203 ipv4ll_announced(struct arp_state
*astate
)
205 struct ipv4ll_state
*state
= IPV4LL_STATE(astate
->iface
);
207 state
->conflicts
= 0;
208 /* Need to keep the arp state so we can defend our IP. */
212 ipv4ll_probe(void *arg
)
215 #ifdef IN_IFF_TENTATIVE
223 ipv4ll_conflicted(struct arp_state
*astate
, const struct arp_msg
*amsg
)
225 struct interface
*ifp
;
226 struct ipv4ll_state
*state
;
229 assert(astate
!= NULL
);
230 assert(astate
->iface
!= NULL
);
232 state
= IPV4LL_STATE(ifp
);
233 assert(state
!= NULL
);
236 /* RFC 3927 2.2.1, Probe Conflict Detection */
238 (amsg
->sip
.s_addr
== astate
->addr
.s_addr
||
239 (amsg
->sip
.s_addr
== 0 && amsg
->tip
.s_addr
== astate
->addr
.s_addr
)))
240 fail
= astate
->addr
.s_addr
;
242 /* RFC 3927 2.5, Conflict Defense */
243 if (IN_LINKLOCAL(ntohl(state
->addr
.s_addr
)) &&
244 amsg
&& amsg
->sip
.s_addr
== state
->addr
.s_addr
)
245 fail
= state
->addr
.s_addr
;
250 astate
->failed
.s_addr
= fail
;
251 arp_report_conflicted(astate
, amsg
);
253 if (astate
->failed
.s_addr
== state
->addr
.s_addr
) {
254 struct timespec now
, defend
;
256 /* RFC 3927 Section 2.5 */
257 defend
.tv_sec
= state
->defend
.tv_sec
+ DEFEND_INTERVAL
;
258 defend
.tv_nsec
= state
->defend
.tv_nsec
;
259 clock_gettime(CLOCK_MONOTONIC
, &now
);
260 if (timespeccmp(&defend
, &now
, >)) {
261 logger(ifp
->ctx
, LOG_WARNING
,
262 "%s: IPv4LL %d second defence failed for %s",
263 ifp
->name
, DEFEND_INTERVAL
,
264 inet_ntoa(state
->addr
));
265 ipv4_deladdr(ifp
, &state
->addr
, &inaddr_llmask
, 1);
267 script_runreason(ifp
, "IPV4LL");
268 state
->addr
.s_addr
= INADDR_ANY
;
270 logger(ifp
->ctx
, LOG_DEBUG
,
271 "%s: defended IPv4LL address %s",
272 ifp
->name
, inet_ntoa(state
->addr
));
279 if (++state
->conflicts
== MAX_CONFLICTS
)
280 logger(ifp
->ctx
, LOG_ERR
,
281 "%s: failed to acquire an IPv4LL address",
283 astate
->addr
.s_addr
= ipv4ll_pick_addr(astate
);
284 eloop_timeout_add_sec(ifp
->ctx
->eloop
,
285 state
->conflicts
>= MAX_CONFLICTS
?
286 RATE_LIMIT_INTERVAL
: PROBE_WAIT
,
287 ipv4ll_probe
, astate
);
291 ipv4ll_arpfree(struct arp_state
*astate
)
293 struct ipv4ll_state
*state
;
295 state
= IPV4LL_STATE(astate
->iface
);
296 if (state
->arp
== astate
)
301 ipv4ll_start(void *arg
)
303 struct interface
*ifp
;
304 struct ipv4ll_state
*state
;
305 struct arp_state
*astate
;
306 struct ipv4_addr
*ia
;
310 if ((state
= IPV4LL_STATE(ifp
)) == NULL
) {
311 ifp
->if_data
[IF_DATA_IPV4LL
] = calloc(1, sizeof(*state
));
312 if ((state
= IPV4LL_STATE(ifp
)) == NULL
) {
313 syslog(LOG_ERR
, "%s: calloc %m", __func__
);
317 state
->addr
.s_addr
= INADDR_ANY
;
320 if (state
->arp
!= NULL
)
323 /* RFC 3927 Section 2.1 states that the random number generator
324 * SHOULD be seeded with a value derived from persistent information
325 * such as the IEEE 802 MAC address so that it usually picks
326 * the same address without persistent storage. */
327 if (state
->conflicts
== 0) {
331 if (sizeof(seed
) > ifp
->hwlen
) {
333 memcpy(&seed
, ifp
->hwaddr
, ifp
->hwlen
);
335 memcpy(&seed
, ifp
->hwaddr
+ ifp
->hwlen
- sizeof(seed
),
337 orig
= initstate(seed
,
338 state
->randomstate
, sizeof(state
->randomstate
));
340 /* Save the original state. */
341 if (ifp
->ctx
->randomstate
== NULL
)
342 ifp
->ctx
->randomstate
= orig
;
344 /* Set back the original state until we need the seeded one. */
345 setstate(ifp
->ctx
->randomstate
);
348 if ((astate
= arp_new(ifp
, NULL
)) == NULL
)
352 astate
->probed_cb
= ipv4ll_probed
;
353 astate
->announced_cb
= ipv4ll_announced
;
354 astate
->conflicted_cb
= ipv4ll_conflicted
;
355 astate
->free_cb
= ipv4ll_arpfree
;
357 /* Find an existing IPv4LL address and ensure we can work with it. */
358 ia
= ipv4_iffindlladdr(ifp
);
359 #ifdef IN_IFF_TENTATIVE
360 if (ia
!= NULL
&& ia
->addr_flags
& IN_IFF_DUPLICATED
) {
361 ipv4_deladdr(ifp
, &ia
->addr
, &ia
->net
, 0);
366 astate
->addr
= ia
->addr
;
367 #ifdef IN_IFF_TENTATIVE
368 if (ia
->addr_flags
& (IN_IFF_TENTATIVE
| IN_IFF_DETACHED
)) {
369 logger(ifp
->ctx
, LOG_INFO
,
370 "%s: waiting for DAD to complete on %s",
371 ifp
->name
, inet_ntoa(ia
->addr
));
374 logger(ifp
->ctx
, LOG_INFO
, "%s: using IPv4LL address %s",
375 ifp
->name
, inet_ntoa(astate
->addr
));
377 ipv4ll_probed(astate
);
381 logger(ifp
->ctx
, LOG_INFO
, "%s: probing for an IPv4LL address",
383 astate
->addr
.s_addr
= ipv4ll_pick_addr(astate
);
384 #ifdef IN_IFF_TENTATIVE
385 ipv4ll_probed(astate
);
392 ipv4ll_freedrop(struct interface
*ifp
, int drop
)
394 struct ipv4ll_state
*state
;
398 state
= IPV4LL_STATE(ifp
);
401 /* Free ARP state first because ipv4_deladdr might also ... */
402 if (state
&& state
->arp
) {
403 eloop_timeout_delete(ifp
->ctx
->eloop
, NULL
, state
->arp
);
404 arp_free(state
->arp
);
408 if (drop
&& (ifp
->options
->options
& DHCPCD_NODROP
) != DHCPCD_NODROP
) {
409 struct ipv4_state
*istate
;
411 if (state
&& state
->addr
.s_addr
!= INADDR_ANY
) {
412 ipv4_deladdr(ifp
, &state
->addr
, &inaddr_llmask
, 1);
413 state
->addr
.s_addr
= INADDR_ANY
;
417 /* Free any other link local addresses that might exist. */
418 if ((istate
= IPV4_STATE(ifp
)) != NULL
) {
419 struct ipv4_addr
*ia
, *ian
;
421 TAILQ_FOREACH_SAFE(ia
, &istate
->addrs
, next
, ian
) {
422 if (IN_LINKLOCAL(ntohl(ia
->addr
.s_addr
))) {
423 ipv4_deladdr(ifp
, &ia
->addr
,
433 ifp
->if_data
[IF_DATA_IPV4LL
] = NULL
;
436 ipv4_buildroutes(ifp
->ctx
);
437 script_runreason(ifp
, "IPV4LL");