]> The Tcpdump Group git mirrors - libpcap/blob - fad-getad.c
Put the different implementations of "pcap_findalldevs()" into separate
[libpcap] / fad-getad.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/fad-getad.c,v 1.1 2002-07-27 18:46:21 guy Exp $ (LBL)";
38 #endif
39
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44 #include <sys/types.h>
45 #include <sys/socket.h>
46
47 #include <errno.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <ifaddrs.h>
51
52 #include "pcap-int.h"
53
54 #ifdef HAVE_OS_PROTO_H
55 #include "os-proto.h"
56 #endif
57
58 /*
59 * Get a list of all interfaces that are up and that we can open.
60 * Returns -1 on error, 0 otherwise.
61 * The list, as returned through "alldevsp", may be null if no interfaces
62 * were up and could be opened.
63 *
64 * This is the implementation used on platforms that have "getifaddrs()".
65 */
66 int
67 pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
68 {
69 pcap_if_t *devlist = NULL;
70 struct ifaddrs *ifap, *ifa;
71 struct sockaddr *broadaddr, *dstaddr;
72 int ret = 0;
73
74 /*
75 * Get the list of interface addresses.
76 *
77 * Note: this won't return information about interfaces
78 * with no addresses; are there any such interfaces
79 * that would be capable of receiving packets?
80 * (Interfaces incapable of receiving packets aren't
81 * very interesting from libpcap's point of view.)
82 *
83 * LAN interfaces will probably have link-layer
84 * addresses; I don't know whether all implementations
85 * of "getifaddrs()" now, or in the future, will return
86 * those.
87 */
88 if (getifaddrs(&ifap) != 0) {
89 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
90 "getifaddrs: %s", pcap_strerror(errno));
91 return (-1);
92 }
93 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
94 /*
95 * Is this interface up?
96 */
97 if (!(ifa->ifa_flags & IFF_UP)) {
98 /*
99 * No, so don't add it to the list.
100 */
101 continue;
102 }
103
104 /*
105 * "ifa_broadaddr" may be non-null even on
106 * non-broadcast interfaces; "ifa_dstaddr"
107 * was, on at least one FreeBSD 4.1 system,
108 * non-null on a non-point-to-point
109 * interface.
110 */
111 if (ifa->ifa_flags & IFF_BROADCAST)
112 broadaddr = ifa->ifa_broadaddr;
113 else
114 broadaddr = NULL;
115 if (ifa->ifa_flags & IFF_POINTOPOINT)
116 dstaddr = ifa->ifa_dstaddr;
117 else
118 dstaddr = NULL;
119
120 /*
121 * Add information for this address to the list.
122 */
123 if (add_addr_to_iflist(&devlist, ifa->ifa_name,
124 ifa->ifa_flags, ifa->ifa_addr, ifa->ifa_netmask,
125 broadaddr, dstaddr, errbuf) < 0) {
126 ret = -1;
127 break;
128 }
129 }
130
131 freeifaddrs(ifap);
132
133 if (ret != -1) {
134 /*
135 * We haven't had any errors yet; do any platform-specific
136 * operations to add devices.
137 */
138 if (pcap_platform_finddevs(&devlist, errbuf) < 0)
139 ret = -1;
140 }
141
142 if (ret == -1) {
143 /*
144 * We had an error; free the list we've been constructing.
145 */
146 if (devlist != NULL) {
147 pcap_freealldevs(devlist);
148 devlist = NULL;
149 }
150 }
151
152 *alldevsp = devlist;
153 return (ret);
154 }