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#ifdef HAVE_CONFIG_H 36#include "config.h" 37#endif 38 39#ifdef WIN32 40#include <pcap-stdinc.h> 41#else /* WIN32 */ 42 43#include <sys/param.h> 44#ifndef MSDOS 45#include <sys/file.h> 46#endif 47#include <sys/ioctl.h> 48#include <sys/socket.h> 49#ifdef HAVE_SYS_SOCKIO_H 50#include <sys/sockio.h> 51#endif 52 53struct mbuf; /* Squelch compiler warnings on some platforms for */ 54struct rtentry; /* declarations in <net/if.h> */ 55#include <net/if.h> 56#include <netinet/in.h> 57#endif /* WIN32 */ 58 59#include <ctype.h> 60#include <errno.h> 61#include <memory.h> 62#include <stdio.h> 63#include <stdlib.h> 64#include <string.h> 65#if !defined(WIN32) && !defined(__BORLANDC__) 66#include <unistd.h> 67#endif /* !WIN32 && !__BORLANDC__ */ 68#ifdef HAVE_LIMITS_H 69#include <limits.h> 70#else 71#define INT_MAX 2147483647 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#ifdef IFF_UP 89#define ISUP(flags) ((flags) & IFF_UP) 90#else 91#define ISUP(flags) 0 92#endif 93 94#ifdef IFF_RUNNING 95#define ISRUNNING(flags) ((flags) & IFF_RUNNING) 96#else 97#define ISRUNNING(flags) 0 98#endif 99 100struct sockaddr * 101dup_sockaddr(struct sockaddr *sa, size_t sa_length) 102{ 103 struct sockaddr *newsa; 104 105 if ((newsa = malloc(sa_length)) == NULL) 106 return (NULL); 107 return (memcpy(newsa, sa, sa_length)); 108} 109 110/* 111 * Construct a "figure of merit" for an interface, for use when sorting 112 * the list of interfaces, in which interfaces that are up are superior 113 * to interfaces that aren't up, interfaces that are up and running are 114 * superior to interfaces that are up but not running, and non-loopback 115 * interfaces that are up and running are superior to loopback interfaces, 116 * and interfaces with the same flags have a figure of merit that's higher 117 * the lower the instance number. 118 * 119 * The goal is to try to put the interfaces most likely to be useful for 120 * capture at the beginning of the list. 121 * 122 * The figure of merit, which is lower the "better" the interface is, 123 * has the uppermost bit set if the interface isn't running, the bit 124 * below that set if the interface isn't up, the bit below that set 125 * if the interface is a loopback interface, and the interface index 126 * in the 29 bits below that. (Yes, we assume u_int is 32 bits.) 127 */ 128static u_int 129get_figure_of_merit(pcap_if_t *dev) 130{ 131 const char *cp; 132 u_int n; 133 134 if (strcmp(dev->name, "any") == 0) { 135 /* 136 * Give the "any" device an artificially high instance 137 * number, so it shows up after all other non-loopback 138 * interfaces. 139 */ 140 n = 0x1FFFFFFF; /* 29 all-1 bits */ 141 } else { 142 /* 143 * A number at the end of the device name string is 144 * assumed to be a unit number. 145 */ 146 cp = dev->name + strlen(dev->name) - 1; 147 while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9') 148 cp--; 149 if (*cp >= '0' && *cp <= '9') 150 n = atoi(cp); 151 else 152 n = 0; 153 } 154 if (!(dev->flags & PCAP_IF_RUNNING)) 155 n |= 0x80000000; 156 if (!(dev->flags & PCAP_IF_UP)) 157 n |= 0x40000000; 158 if (dev->flags & PCAP_IF_LOOPBACK) 159 n |= 0x20000000; 160 return (n); 161} 162 163/* 164 * Look for a given device in the specified list of devices. 165 * 166 * If we find it, return 0 and set *curdev_ret to point to it. 167 * 168 * If we don't find it, check whether we can open it: 169 * 170 * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or 171 * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for 172 * it, as that probably means it exists but doesn't support 173 * packet capture. 174 * 175 * Otherwise, attempt to add an entry for it, with the specified 176 * ifnet flags and description, and, if that succeeds, return 0 177 * and set *curdev_ret to point to the new entry, otherwise 178 * return PCAP_ERROR and set errbuf to an error message. 179 */ 180int 181add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, 182 u_int flags, const char *description, char *errbuf) 183{ 184 pcap_t *p; 185 pcap_if_t *curdev, *prevdev, *nextdev; 186 u_int this_figure_of_merit, nextdev_figure_of_merit; 187 char open_errbuf[PCAP_ERRBUF_SIZE]; 188 int ret; 189 190 /* 191 * Is there already an entry in the list for this interface? 192 */ 193 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { 194 if (strcmp(name, curdev->name) == 0) 195 break; /* yes, we found it */ 196 } 197 198 if (curdev == NULL) { 199 /* 200 * No, we didn't find it. 201 * 202 * Can we open this interface for live capture? 203 * 204 * We do this check so that interfaces that are 205 * supplied by the interface enumeration mechanism 206 * we're using but that don't support packet capture 207 * aren't included in the list. Loopback interfaces 208 * on Solaris are an example of this; we don't just 209 * omit loopback interfaces on all platforms because 210 * you *can* capture on loopback interfaces on some 211 * OSes. 212 * 213 * On OS X, we don't do this check if the device 214 * name begins with "wlt"; at least some versions 215 * of OS X offer monitor mode capturing by having 216 * a separate "monitor mode" device for each wireless 217 * adapter, rather than by implementing the ioctls 218 * that {Free,Net,Open,DragonFly}BSD provide. 219 * Opening that device puts the adapter into monitor 220 * mode, which, at least for some adapters, causes 221 * them to deassociate from the network with which 222 * they're associated. 223 * 224 * Instead, we try to open the corresponding "en" 225 * device (so that we don't end up with, for users 226 * without sufficient privilege to open capture 227 * devices, a list of adapters that only includes 228 * the wlt devices). 229 */ 230#ifdef __APPLE__ 231 if (strncmp(name, "wlt", 3) == 0) { 232 char *en_name; 233 size_t en_name_len; 234 235 /* 236 * Try to allocate a buffer for the "en" 237 * device's name. 238 */ 239 en_name_len = strlen(name) - 1; 240 en_name = malloc(en_name_len + 1); 241 if (en_name == NULL) { 242 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 243 "malloc: %s", pcap_strerror(errno)); 244 return (-1); 245 } 246 strcpy(en_name, "en"); 247 strcat(en_name, name + 3); 248 p = pcap_create(en_name, open_errbuf); 249 free(en_name); 250 } else 251#endif /* __APPLE */ 252 p = pcap_create(name, open_errbuf); 253 if (p == NULL) { 254 /* 255 * The attempt to create the pcap_t failed; 256 * that's probably an indication that we're 257 * out of memory. 258 * 259 * Don't bother including this interface, 260 * but don't treat it as an error. 261 */ 262 *curdev_ret = NULL; 263 return (0); 264 } 265 /* Small snaplen, so we don't try to allocate much memory. */ 266 pcap_set_snaplen(p, 68); 267 ret = pcap_activate(p); 268 pcap_close(p); 269 switch (ret) { 270 271 case PCAP_ERROR_NO_SUCH_DEVICE: 272 case PCAP_ERROR_IFACE_NOT_UP: 273 /* 274 * We expect these two errors - they're the 275 * reason we try to open the device. 276 * 277 * PCAP_ERROR_NO_SUCH_DEVICE typically means 278 * "there's no such device *known to the 279 * OS's capture mechanism*", so, even though 280 * it might be a valid network interface, you 281 * can't capture on it (e.g., the loopback 282 * device in Solaris up to Solaris 10, or 283 * the vmnet devices in OS X with VMware 284 * Fusion). We don't include those devices 285 * in our list of devices, as there's no 286 * point in doing so - they're not available 287 * for capture. 288 * 289 * PCAP_ERROR_IFACE_NOT_UP means that the 290 * OS's capture mechanism doesn't work on 291 * interfaces not marked as up; some capture 292 * mechanisms *do* support that, so we no 293 * longer reject those interfaces out of hand, 294 * but we *do* want to reject them if they 295 * can't be opened for capture. 296 */ 297 *curdev_ret = NULL; 298 return (0); 299 } 300 301 /* 302 * Yes, we can open it, or we can't, for some other 303 * reason. 304 * 305 * If we can open it, we want to offer it for 306 * capture, as you can capture on it. If we can't, 307 * we want to offer it for capture, so that, if 308 * the user tries to capture on it, they'll get 309 * an error and they'll know why they can't 310 * capture on it (e.g., insufficient permissions) 311 * or they'll report it as a problem (and then 312 * have the error message to provide as information). 313 * 314 * Allocate a new entry. 315 */ 316 curdev = malloc(sizeof(pcap_if_t)); 317 if (curdev == NULL) { 318 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 319 "malloc: %s", pcap_strerror(errno)); 320 return (-1); 321 } 322 323 /* 324 * Fill in the entry. 325 */ 326 curdev->next = NULL; 327 curdev->name = strdup(name); 328 if (curdev->name == NULL) { 329 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 330 "malloc: %s", pcap_strerror(errno)); 331 free(curdev); 332 return (-1); 333 } 334 if (description != NULL) { 335 /* 336 * We have a description for this interface. 337 */ 338 curdev->description = strdup(description); 339 if (curdev->description == NULL) { 340 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 341 "malloc: %s", pcap_strerror(errno)); 342 free(curdev->name); 343 free(curdev); 344 return (-1); 345 } 346 } else { 347 /* 348 * We don't. 349 */ 350 curdev->description = NULL; 351 } 352 curdev->addresses = NULL; /* list starts out as empty */ 353 curdev->flags = 0; 354 if (ISLOOPBACK(name, flags)) 355 curdev->flags |= PCAP_IF_LOOPBACK; 356 if (ISUP(flags)) 357 curdev->flags |= PCAP_IF_UP; 358 if (ISRUNNING(flags)) 359 curdev->flags |= PCAP_IF_RUNNING; 360 361 /* 362 * Add it to the list, in the appropriate location. 363 * First, get the "figure of merit" for this 364 * interface. 365 */ 366 this_figure_of_merit = get_figure_of_merit(curdev); 367 368 /* 369 * Now look for the last interface with an figure of merit 370 * less than or equal to the new interface's figure of 371 * merit. 372 * 373 * We start with "prevdev" being NULL, meaning we're before 374 * the first element in the list. 375 */ 376 prevdev = NULL; 377 for (;;) { 378 /* 379 * Get the interface after this one. 380 */ 381 if (prevdev == NULL) { 382 /* 383 * The next element is the first element. 384 */ 385 nextdev = *alldevs; 386 } else 387 nextdev = prevdev->next; 388 389 /* 390 * Are we at the end of the list? 391 */ 392 if (nextdev == NULL) { 393 /* 394 * Yes - we have to put the new entry 395 * after "prevdev". 396 */ 397 break; 398 } 399 400 /* 401 * Is the new interface's figure of merit less 402 * than the next interface's figure of merit, 403 * meaning that the new interface is better 404 * than the next interface? 405 */ 406 nextdev_figure_of_merit = get_figure_of_merit(nextdev); 407 if (this_figure_of_merit < nextdev_figure_of_merit) { 408 /* 409 * Yes - we should put the new entry 410 * before "nextdev", i.e. after "prevdev". 411 */ 412 break; 413 } 414 415 prevdev = nextdev; 416 } 417 418 /* 419 * Insert before "nextdev". 420 */ 421 curdev->next = nextdev; 422 423 /* 424 * Insert after "prevdev" - unless "prevdev" is null, 425 * in which case this is the first interface. 426 */ 427 if (prevdev == NULL) { 428 /* 429 * This is the first interface. Pass back a 430 * pointer to it, and put "curdev" before 431 * "nextdev". 432 */ 433 *alldevs = curdev; 434 } else 435 prevdev->next = curdev; 436 } 437 438 *curdev_ret = curdev; 439 return (0); 440} 441 442/* 443 * Try to get a description for a given device. 444 * Returns a mallocated description if it could and NULL if it couldn't. 445 * 446 * XXX - on FreeBSDs that support it, should it get the sysctl named 447 * "dev.{adapter family name}.{adapter unit}.%desc" to get a description 448 * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800" 449 * with my Cisco 350 card, so the name isn't entirely descriptive. The 450 * "dev.an.0.%pnpinfo" has a better description, although one might argue 451 * that the problem is really a driver bug - if it can find out that it's 452 * a Cisco 340 or 350, rather than an old Aironet card, it should use 453 * that in the description. 454 * 455 * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD 456 * and OpenBSD let you get a description, but it's not generated by the OS, 457 * it's set with another ioctl that ifconfig supports; we use that to get 458 * a description in FreeBSD and OpenBSD, but if there is no such 459 * description available, it still might be nice to get some description 460 * string based on the device type or something such as that. 461 * 462 * In OS X, the System Configuration framework can apparently return 463 * names in 10.4 and later. 464 * 465 * It also appears that freedesktop.org's HAL offers an "info.product" 466 * string, but the HAL specification says it "should not be used in any 467 * UI" and "subsystem/capability specific properties" should be used 468 * instead and, in any case, I think HAL is being deprecated in 469 * favor of other stuff such as DeviceKit. DeviceKit doesn't appear 470 * to have any obvious product information for devices, but maybe 471 * I haven't looked hard enough. 472 * 473 * Using the System Configuration framework, or HAL, or DeviceKit, or 474 * whatever, would require that libpcap applications be linked with 475 * the frameworks/libraries in question. That shouldn't be a problem 476 * for programs linking with the shared version of libpcap (unless 477 * you're running on AIX - which I think is the only UN*X that doesn't 478 * support linking a shared library with other libraries on which it 479 * depends, and having an executable linked only with the first shared 480 * library automatically pick up the other libraries when started - 481 * and using HAL or whatever). Programs linked with the static 482 * version of libpcap would have to use pcap-config with the --static 483 * flag in order to get the right linker flags in order to pick up 484 * the additional libraries/frameworks; those programs need that anyway 485 * for libpcap 1.1 and beyond on Linux, as, by default, it requires 486 * -lnl. 487 * 488 * Do any other UN*Xes, or desktop environments support getting a 489 * description? 490 */ 491static char * 492get_if_description(const char *name) 493{ 494#ifdef SIOCGIFDESCR 495 char *description = NULL; 496 int s; 497 struct ifreq ifrdesc; 498#ifndef IFDESCRSIZE 499 size_t descrlen = 64; 500#else 501 size_t descrlen = IFDESCRSIZE; 502#endif /* IFDESCRSIZE */ 503 504 /* 505 * Get the description for the interface. 506 */ 507 memset(&ifrdesc, 0, sizeof ifrdesc); 508 strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name); 509 s = socket(AF_INET, SOCK_DGRAM, 0); 510 if (s >= 0) { 511#ifdef __FreeBSD__ 512 /* 513 * On FreeBSD, if the buffer isn't big enough for the 514 * description, the ioctl succeeds, but the description 515 * isn't copied, ifr_buffer.length is set to the description 516 * length, and ifr_buffer.buffer is set to NULL. 517 */ 518 for (;;) { 519 free(description); 520 if ((description = malloc(descrlen)) != NULL) { 521 ifrdesc.ifr_buffer.buffer = description; 522 ifrdesc.ifr_buffer.length = descrlen; 523 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) { 524 if (ifrdesc.ifr_buffer.buffer == 525 description) 526 break; 527 else 528 descrlen = ifrdesc.ifr_buffer.length; 529 } else { 530 /* 531 * Failed to get interface description. 532 */ 533 free(description); 534 description = NULL; 535 break; 536 } 537 } else 538 break; 539 } 540#else /* __FreeBSD__ */ 541 /* 542 * The only other OS that currently supports 543 * SIOCGIFDESCR is OpenBSD, and it has no way 544 * to get the description length - it's clamped 545 * to a maximum of IFDESCRSIZE. 546 */ 547 if ((description = malloc(descrlen)) != NULL) { 548 ifrdesc.ifr_data = (caddr_t)description; 549 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) { 550 /* 551 * Failed to get interface description. 552 */ 553 free(description); 554 description = NULL; 555 } 556 } 557#endif /* __FreeBSD__ */ 558 close(s); 559 if (description != NULL && strlen(description) == 0) { 560 free(description); 561 description = NULL; 562 } 563 } 564 565 return (description); 566#else /* SIOCGIFDESCR */ 567 return (NULL); 568#endif /* SIOCGIFDESCR */ 569} 570 571/* 572 * Try to get a description for a given device, and then look for that 573 * device in the specified list of devices. 574 * 575 * If we find it, then, if the specified address isn't null, add it to 576 * the list of addresses for the device and return 0. 577 * 578 * If we don't find it, check whether we can open it: 579 * 580 * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or 581 * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for 582 * it, as that probably means it exists but doesn't support 583 * packet capture. 584 * 585 * Otherwise, attempt to add an entry for it, with the specified 586 * ifnet flags and description, and, if that succeeds, add the 587 * specified address to its list of addresses if that address is 588 * non-null, set *curdev_ret to point to the new entry, and 589 * return 0, otherwise return PCAP_ERROR and set errbuf to an 590 * error message. 591 * 592 * (We can get called with a null address because we might get a list 593 * of interface name/address combinations from the underlying OS, with 594 * the address being absent in some cases, rather than a list of 595 * interfaces with each interface having a list of addresses, so this 596 * call may be the only call made to add to the list, and we want to 597 * add interfaces even if they have no addresses.) 598 */ 599int 600add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags, 601 struct sockaddr *addr, size_t addr_size, 602 struct sockaddr *netmask, size_t netmask_size, 603 struct sockaddr *broadaddr, size_t broadaddr_size, 604 struct sockaddr *dstaddr, size_t dstaddr_size, 605 char *errbuf) 606{ 607 char *description; 608 pcap_if_t *curdev; 609 610 description = get_if_description(name); 611 if (add_or_find_if(&curdev, alldevs, name, flags, description, 612 errbuf) == -1) { 613 free(description); 614 /* 615 * Error - give up. 616 */ 617 return (-1); 618 } 619 free(description); 620 if (curdev == NULL) { 621 /* 622 * Device wasn't added because it can't be opened. 623 * Not a fatal error. 624 */ 625 return (0); 626 } 627 628 if (addr == NULL) { 629 /* 630 * There's no address to add; this entry just meant 631 * "here's a new interface". 632 */ 633 return (0); 634 } 635 636 /* 637 * "curdev" is an entry for this interface, and we have an 638 * address for it; add an entry for that address to the 639 * interface's list of addresses. 640 * 641 * Allocate the new entry and fill it in. 642 */ 643 return (add_addr_to_dev(curdev, addr, addr_size, netmask, 644 netmask_size, broadaddr, broadaddr_size, dstaddr, 645 dstaddr_size, errbuf)); 646} 647 648/* 649 * Add an entry to the list of addresses for an interface. 650 * "curdev" is the entry for that interface. 651 * If this is the first IP address added to the interface, move it 652 * in the list as appropriate. 653 */ 654int 655add_addr_to_dev(pcap_if_t *curdev, 656 struct sockaddr *addr, size_t addr_size, 657 struct sockaddr *netmask, size_t netmask_size, 658 struct sockaddr *broadaddr, size_t broadaddr_size, 659 struct sockaddr *dstaddr, size_t dstaddr_size, 660 char *errbuf) 661{ 662 pcap_addr_t *curaddr, *prevaddr, *nextaddr; 663 664 curaddr = malloc(sizeof(pcap_addr_t)); 665 if (curaddr == NULL) { 666 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 667 "malloc: %s", pcap_strerror(errno)); 668 return (-1); 669 } 670 671 curaddr->next = NULL; 672 if (addr != NULL) { 673 curaddr->addr = dup_sockaddr(addr, addr_size); 674 if (curaddr->addr == NULL) { 675 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 676 "malloc: %s", pcap_strerror(errno)); 677 free(curaddr); 678 return (-1); 679 } 680 } else 681 curaddr->addr = NULL; 682 683 if (netmask != NULL) { 684 curaddr->netmask = dup_sockaddr(netmask, netmask_size); 685 if (curaddr->netmask == NULL) { 686 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 687 "malloc: %s", pcap_strerror(errno)); 688 if (curaddr->addr != NULL) 689 free(curaddr->addr); 690 free(curaddr); 691 return (-1); 692 } 693 } else 694 curaddr->netmask = NULL; 695 696 if (broadaddr != NULL) { 697 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); 698 if (curaddr->broadaddr == NULL) { 699 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 700 "malloc: %s", pcap_strerror(errno)); 701 if (curaddr->netmask != NULL) 702 free(curaddr->netmask); 703 if (curaddr->addr != NULL) 704 free(curaddr->addr); 705 free(curaddr); 706 return (-1); 707 } 708 } else 709 curaddr->broadaddr = NULL; 710 711 if (dstaddr != NULL) { 712 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size); 713 if (curaddr->dstaddr == NULL) { 714 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 715 "malloc: %s", pcap_strerror(errno)); 716 if (curaddr->broadaddr != NULL) 717 free(curaddr->broadaddr); 718 if (curaddr->netmask != NULL) 719 free(curaddr->netmask); 720 if (curaddr->addr != NULL) 721 free(curaddr->addr); 722 free(curaddr); 723 return (-1); 724 } 725 } else 726 curaddr->dstaddr = NULL; 727 728 /* 729 * Find the end of the list of addresses. 730 */ 731 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { 732 nextaddr = prevaddr->next; 733 if (nextaddr == NULL) { 734 /* 735 * This is the end of the list. 736 */ 737 break; 738 } 739 } 740 741 if (prevaddr == NULL) { 742 /* 743 * The list was empty; this is the first member. 744 */ 745 curdev->addresses = curaddr; 746 } else { 747 /* 748 * "prevaddr" is the last member of the list; append 749 * this member to it. 750 */ 751 prevaddr->next = curaddr; 752 } 753 754 return (0); 755} 756 757/* 758 * Look for a given device in the specified list of devices. 759 * 760 * If we find it, return 0. 761 * 762 * If we don't find it, check whether we can open it: 763 * 764 * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or 765 * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for 766 * it, as that probably means it exists but doesn't support 767 * packet capture. 768 * 769 * Otherwise, attempt to add an entry for it, with the specified 770 * ifnet flags and description, and, if that succeeds, return 0 771 * and set *curdev_ret to point to the new entry, otherwise 772 * return PCAP_ERROR and set errbuf to an error message. 773 */ 774int 775pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags, 776 const char *description, char *errbuf) 777{ 778 pcap_if_t *curdev; 779 780 return (add_or_find_if(&curdev, devlist, name, flags, description, 781 errbuf)); 782} 783 784 785/* 786 * Free a list of interfaces. 787 */ 788void 789pcap_freealldevs(pcap_if_t *alldevs) 790{ 791 pcap_if_t *curdev, *nextdev; 792 pcap_addr_t *curaddr, *nextaddr; 793 794 for (curdev = alldevs; curdev != NULL; curdev = nextdev) { 795 nextdev = curdev->next; 796 797 /* 798 * Free all addresses. 799 */ 800 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) { 801 nextaddr = curaddr->next; 802 if (curaddr->addr) 803 free(curaddr->addr); 804 if (curaddr->netmask) 805 free(curaddr->netmask); 806 if (curaddr->broadaddr) 807 free(curaddr->broadaddr); 808 if (curaddr->dstaddr) 809 free(curaddr->dstaddr); 810 free(curaddr); 811 } 812 813 /* 814 * Free the name string. 815 */ 816 free(curdev->name); 817 818 /* 819 * Free the description string, if any. 820 */ 821 if (curdev->description != NULL) 822 free(curdev->description); 823 824 /* 825 * Free the interface. 826 */ 827 free(curdev); 828 } 829} 830 831#if !defined(WIN32) && !defined(MSDOS) 832 833/* 834 * Return the name of a network interface attached to the system, or NULL 835 * if none can be found. The interface must be configured up; the 836 * lowest unit number is preferred; loopback is ignored. 837 */ 838char * 839pcap_lookupdev(errbuf) 840 register char *errbuf; 841{ 842 pcap_if_t *alldevs; 843/* for old BSD systems, including bsdi3 */ 844#ifndef IF_NAMESIZE 845#define IF_NAMESIZE IFNAMSIZ 846#endif 847 static char device[IF_NAMESIZE + 1]; 848 char *ret; 849 850 if (pcap_findalldevs(&alldevs, errbuf) == -1) 851 return (NULL); 852 853 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) { 854 /* 855 * There are no devices on the list, or the first device 856 * on the list is a loopback device, which means there 857 * are no non-loopback devices on the list. This means 858 * we can't return any device. 859 * 860 * XXX - why not return a loopback device? If we can't 861 * capture on it, it won't be on the list, and if it's 862 * on the list, there aren't any non-loopback devices, 863 * so why not just supply it as the default device? 864 */ 865 (void)strlcpy(errbuf, "no suitable device found", 866 PCAP_ERRBUF_SIZE); 867 ret = NULL; 868 } else { 869 /* 870 * Return the name of the first device on the list. 871 */ 872 (void)strlcpy(device, alldevs->name, sizeof(device)); 873 ret = device; 874 } 875 876 pcap_freealldevs(alldevs); 877 return (ret); 878} 879 880int 881pcap_lookupnet(device, netp, maskp, errbuf) 882 register const char *device; 883 register bpf_u_int32 *netp, *maskp; 884 register char *errbuf; 885{ 886 register int fd; 887 register struct sockaddr_in *sin4; 888 struct ifreq ifr; 889 890 /* 891 * The pseudo-device "any" listens on all interfaces and therefore 892 * has the network address and -mask "0.0.0.0" therefore catching 893 * all traffic. Using NULL for the interface is the same as "any". 894 */ 895 if (!device || strcmp(device, "any") == 0 896#ifdef HAVE_DAG_API 897 || strstr(device, "dag") != NULL 898#endif 899#ifdef HAVE_SEPTEL_API 900 || strstr(device, "septel") != NULL 901#endif 902#ifdef PCAP_SUPPORT_BT 903 || strstr(device, "bluetooth") != NULL 904#endif 905#ifdef PCAP_SUPPORT_USB 906 || strstr(device, "usbmon") != NULL 907#endif 908#ifdef HAVE_SNF_API 909 || strstr(device, "snf") != NULL 910#endif 911 ) { 912 *netp = *maskp = 0; 913 return 0; 914 } 915 916 fd = socket(AF_INET, SOCK_DGRAM, 0); 917 if (fd < 0) { 918 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s", 919 pcap_strerror(errno)); 920 return (-1); 921 } 922 memset(&ifr, 0, sizeof(ifr)); 923#ifdef linux 924 /* XXX Work around Linux kernel bug */ 925 ifr.ifr_addr.sa_family = AF_INET; 926#endif 927 (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 928 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { 929 if (errno == EADDRNOTAVAIL) { 930 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 931 "%s: no IPv4 address assigned", device); 932 } else { 933 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 934 "SIOCGIFADDR: %s: %s", 935 device, pcap_strerror(errno)); 936 } 937 (void)close(fd); 938 return (-1); 939 } 940 sin4 = (struct sockaddr_in *)&ifr.ifr_addr; 941 *netp = sin4->sin_addr.s_addr; 942 memset(&ifr, 0, sizeof(ifr)); 943#ifdef linux 944 /* XXX Work around Linux kernel bug */ 945 ifr.ifr_addr.sa_family = AF_INET; 946#endif 947 (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 948 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) { 949 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 950 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno)); 951 (void)close(fd); 952 return (-1); 953 } 954 (void)close(fd); 955 *maskp = sin4->sin_addr.s_addr; 956 if (*maskp == 0) { 957 if (IN_CLASSA(*netp)) 958 *maskp = IN_CLASSA_NET; 959 else if (IN_CLASSB(*netp)) 960 *maskp = IN_CLASSB_NET; 961 else if (IN_CLASSC(*netp)) 962 *maskp = IN_CLASSC_NET; 963 else { 964 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 965 "inet class for 0x%x unknown", *netp); 966 return (-1); 967 } 968 } 969 *netp &= *maskp; 970 return (0); 971} 972 973#elif defined(WIN32) 974 975/* 976 * Return the name of a network interface attached to the system, or NULL 977 * if none can be found. The interface must be configured up; the 978 * lowest unit number is preferred; loopback is ignored. 979 */ 980char * 981pcap_lookupdev(errbuf) 982 register char *errbuf; 983{ 984 DWORD dwVersion; 985 DWORD dwWindowsMajorVersion; 986 dwVersion = GetVersion(); /* get the OS version */ 987 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); 988 989 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { 990 /* 991 * Windows 95, 98, ME. 992 */ 993 ULONG NameLength = 8192; 994 static char AdaptersName[8192]; 995 996 if (PacketGetAdapterNames(AdaptersName,&NameLength) ) 997 return (AdaptersName); 998 else 999 return NULL; 1000 } else { 1001 /* 1002 * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility 1003 */ 1004 ULONG NameLength = 8192; 1005 static WCHAR AdaptersName[8192]; 1006 char *tAstr; 1007 WCHAR *tUstr; 1008 WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR)); 1009 int NAdapts = 0; 1010 1011 if(TAdaptersName == NULL) 1012 { 1013 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure"); 1014 return NULL; 1015 } 1016 1017 if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) ) 1018 { 1019 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 1020 "PacketGetAdapterNames: %s", 1021 pcap_win32strerror()); 1022 free(TAdaptersName); 1023 return NULL; 1024 } 1025 1026 1027 tAstr = (char*)TAdaptersName; 1028 tUstr = (WCHAR*)AdaptersName; 1029 1030 /* 1031 * Convert and copy the device names 1032 */ 1033 while(sscanf(tAstr, "%S", tUstr) > 0) 1034 { 1035 tAstr += strlen(tAstr) + 1; 1036 tUstr += wcslen(tUstr) + 1; 1037 NAdapts ++; 1038 } 1039 1040 tAstr++; 1041 *tUstr = 0; 1042 tUstr++; 1043 1044 /* 1045 * Copy the descriptions 1046 */ 1047 while(NAdapts--) 1048 { 1049 char* tmp = (char*)tUstr; 1050 strcpy(tmp, tAstr); 1051 tmp += strlen(tAstr) + 1; 1052 tUstr = (WCHAR*)tmp; 1053 tAstr += strlen(tAstr) + 1; 1054 } 1055 1056 free(TAdaptersName); 1057 return (char *)(AdaptersName); 1058 } 1059} 1060 1061 1062int 1063pcap_lookupnet(device, netp, maskp, errbuf) 1064 register const char *device; 1065 register bpf_u_int32 *netp, *maskp; 1066 register char *errbuf; 1067{ 1068 /* 1069 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo() 1070 * in order to skip non IPv4 (i.e. IPv6 addresses) 1071 */ 1072 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; 1073 LONG if_addr_size = 1; 1074 struct sockaddr_in *t_addr; 1075 unsigned int i; 1076 1077 if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) { 1078 *netp = *maskp = 0; 1079 return (0); 1080 } 1081 1082 for(i=0; i<MAX_NETWORK_ADDRESSES; i++) 1083 { 1084 if(if_addrs[i].IPAddress.ss_family == AF_INET) 1085 { 1086 t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress); 1087 *netp = t_addr->sin_addr.S_un.S_addr; 1088 t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask); 1089 *maskp = t_addr->sin_addr.S_un.S_addr; 1090 1091 *netp &= *maskp; 1092 return (0); 1093 } 1094 1095 } 1096 1097 *netp = *maskp = 0; 1098 return (0); 1099} 1100 1101#endif /* !WIN32 && !MSDOS */ 1102