main.c revision fee9053f6a8a22ff53d59fc7865230ad41fdf760
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 43#include <avahi-common/malloc.h> 44#include <avahi-common/timeval.h> 45 46#include <avahi-daemon/setproctitle.h> 47 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> 53 54#include "main.h" 55#include "iface.h" 56 57#ifndef __linux__ 58#error "avahi-autoipd is only available on Linux for now" 59#endif 60 61/* An implementation of RFC 3927 */ 62 63/* Constants from the RFC */ 64#define PROBE_WAIT 1 65#define PROBE_NUM 3 66#define PROBE_MIN 1 67#define PROBE_MAX 2 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 74 75#define IPV4LL_NETWORK 0xA9FE0000L 76#define IPV4LL_NETMASK 0xFFFF0000L 77#define IPV4LL_HOSTMASK 0x0000FFFFL 78 79#define ETHER_ADDRLEN 6 80#define ARP_PACKET_SIZE (8+4+4+2*ETHER_ADDRLEN) 81 82typedef enum ArpOperation { 83 ARP_REQUEST = 1, 84 ARP_RESPONSE = 2 85} ArpOperation; 86 87typedef struct ArpPacketInfo { 88 ArpOperation operation; 89 90 uint32_t sender_ip_address, target_ip_address; 91 uint8_t sender_hw_address[ETHER_ADDRLEN], target_hw_address[ETHER_ADDRLEN]; 92} ArpPacketInfo; 93 94static State state = STATE_START; 95static int n_iteration = 0; 96static int n_conflict = 0; 97 98#define RANDOM_DEVICE "/dev/urandom" 99 100static void init_rand_seed(void) { 101 int fd; 102 unsigned seed = 0; 103 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)); 109 close(fd); 110 } 111 112 /* If the initialization failed by some reason, we add the time to the seed */ 113 seed ^= (unsigned) time(NULL); 114 115 srand(seed); 116} 117 118static uint32_t pick_addr(uint32_t old_addr) { 119 uint32_t addr; 120 121 do { 122 unsigned r = (unsigned) rand(); 123 124 /* Reduce to 16 bits */ 125 while (r > 0xFFFF) 126 r = (r >> 16) ^ (r & 0xFFFF); 127 128 addr = htonl(IPV4LL_NETWORK | (uint32_t) r); 129 130 } while (addr == old_addr); 131 132 return addr; 133} 134 135static void* packet_new(const ArpPacketInfo *info, size_t *packet_len) { 136 uint8_t *r; 137 138 assert(info); 139 assert(packet_len); 140 assert(info->operation == ARP_REQUEST || info->operation == ARP_RESPONSE); 141 142 *packet_len = ARP_PACKET_SIZE; 143 r = avahi_new0(uint8_t, *packet_len); 144 145 r[1] = 1; /* HTYPE */ 146 r[2] = 8; /* PTYPE */ 147 r[4] = ETHER_ADDRLEN; /* HLEN */ 148 r[5] = 4; /* PLEN */ 149 r[7] = (uint8_t) info->operation; 150 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); 155 156 return r; 157} 158 159static void *packet_new_probe(uint32_t ip_address, const uint8_t*hw_address, size_t *packet_len) { 160 ArpPacketInfo info; 161 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; 166 167 return packet_new(&info, packet_len); 168} 169 170static void *packet_new_announcement(uint32_t ip_address, const uint8_t* hw_address, size_t *packet_len) { 171 ArpPacketInfo info; 172 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; 178 179 return packet_new(&info, packet_len); 180} 181 182static int packet_parse(const void *data, size_t packet_len, ArpPacketInfo *info) { 183 const uint8_t *p = data; 184 185 assert(data); 186 187 if (packet_len < ARP_PACKET_SIZE) 188 return -1; 189 190 /* Check HTYPE and PTYPE */ 191 if (p[0] != 0 || p[1] != 1 || p[2] != 8 || p[3] != 0) 192 return -1; 193 194 /* Check HLEN, PLEN, OPERATION */ 195 if (p[4] != ETHER_ADDRLEN || p[5] != 4 || p[6] != 0 || (p[7] != 1 && p[7] != 2)) 196 return -1; 197 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); 203 204 return 0; 205} 206 207static 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" 216 }; 217 218 assert(st < STATE_MAX); 219 220 if (st == state && !reset_counter) { 221 n_iteration++; 222 daemon_log(LOG_DEBUG, "State iteration %s-%i", state_table[state], n_iteration); 223 } else { 224 daemon_log(LOG_DEBUG, "State transition %s-%i -> %s-0", state_table[state], n_iteration, state_table[st]); 225 state = st; 226 n_iteration = 0; 227 } 228} 229 230static int add_address(int iface, uint32_t addr) { 231 char buf[64]; 232 233 daemon_log(LOG_INFO, "Configuring address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 234 return 0; 235} 236 237static int remove_address(int iface, uint32_t addr) { 238 char buf[64]; 239 240 daemon_log(LOG_INFO, "Unconfiguring address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 241 return 0; 242} 243 244static int open_socket(int iface, uint8_t *hw_address) { 245 int fd = -1; 246 struct sockaddr_ll sa; 247 socklen_t sa_len; 248 249 if ((fd = socket(PF_PACKET, SOCK_DGRAM, 0)) < 0) { 250 daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno)); 251 goto fail; 252 } 253 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; 258 259 if (bind(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 260 daemon_log(LOG_ERR, "bind() failed: %s", strerror(errno)); 261 goto fail; 262 } 263 264 sa_len = sizeof(sa); 265 if (getsockname(fd, (struct sockaddr*) &sa, &sa_len) < 0) { 266 daemon_log(LOG_ERR, "getsockname() failed: %s", strerror(errno)); 267 goto fail; 268 } 269 270 if (sa.sll_halen != ETHER_ADDRLEN) { 271 daemon_log(LOG_ERR, "getsockname() returned invalid hardware address."); 272 goto fail; 273 } 274 275 memcpy(hw_address, sa.sll_addr, ETHER_ADDRLEN); 276 277 return fd; 278 279fail: 280 if (fd >= 0) 281 close(fd); 282 283 return -1; 284} 285 286static int send_packet(int fd, int iface, void *packet, size_t packet_len) { 287 struct sockaddr_ll sa; 288 289 assert(fd >= 0); 290 assert(packet); 291 assert(packet_len > 0); 292 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); 299 300 if (sendto(fd, packet, packet_len, 0, (struct sockaddr*) &sa, sizeof(sa)) < 0) { 301 daemon_log(LOG_ERR, "sendto() failed: %s", strerror(errno)); 302 return -1; 303 } 304 305 return 0; 306} 307 308static int recv_packet(int fd, void **packet, size_t *packet_len) { 309 int s; 310 struct sockaddr_ll sa; 311 socklen_t sa_len; 312 313 assert(fd >= 0); 314 assert(packet); 315 assert(packet_len); 316 317 *packet = NULL; 318 319 if (ioctl(fd, FIONREAD, &s) < 0) { 320 daemon_log(LOG_ERR, "FIONREAD failed: %s", strerror(errno)); 321 goto fail; 322 } 323 324 assert(s > 0); 325 326 *packet_len = (size_t) s; 327 *packet = avahi_new(uint8_t, s); 328 329 sa_len = sizeof(sa); 330 if (recvfrom(fd, *packet, s, 0, (struct sockaddr*) &sa, &sa_len) < 0) { 331 daemon_log(LOG_ERR, "recvfrom() failed: %s", strerror(errno)); 332 goto fail; 333 } 334 335 return 0; 336 337fail: 338 if (*packet) 339 avahi_free(*packet); 340 341 return -1; 342} 343 344int is_ll_address(uint32_t addr) { 345 return (ntohl(addr) & IPV4LL_NETMASK) == IPV4LL_NETWORK; 346} 347 348static struct timeval *elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) { 349 assert(tv); 350 351 gettimeofday(tv, NULL); 352 353 if (msec) 354 avahi_timeval_add(tv, (AvahiUsec) msec*1000); 355 356 if (jitter) 357 avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*rand()/(RAND_MAX+1.0))); 358 359 return tv; 360} 361 362static int loop(int iface, uint32_t addr) { 363 enum { 364 FD_ARP, 365 FD_IFACE, 366 FD_MAX 367 }; 368 369 int fd = -1, ret = -1; 370 struct timeval next_wakeup; 371 int next_wakeup_valid = 0; 372 char buf[64]; 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]; 379 int iface_fd; 380 Event event = EVENT_NULL; 381 382 if ((fd = open_socket(iface, hw_address)) < 0) 383 goto fail; 384 385 if ((iface_fd = iface_init(iface)) < 0) 386 goto fail; 387 388 if (iface_get_initial_state(&state) < 0) 389 goto fail; 390 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))); 393 addr = 0; 394 } 395 396 if (!addr) { 397 int i; 398 uint32_t a = 1; 399 400 for (i = 0; i < ETHER_ADDRLEN; i++) 401 a += hw_address[i]*i; 402 403 addr = htonl(IPV4LL_NETWORK | (uint32_t) a); 404 } 405 406 daemon_log(LOG_INFO, "Starting with address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 407 408 if (state == STATE_SLEEPING) 409 daemon_log(LOG_INFO, "Routable address already assigned, sleeping."); 410 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; 416 417 for (;;) { 418 int r, timeout; 419 AvahiUsec usec; 420 421 if (state == STATE_START) { 422 423 /* First, wait a random time */ 424 set_state(STATE_WAITING_PROBE, 1); 425 426 elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 427 next_wakeup_valid = 1; 428 429 } else if ((state == STATE_WAITING_PROBE && event == EVENT_TIMEOUT) || 430 (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration < PROBE_NUM-2)) { 431 432 /* Send a probe */ 433 out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 434 set_state(STATE_PROBING, 0); 435 436 elapse_time(&next_wakeup, PROBE_MIN*1000, (PROBE_MAX-PROBE_MIN)*1000); 437 next_wakeup_valid = 1; 438 439 } else if (state == STATE_PROBING && event == EVENT_TIMEOUT && n_iteration >= PROBE_NUM-2) { 440 441 /* Send the last probe */ 442 out_packet = packet_new_probe(addr, hw_address, &out_packet_len); 443 set_state(STATE_WAITING_ANNOUNCE, 1); 444 445 elapse_time(&next_wakeup, ANNOUNCE_WAIT*1000, 0); 446 next_wakeup_valid = 1; 447 448 } else if ((state == STATE_WAITING_ANNOUNCE && event == EVENT_TIMEOUT) || 449 (state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration < ANNOUNCE_NUM-1)) { 450 451 /* Send announcement packet */ 452 out_packet = packet_new_announcement(addr, hw_address, &out_packet_len); 453 set_state(STATE_ANNOUNCING, 0); 454 455 elapse_time(&next_wakeup, ANNOUNCE_INTERVAL*1000, 0); 456 next_wakeup_valid = 1; 457 458 if (n_iteration == 0) { 459 add_address(iface, addr); 460 n_conflict = 0; 461 } 462 463 } else if ((state == STATE_ANNOUNCING && event == EVENT_TIMEOUT && n_iteration >= ANNOUNCE_NUM-1)) { 464 465 daemon_log(LOG_INFO, "Successfully claimed IP address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 466 set_state(STATE_RUNNING, 0); 467 468 next_wakeup_valid = 0; 469 470 } else if (event == EVENT_PACKET) { 471 ArpPacketInfo info; 472 473 assert(in_packet); 474 475 if (packet_parse(in_packet, in_packet_len, &info) < 0) 476 daemon_log(LOG_WARNING, "Failed to parse incoming ARP packet."); 477 else { 478 int conflict = 0; 479 480 if (info.sender_ip_address == addr) { 481 /* Normal conflict */ 482 conflict = 1; 483 daemon_log(LOG_INFO, "Recieved conflicting normal ARP packet."); 484 } else if (state == STATE_WAITING_PROBE || state == STATE_PROBING || state == STATE_WAITING_ANNOUNCE) { 485 /* Probe conflict */ 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."); 488 } 489 490 if (conflict) { 491 492 if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 493 remove_address(iface, addr); 494 495 /* Pick a new address */ 496 addr = pick_addr(addr); 497 498 daemon_log(LOG_INFO, "Trying address %s", inet_ntop(AF_INET, &addr, buf, sizeof(buf))); 499 500 n_conflict++; 501 502 set_state(STATE_WAITING_PROBE, 1); 503 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); 507 } else 508 elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 509 510 next_wakeup_valid = 1; 511 } else 512 daemon_log(LOG_DEBUG, "Ignoring ARP packet."); 513 } 514 515 } else if (event == EVENT_ROUTABLE_ADDR_CONFIGURED) { 516 517 daemon_log(LOG_INFO, "A routable address has been configured."); 518 519 if (state == STATE_RUNNING || state == STATE_ANNOUNCING) 520 remove_address(iface, addr); 521 522 set_state(STATE_SLEEPING, 1); 523 next_wakeup_valid = 0; 524 525 } else if (event == EVENT_ROUTABLE_ADDR_UNCONFIGURED && state == STATE_SLEEPING) { 526 527 daemon_log(LOG_INFO, "No longer a routable address configured, restarting probe process."); 528 529 set_state(STATE_WAITING_PROBE, 1); 530 531 elapse_time(&next_wakeup, 0, PROBE_WAIT*1000); 532 next_wakeup_valid = 1; 533 534 } 535 536 if (out_packet) { 537 daemon_log(LOG_DEBUG, "sending..."); 538 539 if (send_packet(fd, iface, out_packet, out_packet_len) < 0) 540 goto fail; 541 542 avahi_free(out_packet); 543 out_packet = NULL; 544 } 545 546 if (in_packet) { 547 avahi_free(in_packet); 548 in_packet = NULL; 549 } 550 551 event = EVENT_NULL; 552 timeout = -1; 553 554 if (next_wakeup_valid) { 555 usec = avahi_age(&next_wakeup); 556 timeout = usec < 0 ? (int) (-usec/1000) : 0; 557 } 558 559 daemon_log(LOG_DEBUG, "sleeping %ims", timeout); 560 561 while ((r = poll(pollfds, FD_MAX, timeout)) < 0 && errno == EINTR) 562 ; 563 564 if (r < 0) { 565 daemon_log(LOG_ERR, "poll() failed: %s", strerror(r)); 566 break; 567 } else if (r == 0) { 568 event = EVENT_TIMEOUT; 569 next_wakeup_valid = 0; 570 } else { 571 572 if (pollfds[FD_ARP].revents == POLLIN) { 573 if (recv_packet(fd, &in_packet, &in_packet_len) < 0) 574 goto fail; 575 576 if (in_packet) 577 event = EVENT_PACKET; 578 } 579 580 if (event == EVENT_NULL && 581 pollfds[FD_IFACE].revents == POLLIN) { 582 583 if (iface_process(&event) < 0) 584 goto fail; 585 } 586 } 587 } 588 589 ret = 0; 590 591fail: 592 593 avahi_free(out_packet); 594 avahi_free(in_packet); 595 596 if (fd >= 0) 597 close(fd); 598 599 if (iface_fd >= 0) 600 iface_done(); 601 602 return ret; 603} 604 605static int get_ifindex(const char *name) { 606 int fd = -1; 607 struct ifreq ifreq; 608 609 if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 610 daemon_log(LOG_ERR, "socket() failed: %s", strerror(errno)); 611 goto fail; 612 } 613 614 memset(&ifreq, 0, sizeof(ifreq)); 615 strncpy(ifreq.ifr_name, name, IFNAMSIZ-1); 616 ifreq.ifr_name[IFNAMSIZ-1] = 0; 617 618 if (ioctl(fd, SIOCGIFINDEX, &ifreq) < 0) { 619 daemon_log(LOG_ERR, "SIOCGIFINDEX failed: %s", strerror(errno)); 620 goto fail; 621 } 622 623 return ifreq.ifr_ifindex; 624 625fail: 626 627 if (fd >= 0) 628 close(fd); 629 630 return -1; 631} 632 633int main(int argc, char*argv[]) { 634 int ret = 1; 635 int ifindex; 636 uint32_t addr = 0; 637 638 avahi_init_proc_title(argc, argv); 639 640 init_rand_seed(); 641 642 if ((ifindex = get_ifindex(argc >= 2 ? argv[1] : "eth0")) < 0) 643 goto fail; 644 645 if (argc >= 3) 646 addr = inet_addr(argv[2]); 647 648 if (loop(ifindex, addr) < 0) 649 goto fail; 650 651 ret = 0; 652 653 654fail: 655 656 return ret; 657} 658 659/* TODO: 660 661- man page 662- user script 663- chroot/drop privs/caps 664- daemonize 665- defend 666- signals 667- store last used address 668- cmdline 669- setproctitle 670 671*/ 672