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 53 struct mbuf; /* Squelch compiler warnings on some platforms for */ 54 struct 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 #ifndef _WIN32 81 /* Not all systems have IFF_LOOPBACK */ 82 #ifdef IFF_LOOPBACK 83 #define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK) 84 #else 85 #define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \ 86 (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0')) 87 #endif 88 89 #ifdef IFF_UP 90 #define ISUP(flags) ((flags) & IFF_UP) 91 #else 92 #define ISUP(flags) 0 93 #endif 94 95 #ifdef IFF_RUNNING 96 #define ISRUNNING(flags) ((flags) & IFF_RUNNING) 97 #else 98 #define ISRUNNING(flags) 0 99 #endif 100 101 /* 102 * Map UN*X-style interface flags to libpcap flags. 103 */ 104 bpf_u_int32 105 if_flags_to_pcap_flags(const char *name _U_, u_int if_flags) 106 { 107 bpf_u_int32 pcap_flags; 108 109 pcap_flags = 0; 110 if (ISLOOPBACK(name, if_flags)) 111 pcap_flags |= PCAP_IF_LOOPBACK; 112 if (ISUP(if_flags)) 113 pcap_flags |= PCAP_IF_UP; 114 if (ISRUNNING(if_flags)) 115 pcap_flags |= PCAP_IF_RUNNING; 116 return (pcap_flags); 117 } 118 #endif 119 120 static struct sockaddr * 121 dup_sockaddr(struct sockaddr *sa, size_t sa_length) 122 { 123 struct sockaddr *newsa; 124 125 if ((newsa = malloc(sa_length)) == NULL) 126 return (NULL); 127 return (memcpy(newsa, sa, sa_length)); 128 } 129 130 /* 131 * Construct a "figure of merit" for an interface, for use when sorting 132 * the list of interfaces, in which interfaces that are up are superior 133 * to interfaces that aren't up, interfaces that are up and running are 134 * superior to interfaces that are up but not running, and non-loopback 135 * interfaces that are up and running are superior to loopback interfaces, 136 * and interfaces with the same flags have a figure of merit that's higher 137 * the lower the instance number. 138 * 139 * The goal is to try to put the interfaces most likely to be useful for 140 * capture at the beginning of the list. 141 * 142 * The figure of merit, which is lower the "better" the interface is, 143 * has the uppermost bit set if the interface isn't running, the bit 144 * below that set if the interface isn't up, the bit below that set 145 * if the interface is a loopback interface, and the interface index 146 * in the 29 bits below that. (Yes, we assume u_int is 32 bits.) 147 */ 148 static u_int 149 get_figure_of_merit(pcap_if_t *dev) 150 { 151 const char *cp; 152 u_int n; 153 154 if (strcmp(dev->name, "any") == 0) { 155 /* 156 * Give the "any" device an artificially high instance 157 * number, so it shows up after all other non-loopback 158 * interfaces. 159 */ 160 n = 0x1FFFFFFF; /* 29 all-1 bits */ 161 } else { 162 /* 163 * A number at the end of the device name string is 164 * assumed to be a unit number. 165 */ 166 cp = dev->name + strlen(dev->name) - 1; 167 while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9') 168 cp--; 169 if (*cp >= '0' && *cp <= '9') 170 n = atoi(cp); 171 else 172 n = 0; 173 } 174 if (!(dev->flags & PCAP_IF_RUNNING)) 175 n |= 0x80000000; 176 if (!(dev->flags & PCAP_IF_UP)) 177 n |= 0x40000000; 178 if (dev->flags & PCAP_IF_LOOPBACK) 179 n |= 0x20000000; 180 return (n); 181 } 182 183 /* 184 * Try to get a description for a given device. 185 * Returns a mallocated description if it could and NULL if it couldn't. 186 * 187 * XXX - on FreeBSDs that support it, should it get the sysctl named 188 * "dev.{adapter family name}.{adapter unit}.%desc" to get a description 189 * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800" 190 * with my Cisco 350 card, so the name isn't entirely descriptive. The 191 * "dev.an.0.%pnpinfo" has a better description, although one might argue 192 * that the problem is really a driver bug - if it can find out that it's 193 * a Cisco 340 or 350, rather than an old Aironet card, it should use 194 * that in the description. 195 * 196 * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD 197 * and OpenBSD let you get a description, but it's not generated by the OS, 198 * it's set with another ioctl that ifconfig supports; we use that to get 199 * a description in FreeBSD and OpenBSD, but if there is no such 200 * description available, it still might be nice to get some description 201 * string based on the device type or something such as that. 202 * 203 * In OS X, the System Configuration framework can apparently return 204 * names in 10.4 and later. 205 * 206 * It also appears that freedesktop.org's HAL offers an "info.product" 207 * string, but the HAL specification says it "should not be used in any 208 * UI" and "subsystem/capability specific properties" should be used 209 * instead and, in any case, I think HAL is being deprecated in 210 * favor of other stuff such as DeviceKit. DeviceKit doesn't appear 211 * to have any obvious product information for devices, but maybe 212 * I haven't looked hard enough. 213 * 214 * Using the System Configuration framework, or HAL, or DeviceKit, or 215 * whatever, would require that libpcap applications be linked with 216 * the frameworks/libraries in question. That shouldn't be a problem 217 * for programs linking with the shared version of libpcap (unless 218 * you're running on AIX - which I think is the only UN*X that doesn't 219 * support linking a shared library with other libraries on which it 220 * depends, and having an executable linked only with the first shared 221 * library automatically pick up the other libraries when started - 222 * and using HAL or whatever). Programs linked with the static 223 * version of libpcap would have to use pcap-config with the --static 224 * flag in order to get the right linker flags in order to pick up 225 * the additional libraries/frameworks; those programs need that anyway 226 * for libpcap 1.1 and beyond on Linux, as, by default, it requires 227 * -lnl. 228 * 229 * Do any other UN*Xes, or desktop environments support getting a 230 * description? 231 */ 232 static char * 233 get_if_description(const char *name) 234 { 235 #ifdef SIOCGIFDESCR 236 char *description = NULL; 237 int s; 238 struct ifreq ifrdesc; 239 #ifndef IFDESCRSIZE 240 size_t descrlen = 64; 241 #else 242 size_t descrlen = IFDESCRSIZE; 243 #endif /* IFDESCRSIZE */ 244 245 /* 246 * Get the description for the interface. 247 */ 248 memset(&ifrdesc, 0, sizeof ifrdesc); 249 strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name); 250 s = socket(AF_INET, SOCK_DGRAM, 0); 251 if (s >= 0) { 252 #ifdef __FreeBSD__ 253 /* 254 * On FreeBSD, if the buffer isn't big enough for the 255 * description, the ioctl succeeds, but the description 256 * isn't copied, ifr_buffer.length is set to the description 257 * length, and ifr_buffer.buffer is set to NULL. 258 */ 259 for (;;) { 260 free(description); 261 if ((description = malloc(descrlen)) != NULL) { 262 ifrdesc.ifr_buffer.buffer = description; 263 ifrdesc.ifr_buffer.length = descrlen; 264 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) { 265 if (ifrdesc.ifr_buffer.buffer == 266 description) 267 break; 268 else 269 descrlen = ifrdesc.ifr_buffer.length; 270 } else { 271 /* 272 * Failed to get interface description. 273 */ 274 free(description); 275 description = NULL; 276 break; 277 } 278 } else 279 break; 280 } 281 #else /* __FreeBSD__ */ 282 /* 283 * The only other OS that currently supports 284 * SIOCGIFDESCR is OpenBSD, and it has no way 285 * to get the description length - it's clamped 286 * to a maximum of IFDESCRSIZE. 287 */ 288 if ((description = malloc(descrlen)) != NULL) { 289 ifrdesc.ifr_data = (caddr_t)description; 290 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) { 291 /* 292 * Failed to get interface description. 293 */ 294 free(description); 295 description = NULL; 296 } 297 } 298 #endif /* __FreeBSD__ */ 299 close(s); 300 if (description != NULL && strlen(description) == 0) { 301 /* 302 * Description is empty, so discard it. 303 */ 304 free(description); 305 description = NULL; 306 } 307 } 308 309 #ifdef __FreeBSD__ 310 /* 311 * For FreeBSD, if we didn't get a description, and this is 312 * a device with a name of the form usbusN, label it as a USB 313 * bus. 314 */ 315 if (description == NULL) { 316 if (strncmp(name, "usbus", 5) == 0) { 317 /* 318 * OK, it begins with "usbus". 319 */ 320 long busnum; 321 char *p; 322 323 errno = 0; 324 busnum = strtol(name + 5, &p, 10); 325 if (errno == 0 && p != name + 5 && *p == '\0' && 326 busnum >= 0 && busnum <= INT_MAX) { 327 /* 328 * OK, it's a valid number that's not 329 * bigger than INT_MAX. Construct 330 * a description from it. 331 */ 332 static const char descr_prefix[] = "USB bus number "; 333 size_t descr_size; 334 335 /* 336 * Allow enough room for a 32-bit bus number. 337 * sizeof (descr_prefix) includes the 338 * terminating NUL. 339 */ 340 descr_size = sizeof (descr_prefix) + 10; 341 description = malloc(descr_size); 342 if (description != NULL) { 343 pcap_snprintf(description, descr_size, 344 "%s%ld", descr_prefix, busnum); 345 } 346 } 347 } 348 } 349 #endif 350 return (description); 351 #else /* SIOCGIFDESCR */ 352 return (NULL); 353 #endif /* SIOCGIFDESCR */ 354 } 355 356 /* 357 * Look for a given device in the specified list of devices. 358 * 359 * If we find it, return 0 and set *curdev_ret to point to it. 360 * 361 * If we don't find it, check whether we can open it: 362 * 363 * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or 364 * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for 365 * it, as that probably means it exists but doesn't support 366 * packet capture. 367 * 368 * Otherwise, attempt to add an entry for it, with the specified 369 * ifnet flags and description, and, if that succeeds, return 0 370 * and set *curdev_ret to point to the new entry, otherwise 371 * return PCAP_ERROR and set errbuf to an error message. If we 372 * weren't given a description, try to get one. 373 */ 374 int 375 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, 376 bpf_u_int32 flags, const char *description, char *errbuf) 377 { 378 pcap_t *p; 379 pcap_if_t *curdev, *prevdev, *nextdev; 380 u_int this_figure_of_merit, nextdev_figure_of_merit; 381 char open_errbuf[PCAP_ERRBUF_SIZE]; 382 int ret; 383 384 /* 385 * Is there already an entry in the list for this interface? 386 */ 387 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { 388 if (strcmp(name, curdev->name) == 0) 389 break; /* yes, we found it */ 390 } 391 392 if (curdev == NULL) { 393 /* 394 * No, we didn't find it. 395 * 396 * Can we open this interface for live capture? 397 * 398 * We do this check so that interfaces that are 399 * supplied by the interface enumeration mechanism 400 * we're using but that don't support packet capture 401 * aren't included in the list. Loopback interfaces 402 * on Solaris are an example of this; we don't just 403 * omit loopback interfaces on all platforms because 404 * you *can* capture on loopback interfaces on some 405 * OSes. 406 * 407 * On OS X, we don't do this check if the device 408 * name begins with "wlt"; at least some versions 409 * of OS X offer monitor mode capturing by having 410 * a separate "monitor mode" device for each wireless 411 * adapter, rather than by implementing the ioctls 412 * that {Free,Net,Open,DragonFly}BSD provide. 413 * Opening that device puts the adapter into monitor 414 * mode, which, at least for some adapters, causes 415 * them to deassociate from the network with which 416 * they're associated. 417 * 418 * Instead, we try to open the corresponding "en" 419 * device (so that we don't end up with, for users 420 * without sufficient privilege to open capture 421 * devices, a list of adapters that only includes 422 * the wlt devices). 423 */ 424 #ifdef __APPLE__ 425 if (strncmp(name, "wlt", 3) == 0) { 426 char *en_name; 427 size_t en_name_len; 428 429 /* 430 * Try to allocate a buffer for the "en" 431 * device's name. 432 */ 433 en_name_len = strlen(name) - 1; 434 en_name = malloc(en_name_len + 1); 435 if (en_name == NULL) { 436 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 437 "malloc: %s", pcap_strerror(errno)); 438 return (-1); 439 } 440 strcpy(en_name, "en"); 441 strcat(en_name, name + 3); 442 p = pcap_create(en_name, open_errbuf); 443 free(en_name); 444 } else 445 #endif /* __APPLE */ 446 p = pcap_create(name, open_errbuf); 447 if (p == NULL) { 448 /* 449 * The attempt to create the pcap_t failed; 450 * that's probably an indication that we're 451 * out of memory. 452 * 453 * Don't bother including this interface, 454 * but don't treat it as an error. 455 */ 456 *curdev_ret = NULL; 457 return (0); 458 } 459 /* Small snaplen, so we don't try to allocate much memory. */ 460 pcap_set_snaplen(p, 68); 461 ret = pcap_activate(p); 462 pcap_close(p); 463 switch (ret) { 464 465 case PCAP_ERROR_NO_SUCH_DEVICE: 466 case PCAP_ERROR_IFACE_NOT_UP: 467 /* 468 * We expect these two errors - they're the 469 * reason we try to open the device. 470 * 471 * PCAP_ERROR_NO_SUCH_DEVICE typically means 472 * "there's no such device *known to the 473 * OS's capture mechanism*", so, even though 474 * it might be a valid network interface, you 475 * can't capture on it (e.g., the loopback 476 * device in Solaris up to Solaris 10, or 477 * the vmnet devices in OS X with VMware 478 * Fusion). We don't include those devices 479 * in our list of devices, as there's no 480 * point in doing so - they're not available 481 * for capture. 482 * 483 * PCAP_ERROR_IFACE_NOT_UP means that the 484 * OS's capture mechanism doesn't work on 485 * interfaces not marked as up; some capture 486 * mechanisms *do* support that, so we no 487 * longer reject those interfaces out of hand, 488 * but we *do* want to reject them if they 489 * can't be opened for capture. 490 */ 491 *curdev_ret = NULL; 492 return (0); 493 } 494 495 /* 496 * Yes, we can open it, or we can't, for some other 497 * reason. 498 * 499 * If we can open it, we want to offer it for 500 * capture, as you can capture on it. If we can't, 501 * we want to offer it for capture, so that, if 502 * the user tries to capture on it, they'll get 503 * an error and they'll know why they can't 504 * capture on it (e.g., insufficient permissions) 505 * or they'll report it as a problem (and then 506 * have the error message to provide as information). 507 * 508 * Allocate a new entry. 509 */ 510 curdev = malloc(sizeof(pcap_if_t)); 511 if (curdev == NULL) { 512 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 513 "malloc: %s", pcap_strerror(errno)); 514 return (-1); 515 } 516 517 /* 518 * Fill in the entry. 519 */ 520 curdev->next = NULL; 521 curdev->name = strdup(name); 522 if (curdev->name == NULL) { 523 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 524 "malloc: %s", pcap_strerror(errno)); 525 free(curdev); 526 return (-1); 527 } 528 if (description == NULL) { 529 /* 530 * We weren't handed a description for the 531 * interface, so see if we can generate one 532 * ourselves. 533 */ 534 curdev->description = get_if_description(name); 535 } else { 536 /* 537 * We were handed a description; make a copy. 538 */ 539 curdev->description = strdup(description); 540 if (curdev->description == NULL) { 541 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 542 "malloc: %s", pcap_strerror(errno)); 543 free(curdev->name); 544 free(curdev); 545 return (-1); 546 } 547 } 548 curdev->addresses = NULL; /* list starts out as empty */ 549 curdev->flags = flags; 550 551 /* 552 * Add it to the list, in the appropriate location. 553 * First, get the "figure of merit" for this 554 * interface. 555 */ 556 this_figure_of_merit = get_figure_of_merit(curdev); 557 558 /* 559 * Now look for the last interface with an figure of merit 560 * less than or equal to the new interface's figure of 561 * merit. 562 * 563 * We start with "prevdev" being NULL, meaning we're before 564 * the first element in the list. 565 */ 566 prevdev = NULL; 567 for (;;) { 568 /* 569 * Get the interface after this one. 570 */ 571 if (prevdev == NULL) { 572 /* 573 * The next element is the first element. 574 */ 575 nextdev = *alldevs; 576 } else 577 nextdev = prevdev->next; 578 579 /* 580 * Are we at the end of the list? 581 */ 582 if (nextdev == NULL) { 583 /* 584 * Yes - we have to put the new entry 585 * after "prevdev". 586 */ 587 break; 588 } 589 590 /* 591 * Is the new interface's figure of merit less 592 * than the next interface's figure of merit, 593 * meaning that the new interface is better 594 * than the next interface? 595 */ 596 nextdev_figure_of_merit = get_figure_of_merit(nextdev); 597 if (this_figure_of_merit < nextdev_figure_of_merit) { 598 /* 599 * Yes - we should put the new entry 600 * before "nextdev", i.e. after "prevdev". 601 */ 602 break; 603 } 604 605 prevdev = nextdev; 606 } 607 608 /* 609 * Insert before "nextdev". 610 */ 611 curdev->next = nextdev; 612 613 /* 614 * Insert after "prevdev" - unless "prevdev" is null, 615 * in which case this is the first interface. 616 */ 617 if (prevdev == NULL) { 618 /* 619 * This is the first interface. Pass back a 620 * pointer to it, and put "curdev" before 621 * "nextdev". 622 */ 623 *alldevs = curdev; 624 } else 625 prevdev->next = curdev; 626 } 627 628 *curdev_ret = curdev; 629 return (0); 630 } 631 632 /* 633 * Try to get a description for a given device, and then look for that 634 * device in the specified list of devices. 635 * 636 * If we find it, then, if the specified address isn't null, add it to 637 * the list of addresses for the device and return 0. 638 * 639 * If we don't find it, check whether we can open it: 640 * 641 * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or 642 * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for 643 * it, as that probably means it exists but doesn't support 644 * packet capture. 645 * 646 * Otherwise, attempt to add an entry for it, with the specified 647 * ifnet flags, and, if that succeeds, add the specified address 648 * to its list of addresses if that address is non-null, set 649 * *curdev_ret to point to the new entry, and return 0, otherwise 650 * return PCAP_ERROR and set errbuf to an error message. 651 * 652 * (We can get called with a null address because we might get a list 653 * of interface name/address combinations from the underlying OS, with 654 * the address being absent in some cases, rather than a list of 655 * interfaces with each interface having a list of addresses, so this 656 * call may be the only call made to add to the list, and we want to 657 * add interfaces even if they have no addresses.) 658 */ 659 int 660 add_addr_to_iflist(pcap_if_t **alldevs, const char *name, bpf_u_int32 flags, 661 struct sockaddr *addr, size_t addr_size, 662 struct sockaddr *netmask, size_t netmask_size, 663 struct sockaddr *broadaddr, size_t broadaddr_size, 664 struct sockaddr *dstaddr, size_t dstaddr_size, 665 char *errbuf) 666 { 667 pcap_if_t *curdev; 668 669 if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { 670 /* 671 * Error - give up. 672 */ 673 return (-1); 674 } 675 if (curdev == NULL) { 676 /* 677 * Device wasn't added because it can't be opened. 678 * Not a fatal error. 679 */ 680 return (0); 681 } 682 683 if (addr == NULL) { 684 /* 685 * There's no address to add; this entry just meant 686 * "here's a new interface". 687 */ 688 return (0); 689 } 690 691 /* 692 * "curdev" is an entry for this interface, and we have an 693 * address for it; add an entry for that address to the 694 * interface's list of addresses. 695 * 696 * Allocate the new entry and fill it in. 697 */ 698 return (add_addr_to_dev(curdev, addr, addr_size, netmask, 699 netmask_size, broadaddr, broadaddr_size, dstaddr, 700 dstaddr_size, errbuf)); 701 } 702 703 /* 704 * Add an entry to the list of addresses for an interface. 705 * "curdev" is the entry for that interface. 706 * If this is the first IP address added to the interface, move it 707 * in the list as appropriate. 708 */ 709 int 710 add_addr_to_dev(pcap_if_t *curdev, 711 struct sockaddr *addr, size_t addr_size, 712 struct sockaddr *netmask, size_t netmask_size, 713 struct sockaddr *broadaddr, size_t broadaddr_size, 714 struct sockaddr *dstaddr, size_t dstaddr_size, 715 char *errbuf) 716 { 717 pcap_addr_t *curaddr, *prevaddr, *nextaddr; 718 719 curaddr = malloc(sizeof(pcap_addr_t)); 720 if (curaddr == NULL) { 721 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 722 "malloc: %s", pcap_strerror(errno)); 723 return (-1); 724 } 725 726 curaddr->next = NULL; 727 if (addr != NULL) { 728 curaddr->addr = dup_sockaddr(addr, addr_size); 729 if (curaddr->addr == NULL) { 730 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 731 "malloc: %s", pcap_strerror(errno)); 732 free(curaddr); 733 return (-1); 734 } 735 } else 736 curaddr->addr = NULL; 737 738 if (netmask != NULL) { 739 curaddr->netmask = dup_sockaddr(netmask, netmask_size); 740 if (curaddr->netmask == NULL) { 741 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 742 "malloc: %s", pcap_strerror(errno)); 743 if (curaddr->addr != NULL) 744 free(curaddr->addr); 745 free(curaddr); 746 return (-1); 747 } 748 } else 749 curaddr->netmask = NULL; 750 751 if (broadaddr != NULL) { 752 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); 753 if (curaddr->broadaddr == NULL) { 754 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 755 "malloc: %s", pcap_strerror(errno)); 756 if (curaddr->netmask != NULL) 757 free(curaddr->netmask); 758 if (curaddr->addr != NULL) 759 free(curaddr->addr); 760 free(curaddr); 761 return (-1); 762 } 763 } else 764 curaddr->broadaddr = NULL; 765 766 if (dstaddr != NULL) { 767 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size); 768 if (curaddr->dstaddr == NULL) { 769 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, 770 "malloc: %s", pcap_strerror(errno)); 771 if (curaddr->broadaddr != NULL) 772 free(curaddr->broadaddr); 773 if (curaddr->netmask != NULL) 774 free(curaddr->netmask); 775 if (curaddr->addr != NULL) 776 free(curaddr->addr); 777 free(curaddr); 778 return (-1); 779 } 780 } else 781 curaddr->dstaddr = NULL; 782 783 /* 784 * Find the end of the list of addresses. 785 */ 786 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { 787 nextaddr = prevaddr->next; 788 if (nextaddr == NULL) { 789 /* 790 * This is the end of the list. 791 */ 792 break; 793 } 794 } 795 796 if (prevaddr == NULL) { 797 /* 798 * The list was empty; this is the first member. 799 */ 800 curdev->addresses = curaddr; 801 } else { 802 /* 803 * "prevaddr" is the last member of the list; append 804 * this member to it. 805 */ 806 prevaddr->next = curaddr; 807 } 808 809 return (0); 810 } 811 812 /* 813 * Look for a given device in the specified list of devices. 814 * 815 * If we find it, return 0. 816 * 817 * If we don't find it, check whether we can open it: 818 * 819 * If that fails with PCAP_ERROR_NO_SUCH_DEVICE or 820 * PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for 821 * it, as that probably means it exists but doesn't support 822 * packet capture. 823 * 824 * Otherwise, attempt to add an entry for it, with the specified 825 * ifnet flags and description, and, if that succeeds, return 0 826 * and set *curdev_ret to point to the new entry, otherwise 827 * return PCAP_ERROR and set errbuf to an error message. 828 */ 829 int 830 pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags, 831 const char *description, char *errbuf) 832 { 833 pcap_if_t *curdev; 834 835 return (add_or_find_if(&curdev, devlist, name, flags, description, 836 errbuf)); 837 } 838 839 840 /* 841 * Free a list of interfaces. 842 */ 843 void 844 pcap_freealldevs(pcap_if_t *alldevs) 845 { 846 pcap_if_t *curdev, *nextdev; 847 pcap_addr_t *curaddr, *nextaddr; 848 849 for (curdev = alldevs; curdev != NULL; curdev = nextdev) { 850 nextdev = curdev->next; 851 852 /* 853 * Free all addresses. 854 */ 855 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) { 856 nextaddr = curaddr->next; 857 if (curaddr->addr) 858 free(curaddr->addr); 859 if (curaddr->netmask) 860 free(curaddr->netmask); 861 if (curaddr->broadaddr) 862 free(curaddr->broadaddr); 863 if (curaddr->dstaddr) 864 free(curaddr->dstaddr); 865 free(curaddr); 866 } 867 868 /* 869 * Free the name string. 870 */ 871 free(curdev->name); 872 873 /* 874 * Free the description string, if any. 875 */ 876 if (curdev->description != NULL) 877 free(curdev->description); 878 879 /* 880 * Free the interface. 881 */ 882 free(curdev); 883 } 884 } 885