inet.c revision 98530
1/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ 2/* 3 * Copyright (c) 1994, 1995, 1996, 1997, 1998 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the Computer Systems 17 * Engineering Group at Lawrence Berkeley Laboratory. 18 * 4. Neither the name of the University nor of the Laboratory may be used 19 * to endorse or promote products derived from this software without 20 * specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#ifndef lint 36static const char rcsid[] = 37 "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.45 2001/10/28 20:40:43 guy Exp $ (LBL)"; 38#endif 39 40#ifdef HAVE_CONFIG_H 41#include "config.h" 42#endif 43 44#include <sys/param.h> 45#include <sys/file.h> 46#include <sys/ioctl.h> 47#include <sys/socket.h> 48#ifdef HAVE_SYS_SOCKIO_H 49#include <sys/sockio.h> 50#endif 51#include <sys/time.h> /* concession to AIX */ 52 53struct mbuf; 54struct rtentry; 55#include <net/if.h> 56#include <netinet/in.h> 57 58#include <ctype.h> 59#include <errno.h> 60#include <memory.h> 61#include <stdio.h> 62#include <stdlib.h> 63#include <string.h> 64#include <unistd.h> 65#ifdef HAVE_LIMITS_H 66#include <limits.h> 67#else 68#define INT_MAX 2147483647 69#endif 70#ifdef HAVE_IFADDRS_H 71#include <ifaddrs.h> 72#endif 73 74#include "pcap-int.h" 75 76#ifdef HAVE_OS_PROTO_H 77#include "os-proto.h" 78#endif 79 80/* Not all systems have IFF_LOOPBACK */ 81#ifdef IFF_LOOPBACK 82#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK) 83#else 84#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \ 85 (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0')) 86#endif 87 88/* 89 * This is fun. 90 * 91 * In older BSD systems, socket addresses were fixed-length, and 92 * "sizeof (struct sockaddr)" gave the size of the structure. 93 * All addresses fit within a "struct sockaddr". 94 * 95 * In newer BSD systems, the socket address is variable-length, and 96 * there's an "sa_len" field giving the length of the structure; 97 * this allows socket addresses to be longer than 2 bytes of family 98 * and 14 bytes of data. 99 * 100 * Some commercial UNIXes use the old BSD scheme, and some might use 101 * the new BSD scheme. 102 * 103 * GNU libc uses neither scheme, but has an "SA_LEN()" macro that 104 * determines the size based on the address family. 105 */ 106#ifndef SA_LEN 107#ifdef HAVE_SOCKADDR_SA_LEN 108#define SA_LEN(addr) ((addr)->sa_len) 109#else /* HAVE_SOCKADDR_SA_LEN */ 110#define SA_LEN(addr) (sizeof (struct sockaddr)) 111#endif /* HAVE_SOCKADDR_SA_LEN */ 112#endif /* SA_LEN */ 113 114/* 115 * Description string for the "any" device. 116 */ 117static const char any_descr[] = "Pseudo-device that captures on all interfaces"; 118 119static struct sockaddr * 120dup_sockaddr(struct sockaddr *sa) 121{ 122 struct sockaddr *newsa; 123 unsigned int size; 124 125 size = SA_LEN(sa); 126 if ((newsa = malloc(size)) == NULL) 127 return (NULL); 128 return (memcpy(newsa, sa, size)); 129} 130 131static int 132get_instance(char *name) 133{ 134 char *cp, *endcp; 135 int n; 136 137 if (strcmp(name, "any") == 0) { 138 /* 139 * Give the "any" device an artificially high instance 140 * number, so it shows up after all other non-loopback 141 * interfaces. 142 */ 143 return INT_MAX; 144 } 145 146 endcp = name + strlen(name); 147 for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp) 148 continue; 149 150 if (isdigit((unsigned char)*cp)) 151 n = atoi(cp); 152 else 153 n = 0; 154 return (n); 155} 156 157static int 158add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name, 159 u_int flags, const char *description, char *errbuf) 160{ 161 pcap_t *p; 162 pcap_if_t *curdev, *prevdev, *nextdev; 163 int this_instance; 164 165 /* 166 * Can we open this interface for live capture? 167 */ 168 p = pcap_open_live(name, 68, 0, 0, errbuf); 169 if (p == NULL) { 170 /* 171 * No. Don't bother including it. 172 * Don't treat this as an error, though. 173 */ 174 *curdev_ret = NULL; 175 return (0); 176 } 177 pcap_close(p); 178 179 /* 180 * Is there already an entry in the list for this interface? 181 */ 182 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { 183 if (strcmp(name, curdev->name) == 0) 184 break; /* yes, we found it */ 185 } 186 if (curdev == NULL) { 187 /* 188 * No, we didn't find it. 189 * Allocate a new entry. 190 */ 191 curdev = malloc(sizeof(pcap_if_t)); 192 if (curdev == NULL) { 193 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 194 "malloc: %s", pcap_strerror(errno)); 195 return (-1); 196 } 197 198 /* 199 * Fill in the entry. 200 */ 201 curdev->next = NULL; 202 curdev->name = malloc(strlen(name) + 1); 203 strcpy(curdev->name, name); 204 if (description != NULL) { 205 /* 206 * We have a description for this interface. 207 */ 208 curdev->description = malloc(strlen(description) + 1); 209 strcpy(curdev->description, description); 210 } else { 211 /* 212 * We don't. 213 */ 214 curdev->description = NULL; 215 } 216 curdev->addresses = NULL; /* list starts out as empty */ 217 curdev->flags = 0; 218 if (ISLOOPBACK(name, flags)) 219 curdev->flags |= PCAP_IF_LOOPBACK; 220 221 /* 222 * Add it to the list, in the appropriate location. 223 * First, get the instance number of this interface. 224 */ 225 this_instance = get_instance(name); 226 227 /* 228 * Now look for the last interface with an instance number 229 * less than or equal to the new interface's instance 230 * number - except that non-loopback interfaces are 231 * arbitrarily treated as having interface numbers less 232 * than those of loopback interfaces, so the loopback 233 * interfaces are put at the end of the list. 234 * 235 * We start with "prevdev" being NULL, meaning we're before 236 * the first element in the list. 237 */ 238 prevdev = NULL; 239 for (;;) { 240 /* 241 * Get the interface after this one. 242 */ 243 if (prevdev == NULL) { 244 /* 245 * The next element is the first element. 246 */ 247 nextdev = *alldevs; 248 } else 249 nextdev = prevdev->next; 250 251 /* 252 * Are we at the end of the list? 253 */ 254 if (nextdev == NULL) { 255 /* 256 * Yes - we have to put the new entry 257 * after "prevdev". 258 */ 259 break; 260 } 261 262 /* 263 * Is the new interface a non-loopback interface 264 * and the next interface a loopback interface? 265 */ 266 if (!(curdev->flags & PCAP_IF_LOOPBACK) && 267 (nextdev->flags & PCAP_IF_LOOPBACK)) { 268 /* 269 * Yes, we should put the new entry 270 * before "nextdev", i.e. after "prevdev". 271 */ 272 break; 273 } 274 275 /* 276 * Is the new interface's instance number less 277 * than the next interface's instance number, 278 * and is it the case that the new interface is a 279 * non-loopback interface or the next interface is 280 * a loopback interface? 281 * 282 * (The goal of both loopback tests is to make 283 * sure that we never put a loopback interface 284 * before any non-loopback interface and that we 285 * always put a non-loopback interface before all 286 * loopback interfaces.) 287 */ 288 if (this_instance < get_instance(nextdev->name) && 289 (!(curdev->flags & PCAP_IF_LOOPBACK) || 290 (nextdev->flags & PCAP_IF_LOOPBACK))) { 291 /* 292 * Yes - we should put the new entry 293 * before "nextdev", i.e. after "prevdev". 294 */ 295 break; 296 } 297 298 prevdev = nextdev; 299 } 300 301 /* 302 * Insert before "nextdev". 303 */ 304 curdev->next = nextdev; 305 306 /* 307 * Insert after "prevdev" - unless "prevdev" is null, 308 * in which case this is the first interface. 309 */ 310 if (prevdev == NULL) { 311 /* 312 * This is the first interface. Pass back a 313 * pointer to it, and put "curdev" before 314 * "nextdev". 315 */ 316 *alldevs = curdev; 317 } else 318 prevdev->next = curdev; 319 } 320 321 *curdev_ret = curdev; 322 return (0); 323} 324 325static int 326add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, 327 struct sockaddr *addr, struct sockaddr *netmask, 328 struct sockaddr *broadaddr, struct sockaddr *dstaddr, char *errbuf) 329{ 330 pcap_if_t *curdev; 331 pcap_addr_t *curaddr, *prevaddr, *nextaddr; 332 333 if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { 334 /* 335 * Error - give up. 336 */ 337 return (-1); 338 } 339 if (curdev == NULL) { 340 /* 341 * Device wasn't added because it can't be opened. 342 * Not a fatal error. 343 */ 344 return (0); 345 } 346 347 /* 348 * "curdev" is an entry for this interface; add an entry for this 349 * address to its list of addresses. 350 * 351 * Allocate the new entry and fill it in. 352 */ 353 curaddr = malloc(sizeof(pcap_addr_t)); 354 if (curaddr == NULL) { 355 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 356 "malloc: %s", pcap_strerror(errno)); 357 return (-1); 358 } 359 360 curaddr->next = NULL; 361 if (addr != NULL) { 362 curaddr->addr = dup_sockaddr(addr); 363 if (curaddr->addr == NULL) { 364 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 365 "malloc: %s", pcap_strerror(errno)); 366 free(curaddr); 367 return (-1); 368 } 369 } else 370 curaddr->addr = NULL; 371 372 if (netmask != NULL) { 373 curaddr->netmask = dup_sockaddr(netmask); 374 if (curaddr->netmask == NULL) { 375 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 376 "malloc: %s", pcap_strerror(errno)); 377 free(curaddr); 378 return (-1); 379 } 380 } else 381 curaddr->netmask = NULL; 382 383 if (broadaddr != NULL) { 384 curaddr->broadaddr = dup_sockaddr(broadaddr); 385 if (curaddr->broadaddr == NULL) { 386 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 387 "malloc: %s", pcap_strerror(errno)); 388 free(curaddr); 389 return (-1); 390 } 391 } else 392 curaddr->broadaddr = NULL; 393 394 if (dstaddr != NULL) { 395 curaddr->dstaddr = dup_sockaddr(dstaddr); 396 if (curaddr->dstaddr == NULL) { 397 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 398 "malloc: %s", pcap_strerror(errno)); 399 free(curaddr); 400 return (-1); 401 } 402 } else 403 curaddr->dstaddr = NULL; 404 405 /* 406 * Find the end of the list of addresses. 407 */ 408 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { 409 nextaddr = prevaddr->next; 410 if (nextaddr == NULL) { 411 /* 412 * This is the end of the list. 413 */ 414 break; 415 } 416 } 417 418 if (prevaddr == NULL) { 419 /* 420 * The list was empty; this is the first member. 421 */ 422 curdev->addresses = curaddr; 423 } else { 424 /* 425 * "prevaddr" is the last member of the list; append 426 * this member to it. 427 */ 428 prevaddr->next = curaddr; 429 } 430 431 return (0); 432} 433 434static int 435pcap_add_if(pcap_if_t **devlist, char *name, u_int flags, 436 const char *description, char *errbuf) 437{ 438 pcap_if_t *curdev; 439 440 return (add_or_find_if(&curdev, devlist, name, flags, description, 441 errbuf)); 442} 443 444/* 445 * Get a list of all interfaces that are up and that we can open. 446 * Returns -1 on error, 0 otherwise. 447 * The list, as returned through "alldevsp", may be null if no interfaces 448 * were up and could be opened. 449 */ 450#ifdef HAVE_IFADDRS_H 451int 452pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 453{ 454 pcap_if_t *devlist = NULL; 455 struct ifaddrs *ifap, *ifa; 456 struct sockaddr *broadaddr, *dstaddr; 457 int ret = 0; 458 459 /* 460 * Get the list of interface addresses. 461 * 462 * Note: this won't return information about interfaces 463 * with no addresses; are there any such interfaces 464 * that would be capable of receiving packets? 465 * (Interfaces incapable of receiving packets aren't 466 * very interesting from libpcap's point of view.) 467 * 468 * LAN interfaces will probably have link-layer 469 * addresses; I don't know whether all implementations 470 * of "getifaddrs()" now, or in the future, will return 471 * those. 472 */ 473 if (getifaddrs(&ifap) != 0) { 474 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 475 "getifaddrs: %s", pcap_strerror(errno)); 476 return (-1); 477 } 478 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 479 /* 480 * Is this interface up? 481 */ 482 if (!(ifa->ifa_flags & IFF_UP)) { 483 /* 484 * No, so don't add it to the list. 485 */ 486 continue; 487 } 488 489 /* 490 * "ifa_broadaddr" may be non-null even on 491 * non-broadcast interfaces; "ifa_dstaddr" 492 * was, on at least one FreeBSD 4.1 system, 493 * non-null on a non-point-to-point 494 * interface. 495 */ 496 if (ifa->ifa_flags & IFF_BROADCAST) 497 broadaddr = ifa->ifa_broadaddr; 498 else 499 broadaddr = NULL; 500 if (ifa->ifa_flags & IFF_POINTOPOINT) 501 dstaddr = ifa->ifa_dstaddr; 502 else 503 dstaddr = NULL; 504 505 /* 506 * Add information for this address to the list. 507 */ 508 if (add_addr_to_iflist(&devlist, ifa->ifa_name, 509 ifa->ifa_flags, ifa->ifa_addr, ifa->ifa_netmask, 510 broadaddr, dstaddr, errbuf) < 0) { 511 ret = -1; 512 break; 513 } 514 } 515 516 freeifaddrs(ifap); 517 518 if (ret != -1) { 519 /* 520 * We haven't had any errors yet; add the "any" device, 521 * if we can open it. 522 */ 523 if (pcap_add_if(&devlist, "any", 0, any_descr, errbuf) < 0) 524 ret = -1; 525 } 526 527 if (ret == -1) { 528 /* 529 * We had an error; free the list we've been constructing. 530 */ 531 if (devlist != NULL) { 532 pcap_freealldevs(devlist); 533 devlist = NULL; 534 } 535 } 536 537 *alldevsp = devlist; 538 return (ret); 539} 540#else /* HAVE_IFADDRS_H */ 541#ifdef HAVE_PROC_NET_DEV 542/* 543 * Get from "/proc/net/dev" all interfaces listed there; if they're 544 * already in the list of interfaces we have, that won't add another 545 * instance, but if they're not, that'll add them. 546 * 547 * We don't bother getting any addresses for them; it appears you can't 548 * use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and, 549 * although some other types of addresses can be fetched with SIOCGIFADDR, 550 * we don't bother with them for now. 551 * 552 * We also don't fail if we couldn't open "/proc/net/dev"; we just leave 553 * the list of interfaces as is. 554 */ 555static int 556scan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf) 557{ 558 FILE *proc_net_f; 559 char linebuf[512]; 560 int linenum; 561 unsigned char *p; 562 char name[512]; /* XXX - pick a size */ 563 char *q, *saveq; 564 struct ifreq ifrflags; 565 int ret = 0; 566 567 proc_net_f = fopen("/proc/net/dev", "r"); 568 if (proc_net_f == NULL) 569 return (0); 570 571 for (linenum = 1; 572 fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) { 573 /* 574 * Skip the first two lines - they're headers. 575 */ 576 if (linenum <= 2) 577 continue; 578 579 p = &linebuf[0]; 580 581 /* 582 * Skip leading white space. 583 */ 584 while (*p != '\0' && isspace(*p)) 585 p++; 586 if (*p == '\0' || *p == '\n') 587 continue; /* blank line */ 588 589 /* 590 * Get the interface name. 591 */ 592 q = &name[0]; 593 while (*p != '\0' && !isspace(*p)) { 594 if (*p == ':') { 595 /* 596 * This could be the separator between a 597 * name and an alias number, or it could be 598 * the separator between a name with no 599 * alias number and the next field. 600 * 601 * If there's a colon after digits, it 602 * separates the name and the alias number, 603 * otherwise it separates the name and the 604 * next field. 605 */ 606 saveq = q; 607 while (isdigit(*p)) 608 *q++ = *p++; 609 if (*p != ':') { 610 /* 611 * That was the next field, 612 * not the alias number. 613 */ 614 q = saveq; 615 } 616 break; 617 } else 618 *q++ = *p++; 619 } 620 *q = '\0'; 621 622 /* 623 * Get the flags for this interface, and skip it if 624 * it's not up. 625 */ 626 strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name)); 627 if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { 628 if (errno == ENXIO) 629 continue; 630 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 631 "SIOCGIFFLAGS: %.*s: %s", 632 (int)sizeof(ifrflags.ifr_name), 633 ifrflags.ifr_name, 634 pcap_strerror(errno)); 635 ret = -1; 636 break; 637 } 638 if (!(ifrflags.ifr_flags & IFF_UP)) 639 continue; 640 641 /* 642 * Add an entry for this interface, with no addresses. 643 */ 644 if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL, 645 errbuf) == -1) { 646 /* 647 * Failure. 648 */ 649 ret = -1; 650 break; 651 } 652 } 653 if (ret != -1) { 654 /* 655 * Well, we didn't fail for any other reason; did we 656 * fail due to an error reading the file? 657 */ 658 if (ferror(proc_net_f)) { 659 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 660 "Error reading /proc/net/dev: %s", 661 pcap_strerror(errno)); 662 ret = -1; 663 } 664 } 665 666 (void)fclose(proc_net_f); 667 return (ret); 668} 669#endif /* HAVE_PROC_NET_DEV */ 670 671int 672pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 673{ 674 pcap_if_t *devlist = NULL; 675 register int fd; 676 register struct ifreq *ifrp, *ifend, *ifnext; 677 int n; 678 struct ifconf ifc; 679 char *buf = NULL; 680 unsigned buf_size; 681 struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; 682 struct sockaddr *netmask, *broadaddr, *dstaddr; 683 int ret = 0; 684 685 /* 686 * Create a socket from which to fetch the list of interfaces. 687 */ 688 fd = socket(AF_INET, SOCK_DGRAM, 0); 689 if (fd < 0) { 690 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 691 "socket: %s", pcap_strerror(errno)); 692 return (-1); 693 } 694 695 /* 696 * Start with an 8K buffer, and keep growing the buffer until 697 * we get the entire interface list or fail to get it for some 698 * reason other than EINVAL (which is presumed here to mean 699 * "buffer is too small"). 700 */ 701 buf_size = 8192; 702 for (;;) { 703 buf = malloc(buf_size); 704 if (buf == NULL) { 705 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 706 "malloc: %s", pcap_strerror(errno)); 707 (void)close(fd); 708 return (-1); 709 } 710 711 ifc.ifc_len = buf_size; 712 ifc.ifc_buf = buf; 713 memset(buf, 0, buf_size); 714 if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 715 && errno != EINVAL) { 716 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 717 "SIOCGIFCONF: %s", pcap_strerror(errno)); 718 (void)close(fd); 719 free(buf); 720 return (-1); 721 } 722 if (ifc.ifc_len < buf_size) 723 break; 724 free(buf); 725 buf_size *= 2; 726 } 727 728 ifrp = (struct ifreq *)buf; 729 ifend = (struct ifreq *)(buf + ifc.ifc_len); 730 731 for (; ifrp < ifend; ifrp = ifnext) { 732 n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name); 733 if (n < sizeof(*ifrp)) 734 ifnext = ifrp + 1; 735 else 736 ifnext = (struct ifreq *)((char *)ifrp + n); 737 738 /* 739 * Get the flags for this interface, and skip it if it's 740 * not up. 741 */ 742 strncpy(ifrflags.ifr_name, ifrp->ifr_name, 743 sizeof(ifrflags.ifr_name)); 744 if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { 745 if (errno == ENXIO) 746 continue; 747 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 748 "SIOCGIFFLAGS: %.*s: %s", 749 (int)sizeof(ifrflags.ifr_name), 750 ifrflags.ifr_name, 751 pcap_strerror(errno)); 752 ret = -1; 753 break; 754 } 755 if (!(ifrflags.ifr_flags & IFF_UP)) 756 continue; 757 758 /* 759 * Get the netmask for this address on this interface. 760 */ 761 strncpy(ifrnetmask.ifr_name, ifrp->ifr_name, 762 sizeof(ifrnetmask.ifr_name)); 763 memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr, 764 sizeof(ifrnetmask.ifr_addr)); 765 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) { 766 if (errno == EADDRNOTAVAIL) { 767 /* 768 * Not available. 769 */ 770 netmask = NULL; 771 } else { 772 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 773 "SIOCGIFNETMASK: %.*s: %s", 774 (int)sizeof(ifrnetmask.ifr_name), 775 ifrnetmask.ifr_name, 776 pcap_strerror(errno)); 777 ret = -1; 778 break; 779 } 780 } else 781 netmask = &ifrnetmask.ifr_addr; 782 783 /* 784 * Get the broadcast address for this address on this 785 * interface (if any). 786 */ 787 if (ifrflags.ifr_flags & IFF_BROADCAST) { 788 strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name, 789 sizeof(ifrbroadaddr.ifr_name)); 790 memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr, 791 sizeof(ifrbroadaddr.ifr_addr)); 792 if (ioctl(fd, SIOCGIFBRDADDR, 793 (char *)&ifrbroadaddr) < 0) { 794 if (errno == EADDRNOTAVAIL) { 795 /* 796 * Not available. 797 */ 798 broadaddr = NULL; 799 } else { 800 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 801 "SIOCGIFBRDADDR: %.*s: %s", 802 (int)sizeof(ifrbroadaddr.ifr_name), 803 ifrbroadaddr.ifr_name, 804 pcap_strerror(errno)); 805 ret = -1; 806 break; 807 } 808 } else 809 broadaddr = &ifrbroadaddr.ifr_broadaddr; 810 } else { 811 /* 812 * Not a broadcast interface, so no broadcast 813 * address. 814 */ 815 broadaddr = NULL; 816 } 817 818 /* 819 * Get the destination address for this address on this 820 * interface (if any). 821 */ 822 if (ifrflags.ifr_flags & IFF_POINTOPOINT) { 823 strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name, 824 sizeof(ifrdstaddr.ifr_name)); 825 memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr, 826 sizeof(ifrdstaddr.ifr_addr)); 827 if (ioctl(fd, SIOCGIFDSTADDR, 828 (char *)&ifrdstaddr) < 0) { 829 if (errno == EADDRNOTAVAIL) { 830 /* 831 * Not available. 832 */ 833 dstaddr = NULL; 834 } else { 835 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 836 "SIOCGIFDSTADDR: %.*s: %s", 837 (int)sizeof(ifrdstaddr.ifr_name), 838 ifrdstaddr.ifr_name, 839 pcap_strerror(errno)); 840 ret = -1; 841 break; 842 } 843 } else 844 dstaddr = &ifrdstaddr.ifr_dstaddr; 845 } else 846 dstaddr = NULL; 847 848 /* 849 * Add information for this address to the list. 850 */ 851 if (add_addr_to_iflist(&devlist, ifrp->ifr_name, 852 ifrflags.ifr_flags, &ifrp->ifr_addr, 853 netmask, broadaddr, dstaddr, errbuf) < 0) { 854 ret = -1; 855 break; 856 } 857 } 858 free(buf); 859 860#ifdef HAVE_PROC_NET_DEV 861 if (ret != -1) { 862 /* 863 * We haven't had any errors yet; now read "/proc/net/dev", 864 * and add to the list of interfaces all interfaces listed 865 * there that we don't already have, because, on Linux, 866 * SIOCGIFCONF reports only interfaces with IPv4 addresses, 867 * so you need to read "/proc/net/dev" to get the names of 868 * the rest of the interfaces. 869 */ 870 ret = scan_proc_net_dev(&devlist, fd, errbuf); 871 } 872#endif 873 (void)close(fd); 874 875 if (ret != -1) { 876 /* 877 * We haven't had any errors yet; add the "any" device, 878 * if we can open it. 879 */ 880 if (pcap_add_if(&devlist, "any", 0, any_descr, errbuf) < 0) { 881 /* 882 * Oops, we had a fatal error. 883 */ 884 ret = -1; 885 } 886 } 887 888 if (ret == -1) { 889 /* 890 * We had an error; free the list we've been constructing. 891 */ 892 if (devlist != NULL) { 893 pcap_freealldevs(devlist); 894 devlist = NULL; 895 } 896 } 897 898 *alldevsp = devlist; 899 return (ret); 900} 901#endif /* HAVE_IFADDRS_H */ 902 903/* 904 * Free a list of interfaces. 905 */ 906void 907pcap_freealldevs(pcap_if_t *alldevs) 908{ 909 pcap_if_t *curdev, *nextdev; 910 pcap_addr_t *curaddr, *nextaddr; 911 912 for (curdev = alldevs; curdev != NULL; curdev = nextdev) { 913 nextdev = curdev->next; 914 915 /* 916 * Free all addresses. 917 */ 918 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) { 919 nextaddr = curaddr->next; 920 if (curaddr->addr) 921 free(curaddr->addr); 922 if (curaddr->netmask) 923 free(curaddr->netmask); 924 if (curaddr->broadaddr) 925 free(curaddr->broadaddr); 926 if (curaddr->dstaddr) 927 free(curaddr->dstaddr); 928 free(curaddr); 929 } 930 931 /* 932 * Free the name string. 933 */ 934 free(curdev->name); 935 936 /* 937 * Free the description string, if any. 938 */ 939 if (curdev->description != NULL) 940 free(curdev->description); 941 942 /* 943 * Free the interface. 944 */ 945 free(curdev); 946 } 947} 948 949/* 950 * Return the name of a network interface attached to the system, or NULL 951 * if none can be found. The interface must be configured up; the 952 * lowest unit number is preferred; loopback is ignored. 953 */ 954char * 955pcap_lookupdev(errbuf) 956 register char *errbuf; 957{ 958 pcap_if_t *alldevs; 959/* for old BSD systems, including bsdi3 */ 960#ifndef IF_NAMESIZE 961#define IF_NAMESIZE IFNAMSIZ 962#endif 963 static char device[IF_NAMESIZE + 1]; 964 char *ret; 965 966 if (pcap_findalldevs(&alldevs, errbuf) == -1) 967 return (NULL); 968 969 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) { 970 /* 971 * There are no devices on the list, or the first device 972 * on the list is a loopback device, which means there 973 * are no non-loopback devices on the list. This means 974 * we can't return any device. 975 * 976 * XXX - why not return a loopback device? If we can't 977 * capture on it, it won't be on the list, and if it's 978 * on the list, there aren't any non-loopback devices, 979 * so why not just supply it as the default device? 980 */ 981 (void)strlcpy(errbuf, "no suitable device found", 982 PCAP_ERRBUF_SIZE); 983 ret = NULL; 984 } else { 985 /* 986 * Return the name of the first device on the list. 987 */ 988 (void)strlcpy(device, alldevs->name, sizeof(device)); 989 ret = device; 990 } 991 992 pcap_freealldevs(alldevs); 993 return (ret); 994} 995 996int 997pcap_lookupnet(device, netp, maskp, errbuf) 998 register char *device; 999 register bpf_u_int32 *netp, *maskp; 1000 register char *errbuf; 1001{ 1002 register int fd; 1003 register struct sockaddr_in *sin; 1004 struct ifreq ifr; 1005 1006 /* 1007 * The pseudo-device "any" listens on all interfaces and therefore 1008 * has the network address and -mask "0.0.0.0" therefore catching 1009 * all traffic. Using NULL for the interface is the same as "any". 1010 */ 1011 if (!device || strcmp(device, "any") == 0) { 1012 *netp = *maskp = 0; 1013 return 0; 1014 } 1015 1016 fd = socket(AF_INET, SOCK_DGRAM, 0); 1017 if (fd < 0) { 1018 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s", 1019 pcap_strerror(errno)); 1020 return (-1); 1021 } 1022 memset(&ifr, 0, sizeof(ifr)); 1023#ifdef linux 1024 /* XXX Work around Linux kernel bug */ 1025 ifr.ifr_addr.sa_family = AF_INET; 1026#endif 1027 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 1028 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { 1029 if (errno == EADDRNOTAVAIL) { 1030 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 1031 "%s: no IPv4 address assigned", device); 1032 } else { 1033 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 1034 "SIOCGIFADDR: %s: %s", 1035 device, pcap_strerror(errno)); 1036 } 1037 (void)close(fd); 1038 return (-1); 1039 } 1040 sin = (struct sockaddr_in *)&ifr.ifr_addr; 1041 *netp = sin->sin_addr.s_addr; 1042 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) { 1043 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 1044 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno)); 1045 (void)close(fd); 1046 return (-1); 1047 } 1048 (void)close(fd); 1049 *maskp = sin->sin_addr.s_addr; 1050 if (*maskp == 0) { 1051 if (IN_CLASSA(*netp)) 1052 *maskp = IN_CLASSA_NET; 1053 else if (IN_CLASSB(*netp)) 1054 *maskp = IN_CLASSB_NET; 1055 else if (IN_CLASSC(*netp)) 1056 *maskp = IN_CLASSC_NET; 1057 else { 1058 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 1059 "inet class for 0x%x unknown", *netp); 1060 return (-1); 1061 } 1062 } 1063 *netp &= *maskp; 1064 return (0); 1065} 1066