1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/* 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * dhcpcd - DHCP client daemon 3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt * Copyright (c) 2006-2011 Roy Marples <roy@marples.name> 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * All rights reserved 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Redistribution and use in source and binary forms, with or without 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * modification, are permitted provided that the following conditions 8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * are met: 9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 1. Redistributions of source code must retain the above copyright 10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer. 11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 2. Redistributions in binary form must reproduce the above copyright 12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * notice, this list of conditions and the following disclaimer in the 13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * documentation and/or other materials provided with the distribution. 14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * 15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * SUCH DAMAGE. 26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */ 27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <errno.h> 29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <signal.h> 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <stdlib.h> 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <string.h> 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <syslog.h> 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include <unistd.h> 34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 35e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "arp.h" 36e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "bind.h" 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "common.h" 38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "dhcpcd.h" 39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "eloop.h" 40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "if-options.h" 41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "ipv4ll.h" 42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "net.h" 43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#define ARP_LEN \ 45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (sizeof(struct arphdr) + (2 * sizeof(uint32_t)) + (2 * HWADDR_LEN)) 46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int 48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsend_arp(const struct interface *iface, int op, in_addr_t sip, in_addr_t tip) 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint8_t arp_buffer[ARP_LEN]; 51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct arphdr ar; 52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt size_t len; 53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint8_t *p; 54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int retval; 55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ar.ar_hrd = htons(iface->family); 57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ar.ar_pro = htons(ETHERTYPE_IP); 58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ar.ar_hln = iface->hwlen; 59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ar.ar_pln = sizeof(sip); 60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ar.ar_op = htons(op); 61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(arp_buffer, &ar, sizeof(ar)); 62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p = arp_buffer + sizeof(ar); 63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, iface->hwaddr, iface->hwlen); 64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += iface->hwlen; 65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, &sip, sizeof(sip)); 66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += sizeof(sip); 67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* ARP requests should ignore this */ 68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = iface->hwlen; 69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt while (retval--) 70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt *p++ = '\0'; 71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(p, &tip, sizeof(tip)); 72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt p += sizeof(tip); 73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt len = p - arp_buffer; 74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt retval = send_raw_packet(iface, ETHERTYPE_ARP, arp_buffer, len); 75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return retval; 76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void 79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidthandle_arp_failure(struct interface *iface) 80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* If we failed without a magic cookie then we need to try 83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * and defend our IPv4LL address. */ 84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((iface->state->offer != NULL && 85e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->state->offer->cookie != htonl(MAGIC_COOKIE)) || 86e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (iface->state->new != NULL && 87e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->state->new->cookie != htonl(MAGIC_COOKIE))) 88e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 89e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt handle_ipv4ll_failure(iface); 90e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 91e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 92e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 93e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt unlink(iface->leasefile); 94e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!iface->state->lease.frominfo) 95e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt send_decline(iface); 96e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt close_sockets(iface); 97e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt delete_timeout(NULL, iface); 98e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (iface->state->lease.frominfo) 99e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt start_interface(iface); 100e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 101e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_timeout_sec(DHCP_ARP_FAIL, start_interface, iface); 102e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 103e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 104e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void 105e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidthandle_arp_packet(void *arg) 106e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 107e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct interface *iface = arg; 108e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint8_t arp_buffer[ARP_LEN]; 109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct arphdr ar; 110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint32_t reply_s; 111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint32_t reply_t; 112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt uint8_t *hw_s, *hw_t; 113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ssize_t bytes; 114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct if_state *state = iface->state; 115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct if_options *opts = state->options; 116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const char *hwaddr; 117e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct in_addr ina; 118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->fail.s_addr = 0; 120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt for(;;) { 121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt bytes = get_raw_packet(iface, ETHERTYPE_ARP, 122a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt arp_buffer, sizeof(arp_buffer), NULL); 123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (bytes == 0 || bytes == -1) 124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* We must have a full ARP header */ 126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((size_t)bytes < sizeof(ar)) 127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(&ar, arp_buffer, sizeof(ar)); 129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Protocol must be IP. */ 130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ar.ar_pro != htons(ETHERTYPE_IP)) 131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ar.ar_pln != sizeof(reply_s)) 133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Only these types are recognised */ 135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ar.ar_op != htons(ARPOP_REPLY) && 136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ar.ar_op != htons(ARPOP_REQUEST)) 137e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 138e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 139e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Get pointers to the hardware addreses */ 140e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hw_s = arp_buffer + sizeof(ar); 141e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hw_t = hw_s + ar.ar_hln + ar.ar_pln; 142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Ensure we got all the data */ 143e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if ((hw_t + ar.ar_hln + ar.ar_pln) - arp_buffer > bytes) 144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Ignore messages from ourself */ 146e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (ar.ar_hln == iface->hwlen && 147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcmp(hw_s, iface->hwaddr, iface->hwlen) == 0) 148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt continue; 149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Copy out the IP addresses */ 150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(&reply_s, hw_s + ar.ar_hln, ar.ar_pln); 151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt memcpy(&reply_t, hw_t + ar.ar_hln, ar.ar_pln); 152e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Check for arping */ 154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->arping_index && 155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->arping_index <= opts->arping_len && 156e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (reply_s == opts->arping[state->arping_index - 1] || 157e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (reply_s == 0 && 158e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt reply_t == opts->arping[state->arping_index - 1]))) 159e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt { 160e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt ina.s_addr = reply_s; 161e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hwaddr = hwaddr_ntoa((unsigned char *)hw_s, 162e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (size_t)ar.ar_hln); 163e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_INFO, 164e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "%s: found %s on hardware address %s", 165e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->name, inet_ntoa(ina), hwaddr); 166e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (select_profile(iface, hwaddr) == -1 && 167e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno == ENOENT) 168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt select_profile(iface, inet_ntoa(ina)); 169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt close_sockets(iface); 170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt delete_timeout(NULL, iface); 171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt start_interface(iface); 172e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 173e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 174e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 175e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Check for conflict */ 176e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->offer && 177e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (reply_s == state->offer->yiaddr || 178e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (reply_s == 0 && reply_t == state->offer->yiaddr))) 179e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->fail.s_addr = state->offer->yiaddr; 180e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 181e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* Handle IPv4LL conflicts */ 182e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (IN_LINKLOCAL(htonl(iface->addr.s_addr)) && 183e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (reply_s == iface->addr.s_addr || 184e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (reply_s == 0 && reply_t == iface->addr.s_addr))) 185e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->fail.s_addr = iface->addr.s_addr; 186e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 187e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->fail.s_addr) { 188e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "%s: hardware address %s claims %s", 189e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->name, 190e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt hwaddr_ntoa((unsigned char *)hw_s, 191e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt (size_t)ar.ar_hln), 192e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt inet_ntoa(state->fail)); 193e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt errno = EEXIST; 194e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt handle_arp_failure(iface); 195e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 196e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 197e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 198e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 199e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 200e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid 201e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsend_arp_announce(void *arg) 202e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 203e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct interface *iface = arg; 204e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct if_state *state = iface->state; 205e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct timeval tv; 206e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 207a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt if (state->new == NULL) 208a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt return; 209e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (iface->arp_fd == -1) { 210e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt open_socket(iface, ETHERTYPE_ARP); 211e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_event(iface->arp_fd, handle_arp_packet, iface); 212e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 213e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (++state->claims < ANNOUNCE_NUM) 214e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_DEBUG, 215e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "%s: sending ARP announce (%d of %d), " 216e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "next in %d.00 seconds", 217e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->name, state->claims, ANNOUNCE_NUM, ANNOUNCE_WAIT); 218e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 219e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_DEBUG, 220e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "%s: sending ARP announce (%d of %d)", 221e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->name, state->claims, ANNOUNCE_NUM); 222e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (send_arp(iface, ARPOP_REQUEST, 223e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->new->yiaddr, state->new->yiaddr) == -1) 224e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "send_arp: %m"); 225e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->claims < ANNOUNCE_NUM) { 226e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_timeout_sec(ANNOUNCE_WAIT, send_arp_announce, iface); 227e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt return; 228e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 229e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->new->cookie != htonl(MAGIC_COOKIE)) { 230e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt /* We should pretend to be at the end 231e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * of the DHCP negotation cycle unless we rebooted */ 232e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->interval != 0) 233e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->interval = 64; 234e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->probes = 0; 235e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->claims = 0; 236e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt tv.tv_sec = state->interval - DHCP_RAND_MIN; 237e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt tv.tv_usec = arc4random() % (DHCP_RAND_MAX_U - DHCP_RAND_MIN_U); 238e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt timernorm(&tv); 239e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_timeout_tv(&tv, start_discover, iface); 240e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 241e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt delete_event(iface->arp_fd); 242e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt close(iface->arp_fd); 243e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->arp_fd = -1; 244e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 245e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 246e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 247e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid 248e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtsend_arp_probe(void *arg) 249e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 250e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct interface *iface = arg; 251e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct if_state *state = iface->state; 252e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct in_addr addr; 253e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt struct timeval tv; 254e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int arping = 0; 255e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 256e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->arping_index < state->options->arping_len) { 257e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr.s_addr = state->options->arping[state->arping_index]; 258e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt arping = 1; 259e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else if (state->offer) { 260e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->offer->yiaddr) 261e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr.s_addr = state->offer->yiaddr; 262e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 263e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr.s_addr = state->offer->ciaddr; 264e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 265e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt addr.s_addr = iface->addr.s_addr; 266e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 267e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (iface->arp_fd == -1) { 268e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt open_socket(iface, ETHERTYPE_ARP); 269e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_event(iface->arp_fd, handle_arp_packet, iface); 270e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 271e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (state->probes == 0) { 272e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (arping) 273e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_INFO, "%s: searching for %s", 274e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->name, inet_ntoa(addr)); 275e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 276e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_INFO, "%s: checking for %s", 277e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->name, inet_ntoa(addr)); 278e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 279e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (++state->probes < PROBE_NUM) { 280e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt tv.tv_sec = PROBE_MIN; 281e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt tv.tv_usec = arc4random() % (PROBE_MAX_U - PROBE_MIN_U); 282e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt timernorm(&tv); 283e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_timeout_tv(&tv, send_arp_probe, iface); 284e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else { 285e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt tv.tv_sec = ANNOUNCE_WAIT; 286e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt tv.tv_usec = 0; 287e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (arping) { 288e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt state->probes = 0; 289e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (++state->arping_index < state->options->arping_len) 290e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_timeout_tv(&tv, send_arp_probe, iface); 291e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt else 292e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_timeout_tv(&tv, start_interface, iface); 293e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } else 294e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt add_timeout_tv(&tv, bind_interface, iface); 295e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt } 296e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_DEBUG, 297e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt "%s: sending ARP probe (%d of %d), next in %0.2f seconds", 298e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->name, state->probes ? state->probes : PROBE_NUM, PROBE_NUM, 299e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt timeval_to_double(&tv)); 300e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (send_arp(iface, ARPOP_REQUEST, 0, addr.s_addr) == -1) 301e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt syslog(LOG_ERR, "send_arp: %m"); 302e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 303e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 304e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtvoid 305e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstart_arping(struct interface *iface) 306e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{ 307e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->state->probes = 0; 308e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt iface->state->arping_index = 0; 309e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt send_arp_probe(iface); 310e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt} 311