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 #include <sys/types.h> 36 #include <sys/socket.h> 37 #include <netinet/in.h> 38 39 #include <net/if.h> 40 41 #include <ctype.h> 42 #include <errno.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <ifaddrs.h> 47 #include <limits.h> 48 49 #include "pcap-int.h" 50 51 static struct sockaddr * 52 dup_sockaddr(struct sockaddr *sa, size_t sa_length) 53 { 54 struct sockaddr *newsa; 55 56 if ((newsa = malloc(sa_length)) == NULL) 57 return (NULL); 58 return (memcpy(newsa, sa, sa_length)); 59 } 60 61 static int 62 get_instance(const char *name) 63 { 64 const char *cp, *endcp, *errstr; 65 int n; 66 67 if (strcmp(name, "any") == 0) { 68 /* 69 * Give the "any" device an artificially high instance 70 * number, so it shows up after all other non-loopback 71 * interfaces. 72 */ 73 return INT_MAX; 74 } 75 76 endcp = name + strlen(name); 77 for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp) 78 continue; 79 80 n = strtonum(cp, 0, INT_MAX, &errstr); 81 if (errstr != NULL) 82 return -1; 83 return n; 84 } 85 86 static int 87 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, 88 u_int flags, const char *description, char *errbuf) 89 { 90 pcap_t *p; 91 pcap_if_t *curdev, *prevdev, *nextdev; 92 int this_instance; 93 size_t len; 94 95 /* 96 * Can we open this interface for live capture? 97 * 98 * We do this check so that interfaces that are supplied 99 * by the interface enumeration mechanism we're using 100 * but that don't support packet capture aren't included 101 * in the list. An example of this is loopback interfaces 102 * on Solaris; we don't just omit loopback interfaces 103 * because you *can* capture on loopback interfaces on some 104 * OSes. 105 */ 106 p = pcap_open_live(name, 68, 0, 0, errbuf); 107 if (p == NULL) { 108 /* 109 * No. Don't bother including it. 110 * Don't treat this as an error, though. 111 */ 112 *curdev_ret = NULL; 113 return (0); 114 } 115 pcap_close(p); 116 117 /* 118 * Is there already an entry in the list for this interface? 119 */ 120 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { 121 if (strcmp(name, curdev->name) == 0) 122 break; /* yes, we found it */ 123 } 124 if (curdev == NULL) { 125 /* 126 * No, we didn't find it. 127 * Allocate a new entry. 128 */ 129 curdev = calloc(1, sizeof(pcap_if_t)); 130 if (curdev == NULL) { 131 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 132 "calloc: %s", pcap_strerror(errno)); 133 goto fail; 134 } 135 136 /* 137 * Fill in the entry. 138 */ 139 curdev->next = NULL; 140 len = strlen(name) + 1; 141 curdev->name = malloc(len); 142 if (curdev->name == NULL) { 143 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 144 "malloc: %s", pcap_strerror(errno)); 145 goto fail; 146 } 147 strlcpy(curdev->name, name, len); 148 if (description != NULL) { 149 /* 150 * We have a description for this interface. 151 */ 152 len = strlen(description) + 1; 153 curdev->description = malloc(len); 154 if (curdev->description == NULL) { 155 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 156 "malloc: %s", pcap_strerror(errno)); 157 goto fail; 158 } 159 strlcpy(curdev->description, description, len); 160 } 161 curdev->addresses = NULL; /* list starts out as empty */ 162 curdev->flags = 0; 163 if (ISLOOPBACK(name, flags)) 164 curdev->flags |= PCAP_IF_LOOPBACK; 165 166 /* 167 * Add it to the list, in the appropriate location. 168 * First, get the instance number of this interface. 169 */ 170 if ((this_instance = get_instance(name)) == -1) { 171 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 172 "malformed device name: %s", name); 173 goto fail; 174 } 175 176 /* 177 * Now look for the last interface with an instance number 178 * less than or equal to the new interface's instance 179 * number - except that non-loopback interfaces are 180 * arbitrarily treated as having interface numbers less 181 * than those of loopback interfaces, so the loopback 182 * interfaces are put at the end of the list. 183 * 184 * We start with "prevdev" being NULL, meaning we're before 185 * the first element in the list. 186 */ 187 prevdev = NULL; 188 for (;;) { 189 /* 190 * Get the interface after this one. 191 */ 192 if (prevdev == NULL) { 193 /* 194 * The next element is the first element. 195 */ 196 nextdev = *alldevs; 197 } else 198 nextdev = prevdev->next; 199 200 /* 201 * Are we at the end of the list? 202 */ 203 if (nextdev == NULL) { 204 /* 205 * Yes - we have to put the new entry 206 * after "prevdev". 207 */ 208 break; 209 } 210 211 /* 212 * Is the new interface a non-loopback interface 213 * and the next interface a loopback interface? 214 */ 215 if (!(curdev->flags & PCAP_IF_LOOPBACK) && 216 (nextdev->flags & PCAP_IF_LOOPBACK)) { 217 /* 218 * Yes, we should put the new entry 219 * before "nextdev", i.e. after "prevdev". 220 */ 221 break; 222 } 223 224 /* 225 * Is the new interface's instance number less 226 * than the next interface's instance number, 227 * and is it the case that the new interface is a 228 * non-loopback interface or the next interface is 229 * a loopback interface? 230 * 231 * (The goal of both loopback tests is to make 232 * sure that we never put a loopback interface 233 * before any non-loopback interface and that we 234 * always put a non-loopback interface before all 235 * loopback interfaces.) 236 */ 237 if (this_instance < get_instance(nextdev->name) && 238 (!(curdev->flags & PCAP_IF_LOOPBACK) || 239 (nextdev->flags & PCAP_IF_LOOPBACK))) { 240 /* 241 * Yes - we should put the new entry 242 * before "nextdev", i.e. after "prevdev". 243 */ 244 break; 245 } 246 247 prevdev = nextdev; 248 } 249 250 /* 251 * Insert before "nextdev". 252 */ 253 curdev->next = nextdev; 254 255 /* 256 * Insert after "prevdev" - unless "prevdev" is null, 257 * in which case this is the first interface. 258 */ 259 if (prevdev == NULL) { 260 /* 261 * This is the first interface. Pass back a 262 * pointer to it, and put "curdev" before 263 * "nextdev". 264 */ 265 *alldevs = curdev; 266 } else 267 prevdev->next = curdev; 268 } 269 270 *curdev_ret = curdev; 271 return (0); 272 273 fail: 274 if (curdev != NULL) { 275 free(curdev->name); 276 free(curdev->description); 277 free(curdev); 278 } 279 return (-1); 280 } 281 282 static int 283 add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags, 284 struct sockaddr *addr, size_t addr_size, 285 struct sockaddr *netmask, size_t netmask_size, 286 struct sockaddr *broadaddr, size_t broadaddr_size, 287 struct sockaddr *dstaddr, size_t dstaddr_size, 288 char *errbuf) 289 { 290 pcap_if_t *curdev; 291 pcap_addr_t *curaddr, *prevaddr, *nextaddr; 292 293 if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { 294 /* 295 * Error - give up. 296 */ 297 return (-1); 298 } 299 if (curdev == NULL) { 300 /* 301 * Device wasn't added because it can't be opened. 302 * Not a fatal error. 303 */ 304 return (0); 305 } 306 307 /* 308 * "curdev" is an entry for this interface; add an entry for this 309 * address to its list of addresses. 310 * 311 * Allocate the new entry and fill it in. 312 */ 313 curaddr = calloc(1, sizeof(pcap_addr_t)); 314 if (curaddr == NULL) { 315 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 316 "calloc: %s", pcap_strerror(errno)); 317 goto fail; 318 } 319 320 curaddr->next = NULL; 321 if (addr != NULL) { 322 curaddr->addr = dup_sockaddr(addr, addr_size); 323 if (curaddr->addr == NULL) { 324 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 325 "malloc: %s", pcap_strerror(errno)); 326 goto fail; 327 } 328 } 329 330 if (netmask != NULL) { 331 curaddr->netmask = dup_sockaddr(netmask, netmask_size); 332 if (curaddr->netmask == NULL) { 333 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 334 "malloc: %s", pcap_strerror(errno)); 335 goto fail; 336 } 337 } 338 339 if (broadaddr != NULL) { 340 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); 341 if (curaddr->broadaddr == NULL) { 342 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 343 "malloc: %s", pcap_strerror(errno)); 344 goto fail; 345 } 346 } 347 348 if (dstaddr != NULL) { 349 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size); 350 if (curaddr->dstaddr == NULL) { 351 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 352 "malloc: %s", pcap_strerror(errno)); 353 goto fail; 354 } 355 } 356 357 /* 358 * Find the end of the list of addresses. 359 */ 360 for (prevaddr = curdev->addresses; prevaddr != NULL; 361 prevaddr = nextaddr) { 362 nextaddr = prevaddr->next; 363 if (nextaddr == NULL) { 364 /* 365 * This is the end of the list. 366 */ 367 break; 368 } 369 } 370 371 if (prevaddr == NULL) { 372 /* 373 * The list was empty; this is the first member. 374 */ 375 curdev->addresses = curaddr; 376 } else { 377 /* 378 * "prevaddr" is the last member of the list; append 379 * this member to it. 380 */ 381 prevaddr->next = curaddr; 382 } 383 384 return (0); 385 386 fail: 387 if (curaddr != NULL) { 388 free(curaddr->addr); 389 free(curaddr->netmask); 390 free(curaddr->broadaddr); 391 free(curaddr->dstaddr); 392 free(curaddr); 393 } 394 return (-1); 395 } 396 397 /* 398 * Get a list of all interfaces that are up and that we can open. 399 * Returns -1 on error, 0 otherwise. 400 * The list, as returned through "alldevsp", may be null if no interfaces 401 * were up and could be opened. 402 * 403 * This is the implementation used on platforms that have "getifaddrs()". 404 */ 405 int 406 pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 407 { 408 pcap_if_t *devlist = NULL; 409 struct ifaddrs *ifap, *ifa; 410 struct sockaddr *addr, *netmask, *broadaddr, *dstaddr; 411 size_t addr_size, broadaddr_size, dstaddr_size; 412 int ret = 0; 413 414 /* 415 * Get the list of interface addresses. 416 * 417 * Note: this won't return information about interfaces 418 * with no addresses; are there any such interfaces 419 * that would be capable of receiving packets? 420 * (Interfaces incapable of receiving packets aren't 421 * very interesting from libpcap's point of view.) 422 * 423 * LAN interfaces will probably have link-layer 424 * addresses; I don't know whether all implementations 425 * of "getifaddrs()" now, or in the future, will return 426 * those. 427 */ 428 if (getifaddrs(&ifap) != 0) { 429 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 430 "getifaddrs: %s", pcap_strerror(errno)); 431 return (-1); 432 } 433 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { 434 /* 435 * Is this interface up? 436 */ 437 if (!(ifa->ifa_flags & IFF_UP)) { 438 /* 439 * No, so don't add it to the list. 440 */ 441 continue; 442 } 443 444 /* 445 * "ifa_addr" was apparently null on at least one 446 * interface on some system. 447 * 448 * "ifa_broadaddr" may be non-null even on 449 * non-broadcast interfaces, and was null on 450 * at least one OpenBSD 3.4 system on at least 451 * one interface with IFF_BROADCAST set. 452 * 453 * "ifa_dstaddr" was, on at least one FreeBSD 4.1 454 * system, non-null on a non-point-to-point 455 * interface. 456 * 457 * Therefore, we supply the address and netmask only 458 * if "ifa_addr" is non-null (if there's no address, 459 * there's obviously no netmask), and supply the 460 * broadcast and destination addresses if the appropriate 461 * flag is set *and* the appropriate "ifa_" entry doesn't 462 * evaluate to a null pointer. 463 */ 464 if (ifa->ifa_addr != NULL) { 465 addr = ifa->ifa_addr; 466 addr_size = SA_LEN(addr); 467 netmask = ifa->ifa_netmask; 468 } else { 469 addr = NULL; 470 addr_size = 0; 471 netmask = NULL; 472 } 473 if (ifa->ifa_flags & IFF_BROADCAST && 474 ifa->ifa_broadaddr != NULL) { 475 broadaddr = ifa->ifa_broadaddr; 476 broadaddr_size = SA_LEN(broadaddr); 477 } else { 478 broadaddr = NULL; 479 broadaddr_size = 0; 480 } 481 if (ifa->ifa_flags & IFF_POINTOPOINT && 482 ifa->ifa_dstaddr != NULL) { 483 dstaddr = ifa->ifa_dstaddr; 484 dstaddr_size = SA_LEN(ifa->ifa_dstaddr); 485 } else { 486 dstaddr = NULL; 487 dstaddr_size = 0; 488 } 489 490 /* 491 * Add information for this address to the list. 492 */ 493 if (add_addr_to_iflist(&devlist, ifa->ifa_name, 494 ifa->ifa_flags, addr, addr_size, netmask, addr_size, 495 broadaddr, broadaddr_size, dstaddr, dstaddr_size, 496 errbuf) < 0) { 497 ret = -1; 498 break; 499 } 500 } 501 502 freeifaddrs(ifap); 503 504 if (ret == -1) { 505 /* 506 * We had an error; free the list we've been constructing. 507 */ 508 if (devlist != NULL) { 509 pcap_freealldevs(devlist); 510 devlist = NULL; 511 } 512 } 513 514 *alldevsp = devlist; 515 return (ret); 516 } 517