main.c revision 287f9866c923e6afe8ffbbc03b90be64acf395e1
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> 425ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering#include <stdio.h> 435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering#include <getopt.h> 445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering#include <signal.h> 455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering#include <sys/wait.h> 4660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 4760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <avahi-common/malloc.h> 4860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <avahi-common/timeval.h> 4960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 5012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering#include <avahi-daemon/setproctitle.h> 5112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 5260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dfork.h> 5360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dsignal.h> 5460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dlog.h> 5560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dpid.h> 5660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#include <libdaemon/dexec.h> 5760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 5812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering#include "main.h" 5912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering#include "iface.h" 6012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 6160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#ifndef __linux__ 6260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#error "avahi-autoipd is only available on Linux for now" 6360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#endif 6460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 6560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* An implementation of RFC 3927 */ 6660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 6760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* Constants from the RFC */ 6860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_WAIT 1 6960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_NUM 3 7060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_MIN 1 7160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define PROBE_MAX 2 7260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ANNOUNCE_WAIT 2 7360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ANNOUNCE_NUM 2 7460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ANNOUNCE_INTERVAL 2 7560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define MAX_CONFLICTS 10 7660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define RATE_LIMIT_INTERVAL 60 7760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define DEFEND_INTERVAL 10 7860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 7960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define IPV4LL_NETWORK 0xA9FE0000L 8060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define IPV4LL_NETMASK 0xFFFF0000L 8160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define IPV4LL_HOSTMASK 0x0000FFFFL 8260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ETHER_ADDRLEN 6 8460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define ARP_PACKET_SIZE (8+4+4+2*ETHER_ADDRLEN) 8560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringtypedef enum ArpOperation { 8760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ARP_REQUEST = 1, 8860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ARP_RESPONSE = 2 8960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} ArpOperation; 9060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9160d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringtypedef struct ArpPacketInfo { 9260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpOperation operation; 9360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t sender_ip_address, target_ip_address; 9560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t sender_hw_address[ETHER_ADDRLEN], target_hw_address[ETHER_ADDRLEN]; 9660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} ArpPacketInfo; 9760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poetteringstatic State state = STATE_START; 9960d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int n_iteration = 0; 10060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int n_conflict = 0; 10160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 1025ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic char *interface_name = NULL; 1035ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic char *pid_file_name = NULL; 1045ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic uint32_t start_address = 0; 1055ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic char *argv0 = NULL; 1065ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int daemonize = 0; 1075ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int wait_for_address = 0; 1085ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int use_syslog = 0; 1095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int debug = 0; 1105ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int modify_proc_title = 1; 1115b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poetteringstatic int force_bind = 0; 1125ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 1135ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic enum { 1145ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_RUN, 1155ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_KILL, 1165ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_REFRESH, 1175ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_VERSION, 1185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_HELP, 1195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_CHECK 1205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} command = DAEMON_RUN; 1215ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 1225ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringtypedef enum CalloutEvent { 1235ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_BIND, 1245ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_CONFLICT, 1255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_UNBIND, 1265ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_STOP, 1275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_MAX 1285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} CalloutEvent; 1295ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 1307bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poetteringstatic const char * const callout_event_table[CALLOUT_MAX] = { 1317bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering [CALLOUT_BIND] = "BIND", 1327bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering [CALLOUT_CONFLICT] = "CONFLICT", 1337bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering [CALLOUT_UNBIND] = "UNBIND", 1347bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering [CALLOUT_STOP] = "STOP" 1357bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering}; 1367bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 1377bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poetteringtypedef struct CalloutEventInfo { 1387bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering CalloutEvent event; 1397bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering uint32_t address; 1407bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering int ifindex; 1417bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering} CalloutEventInfo; 1427bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 14360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define RANDOM_DEVICE "/dev/urandom" 14460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 1455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering#define DEBUG(x) do {\ 1465ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringif (debug) { \ 1475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering x; \ 1485ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} \ 1495ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} while (0) 1505ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 15160d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void init_rand_seed(void) { 15260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd; 15360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering unsigned seed = 0; 15460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 15560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Try to initialize seed from /dev/urandom, to make it a little 15660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering * less predictable, and to make sure that multiple machines 15760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering * booted at the same time choose different random seeds. */ 15860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) { 15960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering read(fd, &seed, sizeof(seed)); 16060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 16160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 16260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* If the initialization failed by some reason, we add the time to the seed */ 16460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering seed ^= (unsigned) time(NULL); 16560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering srand(seed); 16760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 16860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16960d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic uint32_t pick_addr(uint32_t old_addr) { 17060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t addr; 17160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering do { 17360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering unsigned r = (unsigned) rand(); 17460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Reduce to 16 bits */ 17660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering while (r > 0xFFFF) 17760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r = (r >> 16) ^ (r & 0xFFFF); 17860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = htonl(IPV4LL_NETWORK | (uint32_t) r); 18060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } while (addr == old_addr); 18260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return addr; 18460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 18560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void* packet_new(const ArpPacketInfo *info, size_t *packet_len) { 18760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t *r; 18860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(info); 19060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len); 19160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(info->operation == ARP_REQUEST || info->operation == ARP_RESPONSE); 19260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet_len = ARP_PACKET_SIZE; 19460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r = avahi_new0(uint8_t, *packet_len); 19560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[1] = 1; /* HTYPE */ 19760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[2] = 8; /* PTYPE */ 19860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[4] = ETHER_ADDRLEN; /* HLEN */ 19960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[5] = 4; /* PLEN */ 20060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[7] = (uint8_t) info->operation; 20160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 20260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+8, info->sender_hw_address, ETHER_ADDRLEN); 20360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+14, &info->sender_ip_address, 4); 20460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+18, info->target_hw_address, ETHER_ADDRLEN); 20560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+24, &info->target_ip_address, 4); 20660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 20760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return r; 20860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 20960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 21060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void *packet_new_probe(uint32_t ip_address, const uint8_t*hw_address, size_t *packet_len) { 21160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 21260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 21360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&info, 0, sizeof(info)); 21460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.operation = ARP_REQUEST; 21560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN); 21660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.target_ip_address = ip_address; 21760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 21860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return packet_new(&info, packet_len); 21960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 22060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 22160d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void *packet_new_announcement(uint32_t ip_address, const uint8_t* hw_address, size_t *packet_len) { 22260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 22360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 22460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&info, 0, sizeof(info)); 22560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.operation = ARP_REQUEST; 22660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN); 22760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.target_ip_address = ip_address; 22860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.sender_ip_address = ip_address; 22960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return packet_new(&info, packet_len); 23160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 23260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23360d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int packet_parse(const void *data, size_t packet_len, ArpPacketInfo *info) { 23460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering const uint8_t *p = data; 23560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(data); 23760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (packet_len < ARP_PACKET_SIZE) 23960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 24060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 24160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Check HTYPE and PTYPE */ 24260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (p[0] != 0 || p[1] != 1 || p[2] != 8 || p[3] != 0) 24360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 24460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 24560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Check HLEN, PLEN, OPERATION */ 24660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (p[4] != ETHER_ADDRLEN || p[5] != 4 || p[6] != 0 || (p[7] != 1 && p[7] != 2)) 24760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 24860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 24960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info->operation = p[7]; 25060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info->sender_hw_address, p+8, ETHER_ADDRLEN); 25160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(&info->sender_ip_address, p+14, 4); 25260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info->target_hw_address, p+18, ETHER_ADDRLEN); 25360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(&info->target_ip_address, p+24, 4); 25460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 25560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 25660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 25760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 2585ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic void set_state(State st, int reset_counter, uint32_t address) { 2597bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering static const char* const state_table[] = { 26012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering [STATE_START] = "START", 26160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_WAITING_PROBE] = "WAITING_PROBE", 26260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_PROBING] = "PROBING", 26360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_WAITING_ANNOUNCE] = "WAITING_ANNOUNCE", 26460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_ANNOUNCING] = "ANNOUNCING", 26560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_RUNNING] = "RUNNING", 26660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_SLEEPING] = "SLEEPING" 26760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering }; 2685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering char buf[64]; 26960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 27060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(st < STATE_MAX); 27160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 27260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (st == state && !reset_counter) { 27360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_iteration++; 2745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "State iteration %s-%i", state_table[state], n_iteration)); 27560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else { 2765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "State transition %s-%i -> %s-0", state_table[state], n_iteration, state_table[st])); 27760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering state = st; 27860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_iteration = 0; 27960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 28060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 2815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (modify_proc_title) { 2825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (state == STATE_SLEEPING) 283287f9866c923e6afe8ffbbc03b90be64acf395e1Lennart Poettering avahi_set_proc_title(argv0, "%s: [%s] sleeping", argv0, interface_name); 2845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else if (state == STATE_ANNOUNCING) 285287f9866c923e6afe8ffbbc03b90be64acf395e1Lennart Poettering avahi_set_proc_title(argv0, "%s: [%s] announcing %s", argv0, interface_name, inet_ntop(AF_INET, &address, buf, sizeof(buf))); 2865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else if (state == STATE_RUNNING) 287287f9866c923e6afe8ffbbc03b90be64acf395e1Lennart Poettering avahi_set_proc_title(argv0, "%s: [%s] bound %s", argv0, interface_name, inet_ntop(AF_INET, &address, buf, sizeof(buf))); 2885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else 289287f9866c923e6afe8ffbbc03b90be64acf395e1Lennart Poettering avahi_set_proc_title(argv0, "%s: [%s] probing %s", argv0, interface_name, inet_ntop(AF_INET, &address, buf, sizeof(buf))); 2905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 29160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 29260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 29325ae811f3393baed4930f30278a7595dd8122dfbLennart Poetteringstatic int interface_up(int iface) { 29425ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering int fd = -1; 29525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering struct ifreq ifreq; 29625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 29725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 29825ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno)); 29925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering goto fail; 30025ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering } 30125ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 30225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering memset(&ifreq, 0, sizeof(ifreq)); 30325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (!if_indextoname(iface, ifreq.ifr_name)) { 30425ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering daemon_log(LOG_ERR, "if_indextoname() failed: %s", strerror(errno)); 30525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering goto fail; 30625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering } 30725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 30825ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (ioctl(fd, SIOCGIFFLAGS, &ifreq) < 0) { 30925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering daemon_log(LOG_ERR, "SIOCGIFFLAGS failed: %s", strerror(errno)); 31025ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering goto fail; 31125ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering } 31225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 31325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering ifreq.ifr_flags |= IFF_UP; 31425ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 31525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (ioctl(fd, SIOCSIFFLAGS, &ifreq) < 0) { 31625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering daemon_log(LOG_ERR, "SIOCSIFFLAGS failed: %s", strerror(errno)); 31725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering goto fail; 31825ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering } 31925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 32025ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering close(fd); 32125ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 32225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering return 0; 32325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 32425ae811f3393baed4930f30278a7595dd8122dfbLennart Poetteringfail: 32525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (fd >= 0) 32625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering close(fd); 32725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 32825ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering return -1; 32925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering} 33025ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 33160d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int open_socket(int iface, uint8_t *hw_address) { 33260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd = -1; 33360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 33460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering socklen_t sa_len; 33525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 33625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (interface_up(iface) < 0) 33725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering goto fail; 33860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 33960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) < 0) { 34060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno)); 34160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 34260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 34360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 34460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&sa, 0, sizeof(sa)); 34560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_family = AF_PACKET; 34660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_protocol = htons(ETH_P_ARP); 34760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_ifindex = iface; 34825ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 34960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 35060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "bind() failed: %s", strerror(errno)); 35160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 35260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 35325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 35460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa_len = sizeof(sa); 35560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (getsockname(fd, (struct sockaddr*) &sa, &sa_len) < 0) { 35660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "getsockname() failed: %s", strerror(errno)); 35760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 35860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 35925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 36060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (sa.sll_halen != ETHER_ADDRLEN) { 36160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "getsockname() returned invalid hardware address."); 36260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 36360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 36460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 36560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(hw_address, sa.sll_addr, ETHER_ADDRLEN); 36660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 36760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return fd; 36860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 36960d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 37060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (fd >= 0) 37160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 37260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 37360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 37460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 37560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 37660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int send_packet(int fd, int iface, void *packet, size_t packet_len) { 37760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 37860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 37960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(fd >= 0); 38060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet); 38160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len > 0); 38260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 38360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&sa, 0, sizeof(sa)); 38460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_family = AF_PACKET; 38560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_protocol = htons(ETH_P_ARP); 38660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_ifindex = iface; 38760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_halen = ETHER_ADDRLEN; 38860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(sa.sll_addr, 0xFF, ETHER_ADDRLEN); 38960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 39060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (sendto(fd, packet, packet_len, 0, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 39160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "sendto() failed: %s", strerror(errno)); 39260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 39360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 39460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 39560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 39660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 39760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 39860d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int recv_packet(int fd, void **packet, size_t *packet_len) { 39960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int s; 40060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 40160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering socklen_t sa_len; 40225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering ssize_t r; 40360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(fd >= 0); 40560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet); 40660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len); 40760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet = NULL; 40960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 41060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (ioctl(fd, FIONREAD, &s) < 0) { 41160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "FIONREAD failed: %s", strerror(errno)); 41260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 41360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 41460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 41525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (s <= 0) 41625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering s = 4096; 41760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 41860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet = avahi_new(uint8_t, s); 41960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 42060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa_len = sizeof(sa); 42125ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if ((r = recvfrom(fd, *packet, s, 0, (struct sockaddr*) &sa, &sa_len)) < 0) { 42260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "recvfrom() failed: %s", strerror(errno)); 42360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 42460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 42560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 42625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering *packet_len = (size_t) r; 42725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 42860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 42960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 43060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 43125ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (*packet) { 43260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(*packet); 43325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering *packet = NULL; 43425ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering } 43560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 43660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 43760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 43860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 43912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poetteringint is_ll_address(uint32_t addr) { 44060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return (ntohl(addr) & IPV4LL_NETMASK) == IPV4LL_NETWORK; 44160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 44260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 44360d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic struct timeval *elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) { 44460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(tv); 44560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 44660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering gettimeofday(tv, NULL); 44760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 44860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (msec) 44960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_timeval_add(tv, (AvahiUsec) msec*1000); 45060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 45160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (jitter) 45260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0))); 45360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 45460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return tv; 45560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 45660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 4577bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poetteringstatic FILE* fork_dispatcher(void) { 4587bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering FILE *ret; 4597bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering int fds[2]; 4607bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering pid_t pid; 4617bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4627bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (pipe(fds) < 0) { 4637bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno)); 4647bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto fail; 4657bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 4667bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4677bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if ((pid = fork()) < 0) 4687bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto fail; 4697bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering else if (pid == 0) { 4707bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering FILE *f = NULL; 4717bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering int r = 1; 4727bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4737bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering /* Please note that the signal pipe is not closed at this 4747bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering * point, signals will thus be dispatched in the main 4757bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering * process. */ 4767bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4777bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_retval_done(); 4787bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4797bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering setsid(); 4807bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 481287f9866c923e6afe8ffbbc03b90be64acf395e1Lennart Poettering avahi_set_proc_title(argv0, "%s: [%s] callout dispatcher", argv0, interface_name); 4827bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4837bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering close(fds[1]); 4847bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4857bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (!(f = fdopen(fds[0], "r"))) { 4867bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_ERR, "fdopen() failed: %s", strerror(errno)); 4877bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto dispatcher_fail; 4887bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 4897bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4907bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering for (;;) { 4917bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering CalloutEventInfo info; 4927bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering char name[IFNAMSIZ], buf[64]; 4937bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering int k; 4947bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4957bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (fread(&info, sizeof(info), 1, f) != 1) { 4967bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (feof(f)) 4977bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering break; 4987bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 4997bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_ERR, "fread() failed: %s", strerror(errno)); 5007bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto dispatcher_fail; 5017bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 5027bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5037bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering assert(info.event <= CALLOUT_MAX); 5047bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5057bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (!if_indextoname(info.ifindex, name)) { 5067bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_ERR, "if_indextoname() failed: %s", strerror(errno)); 5077bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering continue; 5087bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 5097bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5107bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (daemon_exec("/", &k, 5117bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering AVAHI_IPCONF_SCRIPT, AVAHI_IPCONF_SCRIPT, 5127bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering callout_event_table[info.event], 5137bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering name, 5147bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering inet_ntop(AF_INET, &info.address, buf, sizeof(buf)), NULL) < 0) { 5157bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5167bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_ERR, "Failed to run script: %s", strerror(errno)); 5177bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering continue; 5187bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 5197bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5207bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (k != 0) 5217bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_WARNING, "Script execution failed with return value %i", k); 5227bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 5237bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5247bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering r = 0; 5257bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5267bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering dispatcher_fail: 5277bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5287bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (f) 5297bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering fclose(f); 5307bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5317bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering _exit(r); 5327bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 5337bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5347bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering /* parent */ 5357bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5367bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering close(fds[0]); 5377bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering fds[0] = -1; 5387bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5397bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (!(ret = fdopen(fds[1], "w"))) { 5407bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_ERR, "fdopen() failed: %s", strerror(errno)); 5417bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto fail; 5427bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 5437bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5447bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering return ret; 5457bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5467bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poetteringfail: 5477bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (fds[0] >= 0) 5487bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering close(fds[0]); 5497bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (fds[1] >= 0) 5507bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering close(fds[1]); 5517bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5527bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering return NULL; 5537bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering} 5547bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5557bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poetteringstatic int do_callout(FILE *f, CalloutEvent event, int iface, uint32_t addr) { 5567bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering CalloutEventInfo info; 5577bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering char buf[64], ifname[IFNAMSIZ]; 5587bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5597bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_INFO, "Callout %s, address %s on interface %s", 5607bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering callout_event_table[event], 5617bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering inet_ntop(AF_INET, &addr, buf, sizeof(buf)), 5627bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if_indextoname(iface, ifname)); 5637bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5647bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering info.event = event; 5657bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering info.ifindex = iface; 5667bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering info.address = addr; 5677bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5687bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (fwrite(&info, sizeof(info), 1, f) != 1 || fflush(f) != 0) { 5697bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering daemon_log(LOG_ERR, "Failed to write callout event: %s", strerror(errno)); 5707bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering return -1; 5717bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering } 5727bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 5737bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering return 0; 5747bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering} 5757bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 57660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int loop(int iface, uint32_t addr) { 57712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering enum { 57812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering FD_ARP, 57912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering FD_IFACE, 5805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering FD_SIGNAL, 5815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering FD_MAX, 58212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering }; 58312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 58460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd = -1, ret = -1; 58560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct timeval next_wakeup; 58660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int next_wakeup_valid = 0; 58760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering char buf[64]; 58860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering void *in_packet = NULL; 58960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering size_t in_packet_len; 59060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering void *out_packet = NULL; 59160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering size_t out_packet_len; 59260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t hw_address[ETHER_ADDRLEN]; 59312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering struct pollfd pollfds[FD_MAX]; 59412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering int iface_fd; 59512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering Event event = EVENT_NULL; 5965ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int retval_sent = !daemonize; 5975ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering State st; 5987bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering FILE *dispatcher = NULL; 5995ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_signal_init(SIGINT, SIGTERM, SIGCHLD, SIGHUP,0); 60160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 6027bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (!(dispatcher = fork_dispatcher())) 6037bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto fail; 6047bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 60560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = open_socket(iface, hw_address)) < 0) 60660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 60760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 60812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if ((iface_fd = iface_init(iface)) < 0) 60912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 61012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 6117bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering/* if (drop_privs() < 0) */ 6127bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering/* goto fail; */ 6137bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 6145b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering if (force_bind) 6155b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering st = STATE_START; 6165b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering else if (iface_get_initial_state(&st) < 0) 61712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 6185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 61960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (addr && !is_ll_address(addr)) { 62060d86f779725e78ae3d295380f15208859cc06ebLennart 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))); 62160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = 0; 62260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 62360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (!addr) { 62560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int i; 62660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t a = 1; 62760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering for (i = 0; i < ETHER_ADDRLEN; i++) 62960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering a += hw_address[i]*i; 63060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 63160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = htonl(IPV4LL_NETWORK | (uint32_t) a); 63260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 63360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 6345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(st, 1, addr); 6355ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 63660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Starting with address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 63760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 63812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_SLEEPING) 63912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "Routable address already assigned, sleeping."); 64012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 6415ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (!retval_sent && (!wait_for_address || state == STATE_SLEEPING)) { 6425ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(0); 6435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering retval_sent = 1; 6445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 6455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 64660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(pollfds, 0, sizeof(pollfds)); 64712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_ARP].fd = fd; 64812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_ARP].events = POLLIN; 64912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].fd = iface_fd; 65012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].events = POLLIN; 6515ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pollfds[FD_SIGNAL].fd = daemon_signal_fd(); 6525ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pollfds[FD_SIGNAL].events = POLLIN; 65360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering for (;;) { 65560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int r, timeout; 65660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering AvahiUsec usec; 65760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_START) { 65960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 66060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* First, wait a random time */ 6615ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_PROBE, 1, addr); 66260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 66360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 66460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 66560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 66660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_WAITING_PROBE && event == EVENT_TIMEOUT) || 66760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration < PROBE_NUM-2)) { 66860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 66960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send a probe */ 67060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 6715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_PROBING, 0, addr); 67260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 67360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, PROBE_MIN*1000, (PROBE_MAX-PROBE_MIN)*1000); 67460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 67560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 67660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration >= PROBE_NUM-2) { 67760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 67860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send the last probe */ 67960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 6805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_ANNOUNCE, 1, addr); 68160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 68260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_WAIT*1000, 0); 68360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 68460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 68560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_WAITING_ANNOUNCE && event == EVENT_TIMEOUT) || 68660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering (state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration < ANNOUNCE_NUM-1)) { 68760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 68860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send announcement packet */ 68960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_announcement(addr, hw_address, &out_packet_len); 6905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_ANNOUNCING, 0, addr); 69160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 69260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0); 69360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 69460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 69560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (n_iteration == 0) { 6967bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (do_callout(dispatcher, CALLOUT_BIND, iface, addr) < 0) 6977bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto fail; 6987bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 69960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_conflict = 0; 7005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7015ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (!retval_sent) { 7025ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(0); 7035ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering retval_sent = 1; 7045ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 70560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 70660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 70760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration >= ANNOUNCE_NUM-1)) { 70860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 70960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Successfully claimed IP address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 7105ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_RUNNING, 0, addr); 711fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering 712fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering next_wakeup_valid = 0; 71360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 71460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (event == EVENT_PACKET) { 71560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 71660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 71760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(in_packet); 71860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 71960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (packet_parse(in_packet, in_packet_len, &info) < 0) 72060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_WARNING, "Failed to parse incoming ARP packet."); 72160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering else { 72260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int conflict = 0; 72360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 72460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (info.sender_ip_address == addr) { 72560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Normal conflict */ 72660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering conflict = 1; 72760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Recieved conflicting normal ARP packet."); 72860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (state == STATE_WAITING_PROBE || state == STATE_PROBING || state == STATE_WAITING_ANNOUNCE) { 72960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Probe conflict */ 73060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering conflict = info.target_ip_address == addr && memcmp(hw_address, info.sender_hw_address, ETHER_ADDRLEN); 73160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Recieved conflicting probe ARP packet."); 73260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 73360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 73460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (conflict) { 73560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 73660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 7377bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (do_callout(dispatcher, CALLOUT_CONFLICT, iface, addr) < 0) 7387bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto fail; 73960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 74060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Pick a new address */ 74160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = pick_addr(addr); 74260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 74360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Trying address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 74460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 74560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_conflict++; 74660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 7475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_PROBE, 1, addr); 74812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 74960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (n_conflict >= MAX_CONFLICTS) { 75060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_WARNING, "Got too many conflicts, rate limiting new probes."); 75160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, RATE_LIMIT_INTERVAL*1000, PROBE_WAIT*1000); 75260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else 75360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 75460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 75560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 75660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else 7575ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "Ignoring irrelevant ARP packet.")); 75860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 75912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 76012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } else if (event == EVENT_ROUTABLE_ADDR_CONFIGURED) { 76112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 76212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "A routable address has been configured."); 76312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 76412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 7657bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (do_callout(dispatcher, CALLOUT_UNBIND, iface, addr) < 0) 7667bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering goto fail; 767fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering 7685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (!retval_sent) { 7695ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(0); 7705ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering retval_sent = 1; 7715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 7725ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_SLEEPING, 1, addr); 774fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering next_wakeup_valid = 0; 77512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 7765b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering } else if (event == EVENT_ROUTABLE_ADDR_UNCONFIGURED && state == STATE_SLEEPING && !force_bind) { 77712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 77812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "No longer a routable address configured, restarting probe process."); 77912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 7805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_PROBE, 1, addr); 78112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 78212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 78312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering next_wakeup_valid = 1; 7845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7855b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering } else if (event == EVENT_REFRESH_REQUEST && state == STATE_RUNNING && !force_bind) { 7865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /* The user requested a reannouncing of the address by a SIGHUP */ 7885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_INFO, "Reannouncing address."); 78912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 7905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /* Send announcement packet */ 7915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering out_packet = packet_new_announcement(addr, hw_address, &out_packet_len); 7925ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_ANNOUNCING, 1, addr); 7935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0); 7955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering next_wakeup_valid = 1; 79660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 79760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 79860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (out_packet) { 7995ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "sending...")); 80060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 80160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (send_packet(fd, iface, out_packet, out_packet_len) < 0) 80260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 80360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 80460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(out_packet); 80560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = NULL; 80660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 80760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 80860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (in_packet) { 80960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(in_packet); 81060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering in_packet = NULL; 81160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 81260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 81312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering event = EVENT_NULL; 81460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering timeout = -1; 81560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 81660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (next_wakeup_valid) { 81760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering usec = avahi_age(&next_wakeup); 81860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering timeout = usec < 0 ? (int) (-usec/1000) : 0; 81960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 82060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8215ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "sleeping %ims", timeout)); 82260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 82312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering while ((r = poll(pollfds, FD_MAX, timeout)) < 0 && errno == EINTR) 82460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ; 82560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 82660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (r < 0) { 82760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "poll() failed: %s", strerror(r)); 8285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto fail; 82960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (r == 0) { 83060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering event = EVENT_TIMEOUT; 83160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 0; 83260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else { 83325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 83425ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 83525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (pollfds[FD_ARP].revents) { 83660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 83725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (pollfds[FD_ARP].revents == POLLERR) { 83825ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering /* The interface is probably down, let's recreate our socket */ 83925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 84025ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering close(fd); 84125ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 84225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if ((fd = open_socket(iface, hw_address)) < 0) 84325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering goto fail; 84425ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 84525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering pollfds[FD_ARP].fd = fd; 84625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 84725ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering } else { 84812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 84925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering assert(pollfds[FD_ARP].revents == POLLIN); 85025ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 85125ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (recv_packet(fd, &in_packet, &in_packet_len) < 0) 85225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering goto fail; 85325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 85425ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering if (in_packet) 85525ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering event = EVENT_PACKET; 85625ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering } 85712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } 85860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 85912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (event == EVENT_NULL && 86025ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering pollfds[FD_IFACE].revents) { 86112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 86225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering assert(pollfds[FD_IFACE].revents == POLLIN); 86325ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering 86412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (iface_process(&event) < 0) 86512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 86612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } 8675ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (event == EVENT_NULL && 86925ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering pollfds[FD_SIGNAL].revents) { 8705ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int sig; 87225ae811f3393baed4930f30278a7595dd8122dfbLennart Poettering assert(pollfds[FD_SIGNAL].revents == POLLIN); 8735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((sig = daemon_signal_next()) <= 0) { 8755ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "daemon_signal_next() failed"); 8765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto fail; 8775ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8785ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8795ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering switch(sig) { 8805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGINT: 8815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGTERM: 8825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_INFO, "Got %s, quitting.", sig == SIGINT ? "SIGINT" : "SIGTERM"); 8835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering ret = 0; 8845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto fail; 8855ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGCHLD: 8875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering waitpid(-1, NULL, WNOHANG); 8885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 8895ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGHUP: 8915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering event = EVENT_REFRESH_REQUEST; 8925ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 8935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 89660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 89760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 89860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 89960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ret = 0; 90060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 90160d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 90260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9035ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 9047bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering do_callout(dispatcher, CALLOUT_STOP, iface, addr); 9055ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 90660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(out_packet); 90760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(in_packet); 90860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 90960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (fd >= 0) 91060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 91112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 91212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (iface_fd >= 0) 91312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering iface_done(); 9145ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9155ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize && !retval_sent) 9165ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(ret); 9177bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 9187bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering if (dispatcher) 9197bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering fclose(dispatcher); 92060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 92160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return ret; 92260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 92360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 92460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic void help(FILE *f, const char *a0) { 9265ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(f, 9275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering "%s [options] INTERFACE\n" 9285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -h --help Show this help\n" 9295ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -D --daemonize Daemonize after startup\n" 9305ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -s --syslog Write log messages to syslog(3) instead of STDERR\n" 9315ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -k --kill Kill a running daemon\n" 9325ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -r --refresh Request a running daemon to refresh it's IP address\n" 9335ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -c --check Return 0 if a daemon is already running\n" 9345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -V --version Show version\n" 9355b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering " -S --start=ADDRESS Start with this address from the IPv4LL range\n" 9365b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering " 169.254.0.0/16\n" 9375b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering " -w --wait Wait until an address has been acquired before\n" 9385b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering " daemonizing\n" 9395ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " --no-proc-title Don't modify process title\n" 9405b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering " --force-bind Assign an IPv4LL address even if routable address\n" 9415b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering " is already assigned\n" 9425ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " --debug Increase verbosity\n", 9435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering a0); 9445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} 9455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9465ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int parse_command_line(int argc, char *argv[]) { 9475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int c; 9485ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9495ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering enum { 9505ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering OPTION_NO_PROC_TITLE = 256, 9515b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering OPTION_FORCE_BIND, 9525ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering OPTION_DEBUG 9535ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering }; 9545ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9555ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering static const struct option long_options[] = { 9565ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "help", no_argument, NULL, 'h' }, 9575ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "daemonize", no_argument, NULL, 'D' }, 9585ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "syslog", no_argument, NULL, 's' }, 9595ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "kill", no_argument, NULL, 'k' }, 9605ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "refresh", no_argument, NULL, 'r' }, 9615ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "check", no_argument, NULL, 'c' }, 9625ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "version", no_argument, NULL, 'V' }, 9635ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "start", required_argument, NULL, 'S' }, 9645ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "wait", no_argument, NULL, 'w' }, 9655ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "no-proc-title", no_argument, NULL, OPTION_NO_PROC_TITLE }, 9665b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering { "force-bind", no_argument, NULL, OPTION_FORCE_BIND }, 9675ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "debug", no_argument, NULL, OPTION_DEBUG }, 9685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { NULL, 0, NULL, 0 } 9695ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering }; 97060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering opterr = 0; 9729d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering while ((c = getopt_long(argc, argv, "hDskrcVS:w", long_options, NULL)) >= 0) { 9735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering switch(c) { 9755ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 's': 9765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering use_syslog = 1; 9775ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 9785ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'h': 9795ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_HELP; 9805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 9815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'D': 9825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemonize = 1; 9835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 9845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'k': 9855ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_KILL; 9865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 9875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'V': 9885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_VERSION; 9895ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 9905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'r': 9915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_REFRESH; 9925ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 9935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'c': 9945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_CHECK; 9955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 9965ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'S': 9975ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9985ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((start_address = inet_addr(optarg)) == (uint32_t) -1) { 9995ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Failed to parse IP address '%s'.", optarg); 10005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 10015ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 10025ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 10035ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'w': 10045ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering wait_for_address = 1; 10055ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 10065ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10075ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case OPTION_NO_PROC_TITLE: 10085ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering modify_proc_title = 0; 10095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 101060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10115ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case OPTION_DEBUG: 10125ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering debug = 1; 10135ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 10145ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10155b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering case OPTION_FORCE_BIND: 10165b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering force_bind = 1; 10175b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering break; 10185b67d0bbb21412bcdf7a271ddf34823f8776dc06Lennart Poettering 10195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering default: 10205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Invalid command line argument: %c\n", c); 10215ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 10225ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 102360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 102460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (command == DAEMON_RUN || 10265ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command == DAEMON_KILL || 10275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command == DAEMON_REFRESH || 10285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command == DAEMON_CHECK) { 102960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10305ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (optind >= argc) { 10315ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Missing interface name.\n"); 10325ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 10335ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 103460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10359d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering interface_name = avahi_strdup(argv[optind++]); 10365ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 10375ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10385ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (optind != argc) { 10395ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Too many arguments\n"); 10405ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 10415ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 10425ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return 0; 10445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} 10455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10465ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic const char* pid_file_proc(void) { 10475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return pid_file_name; 104860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 104960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 105060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringint main(int argc, char*argv[]) { 10515ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int r = 1; 10525ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int wrote_pid_file = 0; 10539d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering char *log_ident = NULL; 105460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 105512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering avahi_init_proc_title(argc, argv); 105660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10577bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering signal(SIGPIPE, SIG_IGN); 10587bf6b7b95b7c3327000794a24e104242598a9f3fLennart Poettering 10595ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((argv0 = strrchr(argv[0], '/'))) 10605ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering argv0++; 10615ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else 10625ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering argv0 = argv[0]; 106360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10649d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering argv0 = avahi_strdup(argv0); 10659d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering 10669d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering daemon_log_ident = argv0; 106760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (parse_command_line(argc, argv) < 0) 10695ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 107060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 10719d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering daemon_log_ident = log_ident = avahi_strdup_printf("%s(%s)", argv0, interface_name); 10729d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering daemon_pid_file_proc = pid_file_proc; 10735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pid_file_name = avahi_strdup_printf(AVAHI_RUNTIME_DIR"/avahi-autoipd.%s.pid", interface_name); 10745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10755ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (command == DAEMON_RUN) { 10765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pid_t pid; 10775ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int ifindex; 10785ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10795ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering init_rand_seed(); 10805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((ifindex = if_nametoindex(interface_name)) <= 0) { 10825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Failed to get index for interface name '%s': %s", interface_name, strerror(errno)); 10835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 10845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 10855ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (getuid() != 0) { 10875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "This program is intended to be run as root."); 10885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 10895ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 10905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((pid = daemon_pid_file_is_running()) >= 0) { 10925ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Daemon already running on PID %u", pid); 10935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 10945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 10955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10965ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize) { 10975ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_init(); 10985ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 10995ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((pid = daemon_fork()) < 0) 11005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 11015ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else if (pid != 0) { 11025ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int ret; 11035ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /** Parent **/ 11045ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11055ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((ret = daemon_retval_wait(20)) < 0) { 11065ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Could not receive return value from daemon process."); 11075ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 11085ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 11095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11105ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = ret; 11115ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 11125ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 11135ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11145ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /* Child */ 11155ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 11165ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11175ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (use_syslog || daemonize) 11185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log_use = DAEMON_LOG_SYSLOG; 11195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering chdir("/"); 11215ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11225ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemon_pid_file_create() < 0) { 11235ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Failed to create PID file: %s", strerror(errno)); 11245ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize) 11265ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(1); 11275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 11285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else 11295ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering wrote_pid_file = 1; 11305ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 1131287f9866c923e6afe8ffbbc03b90be64acf395e1Lennart Poettering avahi_set_proc_title(argv0, "%s: [%s] starting up", argv0, interface_name); 11329d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering 11335ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (loop(ifindex, start_address) < 0) 11345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 11355ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11365ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 11375ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_HELP) { 11385ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering help(stdout, argv0); 11395ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11405ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 11415ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_VERSION) { 11425ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering printf("%s "PACKAGE_VERSION"\n", argv0); 11435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 11455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_KILL) { 11465ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) { 11475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno)); 11485ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 11495ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 11505ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11515ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 11525ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_REFRESH) { 11535ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemon_pid_file_kill(SIGHUP) < 0) { 11545ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno)); 11555ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 11565ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 11575ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11585ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 11595ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_CHECK) 11605ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = (daemon_pid_file_is_running() >= 0) ? 0 : 1; 11615ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11625ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11635ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringfinish: 11645ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11655ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize) 11665ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_done(); 116760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 11685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (wrote_pid_file) 11695ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_pid_file_remove(); 11705ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 11719d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering avahi_free(log_ident); 11729d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering avahi_free(pid_file_name); 11739d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering avahi_free(argv0); 11749d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering avahi_free(interface_name); 11759d709a294b81066a0942a7a642df1b3d4940ad26Lennart Poettering 11765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return r; 117760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 117860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 117960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* TODO: 118060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 118160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- chroot/drop privs/caps 118260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- store last used address 11835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering- man page 118460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 118560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering*/ 1186