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#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#ifdef WIN32
40#include <pcap-stdinc.h>
41#else /* WIN32 */
42
43#include <sys/param.h>
44#ifndef MSDOS
45#include <sys/file.h>
46#endif
47#include <sys/ioctl.h>
48#include <sys/socket.h>
49#ifdef HAVE_SYS_SOCKIO_H
50#include <sys/sockio.h>
51#endif
52
53struct mbuf;		/* Squelch compiler warnings on some platforms for */
54struct rtentry;		/* declarations in <net/if.h> */
55#include <net/if.h>
56#include <netinet/in.h>
57#endif /* WIN32 */
58
59#include <ctype.h>
60#include <errno.h>
61#include <memory.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <string.h>
65#if !defined(WIN32) && !defined(__BORLANDC__)
66#include <unistd.h>
67#endif /* !WIN32 && !__BORLANDC__ */
68#ifdef HAVE_LIMITS_H
69#include <limits.h>
70#else
71#define INT_MAX		2147483647
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#ifdef IFF_UP
89#define ISUP(flags) ((flags) & IFF_UP)
90#else
91#define ISUP(flags) 0
92#endif
93
94#ifdef IFF_RUNNING
95#define ISRUNNING(flags) ((flags) & IFF_RUNNING)
96#else
97#define ISRUNNING(flags) 0
98#endif
99
100struct sockaddr *
101dup_sockaddr(struct sockaddr *sa, size_t sa_length)
102{
103	struct sockaddr *newsa;
104
105	if ((newsa = malloc(sa_length)) == NULL)
106		return (NULL);
107	return (memcpy(newsa, sa, sa_length));
108}
109
110/*
111 * Construct a "figure of merit" for an interface, for use when sorting
112 * the list of interfaces, in which interfaces that are up are superior
113 * to interfaces that aren't up, interfaces that are up and running are
114 * superior to interfaces that are up but not running, and non-loopback
115 * interfaces that are up and running are superior to loopback interfaces,
116 * and interfaces with the same flags have a figure of merit that's higher
117 * the lower the instance number.
118 *
119 * The goal is to try to put the interfaces most likely to be useful for
120 * capture at the beginning of the list.
121 *
122 * The figure of merit, which is lower the "better" the interface is,
123 * has the uppermost bit set if the interface isn't running, the bit
124 * below that set if the interface isn't up, the bit below that set
125 * if the interface is a loopback interface, and the interface index
126 * in the 29 bits below that.  (Yes, we assume u_int is 32 bits.)
127 */
128static u_int
129get_figure_of_merit(pcap_if_t *dev)
130{
131	const char *cp;
132	u_int n;
133
134	if (strcmp(dev->name, "any") == 0) {
135		/*
136		 * Give the "any" device an artificially high instance
137		 * number, so it shows up after all other non-loopback
138		 * interfaces.
139		 */
140		n = 0x1FFFFFFF;	/* 29 all-1 bits */
141	} else {
142		/*
143		 * A number at the end of the device name string is
144		 * assumed to be a unit number.
145		 */
146		cp = dev->name + strlen(dev->name) - 1;
147		while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9')
148			cp--;
149		if (*cp >= '0' && *cp <= '9')
150			n = atoi(cp);
151		else
152			n = 0;
153	}
154	if (!(dev->flags & PCAP_IF_RUNNING))
155		n |= 0x80000000;
156	if (!(dev->flags & PCAP_IF_UP))
157		n |= 0x40000000;
158	if (dev->flags & PCAP_IF_LOOPBACK)
159		n |= 0x20000000;
160	return (n);
161}
162
163/*
164 * Look for a given device in the specified list of devices.
165 *
166 * If we find it, return 0 and set *curdev_ret to point to it.
167 *
168 * If we don't find it, check whether we can open it:
169 *
170 *     If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
171 *     PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
172 *     it, as that probably means it exists but doesn't support
173 *     packet capture.
174 *
175 *     Otherwise, attempt to add an entry for it, with the specified
176 *     ifnet flags and description, and, if that succeeds, return 0
177 *     and set *curdev_ret to point to the new entry, otherwise
178 *     return PCAP_ERROR and set errbuf to an error message.
179 */
180int
181add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
182    u_int flags, const char *description, char *errbuf)
183{
184	pcap_t *p;
185	pcap_if_t *curdev, *prevdev, *nextdev;
186	u_int this_figure_of_merit, nextdev_figure_of_merit;
187	char open_errbuf[PCAP_ERRBUF_SIZE];
188	int ret;
189
190	/*
191	 * Is there already an entry in the list for this interface?
192	 */
193	for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
194		if (strcmp(name, curdev->name) == 0)
195			break;	/* yes, we found it */
196	}
197
198	if (curdev == NULL) {
199		/*
200		 * No, we didn't find it.
201		 *
202		 * Can we open this interface for live capture?
203		 *
204		 * We do this check so that interfaces that are
205		 * supplied by the interface enumeration mechanism
206		 * we're using but that don't support packet capture
207		 * aren't included in the list.  Loopback interfaces
208		 * on Solaris are an example of this; we don't just
209		 * omit loopback interfaces on all platforms because
210		 * you *can* capture on loopback interfaces on some
211		 * OSes.
212		 *
213		 * On OS X, we don't do this check if the device
214		 * name begins with "wlt"; at least some versions
215		 * of OS X offer monitor mode capturing by having
216		 * a separate "monitor mode" device for each wireless
217		 * adapter, rather than by implementing the ioctls
218		 * that {Free,Net,Open,DragonFly}BSD provide.
219		 * Opening that device puts the adapter into monitor
220		 * mode, which, at least for some adapters, causes
221		 * them to deassociate from the network with which
222		 * they're associated.
223		 *
224		 * Instead, we try to open the corresponding "en"
225		 * device (so that we don't end up with, for users
226		 * without sufficient privilege to open capture
227		 * devices, a list of adapters that only includes
228		 * the wlt devices).
229		 */
230#ifdef __APPLE__
231		if (strncmp(name, "wlt", 3) == 0) {
232			char *en_name;
233			size_t en_name_len;
234
235			/*
236			 * Try to allocate a buffer for the "en"
237			 * device's name.
238			 */
239			en_name_len = strlen(name) - 1;
240			en_name = malloc(en_name_len + 1);
241			if (en_name == NULL) {
242				(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
243				    "malloc: %s", pcap_strerror(errno));
244				return (-1);
245			}
246			strcpy(en_name, "en");
247			strcat(en_name, name + 3);
248			p = pcap_create(en_name, open_errbuf);
249			free(en_name);
250		} else
251#endif /* __APPLE */
252		p = pcap_create(name, open_errbuf);
253		if (p == NULL) {
254			/*
255			 * The attempt to create the pcap_t failed;
256			 * that's probably an indication that we're
257			 * out of memory.
258			 *
259			 * Don't bother including this interface,
260			 * but don't treat it as an error.
261			 */
262			*curdev_ret = NULL;
263			return (0);
264		}
265		/* Small snaplen, so we don't try to allocate much memory. */
266		pcap_set_snaplen(p, 68);
267		ret = pcap_activate(p);
268		pcap_close(p);
269		switch (ret) {
270
271		case PCAP_ERROR_NO_SUCH_DEVICE:
272		case PCAP_ERROR_IFACE_NOT_UP:
273			/*
274			 * We expect these two errors - they're the
275			 * reason we try to open the device.
276			 *
277			 * PCAP_ERROR_NO_SUCH_DEVICE typically means
278			 * "there's no such device *known to the
279			 * OS's capture mechanism*", so, even though
280			 * it might be a valid network interface, you
281			 * can't capture on it (e.g., the loopback
282			 * device in Solaris up to Solaris 10, or
283			 * the vmnet devices in OS X with VMware
284			 * Fusion).  We don't include those devices
285			 * in our list of devices, as there's no
286			 * point in doing so - they're not available
287			 * for capture.
288			 *
289			 * PCAP_ERROR_IFACE_NOT_UP means that the
290			 * OS's capture mechanism doesn't work on
291			 * interfaces not marked as up; some capture
292			 * mechanisms *do* support that, so we no
293			 * longer reject those interfaces out of hand,
294			 * but we *do* want to reject them if they
295			 * can't be opened for capture.
296			 */
297			*curdev_ret = NULL;
298			return (0);
299		}
300
301		/*
302		 * Yes, we can open it, or we can't, for some other
303		 * reason.
304		 *
305		 * If we can open it, we want to offer it for
306		 * capture, as you can capture on it.  If we can't,
307		 * we want to offer it for capture, so that, if
308		 * the user tries to capture on it, they'll get
309		 * an error and they'll know why they can't
310		 * capture on it (e.g., insufficient permissions)
311		 * or they'll report it as a problem (and then
312		 * have the error message to provide as information).
313		 *
314		 * Allocate a new entry.
315		 */
316		curdev = malloc(sizeof(pcap_if_t));
317		if (curdev == NULL) {
318			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
319			    "malloc: %s", pcap_strerror(errno));
320			return (-1);
321		}
322
323		/*
324		 * Fill in the entry.
325		 */
326		curdev->next = NULL;
327		curdev->name = strdup(name);
328		if (curdev->name == NULL) {
329			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
330			    "malloc: %s", pcap_strerror(errno));
331			free(curdev);
332			return (-1);
333		}
334		if (description != NULL) {
335			/*
336			 * We have a description for this interface.
337			 */
338			curdev->description = strdup(description);
339			if (curdev->description == NULL) {
340				(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
341				    "malloc: %s", pcap_strerror(errno));
342				free(curdev->name);
343				free(curdev);
344				return (-1);
345			}
346		} else {
347			/*
348			 * We don't.
349			 */
350			curdev->description = NULL;
351		}
352		curdev->addresses = NULL;	/* list starts out as empty */
353		curdev->flags = 0;
354		if (ISLOOPBACK(name, flags))
355			curdev->flags |= PCAP_IF_LOOPBACK;
356		if (ISUP(flags))
357			curdev->flags |= PCAP_IF_UP;
358		if (ISRUNNING(flags))
359			curdev->flags |= PCAP_IF_RUNNING;
360
361		/*
362		 * Add it to the list, in the appropriate location.
363		 * First, get the "figure of merit" for this
364		 * interface.
365		 */
366		this_figure_of_merit = get_figure_of_merit(curdev);
367
368		/*
369		 * Now look for the last interface with an figure of merit
370		 * less than or equal to the new interface's figure of
371		 * merit.
372		 *
373		 * We start with "prevdev" being NULL, meaning we're before
374		 * the first element in the list.
375		 */
376		prevdev = NULL;
377		for (;;) {
378			/*
379			 * Get the interface after this one.
380			 */
381			if (prevdev == NULL) {
382				/*
383				 * The next element is the first element.
384				 */
385				nextdev = *alldevs;
386			} else
387				nextdev = prevdev->next;
388
389			/*
390			 * Are we at the end of the list?
391			 */
392			if (nextdev == NULL) {
393				/*
394				 * Yes - we have to put the new entry
395				 * after "prevdev".
396				 */
397				break;
398			}
399
400			/*
401			 * Is the new interface's figure of merit less
402			 * than the next interface's figure of merit,
403			 * meaning that the new interface is better
404			 * than the next interface?
405			 */
406			nextdev_figure_of_merit = get_figure_of_merit(nextdev);
407			if (this_figure_of_merit < nextdev_figure_of_merit) {
408				/*
409				 * Yes - we should put the new entry
410				 * before "nextdev", i.e. after "prevdev".
411				 */
412				break;
413			}
414
415			prevdev = nextdev;
416		}
417
418		/*
419		 * Insert before "nextdev".
420		 */
421		curdev->next = nextdev;
422
423		/*
424		 * Insert after "prevdev" - unless "prevdev" is null,
425		 * in which case this is the first interface.
426		 */
427		if (prevdev == NULL) {
428			/*
429			 * This is the first interface.  Pass back a
430			 * pointer to it, and put "curdev" before
431			 * "nextdev".
432			 */
433			*alldevs = curdev;
434		} else
435			prevdev->next = curdev;
436	}
437
438	*curdev_ret = curdev;
439	return (0);
440}
441
442/*
443 * Try to get a description for a given device.
444 * Returns a mallocated description if it could and NULL if it couldn't.
445 *
446 * XXX - on FreeBSDs that support it, should it get the sysctl named
447 * "dev.{adapter family name}.{adapter unit}.%desc" to get a description
448 * of the adapter?  Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
449 * with my Cisco 350 card, so the name isn't entirely descriptive.  The
450 * "dev.an.0.%pnpinfo" has a better description, although one might argue
451 * that the problem is really a driver bug - if it can find out that it's
452 * a Cisco 340 or 350, rather than an old Aironet card, it should use
453 * that in the description.
454 *
455 * Do NetBSD, DragonflyBSD, or OpenBSD support this as well?  FreeBSD
456 * and OpenBSD let you get a description, but it's not generated by the OS,
457 * it's set with another ioctl that ifconfig supports; we use that to get
458 * a description in FreeBSD and OpenBSD, but if there is no such
459 * description available, it still might be nice to get some description
460 * string based on the device type or something such as that.
461 *
462 * In OS X, the System Configuration framework can apparently return
463 * names in 10.4 and later.
464 *
465 * It also appears that freedesktop.org's HAL offers an "info.product"
466 * string, but the HAL specification says it "should not be used in any
467 * UI" and "subsystem/capability specific properties" should be used
468 * instead and, in any case, I think HAL is being deprecated in
469 * favor of other stuff such as DeviceKit.  DeviceKit doesn't appear
470 * to have any obvious product information for devices, but maybe
471 * I haven't looked hard enough.
472 *
473 * Using the System Configuration framework, or HAL, or DeviceKit, or
474 * whatever, would require that libpcap applications be linked with
475 * the frameworks/libraries in question.  That shouldn't be a problem
476 * for programs linking with the shared version of libpcap (unless
477 * you're running on AIX - which I think is the only UN*X that doesn't
478 * support linking a shared library with other libraries on which it
479 * depends, and having an executable linked only with the first shared
480 * library automatically pick up the other libraries when started -
481 * and using HAL or whatever).  Programs linked with the static
482 * version of libpcap would have to use pcap-config with the --static
483 * flag in order to get the right linker flags in order to pick up
484 * the additional libraries/frameworks; those programs need that anyway
485 * for libpcap 1.1 and beyond on Linux, as, by default, it requires
486 * -lnl.
487 *
488 * Do any other UN*Xes, or desktop environments support getting a
489 * description?
490 */
491static char *
492get_if_description(const char *name)
493{
494#ifdef SIOCGIFDESCR
495	char *description = NULL;
496	int s;
497	struct ifreq ifrdesc;
498#ifndef IFDESCRSIZE
499	size_t descrlen = 64;
500#else
501	size_t descrlen = IFDESCRSIZE;
502#endif /* IFDESCRSIZE */
503
504	/*
505	 * Get the description for the interface.
506	 */
507	memset(&ifrdesc, 0, sizeof ifrdesc);
508	strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
509	s = socket(AF_INET, SOCK_DGRAM, 0);
510	if (s >= 0) {
511#ifdef __FreeBSD__
512		/*
513		 * On FreeBSD, if the buffer isn't big enough for the
514		 * description, the ioctl succeeds, but the description
515		 * isn't copied, ifr_buffer.length is set to the description
516		 * length, and ifr_buffer.buffer is set to NULL.
517		 */
518		for (;;) {
519			free(description);
520			if ((description = malloc(descrlen)) != NULL) {
521				ifrdesc.ifr_buffer.buffer = description;
522				ifrdesc.ifr_buffer.length = descrlen;
523				if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
524					if (ifrdesc.ifr_buffer.buffer ==
525					    description)
526						break;
527					else
528						descrlen = ifrdesc.ifr_buffer.length;
529				} else {
530					/*
531					 * Failed to get interface description.
532					 */
533					free(description);
534					description = NULL;
535					break;
536				}
537			} else
538				break;
539		}
540#else /* __FreeBSD__ */
541		/*
542		 * The only other OS that currently supports
543		 * SIOCGIFDESCR is OpenBSD, and it has no way
544		 * to get the description length - it's clamped
545		 * to a maximum of IFDESCRSIZE.
546		 */
547		if ((description = malloc(descrlen)) != NULL) {
548			ifrdesc.ifr_data = (caddr_t)description;
549			if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
550				/*
551				 * Failed to get interface description.
552				 */
553				free(description);
554				description = NULL;
555			}
556		}
557#endif /* __FreeBSD__ */
558		close(s);
559		if (description != NULL && strlen(description) == 0) {
560			free(description);
561			description = NULL;
562		}
563	}
564
565	return (description);
566#else /* SIOCGIFDESCR */
567	return (NULL);
568#endif /* SIOCGIFDESCR */
569}
570
571/*
572 * Try to get a description for a given device, and then look for that
573 * device in the specified list of devices.
574 *
575 * If we find it, then, if the specified address isn't null, add it to
576 * the list of addresses for the device and return 0.
577 *
578 * If we don't find it, check whether we can open it:
579 *
580 *     If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
581 *     PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
582 *     it, as that probably means it exists but doesn't support
583 *     packet capture.
584 *
585 *     Otherwise, attempt to add an entry for it, with the specified
586 *     ifnet flags and description, and, if that succeeds, add the
587 *     specified address to its list of addresses if that address is
588 *     non-null, set *curdev_ret to point to the new entry, and
589 *     return 0, otherwise return PCAP_ERROR and set errbuf to an
590 *     error message.
591 *
592 * (We can get called with a null address because we might get a list
593 * of interface name/address combinations from the underlying OS, with
594 * the address being absent in some cases, rather than a list of
595 * interfaces with each interface having a list of addresses, so this
596 * call may be the only call made to add to the list, and we want to
597 * add interfaces even if they have no addresses.)
598 */
599int
600add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
601    struct sockaddr *addr, size_t addr_size,
602    struct sockaddr *netmask, size_t netmask_size,
603    struct sockaddr *broadaddr, size_t broadaddr_size,
604    struct sockaddr *dstaddr, size_t dstaddr_size,
605    char *errbuf)
606{
607	char *description;
608	pcap_if_t *curdev;
609
610	description = get_if_description(name);
611	if (add_or_find_if(&curdev, alldevs, name, flags, description,
612	    errbuf) == -1) {
613		free(description);
614		/*
615		 * Error - give up.
616		 */
617		return (-1);
618	}
619	free(description);
620	if (curdev == NULL) {
621		/*
622		 * Device wasn't added because it can't be opened.
623		 * Not a fatal error.
624		 */
625		return (0);
626	}
627
628	if (addr == NULL) {
629		/*
630		 * There's no address to add; this entry just meant
631		 * "here's a new interface".
632		 */
633		return (0);
634	}
635
636	/*
637	 * "curdev" is an entry for this interface, and we have an
638	 * address for it; add an entry for that address to the
639	 * interface's list of addresses.
640	 *
641	 * Allocate the new entry and fill it in.
642	 */
643	return (add_addr_to_dev(curdev, addr, addr_size, netmask,
644	    netmask_size, broadaddr, broadaddr_size, dstaddr,
645	    dstaddr_size, errbuf));
646}
647
648/*
649 * Add an entry to the list of addresses for an interface.
650 * "curdev" is the entry for that interface.
651 * If this is the first IP address added to the interface, move it
652 * in the list as appropriate.
653 */
654int
655add_addr_to_dev(pcap_if_t *curdev,
656    struct sockaddr *addr, size_t addr_size,
657    struct sockaddr *netmask, size_t netmask_size,
658    struct sockaddr *broadaddr, size_t broadaddr_size,
659    struct sockaddr *dstaddr, size_t dstaddr_size,
660    char *errbuf)
661{
662	pcap_addr_t *curaddr, *prevaddr, *nextaddr;
663
664	curaddr = malloc(sizeof(pcap_addr_t));
665	if (curaddr == NULL) {
666		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
667		    "malloc: %s", pcap_strerror(errno));
668		return (-1);
669	}
670
671	curaddr->next = NULL;
672	if (addr != NULL) {
673		curaddr->addr = dup_sockaddr(addr, addr_size);
674		if (curaddr->addr == NULL) {
675			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
676			    "malloc: %s", pcap_strerror(errno));
677			free(curaddr);
678			return (-1);
679		}
680	} else
681		curaddr->addr = NULL;
682
683	if (netmask != NULL) {
684		curaddr->netmask = dup_sockaddr(netmask, netmask_size);
685		if (curaddr->netmask == NULL) {
686			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
687			    "malloc: %s", pcap_strerror(errno));
688			if (curaddr->addr != NULL)
689				free(curaddr->addr);
690			free(curaddr);
691			return (-1);
692		}
693	} else
694		curaddr->netmask = NULL;
695
696	if (broadaddr != NULL) {
697		curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
698		if (curaddr->broadaddr == NULL) {
699			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
700			    "malloc: %s", pcap_strerror(errno));
701			if (curaddr->netmask != NULL)
702				free(curaddr->netmask);
703			if (curaddr->addr != NULL)
704				free(curaddr->addr);
705			free(curaddr);
706			return (-1);
707		}
708	} else
709		curaddr->broadaddr = NULL;
710
711	if (dstaddr != NULL) {
712		curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
713		if (curaddr->dstaddr == NULL) {
714			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
715			    "malloc: %s", pcap_strerror(errno));
716			if (curaddr->broadaddr != NULL)
717				free(curaddr->broadaddr);
718			if (curaddr->netmask != NULL)
719				free(curaddr->netmask);
720			if (curaddr->addr != NULL)
721				free(curaddr->addr);
722			free(curaddr);
723			return (-1);
724		}
725	} else
726		curaddr->dstaddr = NULL;
727
728	/*
729	 * Find the end of the list of addresses.
730	 */
731	for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
732		nextaddr = prevaddr->next;
733		if (nextaddr == NULL) {
734			/*
735			 * This is the end of the list.
736			 */
737			break;
738		}
739	}
740
741	if (prevaddr == NULL) {
742		/*
743		 * The list was empty; this is the first member.
744		 */
745		curdev->addresses = curaddr;
746	} else {
747		/*
748		 * "prevaddr" is the last member of the list; append
749		 * this member to it.
750		 */
751		prevaddr->next = curaddr;
752	}
753
754	return (0);
755}
756
757/*
758 * Look for a given device in the specified list of devices.
759 *
760 * If we find it, return 0.
761 *
762 * If we don't find it, check whether we can open it:
763 *
764 *     If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
765 *     PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
766 *     it, as that probably means it exists but doesn't support
767 *     packet capture.
768 *
769 *     Otherwise, attempt to add an entry for it, with the specified
770 *     ifnet flags and description, and, if that succeeds, return 0
771 *     and set *curdev_ret to point to the new entry, otherwise
772 *     return PCAP_ERROR and set errbuf to an error message.
773 */
774int
775pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
776    const char *description, char *errbuf)
777{
778	pcap_if_t *curdev;
779
780	return (add_or_find_if(&curdev, devlist, name, flags, description,
781	    errbuf));
782}
783
784
785/*
786 * Free a list of interfaces.
787 */
788void
789pcap_freealldevs(pcap_if_t *alldevs)
790{
791	pcap_if_t *curdev, *nextdev;
792	pcap_addr_t *curaddr, *nextaddr;
793
794	for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
795		nextdev = curdev->next;
796
797		/*
798		 * Free all addresses.
799		 */
800		for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
801			nextaddr = curaddr->next;
802			if (curaddr->addr)
803				free(curaddr->addr);
804			if (curaddr->netmask)
805				free(curaddr->netmask);
806			if (curaddr->broadaddr)
807				free(curaddr->broadaddr);
808			if (curaddr->dstaddr)
809				free(curaddr->dstaddr);
810			free(curaddr);
811		}
812
813		/*
814		 * Free the name string.
815		 */
816		free(curdev->name);
817
818		/*
819		 * Free the description string, if any.
820		 */
821		if (curdev->description != NULL)
822			free(curdev->description);
823
824		/*
825		 * Free the interface.
826		 */
827		free(curdev);
828	}
829}
830
831#if !defined(WIN32) && !defined(MSDOS)
832
833/*
834 * Return the name of a network interface attached to the system, or NULL
835 * if none can be found.  The interface must be configured up; the
836 * lowest unit number is preferred; loopback is ignored.
837 */
838char *
839pcap_lookupdev(errbuf)
840	register char *errbuf;
841{
842	pcap_if_t *alldevs;
843/* for old BSD systems, including bsdi3 */
844#ifndef IF_NAMESIZE
845#define IF_NAMESIZE IFNAMSIZ
846#endif
847	static char device[IF_NAMESIZE + 1];
848	char *ret;
849
850	if (pcap_findalldevs(&alldevs, errbuf) == -1)
851		return (NULL);
852
853	if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
854		/*
855		 * There are no devices on the list, or the first device
856		 * on the list is a loopback device, which means there
857		 * are no non-loopback devices on the list.  This means
858		 * we can't return any device.
859		 *
860		 * XXX - why not return a loopback device?  If we can't
861		 * capture on it, it won't be on the list, and if it's
862		 * on the list, there aren't any non-loopback devices,
863		 * so why not just supply it as the default device?
864		 */
865		(void)strlcpy(errbuf, "no suitable device found",
866		    PCAP_ERRBUF_SIZE);
867		ret = NULL;
868	} else {
869		/*
870		 * Return the name of the first device on the list.
871		 */
872		(void)strlcpy(device, alldevs->name, sizeof(device));
873		ret = device;
874	}
875
876	pcap_freealldevs(alldevs);
877	return (ret);
878}
879
880int
881pcap_lookupnet(device, netp, maskp, errbuf)
882	register const char *device;
883	register bpf_u_int32 *netp, *maskp;
884	register char *errbuf;
885{
886	register int fd;
887	register struct sockaddr_in *sin4;
888	struct ifreq ifr;
889
890	/*
891	 * The pseudo-device "any" listens on all interfaces and therefore
892	 * has the network address and -mask "0.0.0.0" therefore catching
893	 * all traffic. Using NULL for the interface is the same as "any".
894	 */
895	if (!device || strcmp(device, "any") == 0
896#ifdef HAVE_DAG_API
897	    || strstr(device, "dag") != NULL
898#endif
899#ifdef HAVE_SEPTEL_API
900	    || strstr(device, "septel") != NULL
901#endif
902#ifdef PCAP_SUPPORT_BT
903	    || strstr(device, "bluetooth") != NULL
904#endif
905#ifdef PCAP_SUPPORT_USB
906	    || strstr(device, "usbmon") != NULL
907#endif
908#ifdef HAVE_SNF_API
909	    || strstr(device, "snf") != NULL
910#endif
911	    ) {
912		*netp = *maskp = 0;
913		return 0;
914	}
915
916	fd = socket(AF_INET, SOCK_DGRAM, 0);
917	if (fd < 0) {
918		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
919		    pcap_strerror(errno));
920		return (-1);
921	}
922	memset(&ifr, 0, sizeof(ifr));
923#ifdef linux
924	/* XXX Work around Linux kernel bug */
925	ifr.ifr_addr.sa_family = AF_INET;
926#endif
927	(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
928	if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
929		if (errno == EADDRNOTAVAIL) {
930			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
931			    "%s: no IPv4 address assigned", device);
932		} else {
933			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
934			    "SIOCGIFADDR: %s: %s",
935			    device, pcap_strerror(errno));
936		}
937		(void)close(fd);
938		return (-1);
939	}
940	sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
941	*netp = sin4->sin_addr.s_addr;
942	memset(&ifr, 0, sizeof(ifr));
943#ifdef linux
944	/* XXX Work around Linux kernel bug */
945	ifr.ifr_addr.sa_family = AF_INET;
946#endif
947	(void)strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
948	if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
949		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
950		    "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
951		(void)close(fd);
952		return (-1);
953	}
954	(void)close(fd);
955	*maskp = sin4->sin_addr.s_addr;
956	if (*maskp == 0) {
957		if (IN_CLASSA(*netp))
958			*maskp = IN_CLASSA_NET;
959		else if (IN_CLASSB(*netp))
960			*maskp = IN_CLASSB_NET;
961		else if (IN_CLASSC(*netp))
962			*maskp = IN_CLASSC_NET;
963		else {
964			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
965			    "inet class for 0x%x unknown", *netp);
966			return (-1);
967		}
968	}
969	*netp &= *maskp;
970	return (0);
971}
972
973#elif defined(WIN32)
974
975/*
976 * Return the name of a network interface attached to the system, or NULL
977 * if none can be found.  The interface must be configured up; the
978 * lowest unit number is preferred; loopback is ignored.
979 */
980char *
981pcap_lookupdev(errbuf)
982	register char *errbuf;
983{
984	DWORD dwVersion;
985	DWORD dwWindowsMajorVersion;
986	dwVersion = GetVersion();	/* get the OS version */
987	dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
988
989	if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
990		/*
991		 * Windows 95, 98, ME.
992		 */
993		ULONG NameLength = 8192;
994		static char AdaptersName[8192];
995
996		if (PacketGetAdapterNames(AdaptersName,&NameLength) )
997			return (AdaptersName);
998		else
999			return NULL;
1000	} else {
1001		/*
1002		 * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
1003		 */
1004		ULONG NameLength = 8192;
1005		static WCHAR AdaptersName[8192];
1006		char *tAstr;
1007		WCHAR *tUstr;
1008		WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
1009		int NAdapts = 0;
1010
1011		if(TAdaptersName == NULL)
1012		{
1013			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
1014			return NULL;
1015		}
1016
1017		if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
1018		{
1019			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
1020				"PacketGetAdapterNames: %s",
1021				pcap_win32strerror());
1022			free(TAdaptersName);
1023			return NULL;
1024		}
1025
1026
1027		tAstr = (char*)TAdaptersName;
1028		tUstr = (WCHAR*)AdaptersName;
1029
1030		/*
1031		 * Convert and copy the device names
1032		 */
1033		while(sscanf(tAstr, "%S", tUstr) > 0)
1034		{
1035			tAstr += strlen(tAstr) + 1;
1036			tUstr += wcslen(tUstr) + 1;
1037			NAdapts ++;
1038		}
1039
1040		tAstr++;
1041		*tUstr = 0;
1042		tUstr++;
1043
1044		/*
1045		 * Copy the descriptions
1046		 */
1047		while(NAdapts--)
1048		{
1049			char* tmp = (char*)tUstr;
1050			strcpy(tmp, tAstr);
1051			tmp += strlen(tAstr) + 1;
1052			tUstr = (WCHAR*)tmp;
1053			tAstr += strlen(tAstr) + 1;
1054		}
1055
1056		free(TAdaptersName);
1057		return (char *)(AdaptersName);
1058	}
1059}
1060
1061
1062int
1063pcap_lookupnet(device, netp, maskp, errbuf)
1064	register const char *device;
1065	register bpf_u_int32 *netp, *maskp;
1066	register char *errbuf;
1067{
1068	/*
1069	 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
1070	 * in order to skip non IPv4 (i.e. IPv6 addresses)
1071	 */
1072	npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
1073	LONG if_addr_size = 1;
1074	struct sockaddr_in *t_addr;
1075	unsigned int i;
1076
1077	if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
1078		*netp = *maskp = 0;
1079		return (0);
1080	}
1081
1082	for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
1083	{
1084		if(if_addrs[i].IPAddress.ss_family == AF_INET)
1085		{
1086			t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
1087			*netp = t_addr->sin_addr.S_un.S_addr;
1088			t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
1089			*maskp = t_addr->sin_addr.S_un.S_addr;
1090
1091			*netp &= *maskp;
1092			return (0);
1093		}
1094
1095	}
1096
1097	*netp = *maskp = 0;
1098	return (0);
1099}
1100
1101#endif /* !WIN32 && !MSDOS */
1102