1 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
3 * Copyright (c) 1994, 1995, 1996, 1997, 1998
4 * The Regents of the University of California. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
40 #include <pcap-stdinc.h>
43 #include <sys/param.h>
47 #include <sys/ioctl.h>
48 #include <sys/socket.h>
49 #ifdef HAVE_SYS_SOCKIO_H
50 #include <sys/sockio.h>
53 struct mbuf; /* Squelch compiler warnings on some platforms for */
54 struct rtentry; /* declarations in <net/if.h> */
56 #include <netinet/in.h>
64 #if !defined(_WIN32) && !defined(__BORLANDC__)
66 #endif /* !_WIN32 && !__BORLANDC__ */
70 #ifdef HAVE_OS_PROTO_H
74 #if !defined(_WIN32) && !defined(MSDOS)
77 * Return the name of a network interface attached to the system, or NULL
78 * if none can be found. The interface must be configured up; the
79 * lowest unit number is preferred; loopback is ignored.
82 pcap_lookupdev(errbuf)
83 register char *errbuf;
86 /* for old BSD systems, including bsdi3 */
88 #define IF_NAMESIZE IFNAMSIZ
90 static char device[IF_NAMESIZE + 1];
93 if (pcap_findalldevs(&alldevs, errbuf) == -1)
96 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
98 * There are no devices on the list, or the first device
99 * on the list is a loopback device, which means there
100 * are no non-loopback devices on the list. This means
101 * we can't return any device.
103 * XXX - why not return a loopback device? If we can't
104 * capture on it, it won't be on the list, and if it's
105 * on the list, there aren't any non-loopback devices,
106 * so why not just supply it as the default device?
108 (void)strlcpy(errbuf, "no suitable device found",
113 * Return the name of the first device on the list.
115 (void)strlcpy(device, alldevs->name, sizeof(device));
119 pcap_freealldevs(alldevs);
124 pcap_lookupnet(device, netp, maskp, errbuf)
125 register const char *device;
126 register bpf_u_int32 *netp, *maskp;
127 register char *errbuf;
130 register struct sockaddr_in *sin4;
134 * The pseudo-device "any" listens on all interfaces and therefore
135 * has the network address and -mask "0.0.0.0" therefore catching
136 * all traffic. Using NULL for the interface is the same as "any".
138 if (!device || strcmp(device, "any") == 0
140 || strstr(device, "dag") != NULL
142 #ifdef HAVE_SEPTEL_API
143 || strstr(device, "septel") != NULL
145 #ifdef PCAP_SUPPORT_BT
146 || strstr(device, "bluetooth") != NULL
148 #ifdef PCAP_SUPPORT_USB
149 || strstr(device, "usbmon") != NULL
151 #ifdef PCAP_SUPPORT_NETMAP
152 || !strncmp(device, "netmap:", 7)
153 || !strncmp(device, "vale", 4)
156 || strstr(device, "snf") != NULL
163 fd = socket(AF_INET, SOCK_DGRAM, 0);
165 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
166 pcap_strerror(errno));
169 memset(&ifr, 0, sizeof(ifr));
171 /* XXX Work around Linux kernel bug */
172 ifr.ifr_addr.sa_family = AF_INET;
174 (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
175 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
176 if (errno == EADDRNOTAVAIL) {
177 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
178 "%s: no IPv4 address assigned", device);
180 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
181 "SIOCGIFADDR: %s: %s",
182 device, pcap_strerror(errno));
187 sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
188 *netp = sin4->sin_addr.s_addr;
189 memset(&ifr, 0, sizeof(ifr));
191 /* XXX Work around Linux kernel bug */
192 ifr.ifr_addr.sa_family = AF_INET;
194 (void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
195 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
196 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
197 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
202 *maskp = sin4->sin_addr.s_addr;
204 if (IN_CLASSA(*netp))
205 *maskp = IN_CLASSA_NET;
206 else if (IN_CLASSB(*netp))
207 *maskp = IN_CLASSB_NET;
208 else if (IN_CLASSC(*netp))
209 *maskp = IN_CLASSC_NET;
211 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
212 "inet class for 0x%x unknown", *netp);
220 #elif defined(_WIN32)
223 * Return the name of a network interface attached to the system, or NULL
224 * if none can be found. The interface must be configured up; the
225 * lowest unit number is preferred; loopback is ignored.
227 * In the best of all possible worlds, this would be the same as on
228 * UN*X, but there may be software that expects this to return a
229 * full list of devices after the first device.
231 #define ADAPTERSNAME_LEN 8192
233 pcap_lookupdev(errbuf)
234 register char *errbuf;
237 DWORD dwWindowsMajorVersion;
238 char our_errbuf[PCAP_ERRBUF_SIZE+1];
240 #pragma warning (push)
241 #pragma warning (disable: 4996) /* disable MSVC's GetVersion() deprecated warning here */
242 dwVersion = GetVersion(); /* get the OS version */
243 #pragma warning (pop)
244 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
246 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
248 * Windows 95, 98, ME.
250 ULONG NameLength = ADAPTERSNAME_LEN;
251 static char AdaptersName[ADAPTERSNAME_LEN];
253 if (PacketGetAdapterNames(AdaptersName,&NameLength) )
254 return (AdaptersName);
259 * Windows NT (NT 4.0 and later).
260 * Convert the names to Unicode for backward compatibility.
262 ULONG NameLength = ADAPTERSNAME_LEN;
263 static WCHAR AdaptersName[ADAPTERSNAME_LEN];
264 size_t BufferSpaceLeft;
269 WCHAR *TAdaptersName = (WCHAR*)malloc(ADAPTERSNAME_LEN * sizeof(WCHAR));
272 if(TAdaptersName == NULL)
274 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
278 if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
280 pcap_win32_err_to_str(GetLastError(), our_errbuf);
281 (void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
282 "PacketGetAdapterNames: %s", our_errbuf);
288 BufferSpaceLeft = ADAPTERSNAME_LEN * sizeof(WCHAR);
289 tAstr = (char*)TAdaptersName;
290 Unameptr = AdaptersName;
293 * Convert the device names to Unicode into AdapterName.
297 * Length of the name, including the terminating
300 namelen = strlen(tAstr) + 1;
303 * Do we have room for the name in the Unicode
306 if (BufferSpaceLeft < namelen * sizeof(WCHAR)) {
312 BufferSpaceLeft -= namelen * sizeof(WCHAR);
315 * Copy the name, converting ASCII to Unicode.
316 * namelen includes the NUL, so we copy it as
319 for (i = 0; i < namelen; i++)
320 *Unameptr++ = *tAstr++;
323 * Count this adapter.
326 } while (namelen != 1);
329 * Copy the descriptions, but don't convert them from
332 Adescptr = (char *)Unameptr;
337 desclen = strlen(tAstr) + 1;
340 * Do we have room for the name in the Unicode
343 if (BufferSpaceLeft < desclen) {
351 * Just copy the ASCII string.
352 * namelen includes the NUL, so we copy it as
355 memcpy(Adescptr, tAstr, desclen);
358 BufferSpaceLeft -= desclen;
363 return (char *)(AdaptersName);
369 pcap_lookupnet(device, netp, maskp, errbuf)
370 register const char *device;
371 register bpf_u_int32 *netp, *maskp;
372 register char *errbuf;
375 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
376 * in order to skip non IPv4 (i.e. IPv6 addresses)
378 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
379 LONG if_addr_size = 1;
380 struct sockaddr_in *t_addr;
383 if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
388 for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
390 if(if_addrs[i].IPAddress.ss_family == AF_INET)
392 t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
393 *netp = t_addr->sin_addr.S_un.S_addr;
394 t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
395 *maskp = t_addr->sin_addr.S_un.S_addr;
407 #endif /* !_WIN32 && !MSDOS */