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