1 /* 2 * dhcpcd - DHCP client daemon 3 * Copyright (c) 2006-2015 Roy Marples <roy (at) 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 <errno.h> 29 #include <signal.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #define ELOOP_QUEUE 6 35 #include "config.h" 36 #include "arp.h" 37 #include "common.h" 38 #include "dhcp.h" 39 #include "eloop.h" 40 #include "if.h" 41 #include "if-options.h" 42 #include "ipv4ll.h" 43 44 static struct dhcp_message * 45 ipv4ll_make_lease(uint32_t addr) 46 { 47 uint32_t u32; 48 struct dhcp_message *dhcp; 49 uint8_t *p; 50 51 dhcp = calloc(1, sizeof(*dhcp)); 52 if (dhcp == NULL) 53 return NULL; 54 /* Put some LL options in */ 55 dhcp->yiaddr = addr; 56 p = dhcp->options; 57 *p++ = DHO_SUBNETMASK; 58 *p++ = sizeof(u32); 59 u32 = htonl(LINKLOCAL_MASK); 60 memcpy(p, &u32, sizeof(u32)); 61 p += sizeof(u32); 62 *p++ = DHO_BROADCAST; 63 *p++ = sizeof(u32); 64 u32 = htonl(LINKLOCAL_BRDC); 65 memcpy(p, &u32, sizeof(u32)); 66 p += sizeof(u32); 67 *p++ = DHO_END; 68 69 return dhcp; 70 } 71 72 static in_addr_t 73 ipv4ll_pick_addr(const struct arp_state *astate) 74 { 75 in_addr_t addr; 76 struct interface *ifp; 77 const struct dhcp_state *state; 78 79 for (;;) { 80 /* RFC 3927 Section 2.1 states that the first 256 and 81 * last 256 addresses are reserved for future use. 82 * See ipv4ll_start for why we don't use arc4_random. */ 83 addr = ntohl(LINKLOCAL_ADDR | 84 ((uint32_t)(random() % 0xFD00) + 0x0100)); 85 86 /* No point using a failed address */ 87 if (addr == astate->failed.s_addr) 88 continue; 89 90 /* Ensure we don't have the address on another interface */ 91 TAILQ_FOREACH(ifp, astate->iface->ctx->ifaces, next) { 92 state = D_CSTATE(ifp); 93 if (state && state->addr.s_addr == addr) 94 break; 95 } 96 97 /* Yay, this should be a unique and workable IPv4LL address */ 98 if (ifp == NULL) 99 break; 100 } 101 return addr; 102 } 103 104 static void 105 ipv4ll_probed(struct arp_state *astate) 106 { 107 struct dhcp_state *state = D_STATE(astate->iface); 108 109 if (state->state == DHS_IPV4LL_BOUND) { 110 ipv4_finaliseaddr(astate->iface); 111 return; 112 } 113 114 if (state->state != DHS_BOUND) { 115 struct dhcp_message *offer; 116 117 /* A DHCP lease could have already been offered. 118 * Backup and replace once the IPv4LL address is bound */ 119 offer = state->offer; 120 state->offer = ipv4ll_make_lease(astate->addr.s_addr); 121 if (state->offer == NULL) 122 logger(astate->iface->ctx, LOG_ERR, "%s: %m", __func__); 123 else 124 dhcp_bind(astate->iface, astate); 125 state->offer = offer; 126 } 127 } 128 129 static void 130 ipv4ll_announced(struct arp_state *astate) 131 { 132 struct dhcp_state *state = D_STATE(astate->iface); 133 134 state->conflicts = 0; 135 /* Need to keep the arp state so we can defend our IP. */ 136 } 137 138 static void 139 ipv4ll_probe(void *arg) 140 { 141 142 #ifdef IN_IFF_TENTATIVE 143 ipv4ll_probed(arg); 144 #else 145 arp_probe(arg); 146 #endif 147 } 148 149 static void 150 ipv4ll_conflicted(struct arp_state *astate, const struct arp_msg *amsg) 151 { 152 struct dhcp_state *state = D_STATE(astate->iface); 153 in_addr_t fail; 154 155 fail = 0; 156 /* RFC 3927 2.2.1, Probe Conflict Detection */ 157 if (amsg == NULL || 158 (amsg->sip.s_addr == astate->addr.s_addr || 159 (amsg->sip.s_addr == 0 && amsg->tip.s_addr == astate->addr.s_addr))) 160 fail = astate->addr.s_addr; 161 162 /* RFC 3927 2.5, Conflict Defense */ 163 if (IN_LINKLOCAL(htonl(state->addr.s_addr)) && 164 amsg && amsg->sip.s_addr == state->addr.s_addr) 165 fail = state->addr.s_addr; 166 167 if (fail == 0) 168 return; 169 170 astate->failed.s_addr = fail; 171 arp_report_conflicted(astate, amsg); 172 173 if (astate->failed.s_addr == state->addr.s_addr) { 174 time_t up; 175 176 /* RFC 3927 Section 2.5 */ 177 up = uptime(); 178 if (state->defend + DEFEND_INTERVAL > up) { 179 logger(astate->iface->ctx, LOG_WARNING, 180 "%s: IPv4LL %d second defence failed for %s", 181 astate->iface->name, DEFEND_INTERVAL, 182 inet_ntoa(state->addr)); 183 dhcp_drop(astate->iface, "EXPIRE"); 184 } else { 185 logger(astate->iface->ctx, LOG_DEBUG, 186 "%s: defended IPv4LL address %s", 187 astate->iface->name, inet_ntoa(state->addr)); 188 state->defend = up; 189 return; 190 } 191 } 192 193 arp_cancel(astate); 194 if (++state->conflicts == MAX_CONFLICTS) 195 logger(astate->iface->ctx, LOG_ERR, 196 "%s: failed to acquire an IPv4LL address", 197 astate->iface->name); 198 astate->addr.s_addr = ipv4ll_pick_addr(astate); 199 eloop_timeout_add_sec(astate->iface->ctx->eloop, 200 state->conflicts >= MAX_CONFLICTS ? 201 RATE_LIMIT_INTERVAL : PROBE_WAIT, 202 ipv4ll_probe, astate); 203 } 204 205 void 206 ipv4ll_start(void *arg) 207 { 208 struct interface *ifp = arg; 209 struct dhcp_state *state = D_STATE(ifp); 210 struct arp_state *astate; 211 struct ipv4_addr *ap; 212 213 if (state->arp_ipv4ll) 214 return; 215 216 /* RFC 3927 Section 2.1 states that the random number generator 217 * SHOULD be seeded with a value derived from persistent information 218 * such as the IEEE 802 MAC address so that it usually picks 219 * the same address without persistent storage. */ 220 if (state->conflicts == 0) { 221 unsigned int seed; 222 223 if (sizeof(seed) > ifp->hwlen) { 224 seed = 0; 225 memcpy(&seed, ifp->hwaddr, ifp->hwlen); 226 } else 227 memcpy(&seed, ifp->hwaddr + ifp->hwlen - sizeof(seed), 228 sizeof(seed)); 229 initstate(seed, state->randomstate, sizeof(state->randomstate)); 230 } 231 232 if ((astate = arp_new(ifp, NULL)) == NULL) 233 return; 234 235 state->arp_ipv4ll = astate; 236 astate->probed_cb = ipv4ll_probed; 237 astate->announced_cb = ipv4ll_announced; 238 astate->conflicted_cb = ipv4ll_conflicted; 239 240 if (IN_LINKLOCAL(htonl(state->addr.s_addr))) { 241 astate->addr = state->addr; 242 arp_announce(astate); 243 return; 244 } 245 246 if (state->offer && IN_LINKLOCAL(ntohl(state->offer->yiaddr))) { 247 astate->addr.s_addr = state->offer->yiaddr; 248 free(state->offer); 249 state->offer = NULL; 250 ap = ipv4_iffindaddr(ifp, &astate->addr, NULL); 251 } else 252 ap = ipv4_iffindlladdr(ifp); 253 if (ap) { 254 astate->addr = ap->addr; 255 ipv4ll_probed(astate); 256 return; 257 } 258 259 setstate(state->randomstate); 260 /* We maybe rebooting an IPv4LL address. */ 261 if (!IN_LINKLOCAL(htonl(astate->addr.s_addr))) { 262 logger(ifp->ctx, LOG_INFO, "%s: probing for an IPv4LL address", 263 ifp->name); 264 astate->addr.s_addr = INADDR_ANY; 265 } 266 if (astate->addr.s_addr == INADDR_ANY) 267 astate->addr.s_addr = ipv4ll_pick_addr(astate); 268 #ifdef IN_IFF_TENTATIVE 269 ipv4ll_probed(astate); 270 #else 271 arp_probe(astate); 272 #endif 273 } 274 275 void 276 ipv4ll_stop(struct interface *ifp) 277 { 278 struct dhcp_state *state = D_STATE(ifp); 279 280 eloop_timeout_delete(ifp->ctx->eloop, NULL, state->arp_ipv4ll); 281 } 282