]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/fad-helpers.c
Fix multiple vulnerabilities in bzip2.
[FreeBSD/FreeBSD.git] / contrib / libpcap / fad-helpers.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 #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
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 *
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
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 *
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
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
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
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
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
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 }