main.c revision fee9053f6a8a22ff53d59fc7865230ad41fdf760
160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* $Id$ */ 260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/*** 460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering This file is part of avahi. 560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi is free software; you can redistribute it and/or modify it 760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering under the terms of the GNU Lesser General Public License as 860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering published by the Free Software Foundation; either version 2.1 of the 960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering License, or (at your option) any later version. 1060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 1160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi is distributed in the hope that it will be useful, but WITHOUT 1260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 1360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 1460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering Public License for more details. 1560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 1660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering You should have received a copy of the GNU Lesser General Public 1760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering License along with avahi; if not, write to the Free Software 1860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 1960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering USA. 2060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering***/ 2160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 2260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#ifdef HAVE_CONFIG_H 2360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <config.h> 2460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#endif 2560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 2660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <stdlib.h> 2760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <unistd.h> 2860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <sys/socket.h> 2960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <netpacket/packet.h> 3060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <net/ethernet.h> 3160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <fcntl.h> 3260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <time.h> 3360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <assert.h> 3460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <errno.h> 3560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <string.h> 3660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <inttypes.h> 3760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <sys/types.h> 3860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <arpa/inet.h> 3960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <sys/ioctl.h> 4060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <poll.h> 4160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <net/if.h> 4260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 4360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <avahi-common/malloc.h> 4460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <avahi-common/timeval.h> 4560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 4612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering#include <avahi-daemon/setproctitle.h> 4712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 4860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dfork.h> 4960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dsignal.h> 5060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dlog.h> 5160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dpid.h> 5260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dexec.h> 5360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 5412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering#include "main.h" 5512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering#include "iface.h" 5612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 5760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#ifndef __linux__ 5860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#error "avahi-autoipd is only available on Linux for now" 5960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#endif 6060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 6160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* An implementation of RFC 3927 */ 6260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 6360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* Constants from the RFC */ 6460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_WAIT 1 6560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_NUM 3 6660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_MIN 1 6760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_MAX 2 6860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ANNOUNCE_WAIT 2 6960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ANNOUNCE_NUM 2 7060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ANNOUNCE_INTERVAL 2 7160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define MAX_CONFLICTS 10 7260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define RATE_LIMIT_INTERVAL 60 7360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define DEFEND_INTERVAL 10 7460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 7560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define IPV4LL_NETWORK 0xA9FE0000L 7660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define IPV4LL_NETMASK 0xFFFF0000L 7760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define IPV4LL_HOSTMASK 0x0000FFFFL 7860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 7960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ETHER_ADDRLEN 6 8060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ARP_PACKET_SIZE (8+4+4+2*ETHER_ADDRLEN) 8160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8260d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringtypedef enum ArpOperation { 8360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ARP_REQUEST = 1, 8460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ARP_RESPONSE = 2 8560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} ArpOperation; 8660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8760d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringtypedef struct ArpPacketInfo { 8860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpOperation operation; 8960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t sender_ip_address, target_ip_address; 9160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t sender_hw_address[ETHER_ADDRLEN], target_hw_address[ETHER_ADDRLEN]; 9260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} ArpPacketInfo; 9360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poetteringstatic State state = STATE_START; 9560d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int n_iteration = 0; 9660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int n_conflict = 0; 9760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define RANDOM_DEVICE "/dev/urandom" 9960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void init_rand_seed(void) { 10160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd; 10260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering unsigned seed = 0; 10360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Try to initialize seed from /dev/urandom, to make it a little 10560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering * less predictable, and to make sure that multiple machines 10660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering * booted at the same time choose different random seeds. */ 10760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) { 10860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering read(fd, &seed, sizeof(seed)); 10960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 11060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 11160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 11260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* If the initialization failed by some reason, we add the time to the seed */ 11360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering seed ^= (unsigned) time(NULL); 11460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 11560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering srand(seed); 11660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 11760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 11860d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic uint32_t pick_addr(uint32_t old_addr) { 11960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t addr; 12060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 12160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering do { 12260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering unsigned r = (unsigned) rand(); 12360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 12460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Reduce to 16 bits */ 12560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering while (r > 0xFFFF) 12660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r = (r >> 16) ^ (r & 0xFFFF); 12760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 12860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = htonl(IPV4LL_NETWORK | (uint32_t) r); 12960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 13060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } while (addr == old_addr); 13160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 13260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return addr; 13360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 13460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 13560d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void* packet_new(const ArpPacketInfo *info, size_t *packet_len) { 13660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t *r; 13760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 13860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(info); 13960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len); 14060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(info->operation == ARP_REQUEST || info->operation == ARP_RESPONSE); 14160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 14260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet_len = ARP_PACKET_SIZE; 14360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r = avahi_new0(uint8_t, *packet_len); 14460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 14560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[1] = 1; /* HTYPE */ 14660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[2] = 8; /* PTYPE */ 14760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[4] = ETHER_ADDRLEN; /* HLEN */ 14860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[5] = 4; /* PLEN */ 14960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[7] = (uint8_t) info->operation; 15060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 15160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+8, info->sender_hw_address, ETHER_ADDRLEN); 15260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+14, &info->sender_ip_address, 4); 15360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+18, info->target_hw_address, ETHER_ADDRLEN); 15460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+24, &info->target_ip_address, 4); 15560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 15660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return r; 15760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 15860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 15960d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void *packet_new_probe(uint32_t ip_address, const uint8_t*hw_address, size_t *packet_len) { 16060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 16160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&info, 0, sizeof(info)); 16360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.operation = ARP_REQUEST; 16460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN); 16560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.target_ip_address = ip_address; 16660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return packet_new(&info, packet_len); 16860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 16960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void *packet_new_announcement(uint32_t ip_address, const uint8_t* hw_address, size_t *packet_len) { 17160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 17260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&info, 0, sizeof(info)); 17460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.operation = ARP_REQUEST; 17560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN); 17660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.target_ip_address = ip_address; 17760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.sender_ip_address = ip_address; 17860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return packet_new(&info, packet_len); 18060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 18160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18260d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int packet_parse(const void *data, size_t packet_len, ArpPacketInfo *info) { 18360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering const uint8_t *p = data; 18460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(data); 18660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (packet_len < ARP_PACKET_SIZE) 18860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 18960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Check HTYPE and PTYPE */ 19160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (p[0] != 0 || p[1] != 1 || p[2] != 8 || p[3] != 0) 19260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 19360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Check HLEN, PLEN, OPERATION */ 19560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (p[4] != ETHER_ADDRLEN || p[5] != 4 || p[6] != 0 || (p[7] != 1 && p[7] != 2)) 19660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 19760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info->operation = p[7]; 19960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info->sender_hw_address, p+8, ETHER_ADDRLEN); 20060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(&info->sender_ip_address, p+14, 4); 20160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info->target_hw_address, p+18, ETHER_ADDRLEN); 20260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(&info->target_ip_address, p+24, 4); 20360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 20460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 20560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 20660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 20760d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void set_state(State st, int reset_counter) { 20860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering const char* const state_table[] = { 20912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering [STATE_START] = "START", 21060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_WAITING_PROBE] = "WAITING_PROBE", 21160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_PROBING] = "PROBING", 21260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_WAITING_ANNOUNCE] = "WAITING_ANNOUNCE", 21360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_ANNOUNCING] = "ANNOUNCING", 21460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_RUNNING] = "RUNNING", 21560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_SLEEPING] = "SLEEPING" 21660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering }; 21760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 21860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(st < STATE_MAX); 21960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 22060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (st == state && !reset_counter) { 22160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_iteration++; 22260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_DEBUG, "State iteration %s-%i", state_table[state], n_iteration); 22360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else { 22460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_DEBUG, "State transition %s-%i -> %s-0", state_table[state], n_iteration, state_table[st]); 22560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering state = st; 22660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_iteration = 0; 22760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 22860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 22960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int add_address(int iface, uint32_t addr) { 23160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering char buf[64]; 23260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 233fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering daemon_log(LOG_INFO, "Configuring address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 23460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 23560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 23660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23760d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int remove_address(int iface, uint32_t addr) { 23860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering char buf[64]; 23960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 240fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering daemon_log(LOG_INFO, "Unconfiguring address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 24160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 24260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 24360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 24460d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int open_socket(int iface, uint8_t *hw_address) { 24560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd = -1; 24660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 24760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering socklen_t sa_len; 24860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 24960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) < 0) { 25060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno)); 25160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 25260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 25360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 25460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&sa, 0, sizeof(sa)); 25560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_family = AF_PACKET; 25660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_protocol = htons(ETH_P_ARP); 25760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_ifindex = iface; 25860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 25960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 26060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "bind() failed: %s", strerror(errno)); 26160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 26260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 26360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 26460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa_len = sizeof(sa); 26560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (getsockname(fd, (struct sockaddr*) &sa, &sa_len) < 0) { 26660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "getsockname() failed: %s", strerror(errno)); 26760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 26860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 26960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 27060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (sa.sll_halen != ETHER_ADDRLEN) { 27160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "getsockname() returned invalid hardware address."); 27260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 27360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 27460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 27560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(hw_address, sa.sll_addr, ETHER_ADDRLEN); 27660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 27760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return fd; 27860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 27960d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 28060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (fd >= 0) 28160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 28260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 28360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 28460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 28560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 28660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int send_packet(int fd, int iface, void *packet, size_t packet_len) { 28760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 28860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 28960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(fd >= 0); 29060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet); 29160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len > 0); 29260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 29360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&sa, 0, sizeof(sa)); 29460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_family = AF_PACKET; 29560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_protocol = htons(ETH_P_ARP); 29660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_ifindex = iface; 29760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_halen = ETHER_ADDRLEN; 29860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(sa.sll_addr, 0xFF, ETHER_ADDRLEN); 29960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 30060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (sendto(fd, packet, packet_len, 0, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 30160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "sendto() failed: %s", strerror(errno)); 30260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 30360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 30460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 30560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 30660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 30760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 30860d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int recv_packet(int fd, void **packet, size_t *packet_len) { 30960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int s; 31060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 31160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering socklen_t sa_len; 31260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 31360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(fd >= 0); 31460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet); 31560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len); 31660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 31760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet = NULL; 31860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 31960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (ioctl(fd, FIONREAD, &s) < 0) { 32060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "FIONREAD failed: %s", strerror(errno)); 32160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 32260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 32360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 32460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(s > 0); 32560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 32660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet_len = (size_t) s; 32760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet = avahi_new(uint8_t, s); 32860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 32960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa_len = sizeof(sa); 33060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (recvfrom(fd, *packet, s, 0, (struct sockaddr*) &sa, &sa_len) < 0) { 33160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "recvfrom() failed: %s", strerror(errno)); 33260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 33360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 33460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 33560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 33660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 33760d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 33860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (*packet) 33960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(*packet); 34060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 34160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 34260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 34360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 34412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poetteringint is_ll_address(uint32_t addr) { 34560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return (ntohl(addr) & IPV4LL_NETMASK) == IPV4LL_NETWORK; 34660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 34760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 34860d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic struct timeval *elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) { 34960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(tv); 35060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 35160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering gettimeofday(tv, NULL); 35260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 35360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (msec) 35460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_timeval_add(tv, (AvahiUsec) msec*1000); 35560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 35660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (jitter) 35760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0))); 35860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 35960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return tv; 36060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 36160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 36260d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int loop(int iface, uint32_t addr) { 36312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering enum { 36412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering FD_ARP, 36512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering FD_IFACE, 36612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering FD_MAX 36712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering }; 36812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 36960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd = -1, ret = -1; 37060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct timeval next_wakeup; 37160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int next_wakeup_valid = 0; 37260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering char buf[64]; 37360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering void *in_packet = NULL; 37460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering size_t in_packet_len; 37560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering void *out_packet = NULL; 37660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering size_t out_packet_len; 37760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t hw_address[ETHER_ADDRLEN]; 37812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering struct pollfd pollfds[FD_MAX]; 37912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering int iface_fd; 38012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering Event event = EVENT_NULL; 38160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 38260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = open_socket(iface, hw_address)) < 0) 38360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 38460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 38512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if ((iface_fd = iface_init(iface)) < 0) 38612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 38712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 38812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (iface_get_initial_state(&state) < 0) 38912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 39012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 39160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (addr && !is_ll_address(addr)) { 39260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_WARNING, "Requested address %s is not from IPv4LL range 169.254/16, ignoring.", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 39360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = 0; 39460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 39560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 39660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (!addr) { 39760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int i; 39860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t a = 1; 39960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering for (i = 0; i < ETHER_ADDRLEN; i++) 40160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering a += hw_address[i]*i; 40260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = htonl(IPV4LL_NETWORK | (uint32_t) a); 40460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 40560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Starting with address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 40760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_SLEEPING) 40912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "Routable address already assigned, sleeping."); 41012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 41160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(pollfds, 0, sizeof(pollfds)); 41212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_ARP].fd = fd; 41312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_ARP].events = POLLIN; 41412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].fd = iface_fd; 41512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].events = POLLIN; 41660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 41760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering for (;;) { 41860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int r, timeout; 41960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering AvahiUsec usec; 42060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 42112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_START) { 42260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 42360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* First, wait a random time */ 42460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering set_state(STATE_WAITING_PROBE, 1); 42560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 42660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 42760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 42860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 42960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_WAITING_PROBE && event == EVENT_TIMEOUT) || 43060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration < PROBE_NUM-2)) { 43160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 43260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send a probe */ 43360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 43460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering set_state(STATE_PROBING, 0); 43560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 43660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, PROBE_MIN*1000, (PROBE_MAX-PROBE_MIN)*1000); 43760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 43860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 43960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration >= PROBE_NUM-2) { 44060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 44160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send the last probe */ 44260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 44360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering set_state(STATE_WAITING_ANNOUNCE, 1); 44460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 44560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_WAIT*1000, 0); 44660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 44760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 44860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_WAITING_ANNOUNCE && event == EVENT_TIMEOUT) || 44960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering (state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration < ANNOUNCE_NUM-1)) { 45060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 45160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send announcement packet */ 45260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_announcement(addr, hw_address, &out_packet_len); 45360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering set_state(STATE_ANNOUNCING, 0); 45460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 45560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0); 45660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 45760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 45860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (n_iteration == 0) { 45960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering add_address(iface, addr); 46060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_conflict = 0; 46160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 46260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 46360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration >= ANNOUNCE_NUM-1)) { 46460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 46560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Successfully claimed IP address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 46660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering set_state(STATE_RUNNING, 0); 467fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering 468fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering next_wakeup_valid = 0; 46960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 47060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (event == EVENT_PACKET) { 47160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 47260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 47360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(in_packet); 47460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 47560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (packet_parse(in_packet, in_packet_len, &info) < 0) 47660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_WARNING, "Failed to parse incoming ARP packet."); 47760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering else { 47860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int conflict = 0; 47960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 48060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (info.sender_ip_address == addr) { 48160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Normal conflict */ 48260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering conflict = 1; 48360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Recieved conflicting normal ARP packet."); 48460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (state == STATE_WAITING_PROBE || state == STATE_PROBING || state == STATE_WAITING_ANNOUNCE) { 48560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Probe conflict */ 48660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering conflict = info.target_ip_address == addr && memcmp(hw_address, info.sender_hw_address, ETHER_ADDRLEN); 48760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Recieved conflicting probe ARP packet."); 48860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 48960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 49060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (conflict) { 49160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 49260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 49360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering remove_address(iface, addr); 49460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 49560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Pick a new address */ 49660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = pick_addr(addr); 49760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 49860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Trying address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 49960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 50060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_conflict++; 50160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 50212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering set_state(STATE_WAITING_PROBE, 1); 50312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 50460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (n_conflict >= MAX_CONFLICTS) { 50560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_WARNING, "Got too many conflicts, rate limiting new probes."); 50660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, RATE_LIMIT_INTERVAL*1000, PROBE_WAIT*1000); 50760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else 50860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 50960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 51060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 51160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else 51260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_DEBUG, "Ignoring ARP packet."); 51360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 51412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 51512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } else if (event == EVENT_ROUTABLE_ADDR_CONFIGURED) { 51612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 51712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "A routable address has been configured."); 51812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 51912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 52012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering remove_address(iface, addr); 521fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering 522fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering set_state(STATE_SLEEPING, 1); 523fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering next_wakeup_valid = 0; 52412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 52512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } else if (event == EVENT_ROUTABLE_ADDR_UNCONFIGURED && state == STATE_SLEEPING) { 52612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 52712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "No longer a routable address configured, restarting probe process."); 52812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 52912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering set_state(STATE_WAITING_PROBE, 1); 53012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 53112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 53212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering next_wakeup_valid = 1; 53312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 53460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 53560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 53660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (out_packet) { 53760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_DEBUG, "sending..."); 53860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 53960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (send_packet(fd, iface, out_packet, out_packet_len) < 0) 54060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 54160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 54260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(out_packet); 54360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = NULL; 54460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 54560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 54660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (in_packet) { 54760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(in_packet); 54860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering in_packet = NULL; 54960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 55060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 55112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering event = EVENT_NULL; 55260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering timeout = -1; 55360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 55460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (next_wakeup_valid) { 55560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering usec = avahi_age(&next_wakeup); 55660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering timeout = usec < 0 ? (int) (-usec/1000) : 0; 55760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 55860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 55960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_DEBUG, "sleeping %ims", timeout); 56060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 56112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering while ((r = poll(pollfds, FD_MAX, timeout)) < 0 && errno == EINTR) 56260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ; 56360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 56460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (r < 0) { 56560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "poll() failed: %s", strerror(r)); 56660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering break; 56760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (r == 0) { 56860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering event = EVENT_TIMEOUT; 56960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 0; 57060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else { 57160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 57212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (pollfds[FD_ARP].revents == POLLIN) { 57312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (recv_packet(fd, &in_packet, &in_packet_len) < 0) 57412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 57512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 57612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (in_packet) 57712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering event = EVENT_PACKET; 57812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } 57960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 58012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (event == EVENT_NULL && 58112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].revents == POLLIN) { 58212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 58312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (iface_process(&event) < 0) 58412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 58512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } 58660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 58760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 58860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 58960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ret = 0; 59060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 59160d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 59260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 59360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(out_packet); 59460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(in_packet); 59560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 59660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (fd >= 0) 59760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 59812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 59912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (iface_fd >= 0) 60012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering iface_done(); 60160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 60260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return ret; 60360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 60460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 60560d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int get_ifindex(const char *name) { 60660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd = -1; 60760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct ifreq ifreq; 60860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 60960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 61060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno)); 61160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 61260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 61360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 61460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&ifreq, 0, sizeof(ifreq)); 61560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering strncpy(ifreq.ifr_name, name, IFNAMSIZ-1); 61660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ifreq.ifr_name[IFNAMSIZ-1] = 0; 61760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 61860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (ioctl(fd, SIOCGIFINDEX, &ifreq) < 0) { 61960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "SIOCGIFINDEX failed: %s", strerror(errno)); 62060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 62160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 62260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return ifreq.ifr_ifindex; 62460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62560d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 62660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (fd >= 0) 62860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 62960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 63060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 63160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 63260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 63360d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringint main(int argc, char*argv[]) { 63460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int ret = 1; 63560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int ifindex; 63660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t addr = 0; 63760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 63812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering avahi_init_proc_title(argc, argv); 63912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 64060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering init_rand_seed(); 64160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 64260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((ifindex = get_ifindex(argc >= 2 ? argv[1] : "eth0")) < 0) 64360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 64460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 64560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (argc >= 3) 64660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = inet_addr(argv[2]); 64760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 64860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (loop(ifindex, addr) < 0) 64960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 65060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ret = 0; 65260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65460d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 65560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return ret; 65760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 65860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* TODO: 66060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 66160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- man page 66260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- user script 66360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- chroot/drop privs/caps 66460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- daemonize 66560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- defend 66660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- signals 66760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- store last used address 66860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- cmdline 66912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering- setproctitle 67060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 67160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering*/ 672