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