Home | History | Annotate | Download | only in dhcpcd-6.8.2
      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 <sys/socket.h>
     29 #include <sys/types.h>
     30 
     31 #include <net/if.h>
     32 #include <netinet/in.h>
     33 #include <netinet/if_ether.h>
     34 
     35 #include <errno.h>
     36 #include <signal.h>
     37 #include <stdlib.h>
     38 #include <string.h>
     39 #include <unistd.h>
     40 
     41 #define ELOOP_QUEUE 5
     42 #include "config.h"
     43 #include "arp.h"
     44 #include "if.h"
     45 #include "ipv4.h"
     46 #include "common.h"
     47 #include "dhcp.h"
     48 #include "dhcpcd.h"
     49 #include "eloop.h"
     50 #include "if.h"
     51 #include "if-options.h"
     52 #include "ipv4ll.h"
     53 
     54 #define ARP_LEN								      \
     55 	(sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
     56 
     57 static ssize_t
     58 arp_request(const struct interface *ifp, in_addr_t sip, in_addr_t tip,
     59 	    const uint8_t *dest_hw_addr)
     60 {
     61 	uint8_t arp_buffer[ARP_LEN];
     62 	struct arphdr ar;
     63 	size_t len;
     64 	uint8_t *p;
     65 
     66 	ar.ar_hrd = htons(ifp->family);
     67 	ar.ar_pro = htons(ETHERTYPE_IP);
     68 	ar.ar_hln = ifp->hwlen;
     69 	ar.ar_pln = sizeof(sip);
     70 	ar.ar_op = htons(ARPOP_REQUEST);
     71 
     72 	p = arp_buffer;
     73 	len = 0;
     74 
     75 #define CHECK(fun, b, l)						\
     76 	do {								\
     77 		if (len + (l) > sizeof(arp_buffer))			\
     78 			goto eexit;					\
     79 		fun(p, (b), (l));					\
     80 		p += (l);						\
     81 		len += (l);						\
     82 	} while (/* CONSTCOND */ 0)
     83 #define APPEND(b, l)	CHECK(memcpy, b, l)
     84 #define ZERO(l)		CHECK(memset, 0, l)
     85 
     86 	APPEND(&ar, sizeof(ar));
     87 	APPEND(ifp->hwaddr, ifp->hwlen);
     88 	APPEND(&sip, sizeof(sip));
     89 	if (dest_hw_addr)
     90 		APPEND(dest_hw_addr, ifp->hwlen);
     91 	else
     92 		ZERO(ifp->hwlen);
     93 	APPEND(&tip, sizeof(tip));
     94 	return if_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len,
     95 				dest_hw_addr);
     96 
     97 eexit:
     98 	errno = ENOBUFS;
     99 	return -1;
    100 }
    101 
    102 void
    103 arp_report_conflicted(const struct arp_state *astate, const struct arp_msg *amsg)
    104 {
    105 
    106 	if (amsg) {
    107 		char buf[HWADDR_LEN * 3];
    108 
    109 		logger(astate->iface->ctx, LOG_ERR,
    110 		    "%s: hardware address %s claims %s",
    111 		    astate->iface->name,
    112 		    hwaddr_ntoa(amsg->sha, astate->iface->hwlen,
    113 		    buf, sizeof(buf)),
    114 		    inet_ntoa(astate->failed));
    115 	} else
    116 		logger(astate->iface->ctx, LOG_ERR,
    117 		    "%s: DAD detected %s",
    118 		    astate->iface->name, inet_ntoa(astate->failed));
    119 }
    120 
    121 static void
    122 arp_packet(void *arg)
    123 {
    124 	struct interface *ifp = arg;
    125 	const struct interface *ifn;
    126 	uint8_t arp_buffer[ARP_LEN];
    127 	struct arphdr ar;
    128 	struct arp_msg arm;
    129 	ssize_t bytes;
    130 	struct dhcp_state *state;
    131 	struct arp_state *astate, *astaten;
    132 	unsigned char *hw_s, *hw_t;
    133 	int flags;
    134 
    135 	state = D_STATE(ifp);
    136 	state->failed.s_addr = 0;
    137 	flags = 0;
    138 	while (!(flags & RAW_EOF)) {
    139 		bytes = if_readrawpacket(ifp, ETHERTYPE_ARP,
    140 		    arp_buffer, sizeof(arp_buffer), &flags);
    141 		if (bytes == -1) {
    142 			logger(ifp->ctx, LOG_ERR,
    143 			    "%s: arp if_readrawpacket: %m", ifp->name);
    144 			dhcp_close(ifp);
    145 			return;
    146 		}
    147 		/* We must have a full ARP header */
    148 		if ((size_t)bytes < sizeof(ar))
    149 			continue;
    150 		memcpy(&ar, arp_buffer, sizeof(ar));
    151 		/* Families must match */
    152 		if (ar.ar_hrd != htons(ifp->family))
    153 			continue;
    154 		/* Protocol must be IP. */
    155 		if (ar.ar_pro != htons(ETHERTYPE_IP))
    156 			continue;
    157 		if (ar.ar_pln != sizeof(arm.sip.s_addr))
    158 			continue;
    159 		/* Only these types are recognised */
    160 		if (ar.ar_op != htons(ARPOP_REPLY) &&
    161 		    ar.ar_op != htons(ARPOP_REQUEST))
    162 			continue;
    163 
    164 		/* Get pointers to the hardware addreses */
    165 		hw_s = arp_buffer + sizeof(ar);
    166 		hw_t = hw_s + ar.ar_hln + ar.ar_pln;
    167 		/* Ensure we got all the data */
    168 		if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
    169 			continue;
    170 		/* Ignore messages from ourself */
    171 		TAILQ_FOREACH(ifn, ifp->ctx->ifaces, next) {
    172 			if (ar.ar_hln == ifn->hwlen &&
    173 			    memcmp(hw_s, ifn->hwaddr, ifn->hwlen) == 0)
    174 				break;
    175 		}
    176 		if (ifn)
    177 			continue;
    178 		/* Copy out the HW and IP addresses */
    179 		memcpy(&arm.sha, hw_s, ar.ar_hln);
    180 		memcpy(&arm.sip.s_addr, hw_s + ar.ar_hln, ar.ar_pln);
    181 		memcpy(&arm.tha, hw_t, ar.ar_hln);
    182 		memcpy(&arm.tip.s_addr, hw_t + ar.ar_hln, ar.ar_pln);
    183 
    184 		/* Run the conflicts */
    185 		TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, astaten) {
    186 			if (astate->conflicted_cb)
    187 				astate->conflicted_cb(astate, &arm);
    188 		}
    189 	}
    190 }
    191 
    192 static void
    193 arp_open(struct interface *ifp)
    194 {
    195 	struct dhcp_state *state;
    196 
    197 	state = D_STATE(ifp);
    198 	if (state->arp_fd == -1) {
    199 		state->arp_fd = if_openrawsocket(ifp, ETHERTYPE_ARP);
    200 		if (state->arp_fd == -1) {
    201 			logger(ifp->ctx, LOG_ERR, "%s: %s: %m",
    202 			    __func__, ifp->name);
    203 			return;
    204 		}
    205 		eloop_event_add(ifp->ctx->eloop, state->arp_fd,
    206 		    arp_packet, ifp, NULL, NULL);
    207 	}
    208 }
    209 
    210 static void
    211 arp_announced(void *arg)
    212 {
    213 	struct arp_state *astate = arg;
    214 
    215 	if (astate->announced_cb) {
    216 		astate->announced_cb(astate);
    217 		return;
    218 	}
    219 
    220 	/* Nothing more to do, so free us */
    221 	arp_free(astate);
    222 }
    223 
    224 static void
    225 arp_announce1(void *arg)
    226 {
    227 	struct arp_state *astate = arg;
    228 	struct interface *ifp = astate->iface;
    229 
    230 	if (++astate->claims < ANNOUNCE_NUM)
    231 		logger(ifp->ctx, LOG_DEBUG,
    232 		    "%s: ARP announcing %s (%d of %d), "
    233 		    "next in %d.0 seconds",
    234 		    ifp->name, inet_ntoa(astate->addr),
    235 		    astate->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
    236 	else
    237 		logger(ifp->ctx, LOG_DEBUG,
    238 		    "%s: ARP announcing %s (%d of %d)",
    239 		    ifp->name, inet_ntoa(astate->addr),
    240 		    astate->claims, ANNOUNCE_NUM);
    241 	if (arp_request(ifp, astate->addr.s_addr, astate->addr.s_addr,
    242 			NULL) == -1)
    243 		logger(ifp->ctx, LOG_ERR, "send_arp: %m");
    244 	eloop_timeout_add_sec(ifp->ctx->eloop, ANNOUNCE_WAIT,
    245 	    astate->claims < ANNOUNCE_NUM ? arp_announce1 : arp_announced,
    246 	    astate);
    247 }
    248 
    249 void
    250 arp_announce(struct arp_state *astate)
    251 {
    252 
    253 	arp_open(astate->iface);
    254 	astate->claims = 0;
    255 	arp_announce1(astate);
    256 }
    257 
    258 static void
    259 arp_probed(void *arg)
    260 {
    261 	struct arp_state *astate = arg;
    262 
    263 	astate->probed_cb(astate);
    264 }
    265 
    266 static void
    267 arp_probe1(void *arg)
    268 {
    269 	struct arp_state *astate = arg;
    270 	struct interface *ifp = astate->iface;
    271 	struct timespec tv;
    272 	uint8_t *dest_hwaddr = NULL;
    273 
    274 	if (++astate->probes < PROBE_NUM) {
    275 		tv.tv_sec = PROBE_MIN;
    276 		tv.tv_nsec = (suseconds_t)arc4random_uniform(
    277 		    (PROBE_MAX - PROBE_MIN) * NSEC_PER_SEC);
    278 		timespecnorm(&tv);
    279 		eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probe1, astate);
    280 	} else {
    281 		tv.tv_sec = ANNOUNCE_WAIT;
    282 		tv.tv_nsec = 0;
    283 		eloop_timeout_add_tv(ifp->ctx->eloop, &tv, arp_probed, astate);
    284 	}
    285 	logger(ifp->ctx, LOG_INFO,
    286 	    "%s: ARP probing %s (%d of %d), next in %0.1f seconds",
    287 	    ifp->name, inet_ntoa(astate->addr),
    288 	    astate->probes ? astate->probes : PROBE_NUM, PROBE_NUM,
    289 	    timespec_to_double(&tv));
    290 	if (astate->dest_hwlen == ifp->hwlen)
    291 		dest_hwaddr = astate->dest_hwaddr;
    292 	if (arp_request(ifp, astate->src_addr.s_addr,
    293 			astate->addr.s_addr, dest_hwaddr) == -1)
    294 		logger(ifp->ctx, LOG_ERR, "send_arp: %m");
    295 }
    296 
    297 void
    298 arp_probe(struct arp_state *astate)
    299 {
    300 
    301 	arp_open(astate->iface);
    302 	astate->probes = 0;
    303 	logger(astate->iface->ctx, LOG_DEBUG, "%s: probing for %s",
    304 	    astate->iface->name, inet_ntoa(astate->addr));
    305 	arp_probe1(astate);
    306 }
    307 
    308 static struct arp_state *
    309 arp_find(struct interface *ifp, const struct in_addr *addr)
    310 {
    311 	struct arp_state *astate;
    312 	struct dhcp_state *state;
    313 
    314 	state = D_STATE(ifp);
    315 	TAILQ_FOREACH(astate, &state->arp_states, next) {
    316 		if (astate->addr.s_addr == addr->s_addr && astate->iface == ifp)
    317 			return astate;
    318 	}
    319 	errno = ESRCH;
    320 	return NULL;
    321 }
    322 
    323 struct arp_state *
    324 arp_new(struct interface *ifp, const struct in_addr *addr)
    325 {
    326 	struct arp_state *astate;
    327 	struct dhcp_state *state;
    328 
    329 	if (addr && (astate = arp_find(ifp, addr)))
    330 		return astate;
    331 
    332 	if ((astate = calloc(1, sizeof(*astate))) == NULL) {
    333 		logger(ifp->ctx, LOG_ERR, "%s: %s: %m", ifp->name, __func__);
    334 		return NULL;
    335 	}
    336 	state = D_STATE(ifp);
    337 	astate->iface = ifp;
    338 	if (addr)
    339 		astate->addr = *addr;
    340 	TAILQ_INSERT_TAIL(&state->arp_states, astate, next);
    341 	return astate;
    342 }
    343 
    344 void
    345 arp_cancel(struct arp_state *astate)
    346 {
    347 
    348 	eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
    349 }
    350 
    351 void
    352 arp_free(struct arp_state *astate)
    353 {
    354 	struct dhcp_state *state;
    355 
    356 	if (astate) {
    357 		eloop_timeout_delete(astate->iface->ctx->eloop, NULL, astate);
    358 		state = D_STATE(astate->iface);
    359 		TAILQ_REMOVE(&state->arp_states, astate, next);
    360 		if (state->arp_ipv4ll == astate) {
    361 			ipv4ll_stop(astate->iface);
    362 			state->arp_ipv4ll = NULL;
    363 		}
    364 		free(astate);
    365 	}
    366 }
    367 
    368 void
    369 arp_free_but(struct arp_state *astate)
    370 {
    371 	struct arp_state *p, *n;
    372 	struct dhcp_state *state;
    373 
    374 	state = D_STATE(astate->iface);
    375 	TAILQ_FOREACH_SAFE(p, &state->arp_states, next, n) {
    376 		if (p != astate)
    377 			arp_free(p);
    378 	}
    379 }
    380 
    381 void
    382 arp_close(struct interface *ifp)
    383 {
    384 	struct dhcp_state *state = D_STATE(ifp);
    385 	struct arp_state *astate;
    386 
    387 	if (state == NULL)
    388 		return;
    389 
    390 	if (state->arp_fd != -1) {
    391 		eloop_event_delete(ifp->ctx->eloop, state->arp_fd, 0);
    392 		close(state->arp_fd);
    393 		state->arp_fd = -1;
    394 	}
    395 
    396 	while ((astate = TAILQ_FIRST(&state->arp_states))) {
    397 #ifndef __clang_analyzer__
    398 		/* clang guard needed for a more compex variant on this bug:
    399 		 * http://llvm.org/bugs/show_bug.cgi?id=18222 */
    400 		arp_free(astate);
    401 #endif
    402 	}
    403 }
    404 
    405 void
    406 arp_handleifa(int cmd, struct interface *ifp, const struct in_addr *addr,
    407     int flags)
    408 {
    409 #ifdef IN_IFF_DUPLICATED
    410 	struct dhcp_state *state = D_STATE(ifp);
    411 	struct arp_state *astate, *asn;
    412 
    413 	if (cmd != RTM_NEWADDR || (state = D_STATE(ifp)) == NULL)
    414 		return;
    415 
    416 	TAILQ_FOREACH_SAFE(astate, &state->arp_states, next, asn) {
    417 		if (astate->addr.s_addr == addr->s_addr) {
    418 			if (flags & IN_IFF_DUPLICATED) {
    419 				if (astate->conflicted_cb)
    420 					astate->conflicted_cb(astate, NULL);
    421 			} else if (!(flags & IN_IFF_NOTUSEABLE)) {
    422 				if (astate->probed_cb)
    423 					astate->probed_cb(astate);
    424 			}
    425 		}
    426 	}
    427 #else
    428 	UNUSED(cmd);
    429 	UNUSED(ifp);
    430 	UNUSED(addr);
    431 	UNUSED(flags);
    432 #endif
    433 }
    434