• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
53 struct mbuf;		/* Squelch compiler warnings on some platforms for */
54 struct 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 #ifndef _WIN32
81 /* Not all systems have IFF_LOOPBACK */
82 #ifdef IFF_LOOPBACK
83 #define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
84 #else
85 #define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
86     (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
87 #endif
88 
89 #ifdef IFF_UP
90 #define ISUP(flags) ((flags) & IFF_UP)
91 #else
92 #define ISUP(flags) 0
93 #endif
94 
95 #ifdef IFF_RUNNING
96 #define ISRUNNING(flags) ((flags) & IFF_RUNNING)
97 #else
98 #define ISRUNNING(flags) 0
99 #endif
100 
101 /*
102  * Map UN*X-style interface flags to libpcap flags.
103  */
104 bpf_u_int32
if_flags_to_pcap_flags(const char * name _U_,u_int if_flags)105 if_flags_to_pcap_flags(const char *name _U_, u_int if_flags)
106 {
107 	bpf_u_int32 pcap_flags;
108 
109 	pcap_flags = 0;
110 	if (ISLOOPBACK(name, if_flags))
111 		pcap_flags |= PCAP_IF_LOOPBACK;
112 	if (ISUP(if_flags))
113 		pcap_flags |= PCAP_IF_UP;
114 	if (ISRUNNING(if_flags))
115 		pcap_flags |= PCAP_IF_RUNNING;
116 	return (pcap_flags);
117 }
118 #endif
119 
120 static struct sockaddr *
dup_sockaddr(struct sockaddr * sa,size_t sa_length)121 dup_sockaddr(struct sockaddr *sa, size_t sa_length)
122 {
123 	struct sockaddr *newsa;
124 
125 	if ((newsa = malloc(sa_length)) == NULL)
126 		return (NULL);
127 	return (memcpy(newsa, sa, sa_length));
128 }
129 
130 /*
131  * Construct a "figure of merit" for an interface, for use when sorting
132  * the list of interfaces, in which interfaces that are up are superior
133  * to interfaces that aren't up, interfaces that are up and running are
134  * superior to interfaces that are up but not running, and non-loopback
135  * interfaces that are up and running are superior to loopback interfaces,
136  * and interfaces with the same flags have a figure of merit that's higher
137  * the lower the instance number.
138  *
139  * The goal is to try to put the interfaces most likely to be useful for
140  * capture at the beginning of the list.
141  *
142  * The figure of merit, which is lower the "better" the interface is,
143  * has the uppermost bit set if the interface isn't running, the bit
144  * below that set if the interface isn't up, the bit below that set
145  * if the interface is a loopback interface, and the interface index
146  * in the 29 bits below that.  (Yes, we assume u_int is 32 bits.)
147  */
148 static u_int
get_figure_of_merit(pcap_if_t * dev)149 get_figure_of_merit(pcap_if_t *dev)
150 {
151 	const char *cp;
152 	u_int n;
153 
154 	if (strcmp(dev->name, "any") == 0) {
155 		/*
156 		 * Give the "any" device an artificially high instance
157 		 * number, so it shows up after all other non-loopback
158 		 * interfaces.
159 		 */
160 		n = 0x1FFFFFFF;	/* 29 all-1 bits */
161 	} else {
162 		/*
163 		 * A number at the end of the device name string is
164 		 * assumed to be a unit number.
165 		 */
166 		cp = dev->name + strlen(dev->name) - 1;
167 		while (cp-1 >= dev->name && *(cp-1) >= '0' && *(cp-1) <= '9')
168 			cp--;
169 		if (*cp >= '0' && *cp <= '9')
170 			n = atoi(cp);
171 		else
172 			n = 0;
173 	}
174 	if (!(dev->flags & PCAP_IF_RUNNING))
175 		n |= 0x80000000;
176 	if (!(dev->flags & PCAP_IF_UP))
177 		n |= 0x40000000;
178 	if (dev->flags & PCAP_IF_LOOPBACK)
179 		n |= 0x20000000;
180 	return (n);
181 }
182 
183 /*
184  * Try to get a description for a given device.
185  * Returns a mallocated description if it could and NULL if it couldn't.
186  *
187  * XXX - on FreeBSDs that support it, should it get the sysctl named
188  * "dev.{adapter family name}.{adapter unit}.%desc" to get a description
189  * of the adapter?  Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
190  * with my Cisco 350 card, so the name isn't entirely descriptive.  The
191  * "dev.an.0.%pnpinfo" has a better description, although one might argue
192  * that the problem is really a driver bug - if it can find out that it's
193  * a Cisco 340 or 350, rather than an old Aironet card, it should use
194  * that in the description.
195  *
196  * Do NetBSD, DragonflyBSD, or OpenBSD support this as well?  FreeBSD
197  * and OpenBSD let you get a description, but it's not generated by the OS,
198  * it's set with another ioctl that ifconfig supports; we use that to get
199  * a description in FreeBSD and OpenBSD, but if there is no such
200  * description available, it still might be nice to get some description
201  * string based on the device type or something such as that.
202  *
203  * In OS X, the System Configuration framework can apparently return
204  * names in 10.4 and later.
205  *
206  * It also appears that freedesktop.org's HAL offers an "info.product"
207  * string, but the HAL specification says it "should not be used in any
208  * UI" and "subsystem/capability specific properties" should be used
209  * instead and, in any case, I think HAL is being deprecated in
210  * favor of other stuff such as DeviceKit.  DeviceKit doesn't appear
211  * to have any obvious product information for devices, but maybe
212  * I haven't looked hard enough.
213  *
214  * Using the System Configuration framework, or HAL, or DeviceKit, or
215  * whatever, would require that libpcap applications be linked with
216  * the frameworks/libraries in question.  That shouldn't be a problem
217  * for programs linking with the shared version of libpcap (unless
218  * you're running on AIX - which I think is the only UN*X that doesn't
219  * support linking a shared library with other libraries on which it
220  * depends, and having an executable linked only with the first shared
221  * library automatically pick up the other libraries when started -
222  * and using HAL or whatever).  Programs linked with the static
223  * version of libpcap would have to use pcap-config with the --static
224  * flag in order to get the right linker flags in order to pick up
225  * the additional libraries/frameworks; those programs need that anyway
226  * for libpcap 1.1 and beyond on Linux, as, by default, it requires
227  * -lnl.
228  *
229  * Do any other UN*Xes, or desktop environments support getting a
230  * description?
231  */
232 static char *
get_if_description(const char * name)233 get_if_description(const char *name)
234 {
235 #ifdef SIOCGIFDESCR
236 	char *description = NULL;
237 	int s;
238 	struct ifreq ifrdesc;
239 #ifndef IFDESCRSIZE
240 	size_t descrlen = 64;
241 #else
242 	size_t descrlen = IFDESCRSIZE;
243 #endif /* IFDESCRSIZE */
244 
245 	/*
246 	 * Get the description for the interface.
247 	 */
248 	memset(&ifrdesc, 0, sizeof ifrdesc);
249 	strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
250 	s = socket(AF_INET, SOCK_DGRAM, 0);
251 	if (s >= 0) {
252 #ifdef __FreeBSD__
253 		/*
254 		 * On FreeBSD, if the buffer isn't big enough for the
255 		 * description, the ioctl succeeds, but the description
256 		 * isn't copied, ifr_buffer.length is set to the description
257 		 * length, and ifr_buffer.buffer is set to NULL.
258 		 */
259 		for (;;) {
260 			free(description);
261 			if ((description = malloc(descrlen)) != NULL) {
262 				ifrdesc.ifr_buffer.buffer = description;
263 				ifrdesc.ifr_buffer.length = descrlen;
264 				if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
265 					if (ifrdesc.ifr_buffer.buffer ==
266 					    description)
267 						break;
268 					else
269 						descrlen = ifrdesc.ifr_buffer.length;
270 				} else {
271 					/*
272 					 * Failed to get interface description.
273 					 */
274 					free(description);
275 					description = NULL;
276 					break;
277 				}
278 			} else
279 				break;
280 		}
281 #else /* __FreeBSD__ */
282 		/*
283 		 * The only other OS that currently supports
284 		 * SIOCGIFDESCR is OpenBSD, and it has no way
285 		 * to get the description length - it's clamped
286 		 * to a maximum of IFDESCRSIZE.
287 		 */
288 		if ((description = malloc(descrlen)) != NULL) {
289 			ifrdesc.ifr_data = (caddr_t)description;
290 			if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
291 				/*
292 				 * Failed to get interface description.
293 				 */
294 				free(description);
295 				description = NULL;
296 			}
297 		}
298 #endif /* __FreeBSD__ */
299 		close(s);
300 		if (description != NULL && strlen(description) == 0) {
301 			/*
302 			 * Description is empty, so discard it.
303 			 */
304 			free(description);
305 			description = NULL;
306 		}
307 	}
308 
309 #ifdef __FreeBSD__
310 	/*
311 	 * For FreeBSD, if we didn't get a description, and this is
312 	 * a device with a name of the form usbusN, label it as a USB
313 	 * bus.
314 	 */
315 	if (description == NULL) {
316 		if (strncmp(name, "usbus", 5) == 0) {
317 			/*
318 			 * OK, it begins with "usbus".
319 			 */
320 			long busnum;
321 			char *p;
322 
323 			errno = 0;
324 			busnum = strtol(name + 5, &p, 10);
325 			if (errno == 0 && p != name + 5 && *p == '\0' &&
326 			    busnum >= 0 && busnum <= INT_MAX) {
327 				/*
328 				 * OK, it's a valid number that's not
329 				 * bigger than INT_MAX.  Construct
330 				 * a description from it.
331 				 */
332 				static const char descr_prefix[] = "USB bus number ";
333 				size_t descr_size;
334 
335 				/*
336 				 * Allow enough room for a 32-bit bus number.
337 				 * sizeof (descr_prefix) includes the
338 				 * terminating NUL.
339 				 */
340 				descr_size = sizeof (descr_prefix) + 10;
341 				description = malloc(descr_size);
342 				if (description != NULL) {
343 					pcap_snprintf(description, descr_size,
344 					    "%s%ld", descr_prefix, busnum);
345 				}
346 			}
347 		}
348 	}
349 #endif
350 	return (description);
351 #else /* SIOCGIFDESCR */
352 	return (NULL);
353 #endif /* SIOCGIFDESCR */
354 }
355 
356 /*
357  * Look for a given device in the specified list of devices.
358  *
359  * If we find it, return 0 and set *curdev_ret to point to it.
360  *
361  * If we don't find it, check whether we can open it:
362  *
363  *     If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
364  *     PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
365  *     it, as that probably means it exists but doesn't support
366  *     packet capture.
367  *
368  *     Otherwise, attempt to add an entry for it, with the specified
369  *     ifnet flags and description, and, if that succeeds, return 0
370  *     and set *curdev_ret to point to the new entry, otherwise
371  *     return PCAP_ERROR and set errbuf to an error message.  If we
372  *     weren't given a description, try to get one.
373  */
374 int
add_or_find_if(pcap_if_t ** curdev_ret,pcap_if_t ** alldevs,const char * name,bpf_u_int32 flags,const char * description,char * errbuf)375 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
376     bpf_u_int32 flags, const char *description, char *errbuf)
377 {
378 	pcap_t *p;
379 	pcap_if_t *curdev, *prevdev, *nextdev;
380 	u_int this_figure_of_merit, nextdev_figure_of_merit;
381 	char open_errbuf[PCAP_ERRBUF_SIZE];
382 	int ret;
383 
384 	/*
385 	 * Is there already an entry in the list for this interface?
386 	 */
387 	for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
388 		if (strcmp(name, curdev->name) == 0)
389 			break;	/* yes, we found it */
390 	}
391 
392 	if (curdev == NULL) {
393 		/*
394 		 * No, we didn't find it.
395 		 *
396 		 * Can we open this interface for live capture?
397 		 *
398 		 * We do this check so that interfaces that are
399 		 * supplied by the interface enumeration mechanism
400 		 * we're using but that don't support packet capture
401 		 * aren't included in the list.  Loopback interfaces
402 		 * on Solaris are an example of this; we don't just
403 		 * omit loopback interfaces on all platforms because
404 		 * you *can* capture on loopback interfaces on some
405 		 * OSes.
406 		 *
407 		 * On OS X, we don't do this check if the device
408 		 * name begins with "wlt"; at least some versions
409 		 * of OS X offer monitor mode capturing by having
410 		 * a separate "monitor mode" device for each wireless
411 		 * adapter, rather than by implementing the ioctls
412 		 * that {Free,Net,Open,DragonFly}BSD provide.
413 		 * Opening that device puts the adapter into monitor
414 		 * mode, which, at least for some adapters, causes
415 		 * them to deassociate from the network with which
416 		 * they're associated.
417 		 *
418 		 * Instead, we try to open the corresponding "en"
419 		 * device (so that we don't end up with, for users
420 		 * without sufficient privilege to open capture
421 		 * devices, a list of adapters that only includes
422 		 * the wlt devices).
423 		 */
424 #ifdef __APPLE__
425 		if (strncmp(name, "wlt", 3) == 0) {
426 			char *en_name;
427 			size_t en_name_len;
428 
429 			/*
430 			 * Try to allocate a buffer for the "en"
431 			 * device's name.
432 			 */
433 			en_name_len = strlen(name) - 1;
434 			en_name = malloc(en_name_len + 1);
435 			if (en_name == NULL) {
436 				(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
437 				    "malloc: %s", pcap_strerror(errno));
438 				return (-1);
439 			}
440 			strcpy(en_name, "en");
441 			strcat(en_name, name + 3);
442 			p = pcap_create(en_name, open_errbuf);
443 			free(en_name);
444 		} else
445 #endif /* __APPLE */
446 		p = pcap_create(name, open_errbuf);
447 		if (p == NULL) {
448 			/*
449 			 * The attempt to create the pcap_t failed;
450 			 * that's probably an indication that we're
451 			 * out of memory.
452 			 *
453 			 * Don't bother including this interface,
454 			 * but don't treat it as an error.
455 			 */
456 			*curdev_ret = NULL;
457 			return (0);
458 		}
459 		/* Small snaplen, so we don't try to allocate much memory. */
460 		pcap_set_snaplen(p, 68);
461 		ret = pcap_activate(p);
462 		pcap_close(p);
463 		switch (ret) {
464 
465 		case PCAP_ERROR_NO_SUCH_DEVICE:
466 		case PCAP_ERROR_IFACE_NOT_UP:
467 			/*
468 			 * We expect these two errors - they're the
469 			 * reason we try to open the device.
470 			 *
471 			 * PCAP_ERROR_NO_SUCH_DEVICE typically means
472 			 * "there's no such device *known to the
473 			 * OS's capture mechanism*", so, even though
474 			 * it might be a valid network interface, you
475 			 * can't capture on it (e.g., the loopback
476 			 * device in Solaris up to Solaris 10, or
477 			 * the vmnet devices in OS X with VMware
478 			 * Fusion).  We don't include those devices
479 			 * in our list of devices, as there's no
480 			 * point in doing so - they're not available
481 			 * for capture.
482 			 *
483 			 * PCAP_ERROR_IFACE_NOT_UP means that the
484 			 * OS's capture mechanism doesn't work on
485 			 * interfaces not marked as up; some capture
486 			 * mechanisms *do* support that, so we no
487 			 * longer reject those interfaces out of hand,
488 			 * but we *do* want to reject them if they
489 			 * can't be opened for capture.
490 			 */
491 			*curdev_ret = NULL;
492 			return (0);
493 		}
494 
495 		/*
496 		 * Yes, we can open it, or we can't, for some other
497 		 * reason.
498 		 *
499 		 * If we can open it, we want to offer it for
500 		 * capture, as you can capture on it.  If we can't,
501 		 * we want to offer it for capture, so that, if
502 		 * the user tries to capture on it, they'll get
503 		 * an error and they'll know why they can't
504 		 * capture on it (e.g., insufficient permissions)
505 		 * or they'll report it as a problem (and then
506 		 * have the error message to provide as information).
507 		 *
508 		 * Allocate a new entry.
509 		 */
510 		curdev = malloc(sizeof(pcap_if_t));
511 		if (curdev == NULL) {
512 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
513 			    "malloc: %s", pcap_strerror(errno));
514 			return (-1);
515 		}
516 
517 		/*
518 		 * Fill in the entry.
519 		 */
520 		curdev->next = NULL;
521 		curdev->name = strdup(name);
522 		if (curdev->name == NULL) {
523 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
524 			    "malloc: %s", pcap_strerror(errno));
525 			free(curdev);
526 			return (-1);
527 		}
528 		if (description == NULL) {
529 			/*
530 			 * We weren't handed a description for the
531 			 * interface, so see if we can generate one
532 			 * ourselves.
533 			 */
534 			curdev->description = get_if_description(name);
535 		} else {
536 			/*
537 			 * We were handed a description; make a copy.
538 			 */
539 			curdev->description = strdup(description);
540 			if (curdev->description == NULL) {
541 				(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
542 				    "malloc: %s", pcap_strerror(errno));
543 				free(curdev->name);
544 				free(curdev);
545 				return (-1);
546 			}
547 		}
548 		curdev->addresses = NULL;	/* list starts out as empty */
549 		curdev->flags = flags;
550 
551 		/*
552 		 * Add it to the list, in the appropriate location.
553 		 * First, get the "figure of merit" for this
554 		 * interface.
555 		 */
556 		this_figure_of_merit = get_figure_of_merit(curdev);
557 
558 		/*
559 		 * Now look for the last interface with an figure of merit
560 		 * less than or equal to the new interface's figure of
561 		 * merit.
562 		 *
563 		 * We start with "prevdev" being NULL, meaning we're before
564 		 * the first element in the list.
565 		 */
566 		prevdev = NULL;
567 		for (;;) {
568 			/*
569 			 * Get the interface after this one.
570 			 */
571 			if (prevdev == NULL) {
572 				/*
573 				 * The next element is the first element.
574 				 */
575 				nextdev = *alldevs;
576 			} else
577 				nextdev = prevdev->next;
578 
579 			/*
580 			 * Are we at the end of the list?
581 			 */
582 			if (nextdev == NULL) {
583 				/*
584 				 * Yes - we have to put the new entry
585 				 * after "prevdev".
586 				 */
587 				break;
588 			}
589 
590 			/*
591 			 * Is the new interface's figure of merit less
592 			 * than the next interface's figure of merit,
593 			 * meaning that the new interface is better
594 			 * than the next interface?
595 			 */
596 			nextdev_figure_of_merit = get_figure_of_merit(nextdev);
597 			if (this_figure_of_merit < nextdev_figure_of_merit) {
598 				/*
599 				 * Yes - we should put the new entry
600 				 * before "nextdev", i.e. after "prevdev".
601 				 */
602 				break;
603 			}
604 
605 			prevdev = nextdev;
606 		}
607 
608 		/*
609 		 * Insert before "nextdev".
610 		 */
611 		curdev->next = nextdev;
612 
613 		/*
614 		 * Insert after "prevdev" - unless "prevdev" is null,
615 		 * in which case this is the first interface.
616 		 */
617 		if (prevdev == NULL) {
618 			/*
619 			 * This is the first interface.  Pass back a
620 			 * pointer to it, and put "curdev" before
621 			 * "nextdev".
622 			 */
623 			*alldevs = curdev;
624 		} else
625 			prevdev->next = curdev;
626 	}
627 
628 	*curdev_ret = curdev;
629 	return (0);
630 }
631 
632 /*
633  * Try to get a description for a given device, and then look for that
634  * device in the specified list of devices.
635  *
636  * If we find it, then, if the specified address isn't null, add it to
637  * the list of addresses for the device and return 0.
638  *
639  * If we don't find it, check whether we can open it:
640  *
641  *     If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
642  *     PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
643  *     it, as that probably means it exists but doesn't support
644  *     packet capture.
645  *
646  *     Otherwise, attempt to add an entry for it, with the specified
647  *     ifnet flags, and, if that succeeds, add the specified address
648  *     to its list of addresses if that address is non-null, set
649  *     *curdev_ret to point to the new entry, and return 0, otherwise
650  *     return PCAP_ERROR and set errbuf to an error message.
651  *
652  * (We can get called with a null address because we might get a list
653  * of interface name/address combinations from the underlying OS, with
654  * the address being absent in some cases, rather than a list of
655  * interfaces with each interface having a list of addresses, so this
656  * call may be the only call made to add to the list, and we want to
657  * add interfaces even if they have no addresses.)
658  */
659 int
add_addr_to_iflist(pcap_if_t ** alldevs,const char * name,bpf_u_int32 flags,struct sockaddr * addr,size_t addr_size,struct sockaddr * netmask,size_t netmask_size,struct sockaddr * broadaddr,size_t broadaddr_size,struct sockaddr * dstaddr,size_t dstaddr_size,char * errbuf)660 add_addr_to_iflist(pcap_if_t **alldevs, const char *name, bpf_u_int32 flags,
661     struct sockaddr *addr, size_t addr_size,
662     struct sockaddr *netmask, size_t netmask_size,
663     struct sockaddr *broadaddr, size_t broadaddr_size,
664     struct sockaddr *dstaddr, size_t dstaddr_size,
665     char *errbuf)
666 {
667 	pcap_if_t *curdev;
668 
669 	if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
670 		/*
671 		 * Error - give up.
672 		 */
673 		return (-1);
674 	}
675 	if (curdev == NULL) {
676 		/*
677 		 * Device wasn't added because it can't be opened.
678 		 * Not a fatal error.
679 		 */
680 		return (0);
681 	}
682 
683 	if (addr == NULL) {
684 		/*
685 		 * There's no address to add; this entry just meant
686 		 * "here's a new interface".
687 		 */
688 		return (0);
689 	}
690 
691 	/*
692 	 * "curdev" is an entry for this interface, and we have an
693 	 * address for it; add an entry for that address to the
694 	 * interface's list of addresses.
695 	 *
696 	 * Allocate the new entry and fill it in.
697 	 */
698 	return (add_addr_to_dev(curdev, addr, addr_size, netmask,
699 	    netmask_size, broadaddr, broadaddr_size, dstaddr,
700 	    dstaddr_size, errbuf));
701 }
702 
703 /*
704  * Add an entry to the list of addresses for an interface.
705  * "curdev" is the entry for that interface.
706  * If this is the first IP address added to the interface, move it
707  * in the list as appropriate.
708  */
709 int
add_addr_to_dev(pcap_if_t * curdev,struct sockaddr * addr,size_t addr_size,struct sockaddr * netmask,size_t netmask_size,struct sockaddr * broadaddr,size_t broadaddr_size,struct sockaddr * dstaddr,size_t dstaddr_size,char * errbuf)710 add_addr_to_dev(pcap_if_t *curdev,
711     struct sockaddr *addr, size_t addr_size,
712     struct sockaddr *netmask, size_t netmask_size,
713     struct sockaddr *broadaddr, size_t broadaddr_size,
714     struct sockaddr *dstaddr, size_t dstaddr_size,
715     char *errbuf)
716 {
717 	pcap_addr_t *curaddr, *prevaddr, *nextaddr;
718 
719 	curaddr = malloc(sizeof(pcap_addr_t));
720 	if (curaddr == NULL) {
721 		(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
722 		    "malloc: %s", pcap_strerror(errno));
723 		return (-1);
724 	}
725 
726 	curaddr->next = NULL;
727 	if (addr != NULL) {
728 		curaddr->addr = dup_sockaddr(addr, addr_size);
729 		if (curaddr->addr == NULL) {
730 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
731 			    "malloc: %s", pcap_strerror(errno));
732 			free(curaddr);
733 			return (-1);
734 		}
735 	} else
736 		curaddr->addr = NULL;
737 
738 	if (netmask != NULL) {
739 		curaddr->netmask = dup_sockaddr(netmask, netmask_size);
740 		if (curaddr->netmask == NULL) {
741 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
742 			    "malloc: %s", pcap_strerror(errno));
743 			if (curaddr->addr != NULL)
744 				free(curaddr->addr);
745 			free(curaddr);
746 			return (-1);
747 		}
748 	} else
749 		curaddr->netmask = NULL;
750 
751 	if (broadaddr != NULL) {
752 		curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
753 		if (curaddr->broadaddr == NULL) {
754 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
755 			    "malloc: %s", pcap_strerror(errno));
756 			if (curaddr->netmask != NULL)
757 				free(curaddr->netmask);
758 			if (curaddr->addr != NULL)
759 				free(curaddr->addr);
760 			free(curaddr);
761 			return (-1);
762 		}
763 	} else
764 		curaddr->broadaddr = NULL;
765 
766 	if (dstaddr != NULL) {
767 		curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
768 		if (curaddr->dstaddr == NULL) {
769 			(void)pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
770 			    "malloc: %s", pcap_strerror(errno));
771 			if (curaddr->broadaddr != NULL)
772 				free(curaddr->broadaddr);
773 			if (curaddr->netmask != NULL)
774 				free(curaddr->netmask);
775 			if (curaddr->addr != NULL)
776 				free(curaddr->addr);
777 			free(curaddr);
778 			return (-1);
779 		}
780 	} else
781 		curaddr->dstaddr = NULL;
782 
783 	/*
784 	 * Find the end of the list of addresses.
785 	 */
786 	for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
787 		nextaddr = prevaddr->next;
788 		if (nextaddr == NULL) {
789 			/*
790 			 * This is the end of the list.
791 			 */
792 			break;
793 		}
794 	}
795 
796 	if (prevaddr == NULL) {
797 		/*
798 		 * The list was empty; this is the first member.
799 		 */
800 		curdev->addresses = curaddr;
801 	} else {
802 		/*
803 		 * "prevaddr" is the last member of the list; append
804 		 * this member to it.
805 		 */
806 		prevaddr->next = curaddr;
807 	}
808 
809 	return (0);
810 }
811 
812 /*
813  * Look for a given device in the specified list of devices.
814  *
815  * If we find it, return 0.
816  *
817  * If we don't find it, check whether we can open it:
818  *
819  *     If that fails with PCAP_ERROR_NO_SUCH_DEVICE or
820  *     PCAP_ERROR_IFACE_NOT_UP, don't attempt to add an entry for
821  *     it, as that probably means it exists but doesn't support
822  *     packet capture.
823  *
824  *     Otherwise, attempt to add an entry for it, with the specified
825  *     ifnet flags and description, and, if that succeeds, return 0
826  *     and set *curdev_ret to point to the new entry, otherwise
827  *     return PCAP_ERROR and set errbuf to an error message.
828  */
829 int
pcap_add_if(pcap_if_t ** devlist,const char * name,u_int flags,const char * description,char * errbuf)830 pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
831     const char *description, char *errbuf)
832 {
833 	pcap_if_t *curdev;
834 
835 	return (add_or_find_if(&curdev, devlist, name, flags, description,
836 	    errbuf));
837 }
838 
839 
840 /*
841  * Free a list of interfaces.
842  */
843 void
pcap_freealldevs(pcap_if_t * alldevs)844 pcap_freealldevs(pcap_if_t *alldevs)
845 {
846 	pcap_if_t *curdev, *nextdev;
847 	pcap_addr_t *curaddr, *nextaddr;
848 
849 	for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
850 		nextdev = curdev->next;
851 
852 		/*
853 		 * Free all addresses.
854 		 */
855 		for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
856 			nextaddr = curaddr->next;
857 			if (curaddr->addr)
858 				free(curaddr->addr);
859 			if (curaddr->netmask)
860 				free(curaddr->netmask);
861 			if (curaddr->broadaddr)
862 				free(curaddr->broadaddr);
863 			if (curaddr->dstaddr)
864 				free(curaddr->dstaddr);
865 			free(curaddr);
866 		}
867 
868 		/*
869 		 * Free the name string.
870 		 */
871 		free(curdev->name);
872 
873 		/*
874 		 * Free the description string, if any.
875 		 */
876 		if (curdev->description != NULL)
877 			free(curdev->description);
878 
879 		/*
880 		 * Free the interface.
881 		 */
882 		free(curdev);
883 	}
884 }
885