1 /* 2 * arping.c 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: Alexey Kuznetsov, <kuznet (at) ms2.inr.ac.ru> 10 * YOSHIFUJI Hideaki <yoshfuji (at) linux-ipv6.org> 11 */ 12 13 #include <stdlib.h> 14 #include <sys/param.h> 15 #include <sys/socket.h> 16 #include <linux/sockios.h> 17 #include <sys/file.h> 18 #include <sys/time.h> 19 #include <sys/signal.h> 20 #include <sys/ioctl.h> 21 #include <net/if.h> 22 #include <linux/if_packet.h> 23 #include <linux/if_ether.h> 24 #include <net/if_arp.h> 25 #include <sys/uio.h> 26 #ifdef CAPABILITIES 27 #include <sys/prctl.h> 28 #include <sys/capability.h> 29 #endif 30 31 #include <netdb.h> 32 #include <unistd.h> 33 #include <stdio.h> 34 #include <ctype.h> 35 #include <errno.h> 36 #include <string.h> 37 #include <netinet/in.h> 38 #include <arpa/inet.h> 39 40 #ifdef USE_SYSFS 41 #include <sysfs/libsysfs.h> 42 struct sysfs_devattr_values; 43 #endif 44 45 #ifndef WITHOUT_IFADDRS 46 #include <ifaddrs.h> 47 #endif 48 49 #ifdef USE_IDN 50 #include <idna.h> 51 #include <locale.h> 52 #endif 53 54 #include "SNAPSHOT.h" 55 56 static void usage(void) __attribute__((noreturn)); 57 58 #ifdef DEFAULT_DEVICE 59 # define DEFAULT_DEVICE_STR DEFAULT_DEVICE 60 #else 61 # define DEFAULT_DEVICE NULL 62 #endif 63 64 struct device { 65 char *name; 66 int ifindex; 67 #ifndef WITHOUT_IFADDRS 68 struct ifaddrs *ifa; 69 #endif 70 #ifdef USE_SYSFS 71 struct sysfs_devattr_values *sysfs; 72 #endif 73 }; 74 75 int quit_on_reply=0; 76 struct device device = { 77 .name = DEFAULT_DEVICE, 78 }; 79 char *source; 80 struct in_addr src, dst; 81 char *target; 82 int dad, unsolicited, advert; 83 int quiet; 84 int count=-1; 85 int timeout; 86 int unicasting; 87 int s; 88 int broadcast_only; 89 90 struct sockaddr_storage me; 91 struct sockaddr_storage he; 92 93 struct timeval start, last; 94 95 int sent, brd_sent; 96 int received, brd_recv, req_recv; 97 98 #ifndef CAPABILITIES 99 static uid_t euid; 100 #endif 101 102 #define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ 103 ((tv1).tv_usec-(tv2).tv_usec)/1000 ) 104 105 #define OFFSET_OF(name,ele) ((size_t)(((name *)0)->ele)) 106 107 static inline socklen_t sll_len(size_t halen) 108 { 109 socklen_t len = OFFSET_OF(struct sockaddr_ll, sll_addr) + halen; 110 if (len < sizeof(struct sockaddr_ll)) 111 len = sizeof(struct sockaddr_ll); 112 return len; 113 } 114 115 #define SLL_LEN(hln) sll_len(hln) 116 117 void usage(void) 118 { 119 fprintf(stderr, 120 "Usage: arping [-fqbDUAV] [-c count] [-w timeout] [-I device] [-s source] destination\n" 121 " -f : quit on first reply\n" 122 " -q : be quiet\n" 123 " -b : keep broadcasting, don't go unicast\n" 124 " -D : duplicate address detection mode\n" 125 " -U : Unsolicited ARP mode, update your neighbours\n" 126 " -A : ARP answer mode, update your neighbours\n" 127 " -V : print version and exit\n" 128 " -c count : how many packets to send\n" 129 " -w timeout : how long to wait for a reply\n" 130 " -I device : which ethernet device to use" 131 #ifdef DEFAULT_DEVICE_STR 132 " (" DEFAULT_DEVICE_STR ")" 133 #endif 134 "\n" 135 " -s source : source ip address\n" 136 " destination : ask for what ip address\n" 137 ); 138 exit(2); 139 } 140 141 void set_signal(int signo, void (*handler)(void)) 142 { 143 struct sigaction sa; 144 145 memset(&sa, 0, sizeof(sa)); 146 sa.sa_handler = (void (*)(int))handler; 147 sa.sa_flags = SA_RESTART; 148 sigaction(signo, &sa, NULL); 149 } 150 151 #ifdef CAPABILITIES 152 static const cap_value_t caps[] = { CAP_NET_RAW, }; 153 static cap_flag_value_t cap_raw = CAP_CLEAR; 154 #endif 155 156 void limit_capabilities(void) 157 { 158 #ifdef CAPABILITIES 159 cap_t cap_p; 160 161 cap_p = cap_get_proc(); 162 if (!cap_p) { 163 perror("arping: cap_get_proc"); 164 exit(-1); 165 } 166 167 cap_get_flag(cap_p, CAP_NET_RAW, CAP_PERMITTED, &cap_raw); 168 169 if (cap_raw != CAP_CLEAR) { 170 if (cap_clear(cap_p) < 0) { 171 perror("arping: cap_clear"); 172 exit(-1); 173 } 174 175 cap_set_flag(cap_p, CAP_PERMITTED, 1, caps, CAP_SET); 176 177 if (cap_set_proc(cap_p) < 0) { 178 perror("arping: cap_set_proc"); 179 if (errno != EPERM) 180 exit(-1); 181 } 182 } 183 184 if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 185 perror("arping: prctl"); 186 exit(-1); 187 } 188 189 if (setuid(getuid()) < 0) { 190 perror("arping: setuid"); 191 exit(-1); 192 } 193 194 if (prctl(PR_SET_KEEPCAPS, 0) < 0) { 195 perror("arping: prctl"); 196 exit(-1); 197 } 198 199 cap_free(cap_p); 200 #else 201 euid = geteuid(); 202 #endif 203 } 204 205 int modify_capability_raw(int on) 206 { 207 #ifdef CAPABILITIES 208 cap_t cap_p; 209 210 if (cap_raw != CAP_SET) 211 return on ? -1 : 0; 212 213 cap_p = cap_get_proc(); 214 if (!cap_p) { 215 perror("arping: cap_get_proc"); 216 return -1; 217 } 218 219 cap_set_flag(cap_p, CAP_EFFECTIVE, 1, caps, on ? CAP_SET : CAP_CLEAR); 220 221 if (cap_set_proc(cap_p) < 0) { 222 perror("arping: cap_set_proc"); 223 return -1; 224 } 225 226 cap_free(cap_p); 227 #else 228 if (setuid(on ? euid : getuid())) { 229 perror("arping: setuid"); 230 return -1; 231 } 232 #endif 233 return 0; 234 } 235 236 static inline int enable_capability_raw(void) 237 { 238 return modify_capability_raw(1); 239 } 240 241 static inline int disable_capability_raw(void) 242 { 243 return modify_capability_raw(0); 244 } 245 246 void drop_capabilities(void) 247 { 248 #ifdef CAPABILITIES 249 cap_t cap_p = cap_init(); 250 251 if (!cap_p) { 252 perror("arping: cap_init"); 253 exit(-1); 254 } 255 256 if (cap_set_proc(cap_p) < 0) { 257 perror("arping: cap_set_proc"); 258 exit(-1); 259 } 260 261 cap_free(cap_p); 262 #else 263 if (setuid(getuid()) < 0) { 264 perror("arping: setuid"); 265 exit(-1); 266 } 267 #endif 268 } 269 270 int send_pack(int s, struct in_addr src, struct in_addr dst, 271 struct sockaddr_ll *ME, struct sockaddr_ll *HE) 272 { 273 int err; 274 struct timeval now; 275 unsigned char buf[256]; 276 struct arphdr *ah = (struct arphdr*)buf; 277 unsigned char *p = (unsigned char *)(ah+1); 278 279 ah->ar_hrd = htons(ME->sll_hatype); 280 if (ah->ar_hrd == htons(ARPHRD_FDDI)) 281 ah->ar_hrd = htons(ARPHRD_ETHER); 282 ah->ar_pro = htons(ETH_P_IP); 283 ah->ar_hln = ME->sll_halen; 284 ah->ar_pln = 4; 285 ah->ar_op = advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); 286 287 memcpy(p, &ME->sll_addr, ah->ar_hln); 288 p+=ME->sll_halen; 289 290 memcpy(p, &src, 4); 291 p+=4; 292 293 if (advert) 294 memcpy(p, &ME->sll_addr, ah->ar_hln); 295 else 296 memcpy(p, &HE->sll_addr, ah->ar_hln); 297 p+=ah->ar_hln; 298 299 memcpy(p, &dst, 4); 300 p+=4; 301 302 gettimeofday(&now, NULL); 303 err = sendto(s, buf, p-buf, 0, (struct sockaddr*)HE, SLL_LEN(ah->ar_hln)); 304 if (err == p-buf) { 305 last = now; 306 sent++; 307 if (!unicasting) 308 brd_sent++; 309 } 310 return err; 311 } 312 313 void finish(void) 314 { 315 if (!quiet) { 316 printf("Sent %d probes (%d broadcast(s))\n", sent, brd_sent); 317 printf("Received %d response(s)", received); 318 if (brd_recv || req_recv) { 319 printf(" ("); 320 if (req_recv) 321 printf("%d request(s)", req_recv); 322 if (brd_recv) 323 printf("%s%d broadcast(s)", 324 req_recv ? ", " : "", 325 brd_recv); 326 printf(")"); 327 } 328 printf("\n"); 329 fflush(stdout); 330 } 331 if (dad) 332 exit(!!received); 333 if (unsolicited) 334 exit(0); 335 exit(!received); 336 } 337 338 void catcher(void) 339 { 340 struct timeval tv, tv_s, tv_o; 341 342 gettimeofday(&tv, NULL); 343 344 if (start.tv_sec==0) 345 start = tv; 346 347 timersub(&tv, &start, &tv_s); 348 tv_o.tv_sec = timeout; 349 tv_o.tv_usec = 500 * 1000; 350 351 if (count-- == 0 || (timeout && timercmp(&tv_s, &tv_o, >))) 352 finish(); 353 354 timersub(&tv, &last, &tv_s); 355 tv_o.tv_sec = 0; 356 357 if (last.tv_sec==0 || timercmp(&tv_s, &tv_o, >)) { 358 send_pack(s, src, dst, 359 (struct sockaddr_ll *)&me, (struct sockaddr_ll *)&he); 360 if (count == 0 && unsolicited) 361 finish(); 362 } 363 alarm(1); 364 } 365 366 void print_hex(unsigned char *p, int len) 367 { 368 int i; 369 for (i=0; i<len; i++) { 370 printf("%02X", p[i]); 371 if (i != len-1) 372 printf(":"); 373 } 374 } 375 376 int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) 377 { 378 struct timeval tv; 379 struct arphdr *ah = (struct arphdr*)buf; 380 unsigned char *p = (unsigned char *)(ah+1); 381 struct in_addr src_ip, dst_ip; 382 383 gettimeofday(&tv, NULL); 384 385 /* Filter out wild packets */ 386 if (FROM->sll_pkttype != PACKET_HOST && 387 FROM->sll_pkttype != PACKET_BROADCAST && 388 FROM->sll_pkttype != PACKET_MULTICAST) 389 return 0; 390 391 /* Only these types are recognised */ 392 if (ah->ar_op != htons(ARPOP_REQUEST) && 393 ah->ar_op != htons(ARPOP_REPLY)) 394 return 0; 395 396 /* ARPHRD check and this darned FDDI hack here :-( */ 397 if (ah->ar_hrd != htons(FROM->sll_hatype) && 398 (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER))) 399 return 0; 400 401 /* Protocol must be IP. */ 402 if (ah->ar_pro != htons(ETH_P_IP)) 403 return 0; 404 if (ah->ar_pln != 4) 405 return 0; 406 if (ah->ar_hln != ((struct sockaddr_ll *)&me)->sll_halen) 407 return 0; 408 if (len < sizeof(*ah) + 2*(4 + ah->ar_hln)) 409 return 0; 410 memcpy(&src_ip, p+ah->ar_hln, 4); 411 memcpy(&dst_ip, p+ah->ar_hln+4+ah->ar_hln, 4); 412 if (!dad) { 413 if (src_ip.s_addr != dst.s_addr) 414 return 0; 415 if (src.s_addr != dst_ip.s_addr) 416 return 0; 417 if (memcmp(p+ah->ar_hln+4, ((struct sockaddr_ll *)&me)->sll_addr, ah->ar_hln)) 418 return 0; 419 } else { 420 /* DAD packet was: 421 src_ip = 0 (or some src) 422 src_hw = ME 423 dst_ip = tested address 424 dst_hw = <unspec> 425 426 We fail, if receive request/reply with: 427 src_ip = tested_address 428 src_hw != ME 429 if src_ip in request was not zero, check 430 also that it matches to dst_ip, otherwise 431 dst_ip/dst_hw do not matter. 432 */ 433 if (src_ip.s_addr != dst.s_addr) 434 return 0; 435 if (memcmp(p, ((struct sockaddr_ll *)&me)->sll_addr, ((struct sockaddr_ll *)&me)->sll_halen) == 0) 436 return 0; 437 if (src.s_addr && src.s_addr != dst_ip.s_addr) 438 return 0; 439 } 440 if (!quiet) { 441 int s_printed = 0; 442 printf("%s ", FROM->sll_pkttype==PACKET_HOST ? "Unicast" : "Broadcast"); 443 printf("%s from ", ah->ar_op == htons(ARPOP_REPLY) ? "reply" : "request"); 444 printf("%s [", inet_ntoa(src_ip)); 445 print_hex(p, ah->ar_hln); 446 printf("] "); 447 if (dst_ip.s_addr != src.s_addr) { 448 printf("for %s ", inet_ntoa(dst_ip)); 449 s_printed = 1; 450 } 451 if (memcmp(p+ah->ar_hln+4, ((struct sockaddr_ll *)&me)->sll_addr, ah->ar_hln)) { 452 if (!s_printed) 453 printf("for "); 454 printf("["); 455 print_hex(p+ah->ar_hln+4, ah->ar_hln); 456 printf("]"); 457 } 458 if (last.tv_sec) { 459 long usecs = (tv.tv_sec-last.tv_sec) * 1000000 + 460 tv.tv_usec-last.tv_usec; 461 long msecs = (usecs+500)/1000; 462 usecs -= msecs*1000 - 500; 463 printf(" %ld.%03ldms\n", msecs, usecs); 464 } else { 465 printf(" UNSOLICITED?\n"); 466 } 467 fflush(stdout); 468 } 469 received++; 470 if (FROM->sll_pkttype != PACKET_HOST) 471 brd_recv++; 472 if (ah->ar_op == htons(ARPOP_REQUEST)) 473 req_recv++; 474 if (quit_on_reply) 475 finish(); 476 if(!broadcast_only) { 477 memcpy(((struct sockaddr_ll *)&he)->sll_addr, p, ((struct sockaddr_ll *)&me)->sll_halen); 478 unicasting=1; 479 } 480 return 1; 481 } 482 483 #ifdef USE_SYSFS 484 union sysfs_devattr_value { 485 unsigned long ulong; 486 void *ptr; 487 }; 488 489 enum { 490 SYSFS_DEVATTR_IFINDEX, 491 SYSFS_DEVATTR_FLAGS, 492 SYSFS_DEVATTR_ADDR_LEN, 493 #if 0 494 SYSFS_DEVATTR_TYPE, 495 SYSFS_DEVATTR_ADDRESS, 496 #endif 497 SYSFS_DEVATTR_BROADCAST, 498 SYSFS_DEVATTR_NUM 499 }; 500 501 struct sysfs_devattr_values 502 { 503 char *ifname; 504 union sysfs_devattr_value value[SYSFS_DEVATTR_NUM]; 505 }; 506 507 static int sysfs_devattr_ulong_dec(char *ptr, struct sysfs_devattr_values *v, unsigned idx); 508 static int sysfs_devattr_ulong_hex(char *ptr, struct sysfs_devattr_values *v, unsigned idx); 509 static int sysfs_devattr_macaddr(char *ptr, struct sysfs_devattr_values *v, unsigned idx); 510 511 struct sysfs_devattrs { 512 const char *name; 513 int (*handler)(char *ptr, struct sysfs_devattr_values *v, unsigned int idx); 514 int free; 515 } sysfs_devattrs[SYSFS_DEVATTR_NUM] = { 516 [SYSFS_DEVATTR_IFINDEX] = { 517 .name = "ifindex", 518 .handler = sysfs_devattr_ulong_dec, 519 }, 520 [SYSFS_DEVATTR_ADDR_LEN] = { 521 .name = "addr_len", 522 .handler = sysfs_devattr_ulong_dec, 523 }, 524 [SYSFS_DEVATTR_FLAGS] = { 525 .name = "flags", 526 .handler = sysfs_devattr_ulong_hex, 527 }, 528 #if 0 529 [SYSFS_DEVATTR_TYPE] = { 530 .name = "type", 531 .handler = sysfs_devattr_ulong_dec, 532 }, 533 [SYSFS_DEVATTR_ADDRESS] = { 534 .name = "address", 535 .handler = sysfs_devattr_macaddr, 536 .free = 1, 537 }, 538 #endif 539 [SYSFS_DEVATTR_BROADCAST] = { 540 .name = "broadcast", 541 .handler = sysfs_devattr_macaddr, 542 .free = 1, 543 }, 544 }; 545 #endif 546 547 /* 548 * find_device() 549 * 550 * This function checks 1) if the device (if given) is okay for ARP, 551 * or 2) find fist appropriate device on the system. 552 * 553 * Return value: 554 * >0 : Succeeded, and appropriate device not found. 555 * device.ifindex remains 0. 556 * 0 : Succeeded, and approptiate device found. 557 * device.ifindex is set. 558 * <0 : Failed. Support not found, or other 559 * : system error. Try other method. 560 * 561 * If an appropriate device found, it is recorded inside the 562 * "device" variable for later reference. 563 * 564 * We have several implementations for this. 565 * by_ifaddrs(): requires getifaddr() in glibc, and rtnetlink in 566 * kernel. default and recommended for recent systems. 567 * by_sysfs(): requires libsysfs , and sysfs in kernel. 568 * by_ioctl(): unable to list devices without ipv4 address; this 569 * means, you need to supply the device name for 570 * DAD purpose. 571 */ 572 /* Common check for ifa->ifa_flags */ 573 static int check_ifflags(unsigned int ifflags, int fatal) 574 { 575 if (!(ifflags & IFF_UP)) { 576 if (fatal) { 577 if (!quiet) 578 printf("Interface \"%s\" is down\n", device.name); 579 exit(2); 580 } 581 return -1; 582 } 583 if (ifflags & (IFF_NOARP | IFF_LOOPBACK)) { 584 if (fatal) { 585 if (!quiet) 586 printf("Interface \"%s\" is not ARPable\n", device.name); 587 exit(dad ? 0 : 2); 588 } 589 return -1; 590 } 591 return 0; 592 } 593 594 static int find_device_by_ifaddrs(void) 595 { 596 #ifndef WITHOUT_IFADDRS 597 int rc; 598 struct ifaddrs *ifa0, *ifa; 599 int count = 0; 600 601 rc = getifaddrs(&ifa0); 602 if (rc) { 603 perror("getifaddrs"); 604 return -1; 605 } 606 607 for (ifa = ifa0; ifa; ifa = ifa->ifa_next) { 608 if (!ifa->ifa_addr) 609 continue; 610 if (ifa->ifa_addr->sa_family != AF_PACKET) 611 continue; 612 if (device.name && ifa->ifa_name && strcmp(ifa->ifa_name, device.name)) 613 continue; 614 615 if (check_ifflags(ifa->ifa_flags, device.name != NULL) < 0) 616 continue; 617 618 if (!((struct sockaddr_ll *)ifa->ifa_addr)->sll_halen) 619 continue; 620 if (!ifa->ifa_broadaddr) 621 continue; 622 623 device.ifa = ifa; 624 625 if (count++) 626 break; 627 } 628 629 if (count == 1 && device.ifa) { 630 device.ifindex = if_nametoindex(device.ifa->ifa_name); 631 if (!device.ifindex) { 632 perror("arping: if_nametoindex"); 633 freeifaddrs(ifa0); 634 return -1; 635 } 636 device.name = device.ifa->ifa_name; 637 return 0; 638 } 639 return 1; 640 #else 641 return -1; 642 #endif 643 } 644 645 #ifdef USE_SYSFS 646 static void sysfs_devattr_values_init(struct sysfs_devattr_values *v, int do_free) 647 { 648 int i; 649 if (do_free) { 650 free(v->ifname); 651 for (i = 0; i < SYSFS_DEVATTR_NUM; i++) { 652 if (sysfs_devattrs[i].free) 653 free(v->value[i].ptr); 654 } 655 } 656 memset(v, 0, sizeof(*v)); 657 } 658 659 static int sysfs_devattr_ulong(char *ptr, struct sysfs_devattr_values *v, unsigned int idx, 660 unsigned int base) 661 { 662 unsigned long *p; 663 char *ep; 664 665 if (!ptr || !v) 666 return -1; 667 668 p = &v->value[idx].ulong; 669 errno = 0; 670 *p = strtoul(ptr, &ep, base); 671 if ((*ptr && isspace(*ptr & 0xff)) || errno || (*ep != '\0' && *ep != '\n')) 672 goto out; 673 674 return 0; 675 out: 676 return -1; 677 } 678 679 static int sysfs_devattr_ulong_dec(char *ptr, struct sysfs_devattr_values *v, unsigned int idx) 680 { 681 int rc = sysfs_devattr_ulong(ptr, v, idx, 10); 682 return rc; 683 } 684 685 static int sysfs_devattr_ulong_hex(char *ptr, struct sysfs_devattr_values *v, unsigned int idx) 686 { 687 int rc = sysfs_devattr_ulong(ptr, v, idx, 16); 688 return rc; 689 } 690 691 static int sysfs_devattr_macaddr(char *ptr, struct sysfs_devattr_values *v, unsigned int idx) 692 { 693 unsigned char *m; 694 int i; 695 unsigned int addrlen; 696 697 if (!ptr || !v) 698 return -1; 699 700 addrlen = v->value[SYSFS_DEVATTR_ADDR_LEN].ulong; 701 m = malloc(addrlen); 702 703 for (i = 0; i < addrlen; i++) { 704 if (i && *(ptr + i * 3 - 1) != ':') 705 goto out; 706 if (sscanf(ptr + i * 3, "%02hhx", &m[i]) != 1) 707 goto out; 708 } 709 710 v->value[idx].ptr = m; 711 return 0; 712 out: 713 free(m); 714 return -1; 715 } 716 #endif 717 718 int find_device_by_sysfs(void) 719 { 720 int rc = -1; 721 #ifdef USE_SYSFS 722 struct sysfs_class *cls_net; 723 struct dlist *dev_list; 724 struct sysfs_class_device *dev; 725 struct sysfs_attribute *dev_attr; 726 struct sysfs_devattr_values sysfs_devattr_values; 727 int count = 0; 728 729 if (!device.sysfs) { 730 device.sysfs = malloc(sizeof(*device.sysfs)); 731 sysfs_devattr_values_init(device.sysfs, 0); 732 } 733 734 cls_net = sysfs_open_class("net"); 735 if (!cls_net) { 736 perror("sysfs_open_class"); 737 return -1; 738 } 739 740 dev_list = sysfs_get_class_devices(cls_net); 741 if (!dev_list) { 742 perror("sysfs_get_class_devices"); 743 goto out; 744 } 745 746 sysfs_devattr_values_init(&sysfs_devattr_values, 0); 747 748 dlist_for_each_data(dev_list, dev, struct sysfs_class_device) { 749 int i; 750 int rc = -1; 751 752 if (device.name && strcmp(dev->name, device.name)) 753 goto do_next; 754 755 sysfs_devattr_values_init(&sysfs_devattr_values, 1); 756 757 for (i = 0; i < SYSFS_DEVATTR_NUM; i++) { 758 759 dev_attr = sysfs_get_classdev_attr(dev, sysfs_devattrs[i].name); 760 if (!dev_attr) { 761 perror("sysfs_get_classdev_attr"); 762 rc = -1; 763 break; 764 } 765 if (sysfs_read_attribute(dev_attr)) { 766 perror("sysfs_read_attribute"); 767 rc = -1; 768 break; 769 } 770 rc = sysfs_devattrs[i].handler(dev_attr->value, &sysfs_devattr_values, i); 771 772 if (rc < 0) 773 break; 774 } 775 776 if (rc < 0) 777 goto do_next; 778 779 if (check_ifflags(sysfs_devattr_values.value[SYSFS_DEVATTR_FLAGS].ulong, 780 device.name != NULL) < 0) 781 goto do_next; 782 783 if (!sysfs_devattr_values.value[SYSFS_DEVATTR_ADDR_LEN].ulong) 784 goto do_next; 785 786 if (device.sysfs->value[SYSFS_DEVATTR_IFINDEX].ulong) { 787 if (device.sysfs->value[SYSFS_DEVATTR_FLAGS].ulong & IFF_RUNNING) 788 goto do_next; 789 } 790 791 sysfs_devattr_values.ifname = strdup(dev->name); 792 if (!sysfs_devattr_values.ifname) { 793 perror("malloc"); 794 goto out; 795 } 796 797 sysfs_devattr_values_init(device.sysfs, 1); 798 memcpy(device.sysfs, &sysfs_devattr_values, sizeof(*device.sysfs)); 799 sysfs_devattr_values_init(&sysfs_devattr_values, 0); 800 801 if (count++) 802 break; 803 804 continue; 805 do_next: 806 sysfs_devattr_values_init(&sysfs_devattr_values, 1); 807 } 808 809 if (count == 1) { 810 device.ifindex = device.sysfs->value[SYSFS_DEVATTR_IFINDEX].ulong; 811 device.name = device.sysfs->ifname; 812 } 813 rc = !device.ifindex; 814 out: 815 sysfs_close_class(cls_net); 816 #endif 817 return rc; 818 } 819 820 static int check_device_by_ioctl(int s, struct ifreq *ifr) 821 { 822 if (ioctl(s, SIOCGIFFLAGS, ifr) < 0) { 823 perror("ioctl(SIOCGIFINDEX"); 824 return -1; 825 } 826 827 if (check_ifflags(ifr->ifr_flags, device.name != NULL) < 0) 828 return 1; 829 830 if (ioctl(s, SIOCGIFINDEX, ifr) < 0) { 831 perror("ioctl(SIOCGIFINDEX"); 832 return -1; 833 } 834 835 return 0; 836 } 837 838 static int find_device_by_ioctl(void) 839 { 840 int s; 841 struct ifreq *ifr0, *ifr, *ifr_end; 842 size_t ifrsize = sizeof(*ifr); 843 struct ifconf ifc; 844 static struct ifreq ifrbuf; 845 int count = 0; 846 847 s = socket(AF_INET, SOCK_DGRAM, 0); 848 if (s < 0) { 849 perror("socket"); 850 return -1; 851 } 852 853 memset(&ifrbuf, 0, sizeof(ifrbuf)); 854 855 if (device.name) { 856 strncpy(ifrbuf.ifr_name, device.name, sizeof(ifrbuf.ifr_name) - 1); 857 if (check_device_by_ioctl(s, &ifrbuf)) 858 goto out; 859 count++; 860 } else { 861 do { 862 int rc; 863 ifr0 = malloc(ifrsize); 864 if (!ifr0) { 865 perror("malloc"); 866 goto out; 867 } 868 869 ifc.ifc_buf = (char *)ifr0; 870 ifc.ifc_len = ifrsize; 871 872 rc = ioctl(s, SIOCGIFCONF, &ifc); 873 if (rc < 0) { 874 perror("ioctl(SIOCFIFCONF"); 875 goto out; 876 } 877 878 if (ifc.ifc_len + sizeof(*ifr0) + sizeof(struct sockaddr_storage) - sizeof(struct sockaddr) <= ifrsize) 879 break; 880 ifrsize *= 2; 881 free(ifr0); 882 ifr0 = NULL; 883 } while(ifrsize < INT_MAX / 2); 884 885 if (!ifr0) { 886 fprintf(stderr, "arping: too many interfaces!?\n"); 887 goto out; 888 } 889 890 ifr_end = (struct ifreq *)(((char *)ifr0) + ifc.ifc_len - sizeof(*ifr0)); 891 for (ifr = ifr0; ifr <= ifr_end; ifr++) { 892 if (check_device_by_ioctl(s, &ifrbuf)) 893 continue; 894 memcpy(&ifrbuf.ifr_name, ifr->ifr_name, sizeof(ifrbuf.ifr_name)); 895 if (count++) 896 break; 897 } 898 } 899 900 close(s); 901 902 if (count == 1) { 903 device.ifindex = ifrbuf.ifr_ifindex; 904 device.name = ifrbuf.ifr_name; 905 } 906 return !device.ifindex; 907 out: 908 close(s); 909 return -1; 910 } 911 912 static int find_device(void) 913 { 914 int rc; 915 rc = find_device_by_ifaddrs(); 916 if (rc >= 0) 917 goto out; 918 rc = find_device_by_sysfs(); 919 if (rc >= 0) 920 goto out; 921 rc = find_device_by_ioctl(); 922 out: 923 return rc; 924 } 925 926 /* 927 * set_device_broadcast() 928 * 929 * This fills the device "broadcast address" 930 * based on information found by find_device() funcion. 931 */ 932 static int set_device_broadcast_ifaddrs_one(struct device *device, unsigned char *ba, size_t balen, int fatal) 933 { 934 #ifndef WITHOUT_IFADDRS 935 struct ifaddrs *ifa; 936 struct sockaddr_ll *sll; 937 938 if (!device) 939 return -1; 940 941 ifa = device->ifa; 942 if (!ifa) 943 return -1; 944 945 sll = (struct sockaddr_ll *)ifa->ifa_broadaddr; 946 947 if (sll->sll_halen != balen) { 948 if (fatal) { 949 if (!quiet) 950 printf("Address length does not match...\n"); 951 exit(2); 952 } 953 return -1; 954 } 955 memcpy(ba, sll->sll_addr, sll->sll_halen); 956 return 0; 957 #else 958 return -1; 959 #endif 960 } 961 int set_device_broadcast_sysfs(struct device *device, unsigned char *ba, size_t balen) 962 { 963 #ifdef USE_SYSFS 964 struct sysfs_devattr_values *v; 965 if (!device) 966 return -1; 967 v = device->sysfs; 968 if (!v) 969 return -1; 970 if (v->value[SYSFS_DEVATTR_ADDR_LEN].ulong != balen) 971 return -1; 972 memcpy(ba, v->value[SYSFS_DEVATTR_BROADCAST].ptr, balen); 973 return 0; 974 #else 975 return -1; 976 #endif 977 } 978 979 static int set_device_broadcast_fallback(struct device *device, unsigned char *ba, size_t balen) 980 { 981 if (!quiet) 982 fprintf(stderr, "WARNING: using default broadcast address.\n"); 983 memset(ba, -1, balen); 984 return 0; 985 } 986 987 static void set_device_broadcast(struct device *dev, unsigned char *ba, size_t balen) 988 { 989 if (!set_device_broadcast_ifaddrs_one(dev, ba, balen, 0)) 990 return; 991 if (!set_device_broadcast_sysfs(dev, ba, balen)) 992 return; 993 set_device_broadcast_fallback(dev, ba, balen); 994 } 995 996 int 997 main(int argc, char **argv) 998 { 999 int socket_errno; 1000 int ch; 1001 1002 limit_capabilities(); 1003 1004 #ifdef USE_IDN 1005 setlocale(LC_ALL, ""); 1006 #endif 1007 1008 enable_capability_raw(); 1009 1010 s = socket(PF_PACKET, SOCK_DGRAM, 0); 1011 socket_errno = errno; 1012 1013 disable_capability_raw(); 1014 1015 while ((ch = getopt(argc, argv, "h?bfDUAqc:w:s:I:V")) != EOF) { 1016 switch(ch) { 1017 case 'b': 1018 broadcast_only=1; 1019 break; 1020 case 'D': 1021 dad++; 1022 quit_on_reply=1; 1023 break; 1024 case 'U': 1025 unsolicited++; 1026 break; 1027 case 'A': 1028 advert++; 1029 unsolicited++; 1030 break; 1031 case 'q': 1032 quiet++; 1033 break; 1034 case 'c': 1035 count = atoi(optarg); 1036 break; 1037 case 'w': 1038 timeout = atoi(optarg); 1039 break; 1040 case 'I': 1041 device.name = optarg; 1042 break; 1043 case 'f': 1044 quit_on_reply=1; 1045 break; 1046 case 's': 1047 source = optarg; 1048 break; 1049 case 'V': 1050 printf("arping utility, iputils-%s\n", SNAPSHOT); 1051 exit(0); 1052 case 'h': 1053 case '?': 1054 default: 1055 usage(); 1056 } 1057 } 1058 argc -= optind; 1059 argv += optind; 1060 1061 if (argc != 1) 1062 usage(); 1063 1064 target = *argv; 1065 1066 if (device.name && !*device.name) 1067 device.name = NULL; 1068 1069 if (s < 0) { 1070 errno = socket_errno; 1071 perror("arping: socket"); 1072 exit(2); 1073 } 1074 1075 if (find_device() < 0) 1076 exit(2); 1077 1078 if (!device.ifindex) { 1079 if (device.name) { 1080 fprintf(stderr, "arping: Device %s not available.\n", device.name); 1081 exit(2); 1082 } 1083 fprintf(stderr, "arping: device (option -I) is required.\n"); 1084 usage(); 1085 } 1086 1087 if (inet_aton(target, &dst) != 1) { 1088 struct hostent *hp; 1089 char *idn = target; 1090 #ifdef USE_IDN 1091 int rc; 1092 1093 rc = idna_to_ascii_lz(target, &idn, 0); 1094 1095 if (rc != IDNA_SUCCESS) { 1096 fprintf(stderr, "arping: IDN encoding failed: %s\n", idna_strerror(rc)); 1097 exit(2); 1098 } 1099 #endif 1100 1101 hp = gethostbyname2(idn, AF_INET); 1102 if (!hp) { 1103 fprintf(stderr, "arping: unknown host %s\n", target); 1104 exit(2); 1105 } 1106 1107 #ifdef USE_IDN 1108 free(idn); 1109 #endif 1110 1111 memcpy(&dst, hp->h_addr, 4); 1112 } 1113 1114 if (source && inet_aton(source, &src) != 1) { 1115 fprintf(stderr, "arping: invalid source %s\n", source); 1116 exit(2); 1117 } 1118 1119 if (!dad && unsolicited && src.s_addr == 0) 1120 src = dst; 1121 1122 if (!dad || src.s_addr) { 1123 struct sockaddr_in saddr; 1124 int probe_fd = socket(AF_INET, SOCK_DGRAM, 0); 1125 1126 if (probe_fd < 0) { 1127 perror("socket"); 1128 exit(2); 1129 } 1130 if (device.name) { 1131 enable_capability_raw(); 1132 1133 if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device.name, strlen(device.name)+1) == -1) 1134 perror("WARNING: interface is ignored"); 1135 1136 disable_capability_raw(); 1137 } 1138 memset(&saddr, 0, sizeof(saddr)); 1139 saddr.sin_family = AF_INET; 1140 if (src.s_addr) { 1141 saddr.sin_addr = src; 1142 if (bind(probe_fd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { 1143 perror("bind"); 1144 exit(2); 1145 } 1146 } else if (!dad) { 1147 int on = 1; 1148 socklen_t alen = sizeof(saddr); 1149 1150 saddr.sin_port = htons(1025); 1151 saddr.sin_addr = dst; 1152 1153 if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, (char*)&on, sizeof(on)) == -1) 1154 perror("WARNING: setsockopt(SO_DONTROUTE)"); 1155 if (connect(probe_fd, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) { 1156 perror("connect"); 1157 exit(2); 1158 } 1159 if (getsockname(probe_fd, (struct sockaddr*)&saddr, &alen) == -1) { 1160 perror("getsockname"); 1161 exit(2); 1162 } 1163 src = saddr.sin_addr; 1164 } 1165 close(probe_fd); 1166 }; 1167 1168 ((struct sockaddr_ll *)&me)->sll_family = AF_PACKET; 1169 ((struct sockaddr_ll *)&me)->sll_ifindex = device.ifindex; 1170 ((struct sockaddr_ll *)&me)->sll_protocol = htons(ETH_P_ARP); 1171 if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 1172 perror("bind"); 1173 exit(2); 1174 } 1175 1176 if (1) { 1177 socklen_t alen = sizeof(me); 1178 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 1179 perror("getsockname"); 1180 exit(2); 1181 } 1182 } 1183 if (((struct sockaddr_ll *)&me)->sll_halen == 0) { 1184 if (!quiet) 1185 printf("Interface \"%s\" is not ARPable (no ll address)\n", device.name); 1186 exit(dad?0:2); 1187 } 1188 1189 he = me; 1190 1191 set_device_broadcast(&device, ((struct sockaddr_ll *)&he)->sll_addr, 1192 ((struct sockaddr_ll *)&he)->sll_halen); 1193 1194 if (!quiet) { 1195 printf("ARPING %s ", inet_ntoa(dst)); 1196 printf("from %s %s\n", inet_ntoa(src), device.name ? : ""); 1197 } 1198 1199 if (!src.s_addr && !dad) { 1200 fprintf(stderr, "arping: no source address in not-DAD mode\n"); 1201 exit(2); 1202 } 1203 1204 drop_capabilities(); 1205 1206 set_signal(SIGINT, finish); 1207 set_signal(SIGALRM, catcher); 1208 1209 catcher(); 1210 1211 while(1) { 1212 sigset_t sset, osset; 1213 unsigned char packet[4096]; 1214 struct sockaddr_storage from; 1215 socklen_t alen = sizeof(from); 1216 int cc; 1217 1218 if ((cc = recvfrom(s, packet, sizeof(packet), 0, 1219 (struct sockaddr *)&from, &alen)) < 0) { 1220 perror("arping: recvfrom"); 1221 continue; 1222 } 1223 1224 sigemptyset(&sset); 1225 sigaddset(&sset, SIGALRM); 1226 sigaddset(&sset, SIGINT); 1227 sigprocmask(SIG_BLOCK, &sset, &osset); 1228 recv_pack(packet, cc, (struct sockaddr_ll *)&from); 1229 sigprocmask(SIG_SETMASK, &osset, NULL); 1230 } 1231 } 1232 1233 1234