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