main.c revision 5ea98f8caf0e163ad1f51039b8a2d13e3fe0e86c
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; 1115ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 1125ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic enum { 1135ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_RUN, 1145ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_KILL, 1155ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_REFRESH, 1165ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_VERSION, 1175ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_HELP, 1185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DAEMON_CHECK 1195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} command = DAEMON_RUN; 1205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 1215ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringtypedef enum CalloutEvent { 1225ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_BIND, 1235ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_CONFLICT, 1245ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_UNBIND, 1255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_STOP, 1265ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering CALLOUT_MAX 1275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} CalloutEvent; 1285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 12960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering#define RANDOM_DEVICE "/dev/urandom" 13060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 1315ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering#define DEBUG(x) do {\ 1325ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringif (debug) { \ 1335ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering x; \ 1345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} \ 1355ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} while (0) 1365ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 13760d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void init_rand_seed(void) { 13860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd; 13960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering unsigned seed = 0; 14060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 14160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Try to initialize seed from /dev/urandom, to make it a little 14260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering * less predictable, and to make sure that multiple machines 14360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering * booted at the same time choose different random seeds. */ 14460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) { 14560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering read(fd, &seed, sizeof(seed)); 14660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 14760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 14860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 14960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* If the initialization failed by some reason, we add the time to the seed */ 15060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering seed ^= (unsigned) time(NULL); 15160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 15260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering srand(seed); 15360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 15460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 15560d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic uint32_t pick_addr(uint32_t old_addr) { 15660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t addr; 15760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 15860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering do { 15960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering unsigned r = (unsigned) rand(); 16060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Reduce to 16 bits */ 16260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering while (r > 0xFFFF) 16360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r = (r >> 16) ^ (r & 0xFFFF); 16460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = htonl(IPV4LL_NETWORK | (uint32_t) r); 16660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } while (addr == old_addr); 16860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 16960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return addr; 17060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 17160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17260d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void* packet_new(const ArpPacketInfo *info, size_t *packet_len) { 17360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t *r; 17460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(info); 17660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len); 17760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(info->operation == ARP_REQUEST || info->operation == ARP_RESPONSE); 17860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 17960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet_len = ARP_PACKET_SIZE; 18060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r = avahi_new0(uint8_t, *packet_len); 18160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[1] = 1; /* HTYPE */ 18360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[2] = 8; /* PTYPE */ 18460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[4] = ETHER_ADDRLEN; /* HLEN */ 18560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[5] = 4; /* PLEN */ 18660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering r[7] = (uint8_t) info->operation; 18760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 18860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+8, info->sender_hw_address, ETHER_ADDRLEN); 18960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+14, &info->sender_ip_address, 4); 19060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+18, info->target_hw_address, ETHER_ADDRLEN); 19160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(r+24, &info->target_ip_address, 4); 19260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return r; 19460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 19560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void *packet_new_probe(uint32_t ip_address, const uint8_t*hw_address, size_t *packet_len) { 19760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 19860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 19960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&info, 0, sizeof(info)); 20060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.operation = ARP_REQUEST; 20160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN); 20260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.target_ip_address = ip_address; 20360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 20460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return packet_new(&info, packet_len); 20560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 20660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 20760d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic void *packet_new_announcement(uint32_t ip_address, const uint8_t* hw_address, size_t *packet_len) { 20860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 20960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 21060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&info, 0, sizeof(info)); 21160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.operation = ARP_REQUEST; 21260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN); 21360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.target_ip_address = ip_address; 21460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info.sender_ip_address = ip_address; 21560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 21660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return packet_new(&info, packet_len); 21760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 21860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 21960d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int packet_parse(const void *data, size_t packet_len, ArpPacketInfo *info) { 22060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering const uint8_t *p = data; 22160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 22260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(data); 22360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 22460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (packet_len < ARP_PACKET_SIZE) 22560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 22660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 22760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Check HTYPE and PTYPE */ 22860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (p[0] != 0 || p[1] != 1 || p[2] != 8 || p[3] != 0) 22960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 23060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Check HLEN, PLEN, OPERATION */ 23260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (p[4] != ETHER_ADDRLEN || p[5] != 4 || p[6] != 0 || (p[7] != 1 && p[7] != 2)) 23360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 23460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 23560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering info->operation = p[7]; 23660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info->sender_hw_address, p+8, ETHER_ADDRLEN); 23760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(&info->sender_ip_address, p+14, 4); 23860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(info->target_hw_address, p+18, ETHER_ADDRLEN); 23960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(&info->target_ip_address, p+24, 4); 24060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 24160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 24260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 24360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 2445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic void set_state(State st, int reset_counter, uint32_t address) { 24560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering const char* const state_table[] = { 24612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering [STATE_START] = "START", 24760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_WAITING_PROBE] = "WAITING_PROBE", 24860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_PROBING] = "PROBING", 24960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_WAITING_ANNOUNCE] = "WAITING_ANNOUNCE", 25060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_ANNOUNCING] = "ANNOUNCING", 25160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_RUNNING] = "RUNNING", 25260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering [STATE_SLEEPING] = "SLEEPING" 25360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering }; 2545ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering char buf[64]; 25560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 25660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(st < STATE_MAX); 25760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 25860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (st == state && !reset_counter) { 25960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_iteration++; 2605ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "State iteration %s-%i", state_table[state], n_iteration)); 26160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else { 2625ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "State transition %s-%i -> %s-0", state_table[state], n_iteration, state_table[st])); 26360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering state = st; 26460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_iteration = 0; 26560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 26660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 2675ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (modify_proc_title) { 2685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (state == STATE_SLEEPING) 2695ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering avahi_set_proc_title("%s: sleeping", argv0); 2705ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else if (state == STATE_ANNOUNCING) 2715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering avahi_set_proc_title("%s: announcing %s", argv0, inet_ntop(AF_INET, &address, buf, sizeof(buf))); 2725ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else if (state == STATE_RUNNING) 2735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering avahi_set_proc_title("%s: bound %s", argv0, inet_ntop(AF_INET, &address, buf, sizeof(buf))); 2745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else 2755ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering avahi_set_proc_title("%s: probing %s", argv0, inet_ntop(AF_INET, &address, buf, sizeof(buf))); 2765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 27760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 27860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 2795ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int do_callout(CalloutEvent event, int iface, uint32_t addr) { 2805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering char buf[64], ifname[IFNAMSIZ]; 2815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering const char * const event_table[CALLOUT_MAX] = { 2825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering [CALLOUT_BIND] = "BIND", 2835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering [CALLOUT_CONFLICT] = "CONFLICT", 2845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering [CALLOUT_UNBIND] = "UNBIND", 2855ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering [CALLOUT_STOP] = "STOP" 2865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering }; 2875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 2885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_INFO, "Callout %s, address %s on interface %s", 2895ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering event_table[event], 2905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering inet_ntop(AF_INET, &addr, buf, sizeof(buf)), 2915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if_indextoname(iface, ifname)); 29260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 29360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 29460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 29560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 29660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int open_socket(int iface, uint8_t *hw_address) { 29760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd = -1; 29860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 29960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering socklen_t sa_len; 30060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 30160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) < 0) { 30260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno)); 30360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 30460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 30560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 30660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&sa, 0, sizeof(sa)); 30760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_family = AF_PACKET; 30860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_protocol = htons(ETH_P_ARP); 30960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_ifindex = iface; 31060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 31160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 31260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "bind() failed: %s", strerror(errno)); 31360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 31460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 31560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 31660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa_len = sizeof(sa); 31760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (getsockname(fd, (struct sockaddr*) &sa, &sa_len) < 0) { 31860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "getsockname() failed: %s", strerror(errno)); 31960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 32060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 32160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 32260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (sa.sll_halen != ETHER_ADDRLEN) { 32360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "getsockname() returned invalid hardware address."); 32460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 32560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 32660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 32760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memcpy(hw_address, sa.sll_addr, ETHER_ADDRLEN); 32860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 32960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return fd; 33060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 33160d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 33260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (fd >= 0) 33360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 33460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 33560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 33660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 33760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 33860d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int send_packet(int fd, int iface, void *packet, size_t packet_len) { 33960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 34060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 34160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(fd >= 0); 34260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet); 34360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len > 0); 34460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 34560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(&sa, 0, sizeof(sa)); 34660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_family = AF_PACKET; 34760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_protocol = htons(ETH_P_ARP); 34860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_ifindex = iface; 34960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa.sll_halen = ETHER_ADDRLEN; 35060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(sa.sll_addr, 0xFF, ETHER_ADDRLEN); 35160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 35260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (sendto(fd, packet, packet_len, 0, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 35360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "sendto() failed: %s", strerror(errno)); 35460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 35560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 35660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 35760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 35860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 35960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 36060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int recv_packet(int fd, void **packet, size_t *packet_len) { 36160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int s; 36260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct sockaddr_ll sa; 36360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering socklen_t sa_len; 36460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 36560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(fd >= 0); 36660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet); 36760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(packet_len); 36860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 36960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet = NULL; 37060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 37160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (ioctl(fd, FIONREAD, &s) < 0) { 37260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "FIONREAD failed: %s", strerror(errno)); 37360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 37460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 37560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 37660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(s > 0); 37760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 37860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet_len = (size_t) s; 37960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering *packet = avahi_new(uint8_t, s); 38060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 38160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering sa_len = sizeof(sa); 38260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (recvfrom(fd, *packet, s, 0, (struct sockaddr*) &sa, &sa_len) < 0) { 38360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "recvfrom() failed: %s", strerror(errno)); 38460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 38560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 38660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 38760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return 0; 38860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 38960d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 39060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (*packet) 39160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(*packet); 39260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 39360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return -1; 39460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 39560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 39612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poetteringint is_ll_address(uint32_t addr) { 39760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return (ntohl(addr) & IPV4LL_NETMASK) == IPV4LL_NETWORK; 39860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 39960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40060d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic struct timeval *elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) { 40160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(tv); 40260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering gettimeofday(tv, NULL); 40460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (msec) 40660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_timeval_add(tv, (AvahiUsec) msec*1000); 40760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 40860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (jitter) 40960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0))); 41060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 41160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return tv; 41260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 41360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 41460d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringstatic int loop(int iface, uint32_t addr) { 41512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering enum { 41612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering FD_ARP, 41712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering FD_IFACE, 4185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering FD_SIGNAL, 4195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering FD_MAX, 42012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering }; 42112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 42260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int fd = -1, ret = -1; 42360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering struct timeval next_wakeup; 42460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int next_wakeup_valid = 0; 42560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering char buf[64]; 42660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering void *in_packet = NULL; 42760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering size_t in_packet_len; 42860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering void *out_packet = NULL; 42960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering size_t out_packet_len; 43060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint8_t hw_address[ETHER_ADDRLEN]; 43112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering struct pollfd pollfds[FD_MAX]; 43212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering int iface_fd; 43312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering Event event = EVENT_NULL; 4345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int retval_sent = !daemonize; 4355ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering State st; 4365ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 4375ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_signal_init(SIGINT, SIGTERM, SIGCHLD, SIGHUP,0); 43860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 43960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if ((fd = open_socket(iface, hw_address)) < 0) 44060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 44160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 44212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if ((iface_fd = iface_init(iface)) < 0) 44312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 44412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 4455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (iface_get_initial_state(&st) < 0) 44612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 4475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 44860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (addr && !is_ll_address(addr)) { 44960d86f779725e78ae3d295380f15208859cc06ebLennart 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))); 45060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = 0; 45160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 45260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 45360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (!addr) { 45460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int i; 45560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering uint32_t a = 1; 45660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 45760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering for (i = 0; i < ETHER_ADDRLEN; i++) 45860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering a += hw_address[i]*i; 45960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 46060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = htonl(IPV4LL_NETWORK | (uint32_t) a); 46160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 46260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 4635ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(st, 1, addr); 4645ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 46560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Starting with address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 46660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 46712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_SLEEPING) 46812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "Routable address already assigned, sleeping."); 46912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 4705ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (!retval_sent && (!wait_for_address || state == STATE_SLEEPING)) { 4715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(0); 4725ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering retval_sent = 1; 4735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 4745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 47560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering memset(pollfds, 0, sizeof(pollfds)); 47612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_ARP].fd = fd; 47712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_ARP].events = POLLIN; 47812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].fd = iface_fd; 47912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].events = POLLIN; 4805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pollfds[FD_SIGNAL].fd = daemon_signal_fd(); 4815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pollfds[FD_SIGNAL].events = POLLIN; 48260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 48360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering for (;;) { 48460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int r, timeout; 48560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering AvahiUsec usec; 48660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 48712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_START) { 48860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 48960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* First, wait a random time */ 4905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_PROBE, 1, addr); 49160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 49260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 49360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 49460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 49560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_WAITING_PROBE && event == EVENT_TIMEOUT) || 49660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration < PROBE_NUM-2)) { 49760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 49860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send a probe */ 49960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 5005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_PROBING, 0, addr); 50160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 50260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, PROBE_MIN*1000, (PROBE_MAX-PROBE_MIN)*1000); 50360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 50460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 50560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration >= PROBE_NUM-2) { 50660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 50760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send the last probe */ 50860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 5095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_ANNOUNCE, 1, addr); 51060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 51160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_WAIT*1000, 0); 51260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 51360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 51460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_WAITING_ANNOUNCE && event == EVENT_TIMEOUT) || 51560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering (state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration < ANNOUNCE_NUM-1)) { 51660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 51760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Send announcement packet */ 51860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = packet_new_announcement(addr, hw_address, &out_packet_len); 5195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_ANNOUNCING, 0, addr); 52060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 52160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0); 52260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 52360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 52460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (n_iteration == 0) { 5255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering do_callout(CALLOUT_BIND, iface, addr); 52660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_conflict = 0; 5275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 5285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (!retval_sent) { 5295ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(0); 5305ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering retval_sent = 1; 5315ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 53260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 53360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 53460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if ((state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration >= ANNOUNCE_NUM-1)) { 53560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 53660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Successfully claimed IP address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 5375ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_RUNNING, 0, addr); 538fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering 539fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering next_wakeup_valid = 0; 54060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 54160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (event == EVENT_PACKET) { 54260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ArpPacketInfo info; 54360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 54460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering assert(in_packet); 54560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 54660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (packet_parse(in_packet, in_packet_len, &info) < 0) 54760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_WARNING, "Failed to parse incoming ARP packet."); 54860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering else { 54960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering int conflict = 0; 55060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 55160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (info.sender_ip_address == addr) { 55260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Normal conflict */ 55360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering conflict = 1; 55460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Recieved conflicting normal ARP packet."); 55560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (state == STATE_WAITING_PROBE || state == STATE_PROBING || state == STATE_WAITING_ANNOUNCE) { 55660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Probe conflict */ 55760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering conflict = info.target_ip_address == addr && memcmp(hw_address, info.sender_hw_address, ETHER_ADDRLEN); 55860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Recieved conflicting probe ARP packet."); 55960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 56060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 56160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (conflict) { 56260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 56360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 5645ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering do_callout(CALLOUT_CONFLICT, iface, addr); 56560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 56660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering /* Pick a new address */ 56760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering addr = pick_addr(addr); 56860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 56960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_INFO, "Trying address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 57060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 57160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering n_conflict++; 57260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 5735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_PROBE, 1, addr); 57412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 57560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (n_conflict >= MAX_CONFLICTS) { 57660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_WARNING, "Got too many conflicts, rate limiting new probes."); 57760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, RATE_LIMIT_INTERVAL*1000, PROBE_WAIT*1000); 57860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else 57960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 58060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 58160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 1; 58260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else 5835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "Ignoring irrelevant ARP packet.")); 58460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 58512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 58612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } else if (event == EVENT_ROUTABLE_ADDR_CONFIGURED) { 58712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 58812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "A routable address has been configured."); 58912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 59012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 5915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering do_callout(CALLOUT_UNBIND, iface, addr); 592fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering 5935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (!retval_sent) { 5945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(0); 5955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering retval_sent = 1; 5965ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 5975ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 5985ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_SLEEPING, 1, addr); 599fee9053f6a8a22ff53d59fc7865230ad41fdf760Lennart Poettering next_wakeup_valid = 0; 60012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 60112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } else if (event == EVENT_ROUTABLE_ADDR_UNCONFIGURED && state == STATE_SLEEPING) { 60212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 60312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering daemon_log(LOG_INFO, "No longer a routable address configured, restarting probe process."); 60412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 6055ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_WAITING_PROBE, 1, addr); 60612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 60712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 60812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering next_wakeup_valid = 1; 6095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6105ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (event == EVENT_REFRESH_REQUEST && state == STATE_RUNNING) { 6115ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6125ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /* The user requested a reannouncing of the address by a SIGHUP */ 6135ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_INFO, "Reannouncing address."); 61412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 6155ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /* Send announcement packet */ 6165ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering out_packet = packet_new_announcement(addr, hw_address, &out_packet_len); 6175ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering set_state(STATE_ANNOUNCING, 1, addr); 6185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0); 6205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering next_wakeup_valid = 1; 62160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 62260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (out_packet) { 6245ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "sending...")); 62560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (send_packet(fd, iface, out_packet, out_packet_len) < 0) 62760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering goto fail; 62860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 62960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(out_packet); 63060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering out_packet = NULL; 63160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 63260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 63360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (in_packet) { 63460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(in_packet); 63560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering in_packet = NULL; 63660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 63760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 63812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering event = EVENT_NULL; 63960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering timeout = -1; 64060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 64160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (next_wakeup_valid) { 64260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering usec = avahi_age(&next_wakeup); 64360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering timeout = usec < 0 ? (int) (-usec/1000) : 0; 64460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 64560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 6465ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering DEBUG(daemon_log(LOG_DEBUG, "sleeping %ims", timeout)); 64760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 64812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering while ((r = poll(pollfds, FD_MAX, timeout)) < 0 && errno == EINTR) 64960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ; 65060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (r < 0) { 65260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering daemon_log(LOG_ERR, "poll() failed: %s", strerror(r)); 6535ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto fail; 65460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else if (r == 0) { 65560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering event = EVENT_TIMEOUT; 65660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering next_wakeup_valid = 0; 65760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } else { 65860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 65912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (pollfds[FD_ARP].revents == POLLIN) { 66012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (recv_packet(fd, &in_packet, &in_packet_len) < 0) 66112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 66212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 66312874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (in_packet) 66412874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering event = EVENT_PACKET; 66512874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } 66660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 66712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (event == EVENT_NULL && 66812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering pollfds[FD_IFACE].revents == POLLIN) { 66912874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 67012874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (iface_process(&event) < 0) 67112874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering goto fail; 67212874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering } 6735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (event == EVENT_NULL && 6755ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pollfds[FD_SIGNAL].revents == POLLIN) { 6765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6775ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int sig; 6785ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6795ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((sig = daemon_signal_next()) <= 0) { 6805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "daemon_signal_next() failed"); 6815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto fail; 6825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 6835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering switch(sig) { 6855ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGINT: 6865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGTERM: 6875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_INFO, "Got %s, quitting.", sig == SIGINT ? "SIGINT" : "SIGTERM"); 6885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering ret = 0; 6895ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto fail; 6905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGCHLD: 6925ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering waitpid(-1, NULL, WNOHANG); 6935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 6945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 6955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case SIGHUP: 6965ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering event = EVENT_REFRESH_REQUEST; 6975ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 6985ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 6995ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 70160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 70260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 70360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 70460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering ret = 0; 70560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 70660d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringfail: 70760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 7085ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 7095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering do_callout(CALLOUT_STOP, iface, addr); 7105ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 71160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(out_packet); 71260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering avahi_free(in_packet); 71360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 71460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering if (fd >= 0) 71560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering close(fd); 71612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering 71712874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering if (iface_fd >= 0) 71812874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering iface_done(); 7195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize && !retval_sent) 7215ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(ret); 72260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 72360d86f779725e78ae3d295380f15208859cc06ebLennart Poettering return ret; 72460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 72560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 72660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 7275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic void help(FILE *f, const char *a0) { 7285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(f, 7295ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering "%s [options] INTERFACE\n" 7305ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -h --help Show this help\n" 7315ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -D --daemonize Daemonize after startup\n" 7325ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -s --syslog Write log messages to syslog(3) instead of STDERR\n" 7335ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -k --kill Kill a running daemon\n" 7345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -r --refresh Request a running daemon to refresh it's IP address\n" 7355ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -c --check Return 0 if a daemon is already running\n" 7365ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -V --version Show version\n" 7375ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -S --start=ADDRESS Start with this address from the IPv4LL range 169.254.0.0/16\n" 7385ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " -w --wait Wait until an address has been acquired before daemonizing\n" 7395ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " --no-proc-title Don't modify process title\n" 7405ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering " --debug Increase verbosity\n", 7415ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering a0); 7425ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} 7435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic int parse_command_line(int argc, char *argv[]) { 7455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int c; 7465ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering enum { 7485ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering OPTION_NO_PROC_TITLE = 256, 7495ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering OPTION_DEBUG 7505ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering }; 7515ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7525ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering static const struct option long_options[] = { 7535ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "help", no_argument, NULL, 'h' }, 7545ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "daemonize", no_argument, NULL, 'D' }, 7555ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "syslog", no_argument, NULL, 's' }, 7565ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "kill", no_argument, NULL, 'k' }, 7575ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "refresh", no_argument, NULL, 'r' }, 7585ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "check", no_argument, NULL, 'c' }, 7595ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "version", no_argument, NULL, 'V' }, 7605ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "start", required_argument, NULL, 'S' }, 7615ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "wait", no_argument, NULL, 'w' }, 7625ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "no-proc-title", no_argument, NULL, OPTION_NO_PROC_TITLE }, 7635ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { "debug", no_argument, NULL, OPTION_DEBUG }, 7645ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering { NULL, 0, NULL, 0 } 7655ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering }; 76660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 7675ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering opterr = 0; 7685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering while ((c = getopt_long(argc, argv, "hDkVrcS:", long_options, NULL)) >= 0) { 7695ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7705ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering switch(c) { 7715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 's': 7725ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering use_syslog = 1; 7735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'h': 7755ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_HELP; 7765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7775ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'D': 7785ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemonize = 1; 7795ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'k': 7815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_KILL; 7825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'V': 7845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_VERSION; 7855ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'r': 7875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_REFRESH; 7885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7895ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'c': 7905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command = DAEMON_CHECK; 7915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7925ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'S': 7935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 7945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((start_address = inet_addr(optarg)) == (uint32_t) -1) { 7955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Failed to parse IP address '%s'.", optarg); 7965ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 7975ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 7985ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 7995ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case 'w': 8005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering wait_for_address = 1; 8015ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 8025ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8035ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case OPTION_NO_PROC_TITLE: 8045ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering modify_proc_title = 0; 8055ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 80660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8075ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering case OPTION_DEBUG: 8085ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering debug = 1; 8095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering break; 8105ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8115ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering default: 8125ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Invalid command line argument: %c\n", c); 8135ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 8145ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 81560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering } 81660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8175ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (command == DAEMON_RUN || 8185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command == DAEMON_KILL || 8195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command == DAEMON_REFRESH || 8205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering command == DAEMON_CHECK) { 82160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8225ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (optind >= argc) { 8235ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Missing interface name.\n"); 8245ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 8255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 82660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering interface_name = argv[optind++]; 8285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8295ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8305ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (optind != argc) { 8315ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering fprintf(stderr, "Too many arguments\n"); 8325ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return -1; 8335ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8355ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return 0; 8365ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering} 8375ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8385ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringstatic const char* pid_file_proc(void) { 8395ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return pid_file_name; 84060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 84160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 84260d86f779725e78ae3d295380f15208859cc06ebLennart Poetteringint main(int argc, char*argv[]) { 8435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int r = 1; 8445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int wrote_pid_file = 0; 84560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 84612874f5d761b4b80ac27c1fc758a93b69d92c34cLennart Poettering avahi_init_proc_title(argc, argv); 84760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8485ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((argv0 = strrchr(argv[0], '/'))) 8495ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering argv0++; 8505ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else 8515ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering argv0 = argv[0]; 85260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8535ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_pid_file_ident = daemon_log_ident = argv0; 8545ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_pid_file_proc = pid_file_proc; 85560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8565ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (parse_command_line(argc, argv) < 0) 8575ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 85860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 8595ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pid_file_name = avahi_strdup_printf(AVAHI_RUNTIME_DIR"/avahi-autoipd.%s.pid", interface_name); 8605ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8615ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (command == DAEMON_RUN) { 8625ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering pid_t pid; 8635ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int ifindex; 8645ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8655ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering init_rand_seed(); 8665ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8675ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((ifindex = if_nametoindex(interface_name)) <= 0) { 8685ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Failed to get index for interface name '%s': %s", interface_name, strerror(errno)); 8695ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 8705ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8715ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8725ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (getuid() != 0) { 8735ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "This program is intended to be run as root."); 8745ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 8755ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8765ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8775ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((pid = daemon_pid_file_is_running()) >= 0) { 8785ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Daemon already running on PID %u", pid); 8795ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 8805ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8815ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8825ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize) { 8835ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_init(); 8845ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8855ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((pid = daemon_fork()) < 0) 8865ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 8875ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering else if (pid != 0) { 8885ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering int ret; 8895ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /** Parent **/ 8905ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8915ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if ((ret = daemon_retval_wait(20)) < 0) { 8925ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Could not receive return value from daemon process."); 8935ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 8945ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8955ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 8965ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = ret; 8975ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 8985ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 8995ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9005ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering /* Child */ 9015ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 9025ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9035ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (use_syslog || daemonize) 9045ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log_use = DAEMON_LOG_SYSLOG; 9055ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9065ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering chdir("/"); 9075ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9085ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemon_pid_file_create() < 0) { 9095ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_ERR, "Failed to create PID file: %s", strerror(errno)); 9105ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9115ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize) 9125ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_send(1); 9135ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 9145ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else 9155ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering wrote_pid_file = 1; 9165ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9175ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (loop(ifindex, start_address) < 0) 9185ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 9195ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9205ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 9215ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_HELP) { 9225ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering help(stdout, argv0); 9235ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9245ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 9255ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_VERSION) { 9265ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering printf("%s "PACKAGE_VERSION"\n", argv0); 9275ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9285ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 9295ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_KILL) { 9305ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) { 9315ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno)); 9325ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 9335ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 9345ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9355ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 9365ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_REFRESH) { 9375ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemon_pid_file_kill(SIGHUP) < 0) { 9385ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno)); 9395ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering goto finish; 9405ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } 9415ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9425ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = 0; 9435ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering } else if (command == DAEMON_CHECK) 9445ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering r = (daemon_pid_file_is_running() >= 0) ? 0 : 1; 9455ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9465ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9475ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poetteringfinish: 9485ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9495ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (daemonize) 9505ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_retval_done(); 95160d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 9525ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering if (wrote_pid_file) 9535ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering daemon_pid_file_remove(); 9545ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering 9555ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering return r; 95660d86f779725e78ae3d295380f15208859cc06ebLennart Poettering} 95760d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 95860d86f779725e78ae3d295380f15208859cc06ebLennart Poettering/* TODO: 95960d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 96060d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- chroot/drop privs/caps 9615ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering- user script 96260d86f779725e78ae3d295380f15208859cc06ebLennart Poettering- store last used address 9635ea98f8caf0e163ad1f51039b8a2d13e3fe0e86cLennart Poettering- man page 96460d86f779725e78ae3d295380f15208859cc06ebLennart Poettering 96560d86f779725e78ae3d295380f15208859cc06ebLennart Poettering*/ 966