Home | History | Annotate | Download | only in dhcpcd
      1 /*
      2  * dhcpcd - DHCP client daemon
      3  * Copyright (c) 2006-2011 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 <syslog.h>
     33 #include <unistd.h>
     34 
     35 #include "arp.h"
     36 #include "bind.h"
     37 #include "common.h"
     38 #include "dhcpcd.h"
     39 #include "eloop.h"
     40 #include "if-options.h"
     41 #include "ipv4ll.h"
     42 #include "net.h"
     43 
     44 #define ARP_LEN								      \
     45 	(sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN))
     46 
     47 static int
     48 send_arp(const struct interface *iface, int op, in_addr_t sip, in_addr_t tip)
     49 {
     50 	uint8_t arp_buffer[ARP_LEN];
     51 	struct arphdr ar;
     52 	size_t len;
     53 	uint8_t *p;
     54 	int retval;
     55 
     56 	ar.ar_hrd = htons(iface->family);
     57 	ar.ar_pro = htons(ETHERTYPE_IP);
     58 	ar.ar_hln = iface->hwlen;
     59 	ar.ar_pln = sizeof(sip);
     60 	ar.ar_op = htons(op);
     61 	memcpy(arp_buffer, &ar, sizeof(ar));
     62 	p = arp_buffer + sizeof(ar);
     63 	memcpy(p, iface->hwaddr, iface->hwlen);
     64 	p += iface->hwlen;
     65 	memcpy(p, &sip, sizeof(sip));
     66 	p += sizeof(sip);
     67 	/* ARP requests should ignore this */
     68 	retval = iface->hwlen;
     69 	while (retval--)
     70 		*p++ = '\0';
     71 	memcpy(p, &tip, sizeof(tip));
     72 	p += sizeof(tip);
     73 	len = p - arp_buffer;
     74 	retval = send_raw_packet(iface, ETHERTYPE_ARP, arp_buffer, len);
     75 	return retval;
     76 }
     77 
     78 static void
     79 handle_arp_failure(struct interface *iface)
     80 {
     81 
     82 	/* If we failed without a magic cookie then we need to try
     83 	 * and defend our IPv4LL address. */
     84 	if ((iface->state->offer != NULL &&
     85 		iface->state->offer->cookie != htonl(MAGIC_COOKIE)) ||
     86 	    (iface->state->new != NULL &&
     87 		iface->state->new->cookie != htonl(MAGIC_COOKIE)))
     88 	{
     89 		handle_ipv4ll_failure(iface);
     90 		return;
     91 	}
     92 
     93 	unlink(iface->leasefile);
     94 	if (!iface->state->lease.frominfo)
     95 		send_decline(iface);
     96 	close_sockets(iface);
     97 	delete_timeout(NULL, iface);
     98 	if (iface->state->lease.frominfo)
     99 		start_interface(iface);
    100 	else
    101 		add_timeout_sec(DHCP_ARP_FAIL, start_interface, iface);
    102 }
    103 
    104 static void
    105 handle_arp_packet(void *arg)
    106 {
    107 	struct interface *iface = arg;
    108 	uint8_t arp_buffer[ARP_LEN];
    109 	struct arphdr ar;
    110 	uint32_t reply_s;
    111 	uint32_t reply_t;
    112 	uint8_t *hw_s, *hw_t;
    113 	ssize_t bytes;
    114 	struct if_state *state = iface->state;
    115 	struct if_options *opts = state->options;
    116 	const char *hwaddr;
    117 	struct in_addr ina;
    118 
    119 	state->fail.s_addr = 0;
    120 	for(;;) {
    121 		bytes = get_raw_packet(iface, ETHERTYPE_ARP,
    122 		    arp_buffer, sizeof(arp_buffer), NULL);
    123 		if (bytes == 0 || bytes == -1)
    124 			return;
    125 		/* We must have a full ARP header */
    126 		if ((size_t)bytes < sizeof(ar))
    127 			continue;
    128 		memcpy(&ar, arp_buffer, sizeof(ar));
    129 		/* Protocol must be IP. */
    130 		if (ar.ar_pro != htons(ETHERTYPE_IP))
    131 			continue;
    132 		if (ar.ar_pln != sizeof(reply_s))
    133 			continue;
    134 		/* Only these types are recognised */
    135 		if (ar.ar_op != htons(ARPOP_REPLY) &&
    136 		    ar.ar_op != htons(ARPOP_REQUEST))
    137 			continue;
    138 
    139 		/* Get pointers to the hardware addreses */
    140 		hw_s = arp_buffer + sizeof(ar);
    141 		hw_t = hw_s + ar.ar_hln + ar.ar_pln;
    142 		/* Ensure we got all the data */
    143 		if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes)
    144 			continue;
    145 		/* Ignore messages from ourself */
    146 		if (ar.ar_hln == iface->hwlen &&
    147 		    memcmp(hw_s, iface->hwaddr, iface->hwlen) == 0)
    148 			continue;
    149 		/* Copy out the IP addresses */
    150 		memcpy(&reply_s, hw_s + ar.ar_hln, ar.ar_pln);
    151 		memcpy(&reply_t, hw_t + ar.ar_hln, ar.ar_pln);
    152 
    153 		/* Check for arping */
    154 		if (state->arping_index &&
    155 		    state->arping_index <= opts->arping_len &&
    156 		    (reply_s == opts->arping[state->arping_index - 1] ||
    157 			(reply_s == 0 &&
    158 			    reply_t == opts->arping[state->arping_index - 1])))
    159 		{
    160 			ina.s_addr = reply_s;
    161 			hwaddr = hwaddr_ntoa((unsigned char *)hw_s,
    162 			    (size_t)ar.ar_hln);
    163 			syslog(LOG_INFO,
    164 			    "%s: found %s on hardware address %s",
    165 			    iface->name, inet_ntoa(ina), hwaddr);
    166 			if (select_profile(iface, hwaddr) == -1 &&
    167 			    errno == ENOENT)
    168 				select_profile(iface, inet_ntoa(ina));
    169 			close_sockets(iface);
    170 			delete_timeout(NULL, iface);
    171 			start_interface(iface);
    172 			return;
    173 		}
    174 
    175 		/* Check for conflict */
    176 		if (state->offer &&
    177 		    (reply_s == state->offer->yiaddr ||
    178 			(reply_s == 0 && reply_t == state->offer->yiaddr)))
    179 			state->fail.s_addr = state->offer->yiaddr;
    180 
    181 		/* Handle IPv4LL conflicts */
    182 		if (IN_LINKLOCAL(htonl(iface->addr.s_addr)) &&
    183 		    (reply_s == iface->addr.s_addr ||
    184 			(reply_s == 0 && reply_t == iface->addr.s_addr)))
    185 			state->fail.s_addr = iface->addr.s_addr;
    186 
    187 		if (state->fail.s_addr) {
    188 			syslog(LOG_ERR, "%s: hardware address %s claims %s",
    189 			    iface->name,
    190 			    hwaddr_ntoa((unsigned char *)hw_s,
    191 				(size_t)ar.ar_hln),
    192 			    inet_ntoa(state->fail));
    193 			errno = EEXIST;
    194 			handle_arp_failure(iface);
    195 			return;
    196 		}
    197 	}
    198 }
    199 
    200 void
    201 send_arp_announce(void *arg)
    202 {
    203 	struct interface *iface = arg;
    204 	struct if_state *state = iface->state;
    205 	struct timeval tv;
    206 
    207 	if (state->new == NULL)
    208 		return;
    209 	if (iface->arp_fd == -1) {
    210 		open_socket(iface, ETHERTYPE_ARP);
    211 		add_event(iface->arp_fd, handle_arp_packet, iface);
    212 	}
    213 	if (++state->claims < ANNOUNCE_NUM)
    214 		syslog(LOG_DEBUG,
    215 		    "%s: sending ARP announce (%d of %d), "
    216 		    "next in %d.00 seconds",
    217 		    iface->name, state->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT);
    218 	else
    219 		syslog(LOG_DEBUG,
    220 		    "%s: sending ARP announce (%d of %d)",
    221 		    iface->name, state->claims, ANNOUNCE_NUM);
    222 	if (send_arp(iface, ARPOP_REQUEST,
    223 		state->new->yiaddr, state->new->yiaddr) == -1)
    224 		syslog(LOG_ERR, "send_arp: %m");
    225 	if (state->claims < ANNOUNCE_NUM) {
    226 		add_timeout_sec(ANNOUNCE_WAIT, send_arp_announce, iface);
    227 		return;
    228 	}
    229 	if (state->new->cookie != htonl(MAGIC_COOKIE)) {
    230 		/* We should pretend to be at the end
    231 		 * of the DHCP negotation cycle unless we rebooted */
    232 		if (state->interval != 0)
    233 			state->interval = 64;
    234 		state->probes = 0;
    235 		state->claims = 0;
    236 		tv.tv_sec = state->interval - DHCP_RAND_MIN;
    237 		tv.tv_usec = arc4random() % (DHCP_RAND_MAX_U - DHCP_RAND_MIN_U);
    238 		timernorm(&tv);
    239 		add_timeout_tv(&tv, start_discover, iface);
    240 	} else {
    241 		delete_event(iface->arp_fd);
    242 		close(iface->arp_fd);
    243 		iface->arp_fd = -1;
    244 	}
    245 }
    246 
    247 void
    248 send_arp_probe(void *arg)
    249 {
    250 	struct interface *iface = arg;
    251 	struct if_state *state = iface->state;
    252 	struct in_addr addr;
    253 	struct timeval tv;
    254 	int arping = 0;
    255 
    256 	if (state->arping_index < state->options->arping_len) {
    257 		addr.s_addr = state->options->arping[state->arping_index];
    258 		arping = 1;
    259 	} else if (state->offer) {
    260 		if (state->offer->yiaddr)
    261 			addr.s_addr = state->offer->yiaddr;
    262 		else
    263 			addr.s_addr = state->offer->ciaddr;
    264 	} else
    265 		addr.s_addr = iface->addr.s_addr;
    266 
    267 	if (iface->arp_fd == -1) {
    268 		open_socket(iface, ETHERTYPE_ARP);
    269 		add_event(iface->arp_fd, handle_arp_packet, iface);
    270 	}
    271 	if (state->probes == 0) {
    272 		if (arping)
    273 			syslog(LOG_INFO, "%s: searching for %s",
    274 			    iface->name, inet_ntoa(addr));
    275 		else
    276 			syslog(LOG_INFO, "%s: checking for %s",
    277 			    iface->name, inet_ntoa(addr));
    278 	}
    279 	if (++state->probes < PROBE_NUM) {
    280 		tv.tv_sec = PROBE_MIN;
    281 		tv.tv_usec = arc4random() % (PROBE_MAX_U - PROBE_MIN_U);
    282 		timernorm(&tv);
    283 		add_timeout_tv(&tv, send_arp_probe, iface);
    284 	} else {
    285 		tv.tv_sec = ANNOUNCE_WAIT;
    286 		tv.tv_usec = 0;
    287 		if (arping) {
    288 			state->probes = 0;
    289 			if (++state->arping_index < state->options->arping_len)
    290 				add_timeout_tv(&tv, send_arp_probe, iface);
    291 			else
    292 				add_timeout_tv(&tv, start_interface, iface);
    293 		} else
    294 			add_timeout_tv(&tv, bind_interface, iface);
    295 	}
    296 	syslog(LOG_DEBUG,
    297 	    "%s: sending ARP probe (%d of %d), next in %0.2f seconds",
    298 	    iface->name, state->probes ? state->probes : PROBE_NUM, PROBE_NUM,
    299 	    timeval_to_double(&tv));
    300 	if (send_arp(iface, ARPOP_REQUEST, 0, addr.s_addr) == -1)
    301 		syslog(LOG_ERR, "send_arp: %m");
    302 }
    303 
    304 void
    305 start_arping(struct interface *iface)
    306 {
    307 	iface->state->probes = 0;
    308 	iface->state->arping_index = 0;
    309 	send_arp_probe(iface);
    310 }
    311