]> git.meshlink.io Git - catta/blob - avahi-autoipd/main.c
implement command line parsing, signal handling, daemonization
[catta] / avahi-autoipd / main.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5  
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10  
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <sys/socket.h>
29 #include <netpacket/packet.h>
30 #include <net/ethernet.h>
31 #include <fcntl.h>
32 #include <time.h>
33 #include <assert.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <inttypes.h>
37 #include <sys/types.h>
38 #include <arpa/inet.h>
39 #include <sys/ioctl.h>
40 #include <poll.h>
41 #include <net/if.h>
42 #include <stdio.h>
43 #include <getopt.h>
44 #include <signal.h>
45 #include <sys/wait.h>
46
47 #include <avahi-common/malloc.h>
48 #include <avahi-common/timeval.h>
49
50 #include <avahi-daemon/setproctitle.h>
51
52 #include <libdaemon/dfork.h>
53 #include <libdaemon/dsignal.h>
54 #include <libdaemon/dlog.h>
55 #include <libdaemon/dpid.h>
56 #include <libdaemon/dexec.h>
57
58 #include "main.h"
59 #include "iface.h"
60
61 #ifndef __linux__
62 #error "avahi-autoipd is only available on Linux for now"
63 #endif
64
65 /* An implementation of RFC 3927 */
66
67 /* Constants from the RFC */
68 #define PROBE_WAIT 1
69 #define PROBE_NUM 3
70 #define PROBE_MIN 1
71 #define PROBE_MAX 2
72 #define ANNOUNCE_WAIT 2
73 #define ANNOUNCE_NUM 2
74 #define ANNOUNCE_INTERVAL 2
75 #define MAX_CONFLICTS 10
76 #define RATE_LIMIT_INTERVAL 60
77 #define DEFEND_INTERVAL 10
78
79 #define IPV4LL_NETWORK 0xA9FE0000L
80 #define IPV4LL_NETMASK 0xFFFF0000L
81 #define IPV4LL_HOSTMASK 0x0000FFFFL
82
83 #define ETHER_ADDRLEN 6
84 #define ARP_PACKET_SIZE (8+4+4+2*ETHER_ADDRLEN)
85
86 typedef enum ArpOperation {
87     ARP_REQUEST = 1,
88     ARP_RESPONSE = 2
89 } ArpOperation;
90
91 typedef struct ArpPacketInfo {
92     ArpOperation operation;
93
94     uint32_t sender_ip_address, target_ip_address;
95     uint8_t sender_hw_address[ETHER_ADDRLEN], target_hw_address[ETHER_ADDRLEN];
96 } ArpPacketInfo;
97
98 static State state = STATE_START;
99 static int n_iteration = 0;
100 static int n_conflict = 0;
101
102 static char *interface_name = NULL;
103 static char *pid_file_name = NULL;
104 static uint32_t start_address = 0;
105 static char *argv0 = NULL;
106 static int daemonize = 0;
107 static int wait_for_address = 0;
108 static int use_syslog = 0;
109 static int debug = 0;
110 static int modify_proc_title = 1;
111
112 static enum {
113     DAEMON_RUN,
114     DAEMON_KILL,
115     DAEMON_REFRESH,
116     DAEMON_VERSION,
117     DAEMON_HELP,
118     DAEMON_CHECK
119 } command = DAEMON_RUN;
120
121 typedef enum CalloutEvent {
122     CALLOUT_BIND,
123     CALLOUT_CONFLICT,
124     CALLOUT_UNBIND,
125     CALLOUT_STOP,
126     CALLOUT_MAX
127 } CalloutEvent;
128
129 #define RANDOM_DEVICE "/dev/urandom"
130
131 #define DEBUG(x) do {\
132 if (debug) { \
133     x; \
134 } \
135 } while (0)
136
137 static void init_rand_seed(void) {
138     int fd;
139     unsigned seed = 0;
140
141     /* Try to initialize seed from /dev/urandom, to make it a little
142      * less predictable, and to make sure that multiple machines
143      * booted at the same time choose different random seeds.  */
144     if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) {
145         read(fd, &seed, sizeof(seed));
146         close(fd);
147     }
148
149     /* If the initialization failed by some reason, we add the time to the seed */
150     seed ^= (unsigned) time(NULL);
151
152     srand(seed);
153 }
154
155 static uint32_t pick_addr(uint32_t old_addr) {
156     uint32_t addr;
157
158     do {
159         unsigned r = (unsigned) rand();
160
161         /* Reduce to 16 bits */
162         while (r > 0xFFFF)
163             r = (r >> 16) ^ (r & 0xFFFF);
164         
165         addr = htonl(IPV4LL_NETWORK | (uint32_t) r);
166
167     } while (addr == old_addr);
168
169     return addr;
170 }
171
172 static void* packet_new(const ArpPacketInfo *info, size_t *packet_len) {
173     uint8_t *r;
174
175     assert(info);
176     assert(packet_len);
177     assert(info->operation == ARP_REQUEST || info->operation == ARP_RESPONSE);
178
179     *packet_len = ARP_PACKET_SIZE;
180     r = avahi_new0(uint8_t, *packet_len);
181     
182     r[1] = 1; /* HTYPE */
183     r[2] = 8; /* PTYPE */
184     r[4] = ETHER_ADDRLEN; /* HLEN */
185     r[5] = 4; /* PLEN */
186     r[7] = (uint8_t) info->operation;
187
188     memcpy(r+8, info->sender_hw_address, ETHER_ADDRLEN);
189     memcpy(r+14, &info->sender_ip_address, 4);
190     memcpy(r+18, info->target_hw_address, ETHER_ADDRLEN);
191     memcpy(r+24, &info->target_ip_address, 4);
192
193     return r;
194 }
195
196 static void *packet_new_probe(uint32_t ip_address, const uint8_t*hw_address, size_t *packet_len) {
197     ArpPacketInfo info;
198     
199     memset(&info, 0, sizeof(info));
200     info.operation = ARP_REQUEST;
201     memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN);
202     info.target_ip_address = ip_address;
203
204     return packet_new(&info, packet_len);
205 }
206
207 static void *packet_new_announcement(uint32_t ip_address, const uint8_t* hw_address, size_t *packet_len) {
208     ArpPacketInfo info;
209
210     memset(&info, 0, sizeof(info));
211     info.operation = ARP_REQUEST;
212     memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN);
213     info.target_ip_address = ip_address;
214     info.sender_ip_address = ip_address;
215
216     return packet_new(&info, packet_len);
217 }
218
219 static int packet_parse(const void *data, size_t packet_len, ArpPacketInfo *info) {
220     const uint8_t *p = data;
221     
222     assert(data);
223
224     if (packet_len < ARP_PACKET_SIZE)
225         return -1;
226
227     /* Check HTYPE and PTYPE */
228     if (p[0] != 0 || p[1] != 1 || p[2] != 8 || p[3] != 0)
229         return -1;
230
231     /* Check HLEN, PLEN, OPERATION */
232     if (p[4] != ETHER_ADDRLEN || p[5] != 4 || p[6] != 0 || (p[7] != 1 && p[7] != 2))
233         return -1;
234     
235     info->operation = p[7];
236     memcpy(info->sender_hw_address, p+8, ETHER_ADDRLEN);
237     memcpy(&info->sender_ip_address, p+14, 4);
238     memcpy(info->target_hw_address, p+18, ETHER_ADDRLEN);
239     memcpy(&info->target_ip_address, p+24, 4);
240
241     return 0;
242 }
243
244 static void set_state(State st, int reset_counter, uint32_t address) {
245     const char* const state_table[] = {
246         [STATE_START] = "START",
247         [STATE_WAITING_PROBE] = "WAITING_PROBE",
248         [STATE_PROBING] = "PROBING",
249         [STATE_WAITING_ANNOUNCE] = "WAITING_ANNOUNCE", 
250         [STATE_ANNOUNCING] = "ANNOUNCING",
251         [STATE_RUNNING] = "RUNNING",
252         [STATE_SLEEPING] = "SLEEPING"
253     };
254     char buf[64];
255     
256     assert(st < STATE_MAX);
257
258     if (st == state && !reset_counter) {
259         n_iteration++;
260         DEBUG(daemon_log(LOG_DEBUG, "State iteration %s-%i", state_table[state], n_iteration));
261     } else {
262         DEBUG(daemon_log(LOG_DEBUG, "State transition %s-%i -> %s-0", state_table[state], n_iteration, state_table[st]));
263         state = st;
264         n_iteration = 0;
265     }
266
267     if (modify_proc_title) {
268         if (state == STATE_SLEEPING) 
269             avahi_set_proc_title("%s: sleeping", argv0);
270         else if (state == STATE_ANNOUNCING)
271             avahi_set_proc_title("%s: announcing %s", argv0, inet_ntop(AF_INET, &address, buf, sizeof(buf)));
272         else if (state == STATE_RUNNING)
273             avahi_set_proc_title("%s: bound %s", argv0, inet_ntop(AF_INET, &address, buf, sizeof(buf)));
274         else
275             avahi_set_proc_title("%s: probing %s", argv0, inet_ntop(AF_INET, &address, buf, sizeof(buf)));
276     }
277 }
278
279 static int do_callout(CalloutEvent event, int iface, uint32_t addr) {
280     char buf[64], ifname[IFNAMSIZ];
281     const char * const event_table[CALLOUT_MAX] = {
282         [CALLOUT_BIND] = "BIND",
283         [CALLOUT_CONFLICT] = "CONFLICT",
284         [CALLOUT_UNBIND] = "UNBIND",
285         [CALLOUT_STOP] = "STOP"
286     };
287
288     daemon_log(LOG_INFO, "Callout %s, address %s on interface %s",
289                event_table[event],
290                inet_ntop(AF_INET, &addr, buf, sizeof(buf)),
291                if_indextoname(iface, ifname));
292     
293     return 0;
294 }
295
296 static int open_socket(int iface, uint8_t *hw_address) {
297     int fd = -1;
298     struct sockaddr_ll sa;
299     socklen_t sa_len;
300     
301     if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) < 0) {
302         daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno));
303         goto fail;
304     }
305
306     memset(&sa, 0, sizeof(sa));
307     sa.sll_family = AF_PACKET;
308     sa.sll_protocol = htons(ETH_P_ARP);
309     sa.sll_ifindex = iface;
310
311     if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) {
312         daemon_log(LOG_ERR, "bind() failed: %s", strerror(errno));
313         goto fail;
314     }
315
316     sa_len = sizeof(sa);
317     if (getsockname(fd, (struct sockaddr*) &sa, &sa_len) < 0) {
318         daemon_log(LOG_ERR, "getsockname() failed: %s", strerror(errno));
319         goto fail;
320     }
321
322     if (sa.sll_halen != ETHER_ADDRLEN) {
323         daemon_log(LOG_ERR, "getsockname() returned invalid hardware address.");
324         goto fail;
325     }
326
327     memcpy(hw_address, sa.sll_addr, ETHER_ADDRLEN);
328
329     return fd;
330     
331 fail:
332     if (fd >= 0)
333         close(fd);
334
335     return -1;
336 }
337
338 static int send_packet(int fd, int iface, void *packet, size_t packet_len) {
339     struct sockaddr_ll sa;
340     
341     assert(fd >= 0);
342     assert(packet);
343     assert(packet_len > 0);
344
345     memset(&sa, 0, sizeof(sa));
346     sa.sll_family = AF_PACKET;
347     sa.sll_protocol = htons(ETH_P_ARP);
348     sa.sll_ifindex = iface;
349     sa.sll_halen = ETHER_ADDRLEN;
350     memset(sa.sll_addr, 0xFF, ETHER_ADDRLEN);
351
352     if (sendto(fd, packet, packet_len, 0, (struct sockaddr*) &sa, sizeof(sa)) < 0) {
353         daemon_log(LOG_ERR, "sendto() failed: %s", strerror(errno));
354         return -1;
355     }
356
357     return 0;
358 }
359
360 static int recv_packet(int fd, void **packet, size_t *packet_len) {
361     int s;
362     struct sockaddr_ll sa;
363     socklen_t sa_len;
364     
365     assert(fd >= 0);
366     assert(packet);
367     assert(packet_len);
368
369     *packet = NULL;
370
371     if (ioctl(fd, FIONREAD, &s) < 0) {
372         daemon_log(LOG_ERR, "FIONREAD failed: %s", strerror(errno));
373         goto fail;
374     }
375
376     assert(s > 0);
377
378     *packet_len = (size_t) s;
379     *packet = avahi_new(uint8_t, s);
380
381     sa_len = sizeof(sa);
382     if (recvfrom(fd, *packet, s, 0, (struct sockaddr*) &sa, &sa_len) < 0) {
383         daemon_log(LOG_ERR, "recvfrom() failed: %s", strerror(errno));
384         goto fail;
385     }
386     
387     return 0;
388     
389 fail:
390     if (*packet)
391         avahi_free(*packet);
392
393     return -1;
394 }
395  
396 int is_ll_address(uint32_t addr) {
397     return (ntohl(addr) & IPV4LL_NETMASK) == IPV4LL_NETWORK;
398 }
399
400 static struct timeval *elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) {
401     assert(tv);
402
403     gettimeofday(tv, NULL);
404
405     if (msec)
406         avahi_timeval_add(tv, (AvahiUsec) msec*1000);
407
408     if (jitter)
409         avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0)));
410         
411     return tv;
412 }
413
414 static int loop(int iface, uint32_t addr) {
415     enum {
416         FD_ARP,
417         FD_IFACE,
418         FD_SIGNAL,
419         FD_MAX,
420     };
421
422     int fd = -1, ret = -1;
423     struct timeval next_wakeup;
424     int next_wakeup_valid = 0;
425     char buf[64];
426     void *in_packet = NULL;
427     size_t in_packet_len;
428     void *out_packet = NULL;
429     size_t out_packet_len;
430     uint8_t hw_address[ETHER_ADDRLEN];
431     struct pollfd pollfds[FD_MAX];
432     int iface_fd;
433     Event event = EVENT_NULL;
434     int retval_sent = !daemonize;
435     State st;
436
437     daemon_signal_init(SIGINT, SIGTERM, SIGCHLD, SIGHUP,0);
438
439     if ((fd = open_socket(iface, hw_address)) < 0)
440         goto fail;
441
442     if ((iface_fd = iface_init(iface)) < 0)
443         goto fail;
444
445     if (iface_get_initial_state(&st) < 0)
446         goto fail;
447
448     if (addr && !is_ll_address(addr)) {
449         daemon_log(LOG_WARNING, "Requested address %s is not from IPv4LL range 169.254/16, ignoring.", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
450         addr = 0;
451     }
452
453     if (!addr) {
454         int i;
455         uint32_t a = 1;
456
457         for (i = 0; i < ETHER_ADDRLEN; i++)
458             a += hw_address[i]*i;
459
460         addr = htonl(IPV4LL_NETWORK | (uint32_t) a);
461     }
462
463     set_state(st, 1, addr);
464     
465     daemon_log(LOG_INFO, "Starting with address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
466
467     if (state == STATE_SLEEPING)
468         daemon_log(LOG_INFO, "Routable address already assigned, sleeping.");
469
470     if (!retval_sent && (!wait_for_address || state == STATE_SLEEPING)) {
471         daemon_retval_send(0);
472         retval_sent = 1;
473     }
474
475     memset(pollfds, 0, sizeof(pollfds));
476     pollfds[FD_ARP].fd = fd;
477     pollfds[FD_ARP].events = POLLIN;
478     pollfds[FD_IFACE].fd = iface_fd;
479     pollfds[FD_IFACE].events = POLLIN;
480     pollfds[FD_SIGNAL].fd = daemon_signal_fd();
481     pollfds[FD_SIGNAL].events = POLLIN;
482     
483     for (;;) {
484         int r, timeout;
485         AvahiUsec usec;
486
487         if (state == STATE_START) {
488
489             /* First, wait a random time */
490             set_state(STATE_WAITING_PROBE, 1, addr);
491
492             elapse_time(&next_wakeup, 0, PROBE_WAIT*1000);
493             next_wakeup_valid = 1;
494
495         } else if ((state == STATE_WAITING_PROBE && event == EVENT_TIMEOUT) ||
496                    (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration < PROBE_NUM-2)) {
497
498             /* Send a probe */
499             out_packet = packet_new_probe(addr, hw_address, &out_packet_len);
500             set_state(STATE_PROBING, 0, addr);
501
502             elapse_time(&next_wakeup, PROBE_MIN*1000, (PROBE_MAX-PROBE_MIN)*1000);
503             next_wakeup_valid = 1;
504             
505         } else if (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration >= PROBE_NUM-2) {
506
507             /* Send the last probe */
508             out_packet = packet_new_probe(addr, hw_address, &out_packet_len);
509             set_state(STATE_WAITING_ANNOUNCE, 1, addr);
510
511             elapse_time(&next_wakeup, ANNOUNCE_WAIT*1000, 0);
512             next_wakeup_valid = 1;
513             
514         } else if ((state == STATE_WAITING_ANNOUNCE && event == EVENT_TIMEOUT) ||
515                    (state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration < ANNOUNCE_NUM-1)) {
516
517             /* Send announcement packet */
518             out_packet = packet_new_announcement(addr, hw_address, &out_packet_len);
519             set_state(STATE_ANNOUNCING, 0, addr);
520
521             elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0);
522             next_wakeup_valid = 1;
523             
524             if (n_iteration == 0) {
525                 do_callout(CALLOUT_BIND, iface, addr);
526                 n_conflict = 0;
527
528                 if (!retval_sent) {
529                     daemon_retval_send(0);
530                     retval_sent = 1;
531                 }
532             }
533
534         } else if ((state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration >= ANNOUNCE_NUM-1)) {
535
536             daemon_log(LOG_INFO, "Successfully claimed IP address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
537             set_state(STATE_RUNNING, 0, addr);
538
539             next_wakeup_valid = 0;
540             
541         } else if (event == EVENT_PACKET) {
542             ArpPacketInfo info;
543
544             assert(in_packet);
545             
546             if (packet_parse(in_packet, in_packet_len, &info) < 0)
547                 daemon_log(LOG_WARNING, "Failed to parse incoming ARP packet.");
548             else {
549                 int conflict = 0;
550
551                 if (info.sender_ip_address == addr) {
552                     /* Normal conflict */
553                     conflict = 1;
554                     daemon_log(LOG_INFO, "Recieved conflicting normal ARP packet.");
555                 } else if (state == STATE_WAITING_PROBE || state == STATE_PROBING || state == STATE_WAITING_ANNOUNCE) {
556                     /* Probe conflict */
557                     conflict = info.target_ip_address == addr && memcmp(hw_address, info.sender_hw_address, ETHER_ADDRLEN);
558                     daemon_log(LOG_INFO, "Recieved conflicting probe ARP packet.");
559                 }
560
561                 if (conflict) {
562                     
563                     if (state == STATE_RUNNING || state == STATE_ANNOUNCING)
564                         do_callout(CALLOUT_CONFLICT, iface, addr);
565                     
566                     /* Pick a new address */
567                     addr = pick_addr(addr);
568
569                     daemon_log(LOG_INFO, "Trying address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
570
571                     n_conflict++;
572
573                     set_state(STATE_WAITING_PROBE, 1, addr);
574                     
575                     if (n_conflict >= MAX_CONFLICTS) {
576                         daemon_log(LOG_WARNING, "Got too many conflicts, rate limiting new probes.");
577                         elapse_time(&next_wakeup, RATE_LIMIT_INTERVAL*1000, PROBE_WAIT*1000);
578                     } else
579                         elapse_time(&next_wakeup, 0, PROBE_WAIT*1000);
580
581                     next_wakeup_valid = 1;
582                 } else
583                     DEBUG(daemon_log(LOG_DEBUG, "Ignoring irrelevant ARP packet."));
584             }
585             
586         } else if (event == EVENT_ROUTABLE_ADDR_CONFIGURED) {
587
588             daemon_log(LOG_INFO, "A routable address has been configured.");
589
590             if (state == STATE_RUNNING || state == STATE_ANNOUNCING)
591                 do_callout(CALLOUT_UNBIND, iface, addr);
592
593             if (!retval_sent) {
594                 daemon_retval_send(0);
595                 retval_sent = 1;
596             }
597             
598             set_state(STATE_SLEEPING, 1, addr);
599             next_wakeup_valid = 0;
600             
601         } else if (event == EVENT_ROUTABLE_ADDR_UNCONFIGURED && state == STATE_SLEEPING) {
602
603             daemon_log(LOG_INFO, "No longer a routable address configured, restarting probe process.");
604
605             set_state(STATE_WAITING_PROBE, 1, addr);
606
607             elapse_time(&next_wakeup, 0, PROBE_WAIT*1000);
608             next_wakeup_valid = 1;
609
610         } else if (event == EVENT_REFRESH_REQUEST && state == STATE_RUNNING) {
611
612             /* The user requested a reannouncing of the address by a SIGHUP */
613             daemon_log(LOG_INFO, "Reannouncing address.");
614             
615             /* Send announcement packet */
616             out_packet = packet_new_announcement(addr, hw_address, &out_packet_len);
617             set_state(STATE_ANNOUNCING, 1, addr);
618
619             elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0);
620             next_wakeup_valid = 1;
621         }
622         
623         if (out_packet) {
624             DEBUG(daemon_log(LOG_DEBUG, "sending..."));
625             
626             if (send_packet(fd, iface, out_packet, out_packet_len) < 0)
627                 goto fail;
628             
629             avahi_free(out_packet);
630             out_packet = NULL;
631         }
632
633         if (in_packet) {
634             avahi_free(in_packet);
635             in_packet = NULL;
636         }
637
638         event = EVENT_NULL;
639         timeout = -1;
640         
641         if (next_wakeup_valid) {
642             usec = avahi_age(&next_wakeup);
643             timeout = usec < 0 ? (int) (-usec/1000) : 0;
644         }
645
646         DEBUG(daemon_log(LOG_DEBUG, "sleeping %ims", timeout));
647                     
648         while ((r = poll(pollfds, FD_MAX, timeout)) < 0 && errno == EINTR)
649             ;
650
651         if (r < 0) {
652             daemon_log(LOG_ERR, "poll() failed: %s", strerror(r));
653             goto fail;
654         } else if (r == 0) {
655             event = EVENT_TIMEOUT;
656             next_wakeup_valid = 0;
657         } else {
658
659             if (pollfds[FD_ARP].revents == POLLIN) {
660                 if (recv_packet(fd, &in_packet, &in_packet_len) < 0)
661                     goto fail;
662                 
663                 if (in_packet)
664                     event = EVENT_PACKET;
665             }
666
667             if (event == EVENT_NULL &&
668                 pollfds[FD_IFACE].revents == POLLIN) {
669                 
670                 if (iface_process(&event) < 0)
671                     goto fail;
672             }
673
674             if (event == EVENT_NULL &&
675                 pollfds[FD_SIGNAL].revents == POLLIN) {
676
677                 int sig;
678
679                 if ((sig = daemon_signal_next()) <= 0) {
680                     daemon_log(LOG_ERR, "daemon_signal_next() failed");
681                     goto fail;
682                 }
683
684                 switch(sig) {
685                     case SIGINT:
686                     case SIGTERM:
687                         daemon_log(LOG_INFO, "Got %s, quitting.", sig == SIGINT ? "SIGINT" : "SIGTERM");
688                         ret = 0;
689                         goto fail;
690
691                     case SIGCHLD:
692                         waitpid(-1, NULL, WNOHANG);
693                         break;
694                     
695                     case SIGHUP:
696                         event = EVENT_REFRESH_REQUEST;
697                         break;
698                 }
699                 
700             }
701         }
702     }
703
704     ret = 0;
705     
706 fail:
707
708     if (state == STATE_RUNNING || state == STATE_ANNOUNCING)
709         do_callout(CALLOUT_STOP, iface, addr);
710
711     avahi_free(out_packet);
712     avahi_free(in_packet);
713     
714     if (fd >= 0)
715         close(fd);
716
717     if (iface_fd >= 0)
718         iface_done();
719
720     if (daemonize && !retval_sent)
721         daemon_retval_send(ret);
722     
723     return ret;
724 }
725
726
727 static void help(FILE *f, const char *a0) {
728     fprintf(f,
729             "%s [options] INTERFACE\n"
730             "    -h --help           Show this help\n"
731             "    -D --daemonize      Daemonize after startup\n"
732             "    -s --syslog         Write log messages to syslog(3) instead of STDERR\n"
733             "    -k --kill           Kill a running daemon\n"
734             "    -r --refresh        Request a running daemon to refresh it's IP address\n"
735             "    -c --check          Return 0 if a daemon is already running\n"
736             "    -V --version        Show version\n"
737             "    -S --start=ADDRESS  Start with this address from the IPv4LL range 169.254.0.0/16\n"
738             "    -w --wait           Wait until an address has been acquired before daemonizing\n"
739             "       --no-proc-title  Don't modify process title\n"
740             "       --debug          Increase verbosity\n",
741             a0);
742 }
743
744 static int parse_command_line(int argc, char *argv[]) {
745     int c;
746     
747     enum {
748         OPTION_NO_PROC_TITLE = 256,
749         OPTION_DEBUG
750     };
751     
752     static const struct option long_options[] = {
753         { "help",          no_argument,       NULL, 'h' },
754         { "daemonize",     no_argument,       NULL, 'D' },
755         { "syslog",        no_argument,       NULL, 's' },
756         { "kill",          no_argument,       NULL, 'k' },
757         { "refresh",       no_argument,       NULL, 'r' },
758         { "check",         no_argument,       NULL, 'c' },
759         { "version",       no_argument,       NULL, 'V' },
760         { "start",         required_argument, NULL, 'S' },
761         { "wait",          no_argument,       NULL, 'w' },
762         { "no-proc-title", no_argument,       NULL, OPTION_NO_PROC_TITLE },
763         { "debug",         no_argument,       NULL, OPTION_DEBUG },
764         { NULL, 0, NULL, 0 }
765     };
766
767     opterr = 0;
768     while ((c = getopt_long(argc, argv, "hDkVrcS:", long_options, NULL)) >= 0) {
769
770         switch(c) {
771             case 's':
772                 use_syslog = 1;
773                 break;
774             case 'h':
775                 command = DAEMON_HELP;
776                 break;
777             case 'D':
778                 daemonize = 1;
779                 break;
780             case 'k':
781                 command = DAEMON_KILL;
782                 break;
783             case 'V':
784                 command = DAEMON_VERSION;
785                 break;
786             case 'r':
787                 command = DAEMON_REFRESH;
788                 break;
789             case 'c':
790                 command = DAEMON_CHECK;
791                 break;
792             case 'S':
793                 
794                 if ((start_address = inet_addr(optarg)) == (uint32_t) -1) {
795                     fprintf(stderr, "Failed to parse IP address '%s'.", optarg);
796                     return -1;
797                 }
798                 break;
799             case 'w':
800                 wait_for_address = 1;
801                 break;
802                 
803             case OPTION_NO_PROC_TITLE:
804                 modify_proc_title = 0;
805                 break;
806
807             case OPTION_DEBUG:
808                 debug = 1;
809                 break;
810
811             default:
812                 fprintf(stderr, "Invalid command line argument: %c\n", c);
813                 return -1;
814         }
815     }
816
817     if (command == DAEMON_RUN ||
818         command == DAEMON_KILL ||
819         command == DAEMON_REFRESH ||
820         command == DAEMON_CHECK) {
821
822         if (optind >= argc) {
823             fprintf(stderr, "Missing interface name.\n");
824             return -1;
825         }
826
827         interface_name = argv[optind++];
828     }
829
830     if (optind != argc) {
831         fprintf(stderr, "Too many arguments\n");
832         return -1;
833     }
834         
835     return 0;
836 }
837
838 static const char* pid_file_proc(void) {
839     return pid_file_name;
840 }
841
842 int main(int argc, char*argv[]) {
843     int r = 1;
844     int wrote_pid_file = 0;
845
846     avahi_init_proc_title(argc, argv);
847
848     if ((argv0 = strrchr(argv[0], '/')))
849         argv0++;
850     else
851         argv0 = argv[0];
852
853     daemon_pid_file_ident = daemon_log_ident = argv0;
854     daemon_pid_file_proc = pid_file_proc;
855     
856     if (parse_command_line(argc, argv) < 0)
857         goto finish;
858
859     pid_file_name = avahi_strdup_printf(AVAHI_RUNTIME_DIR"/avahi-autoipd.%s.pid", interface_name);
860
861     if (command == DAEMON_RUN) {
862         pid_t pid;
863         int ifindex;
864
865         init_rand_seed();
866         
867         if ((ifindex = if_nametoindex(interface_name)) <= 0) {
868             daemon_log(LOG_ERR, "Failed to get index for interface name '%s': %s", interface_name, strerror(errno));
869             goto finish;
870         }
871
872         if (getuid() != 0) {
873             daemon_log(LOG_ERR, "This program is intended to be run as root.");
874             goto finish;
875         }
876
877         if ((pid = daemon_pid_file_is_running()) >= 0) {
878             daemon_log(LOG_ERR, "Daemon already running on PID %u", pid);
879             goto finish;
880         }
881
882         if (daemonize) {
883             daemon_retval_init();
884             
885             if ((pid = daemon_fork()) < 0)
886                 goto finish;
887             else if (pid != 0) {
888                 int ret;
889                 /** Parent **/
890
891                 if ((ret = daemon_retval_wait(20)) < 0) {
892                     daemon_log(LOG_ERR, "Could not receive return value from daemon process.");
893                     goto finish;
894                 }
895
896                 r = ret;
897                 goto finish;
898             }
899
900             /* Child */
901         }
902
903         if (use_syslog || daemonize)
904             daemon_log_use = DAEMON_LOG_SYSLOG;
905
906         chdir("/");
907
908         if (daemon_pid_file_create() < 0) {
909             daemon_log(LOG_ERR, "Failed to create PID file: %s", strerror(errno));
910
911             if (daemonize)
912                 daemon_retval_send(1);
913             goto finish;
914         } else
915             wrote_pid_file = 1;
916
917         if (loop(ifindex, start_address) < 0)
918             goto finish;
919
920         r = 0;
921     } else if (command == DAEMON_HELP) {
922         help(stdout, argv0);
923         
924         r = 0;
925     } else if (command == DAEMON_VERSION) {
926         printf("%s "PACKAGE_VERSION"\n", argv0);
927         
928         r = 0;
929     } else if (command == DAEMON_KILL) {
930         if (daemon_pid_file_kill_wait(SIGTERM, 5) < 0) {
931             daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno));
932             goto finish;
933         }
934         
935         r = 0;
936     } else if (command == DAEMON_REFRESH) {
937         if (daemon_pid_file_kill(SIGHUP) < 0) {
938             daemon_log(LOG_WARNING, "Failed to kill daemon: %s", strerror(errno));
939             goto finish;
940         }
941
942         r = 0;
943     } else if (command == DAEMON_CHECK)
944         r = (daemon_pid_file_is_running() >= 0) ? 0 : 1;
945
946
947 finish:
948
949     if (daemonize)
950         daemon_retval_done();
951     
952     if (wrote_pid_file)
953         daemon_pid_file_remove();
954
955     return r;
956 }
957
958 /* TODO:
959
960 - chroot/drop privs/caps
961 - user script
962 - store last used address
963 - man page
964
965 */