4 This file is part of avahi.
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.
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.
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
28 #include <sys/socket.h>
29 #include <netpacket/packet.h>
30 #include <net/ethernet.h>
37 #include <sys/types.h>
38 #include <arpa/inet.h>
39 #include <sys/ioctl.h>
43 #include <avahi-common/malloc.h>
44 #include <avahi-common/timeval.h>
46 #include <avahi-daemon/setproctitle.h>
48 #include <libdaemon/dfork.h>
49 #include <libdaemon/dsignal.h>
50 #include <libdaemon/dlog.h>
51 #include <libdaemon/dpid.h>
52 #include <libdaemon/dexec.h>
58 #error "avahi-autoipd is only available on Linux for now"
61 /* An implementation of RFC 3927 */
63 /* Constants from the RFC */
68 #define ANNOUNCE_WAIT 2
69 #define ANNOUNCE_NUM 2
70 #define ANNOUNCE_INTERVAL 2
71 #define MAX_CONFLICTS 10
72 #define RATE_LIMIT_INTERVAL 60
73 #define DEFEND_INTERVAL 10
75 #define IPV4LL_NETWORK 0xA9FE0000L
76 #define IPV4LL_NETMASK 0xFFFF0000L
77 #define IPV4LL_HOSTMASK 0x0000FFFFL
79 #define ETHER_ADDRLEN 6
80 #define ARP_PACKET_SIZE (8+4+4+2*ETHER_ADDRLEN)
82 typedef enum ArpOperation {
87 typedef struct ArpPacketInfo {
88 ArpOperation operation;
90 uint32_t sender_ip_address, target_ip_address;
91 uint8_t sender_hw_address[ETHER_ADDRLEN], target_hw_address[ETHER_ADDRLEN];
94 static State state = STATE_START;
95 static int n_iteration = 0;
96 static int n_conflict = 0;
98 #define RANDOM_DEVICE "/dev/urandom"
100 static void init_rand_seed(void) {
104 /* Try to initialize seed from /dev/urandom, to make it a little
105 * less predictable, and to make sure that multiple machines
106 * booted at the same time choose different random seeds. */
107 if ((fd = open(RANDOM_DEVICE, O_RDONLY)) >= 0) {
108 read(fd, &seed, sizeof(seed));
112 /* If the initialization failed by some reason, we add the time to the seed */
113 seed ^= (unsigned) time(NULL);
118 static uint32_t pick_addr(uint32_t old_addr) {
122 unsigned r = (unsigned) rand();
124 /* Reduce to 16 bits */
126 r = (r >> 16) ^ (r & 0xFFFF);
128 addr = htonl(IPV4LL_NETWORK | (uint32_t) r);
130 } while (addr == old_addr);
135 static void* packet_new(const ArpPacketInfo *info, size_t *packet_len) {
140 assert(info->operation == ARP_REQUEST || info->operation == ARP_RESPONSE);
142 *packet_len = ARP_PACKET_SIZE;
143 r = avahi_new0(uint8_t, *packet_len);
145 r[1] = 1; /* HTYPE */
146 r[2] = 8; /* PTYPE */
147 r[4] = ETHER_ADDRLEN; /* HLEN */
149 r[7] = (uint8_t) info->operation;
151 memcpy(r+8, info->sender_hw_address, ETHER_ADDRLEN);
152 memcpy(r+14, &info->sender_ip_address, 4);
153 memcpy(r+18, info->target_hw_address, ETHER_ADDRLEN);
154 memcpy(r+24, &info->target_ip_address, 4);
159 static void *packet_new_probe(uint32_t ip_address, const uint8_t*hw_address, size_t *packet_len) {
162 memset(&info, 0, sizeof(info));
163 info.operation = ARP_REQUEST;
164 memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN);
165 info.target_ip_address = ip_address;
167 return packet_new(&info, packet_len);
170 static void *packet_new_announcement(uint32_t ip_address, const uint8_t* hw_address, size_t *packet_len) {
173 memset(&info, 0, sizeof(info));
174 info.operation = ARP_REQUEST;
175 memcpy(info.sender_hw_address, hw_address, ETHER_ADDRLEN);
176 info.target_ip_address = ip_address;
177 info.sender_ip_address = ip_address;
179 return packet_new(&info, packet_len);
182 static int packet_parse(const void *data, size_t packet_len, ArpPacketInfo *info) {
183 const uint8_t *p = data;
187 if (packet_len < ARP_PACKET_SIZE)
190 /* Check HTYPE and PTYPE */
191 if (p[0] != 0 || p[1] != 1 || p[2] != 8 || p[3] != 0)
194 /* Check HLEN, PLEN, OPERATION */
195 if (p[4] != ETHER_ADDRLEN || p[5] != 4 || p[6] != 0 || (p[7] != 1 && p[7] != 2))
198 info->operation = p[7];
199 memcpy(info->sender_hw_address, p+8, ETHER_ADDRLEN);
200 memcpy(&info->sender_ip_address, p+14, 4);
201 memcpy(info->target_hw_address, p+18, ETHER_ADDRLEN);
202 memcpy(&info->target_ip_address, p+24, 4);
207 static void set_state(State st, int reset_counter) {
208 const char* const state_table[] = {
209 [STATE_START] = "START",
210 [STATE_WAITING_PROBE] = "WAITING_PROBE",
211 [STATE_PROBING] = "PROBING",
212 [STATE_WAITING_ANNOUNCE] = "WAITING_ANNOUNCE",
213 [STATE_ANNOUNCING] = "ANNOUNCING",
214 [STATE_RUNNING] = "RUNNING",
215 [STATE_SLEEPING] = "SLEEPING"
218 assert(st < STATE_MAX);
220 if (st == state && !reset_counter) {
222 daemon_log(LOG_DEBUG, "State iteration %s-%i", state_table[state], n_iteration);
224 daemon_log(LOG_DEBUG, "State transition %s-%i -> %s-0", state_table[state], n_iteration, state_table[st]);
230 static int add_address(int iface, uint32_t addr) {
233 daemon_log(LOG_INFO, "Configuring address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
237 static int remove_address(int iface, uint32_t addr) {
240 daemon_log(LOG_INFO, "Unconfiguring address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
244 static int open_socket(int iface, uint8_t *hw_address) {
246 struct sockaddr_ll sa;
249 if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) < 0) {
250 daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno));
254 memset(&sa, 0, sizeof(sa));
255 sa.sll_family = AF_PACKET;
256 sa.sll_protocol = htons(ETH_P_ARP);
257 sa.sll_ifindex = iface;
259 if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) {
260 daemon_log(LOG_ERR, "bind() failed: %s", strerror(errno));
265 if (getsockname(fd, (struct sockaddr*) &sa, &sa_len) < 0) {
266 daemon_log(LOG_ERR, "getsockname() failed: %s", strerror(errno));
270 if (sa.sll_halen != ETHER_ADDRLEN) {
271 daemon_log(LOG_ERR, "getsockname() returned invalid hardware address.");
275 memcpy(hw_address, sa.sll_addr, ETHER_ADDRLEN);
286 static int send_packet(int fd, int iface, void *packet, size_t packet_len) {
287 struct sockaddr_ll sa;
291 assert(packet_len > 0);
293 memset(&sa, 0, sizeof(sa));
294 sa.sll_family = AF_PACKET;
295 sa.sll_protocol = htons(ETH_P_ARP);
296 sa.sll_ifindex = iface;
297 sa.sll_halen = ETHER_ADDRLEN;
298 memset(sa.sll_addr, 0xFF, ETHER_ADDRLEN);
300 if (sendto(fd, packet, packet_len, 0, (struct sockaddr*) &sa, sizeof(sa)) < 0) {
301 daemon_log(LOG_ERR, "sendto() failed: %s", strerror(errno));
308 static int recv_packet(int fd, void **packet, size_t *packet_len) {
310 struct sockaddr_ll sa;
319 if (ioctl(fd, FIONREAD, &s) < 0) {
320 daemon_log(LOG_ERR, "FIONREAD failed: %s", strerror(errno));
326 *packet_len = (size_t) s;
327 *packet = avahi_new(uint8_t, s);
330 if (recvfrom(fd, *packet, s, 0, (struct sockaddr*) &sa, &sa_len) < 0) {
331 daemon_log(LOG_ERR, "recvfrom() failed: %s", strerror(errno));
344 int is_ll_address(uint32_t addr) {
345 return (ntohl(addr) & IPV4LL_NETMASK) == IPV4LL_NETWORK;
348 static struct timeval *elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) {
351 gettimeofday(tv, NULL);
354 avahi_timeval_add(tv, (AvahiUsec) msec*1000);
357 avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0)));
362 static int loop(int iface, uint32_t addr) {
369 int fd = -1, ret = -1;
370 struct timeval next_wakeup;
371 int next_wakeup_valid = 0;
373 void *in_packet = NULL;
374 size_t in_packet_len;
375 void *out_packet = NULL;
376 size_t out_packet_len;
377 uint8_t hw_address[ETHER_ADDRLEN];
378 struct pollfd pollfds[FD_MAX];
380 Event event = EVENT_NULL;
382 if ((fd = open_socket(iface, hw_address)) < 0)
385 if ((iface_fd = iface_init(iface)) < 0)
388 if (iface_get_initial_state(&state) < 0)
391 if (addr && !is_ll_address(addr)) {
392 daemon_log(LOG_WARNING, "Requested address %s is not from IPv4LL range 169.254/16, ignoring.", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
400 for (i = 0; i < ETHER_ADDRLEN; i++)
401 a += hw_address[i]*i;
403 addr = htonl(IPV4LL_NETWORK | (uint32_t) a);
406 daemon_log(LOG_INFO, "Starting with address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
408 if (state == STATE_SLEEPING)
409 daemon_log(LOG_INFO, "Routable address already assigned, sleeping.");
411 memset(pollfds, 0, sizeof(pollfds));
412 pollfds[FD_ARP].fd = fd;
413 pollfds[FD_ARP].events = POLLIN;
414 pollfds[FD_IFACE].fd = iface_fd;
415 pollfds[FD_IFACE].events = POLLIN;
421 if (state == STATE_START) {
423 /* First, wait a random time */
424 set_state(STATE_WAITING_PROBE, 1);
426 elapse_time(&next_wakeup, 0, PROBE_WAIT*1000);
427 next_wakeup_valid = 1;
429 } else if ((state == STATE_WAITING_PROBE && event == EVENT_TIMEOUT) ||
430 (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration < PROBE_NUM-2)) {
433 out_packet = packet_new_probe(addr, hw_address, &out_packet_len);
434 set_state(STATE_PROBING, 0);
436 elapse_time(&next_wakeup, PROBE_MIN*1000, (PROBE_MAX-PROBE_MIN)*1000);
437 next_wakeup_valid = 1;
439 } else if (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration >= PROBE_NUM-2) {
441 /* Send the last probe */
442 out_packet = packet_new_probe(addr, hw_address, &out_packet_len);
443 set_state(STATE_WAITING_ANNOUNCE, 1);
445 elapse_time(&next_wakeup, ANNOUNCE_WAIT*1000, 0);
446 next_wakeup_valid = 1;
448 } else if ((state == STATE_WAITING_ANNOUNCE && event == EVENT_TIMEOUT) ||
449 (state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration < ANNOUNCE_NUM-1)) {
451 /* Send announcement packet */
452 out_packet = packet_new_announcement(addr, hw_address, &out_packet_len);
453 set_state(STATE_ANNOUNCING, 0);
455 elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0);
456 next_wakeup_valid = 1;
458 if (n_iteration == 0) {
459 add_address(iface, addr);
463 } else if ((state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration >= ANNOUNCE_NUM-1)) {
465 daemon_log(LOG_INFO, "Successfully claimed IP address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
466 set_state(STATE_RUNNING, 0);
468 next_wakeup_valid = 0;
470 } else if (event == EVENT_PACKET) {
475 if (packet_parse(in_packet, in_packet_len, &info) < 0)
476 daemon_log(LOG_WARNING, "Failed to parse incoming ARP packet.");
480 if (info.sender_ip_address == addr) {
481 /* Normal conflict */
483 daemon_log(LOG_INFO, "Recieved conflicting normal ARP packet.");
484 } else if (state == STATE_WAITING_PROBE || state == STATE_PROBING || state == STATE_WAITING_ANNOUNCE) {
486 conflict = info.target_ip_address == addr && memcmp(hw_address, info.sender_hw_address, ETHER_ADDRLEN);
487 daemon_log(LOG_INFO, "Recieved conflicting probe ARP packet.");
492 if (state == STATE_RUNNING || state == STATE_ANNOUNCING)
493 remove_address(iface, addr);
495 /* Pick a new address */
496 addr = pick_addr(addr);
498 daemon_log(LOG_INFO, "Trying address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
502 set_state(STATE_WAITING_PROBE, 1);
504 if (n_conflict >= MAX_CONFLICTS) {
505 daemon_log(LOG_WARNING, "Got too many conflicts, rate limiting new probes.");
506 elapse_time(&next_wakeup, RATE_LIMIT_INTERVAL*1000, PROBE_WAIT*1000);
508 elapse_time(&next_wakeup, 0, PROBE_WAIT*1000);
510 next_wakeup_valid = 1;
512 daemon_log(LOG_DEBUG, "Ignoring ARP packet.");
515 } else if (event == EVENT_ROUTABLE_ADDR_CONFIGURED) {
517 daemon_log(LOG_INFO, "A routable address has been configured.");
519 if (state == STATE_RUNNING || state == STATE_ANNOUNCING)
520 remove_address(iface, addr);
522 set_state(STATE_SLEEPING, 1);
523 next_wakeup_valid = 0;
525 } else if (event == EVENT_ROUTABLE_ADDR_UNCONFIGURED && state == STATE_SLEEPING) {
527 daemon_log(LOG_INFO, "No longer a routable address configured, restarting probe process.");
529 set_state(STATE_WAITING_PROBE, 1);
531 elapse_time(&next_wakeup, 0, PROBE_WAIT*1000);
532 next_wakeup_valid = 1;
537 daemon_log(LOG_DEBUG, "sending...");
539 if (send_packet(fd, iface, out_packet, out_packet_len) < 0)
542 avahi_free(out_packet);
547 avahi_free(in_packet);
554 if (next_wakeup_valid) {
555 usec = avahi_age(&next_wakeup);
556 timeout = usec < 0 ? (int) (-usec/1000) : 0;
559 daemon_log(LOG_DEBUG, "sleeping %ims", timeout);
561 while ((r = poll(pollfds, FD_MAX, timeout)) < 0 && errno == EINTR)
565 daemon_log(LOG_ERR, "poll() failed: %s", strerror(r));
568 event = EVENT_TIMEOUT;
569 next_wakeup_valid = 0;
572 if (pollfds[FD_ARP].revents == POLLIN) {
573 if (recv_packet(fd, &in_packet, &in_packet_len) < 0)
577 event = EVENT_PACKET;
580 if (event == EVENT_NULL &&
581 pollfds[FD_IFACE].revents == POLLIN) {
583 if (iface_process(&event) < 0)
593 avahi_free(out_packet);
594 avahi_free(in_packet);
605 static int get_ifindex(const char *name) {
609 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
610 daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno));
614 memset(&ifreq, 0, sizeof(ifreq));
615 strncpy(ifreq.ifr_name, name, IFNAMSIZ-1);
616 ifreq.ifr_name[IFNAMSIZ-1] = 0;
618 if (ioctl(fd, SIOCGIFINDEX, &ifreq) < 0) {
619 daemon_log(LOG_ERR, "SIOCGIFINDEX failed: %s", strerror(errno));
623 return ifreq.ifr_ifindex;
633 int main(int argc, char*argv[]) {
638 avahi_init_proc_title(argc, argv);
642 if ((ifindex = get_ifindex(argc >= 2 ? argv[1] : "eth0")) < 0)
646 addr = inet_addr(argv[2]);
648 if (loop(ifindex, addr) < 0)
663 - chroot/drop privs/caps
667 - store last used address