1 #include <sys/cdefs.h> 2 __RCSID("$NetBSD: ipv4ll.c,v 1.12 2015/08/21 10:39:00 roy Exp $"); 3 4 /* 5 * dhcpcd - DHCP client daemon 6 * Copyright (c) 2006-2015 Roy Marples <roy@marples.name> 7 * All rights reserved 8 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 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. 17 * 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 28 * SUCH DAMAGE. 29 */ 30 31 #include <arpa/inet.h> 32 33 #include <assert.h> 34 #include <errno.h> 35 #include <signal.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <unistd.h> 39 40 #define ELOOP_QUEUE 6 41 #include "config.h" 42 #include "arp.h" 43 #include "common.h" 44 #include "eloop.h" 45 #include "if.h" 46 #include "if-options.h" 47 #include "ipv4.h" 48 #include "ipv4ll.h" 49 #include "script.h" 50 51 const struct in_addr inaddr_llmask = { HTONL(LINKLOCAL_MASK) }; 52 const struct in_addr inaddr_llbcast = { HTONL(LINKLOCAL_BRDC) }; 53 54 static in_addr_t 55 ipv4ll_pick_addr(const struct arp_state *astate) 56 { 57 struct in_addr addr; 58 struct ipv4ll_state *istate; 59 60 istate = IPV4LL_STATE(astate->iface); 61 setstate(istate->randomstate); 62 63 do { 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)); 69 70 /* No point using a failed address */ 71 if (addr.s_addr == astate->failed.s_addr) 72 continue; 73 /* Ensure we don't have the address on another interface */ 74 } while (ipv4_findaddr(astate->iface->ctx, &addr) != NULL); 75 76 /* Restore the original random state */ 77 setstate(astate->iface->ctx->randomstate); 78 79 return addr.s_addr; 80 } 81 82 struct rt * 83 ipv4ll_subnet_route(const struct interface *ifp) 84 { 85 const struct ipv4ll_state *state; 86 struct rt *rt; 87 88 assert(ifp != NULL); 89 if ((state = IPV4LL_CSTATE(ifp)) == NULL || 90 state->addr.s_addr == INADDR_ANY) 91 return NULL; 92 93 if ((rt = calloc(1, sizeof(*rt))) == NULL) { 94 logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__); 95 return NULL; 96 } 97 rt->iface = ifp; 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; 102 return rt; 103 } 104 105 struct rt * 106 ipv4ll_default_route(const struct interface *ifp) 107 { 108 const struct ipv4ll_state *state; 109 struct rt *rt; 110 111 assert(ifp != NULL); 112 if ((state = IPV4LL_CSTATE(ifp)) == NULL || 113 state->addr.s_addr == INADDR_ANY) 114 return NULL; 115 116 if ((rt = calloc(1, sizeof(*rt))) == NULL) { 117 logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__); 118 return NULL; 119 } 120 rt->iface = ifp; 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; 125 return rt; 126 } 127 128 ssize_t 129 ipv4ll_env(char **env, const char *prefix, const struct interface *ifp) 130 { 131 const struct ipv4ll_state *state; 132 const char *pf = prefix == NULL ? "" : "_"; 133 struct in_addr netnum; 134 135 assert(ifp != NULL); 136 if ((state = IPV4LL_CSTATE(ifp)) == NULL) 137 return 0; 138 139 if (env == NULL) 140 return 5; 141 142 /* Emulate a DHCP environment */ 143 if (asprintf(&env[0], "%s%sip_address=%s", 144 prefix, pf, inet_ntoa(state->addr)) == -1) 145 return -1; 146 if (asprintf(&env[1], "%s%ssubnet_mask=%s", 147 prefix, pf, inet_ntoa(inaddr_llmask)) == -1) 148 return -1; 149 if (asprintf(&env[2], "%s%ssubnet_cidr=%d", 150 prefix, pf, inet_ntocidr(inaddr_llmask)) == -1) 151 return -1; 152 if (asprintf(&env[3], "%s%sbroadcast_address=%s", 153 prefix, pf, inet_ntoa(inaddr_llbcast)) == -1) 154 return -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) 158 return -1; 159 return 5; 160 } 161 162 static void 163 ipv4ll_probed(struct arp_state *astate) 164 { 165 struct interface *ifp; 166 struct ipv4ll_state *state; 167 struct ipv4_addr *ia; 168 169 assert(astate != NULL); 170 assert(astate->iface != NULL); 171 172 ifp = astate->iface; 173 state = IPV4LL_STATE(ifp); 174 assert(state != NULL); 175 176 ia = ipv4_iffindaddr(ifp, &astate->addr, &inaddr_llmask); 177 #ifdef IN_IFF_NOTREADY 178 if (ia == NULL || ia->addr_flags & IN_IFF_NOTREADY) 179 #endif 180 logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s", 181 ifp->name, inet_ntoa(astate->addr)); 182 if (ia == NULL) 183 ia = ipv4_addaddr(ifp, &astate->addr, 184 &inaddr_llmask, &inaddr_llbcast); 185 if (ia == NULL) 186 return; 187 #ifdef IN_IFF_NOTREADY 188 if (ia->addr_flags & IN_IFF_NOTREADY) 189 return; 190 logger(ifp->ctx, LOG_DEBUG, "%s: DAD completed for %s", 191 ifp->name, inet_ntoa(astate->addr)); 192 #endif 193 state->addr = astate->addr; 194 timespecclear(&state->defend); 195 if_initrt(ifp); 196 ipv4_buildroutes(ifp->ctx); 197 arp_announce(astate); 198 script_runreason(ifp, "IPV4LL"); 199 dhcpcd_daemonise(ifp->ctx); 200 } 201 202 static void 203 ipv4ll_announced(struct arp_state *astate) 204 { 205 struct ipv4ll_state *state = IPV4LL_STATE(astate->iface); 206 207 state->conflicts = 0; 208 /* Need to keep the arp state so we can defend our IP. */ 209 } 210 211 static void 212 ipv4ll_probe(void *arg) 213 { 214 215 #ifdef IN_IFF_TENTATIVE 216 ipv4ll_probed(arg); 217 #else 218 arp_probe(arg); 219 #endif 220 } 221 222 static void 223 ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg) 224 { 225 struct interface *ifp; 226 struct ipv4ll_state *state; 227 in_addr_t fail; 228 229 assert(astate != NULL); 230 assert(astate->iface != NULL); 231 ifp = astate->iface; 232 state = IPV4LL_STATE(ifp); 233 assert(state != NULL); 234 235 fail = 0; 236 /* RFC 3927 2.2.1, Probe Conflict Detection */ 237 if (amsg == NULL || 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; 241 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; 246 247 if (fail == 0) 248 return; 249 250 astate->failed.s_addr = fail; 251 arp_report_conflicted(astate, amsg); 252 253 if (astate->failed.s_addr == state->addr.s_addr) { 254 struct timespec now, defend; 255 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); 266 state->down = 1; 267 script_runreason(ifp, "IPV4LL"); 268 state->addr.s_addr = INADDR_ANY; 269 } else { 270 logger(ifp->ctx, LOG_DEBUG, 271 "%s: defended IPv4LL address %s", 272 ifp->name, inet_ntoa(state->addr)); 273 state->defend = now; 274 return; 275 } 276 } 277 278 arp_cancel(astate); 279 if (++state->conflicts == MAX_CONFLICTS) 280 logger(ifp->ctx, LOG_ERR, 281 "%s: failed to acquire an IPv4LL address", 282 ifp->name); 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); 288 } 289 290 static void 291 ipv4ll_arpfree(struct arp_state *astate) 292 { 293 struct ipv4ll_state *state; 294 295 state = IPV4LL_STATE(astate->iface); 296 if (state->arp == astate) 297 state->arp = NULL; 298 } 299 300 void 301 ipv4ll_start(void *arg) 302 { 303 struct interface *ifp; 304 struct ipv4ll_state *state; 305 struct arp_state *astate; 306 struct ipv4_addr *ia; 307 308 assert(arg != NULL); 309 ifp = arg; 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__); 314 return; 315 } 316 317 state->addr.s_addr = INADDR_ANY; 318 } 319 320 if (state->arp != NULL) 321 return; 322 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) { 328 unsigned int seed; 329 char *orig; 330 331 if (sizeof(seed) > ifp->hwlen) { 332 seed = 0; 333 memcpy(&seed, ifp->hwaddr, ifp->hwlen); 334 } else 335 memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed), 336 sizeof(seed)); 337 orig = initstate(seed, 338 state->randomstate, sizeof(state->randomstate)); 339 340 /* Save the original state. */ 341 if (ifp->ctx->randomstate == NULL) 342 ifp->ctx->randomstate = orig; 343 344 /* Set back the original state until we need the seeded one. */ 345 setstate(ifp->ctx->randomstate); 346 } 347 348 if ((astate = arp_new(ifp, NULL)) == NULL) 349 return; 350 351 state->arp = astate; 352 astate->probed_cb = ipv4ll_probed; 353 astate->announced_cb = ipv4ll_announced; 354 astate->conflicted_cb = ipv4ll_conflicted; 355 astate->free_cb = ipv4ll_arpfree; 356 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); 362 ia = NULL; 363 } 364 #endif 365 if (ia != NULL) { 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)); 372 return; 373 } 374 logger(ifp->ctx, LOG_INFO, "%s: using IPv4LL address %s", 375 ifp->name, inet_ntoa(astate->addr)); 376 #endif 377 ipv4ll_probed(astate); 378 return; 379 } 380 381 logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address", 382 ifp->name); 383 astate->addr.s_addr = ipv4ll_pick_addr(astate); 384 #ifdef IN_IFF_TENTATIVE 385 ipv4ll_probed(astate); 386 #else 387 arp_probe(astate); 388 #endif 389 } 390 391 void 392 ipv4ll_freedrop(struct interface *ifp, int drop) 393 { 394 struct ipv4ll_state *state; 395 int dropped; 396 397 assert(ifp != NULL); 398 state = IPV4LL_STATE(ifp); 399 dropped = 0; 400 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); 405 state->arp = NULL; 406 } 407 408 if (drop && (ifp->options->options & DHCPCD_NODROP) != DHCPCD_NODROP) { 409 struct ipv4_state *istate; 410 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; 414 dropped = 1; 415 } 416 417 /* Free any other link local addresses that might exist. */ 418 if ((istate = IPV4_STATE(ifp)) != NULL) { 419 struct ipv4_addr *ia, *ian; 420 421 TAILQ_FOREACH_SAFE(ia, &istate->addrs, next, ian) { 422 if (IN_LINKLOCAL(ntohl(ia->addr.s_addr))) { 423 ipv4_deladdr(ifp, &ia->addr, 424 &ia->net, 0); 425 dropped = 1; 426 } 427 } 428 } 429 } 430 431 if (state) { 432 free(state); 433 ifp->if_data[IF_DATA_IPV4LL] = NULL; 434 435 if (dropped) { 436 ipv4_buildroutes(ifp->ctx); 437 script_runreason(ifp, "IPV4LL"); 438 } 439 } 440 } 441