]> The Tcpdump Group git mirrors - libpcap/blob - inet.c
Merge pull request #337 from crondaemon/master
[libpcap] / inet.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 /* 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
100 struct sockaddr *
101 dup_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 static int
111 get_instance(const char *name)
112 {
113 const char *cp, *endcp;
114 int n;
115
116 if (strcmp(name, "any") == 0) {
117 /*
118 * Give the "any" device an artificially high instance
119 * number, so it shows up after all other non-loopback
120 * interfaces.
121 */
122 return INT_MAX;
123 }
124
125 endcp = name + strlen(name);
126 for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
127 continue;
128
129 if (isdigit((unsigned char)*cp))
130 n = atoi(cp);
131 else
132 n = 0;
133 return (n);
134 }
135
136 int
137 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
138 u_int flags, const char *description, char *errbuf)
139 {
140 pcap_t *p;
141 pcap_if_t *curdev, *prevdev, *nextdev;
142 int this_instance;
143 char open_errbuf[PCAP_ERRBUF_SIZE];
144
145 /*
146 * Is there already an entry in the list for this interface?
147 */
148 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
149 if (strcmp(name, curdev->name) == 0)
150 break; /* yes, we found it */
151 }
152
153 if (curdev == NULL) {
154 /*
155 * No, we didn't find it.
156 *
157 * Can we open this interface for live capture?
158 *
159 * We do this check so that interfaces that are
160 * supplied by the interface enumeration mechanism
161 * we're using but that don't support packet capture
162 * aren't included in the list. Loopback interfaces
163 * on Solaris are an example of this; we don't just
164 * omit loopback interfaces on all platforms because
165 * you *can* capture on loopback interfaces on some
166 * OSes.
167 *
168 * On OS X, we don't do this check if the device
169 * name begins with "wlt"; at least some versions
170 * of OS X offer monitor mode capturing by having
171 * a separate "monitor mode" device for each wireless
172 * adapter, rather than by implementing the ioctls
173 * that {Free,Net,Open,DragonFly}BSD provide.
174 * Opening that device puts the adapter into monitor
175 * mode, which, at least for some adapters, causes
176 * them to deassociate from the network with which
177 * they're associated.
178 *
179 * Instead, we try to open the corresponding "en"
180 * device (so that we don't end up with, for users
181 * without sufficient privilege to open capture
182 * devices, a list of adapters that only includes
183 * the wlt devices).
184 */
185 #ifdef __APPLE__
186 if (strncmp(name, "wlt", 3) == 0) {
187 char *en_name;
188 size_t en_name_len;
189
190 /*
191 * Try to allocate a buffer for the "en"
192 * device's name.
193 */
194 en_name_len = strlen(name) - 1;
195 en_name = malloc(en_name_len + 1);
196 if (en_name == NULL) {
197 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
198 "malloc: %s", pcap_strerror(errno));
199 return (-1);
200 }
201 strcpy(en_name, "en");
202 strcat(en_name, name + 3);
203 p = pcap_open_live(en_name, 68, 0, 0, open_errbuf);
204 free(en_name);
205 } else
206 #endif /* __APPLE */
207 p = pcap_open_live(name, 68, 0, 0, open_errbuf);
208 if (p == NULL) {
209 /*
210 * No. Don't bother including it.
211 * Don't treat this as an error, though.
212 */
213 *curdev_ret = NULL;
214 return (0);
215 }
216 pcap_close(p);
217
218 /*
219 * Yes, we can open it.
220 * Allocate a new entry.
221 */
222 curdev = malloc(sizeof(pcap_if_t));
223 if (curdev == NULL) {
224 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
225 "malloc: %s", pcap_strerror(errno));
226 return (-1);
227 }
228
229 /*
230 * Fill in the entry.
231 */
232 curdev->next = NULL;
233 curdev->name = strdup(name);
234 if (curdev->name == NULL) {
235 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
236 "malloc: %s", pcap_strerror(errno));
237 free(curdev);
238 return (-1);
239 }
240 if (description != NULL) {
241 /*
242 * We have a description for this interface.
243 */
244 curdev->description = strdup(description);
245 if (curdev->description == NULL) {
246 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
247 "malloc: %s", pcap_strerror(errno));
248 free(curdev->name);
249 free(curdev);
250 return (-1);
251 }
252 } else {
253 /*
254 * We don't.
255 */
256 curdev->description = NULL;
257 }
258 curdev->addresses = NULL; /* list starts out as empty */
259 curdev->flags = 0;
260 if (ISLOOPBACK(name, flags))
261 curdev->flags |= PCAP_IF_LOOPBACK;
262 if (ISUP(flags))
263 curdev->flags |= PCAP_IF_UP;
264 if (ISRUNNING(flags))
265 curdev->flags |= PCAP_IF_RUNNING;
266
267 /*
268 * Add it to the list, in the appropriate location.
269 * First, get the instance number of this interface.
270 */
271 this_instance = get_instance(name);
272
273 /*
274 * Now look for the last interface with an instance number
275 * less than or equal to the new interface's instance
276 * number - except that non-loopback interfaces are
277 * arbitrarily treated as having interface numbers less
278 * than those of loopback interfaces, so the loopback
279 * interfaces are put at the end of the list.
280 *
281 * We start with "prevdev" being NULL, meaning we're before
282 * the first element in the list.
283 */
284 prevdev = NULL;
285 for (;;) {
286 /*
287 * Get the interface after this one.
288 */
289 if (prevdev == NULL) {
290 /*
291 * The next element is the first element.
292 */
293 nextdev = *alldevs;
294 } else
295 nextdev = prevdev->next;
296
297 /*
298 * Are we at the end of the list?
299 */
300 if (nextdev == NULL) {
301 /*
302 * Yes - we have to put the new entry
303 * after "prevdev".
304 */
305 break;
306 }
307
308 /*
309 * Is the new interface a non-loopback interface
310 * and the next interface a loopback interface?
311 */
312 if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
313 (nextdev->flags & PCAP_IF_LOOPBACK)) {
314 /*
315 * Yes, we should put the new entry
316 * before "nextdev", i.e. after "prevdev".
317 */
318 break;
319 }
320
321 /*
322 * Is the new interface's instance number less
323 * than the next interface's instance number,
324 * and is it the case that the new interface is a
325 * non-loopback interface or the next interface is
326 * a loopback interface?
327 *
328 * (The goal of both loopback tests is to make
329 * sure that we never put a loopback interface
330 * before any non-loopback interface and that we
331 * always put a non-loopback interface before all
332 * loopback interfaces.)
333 */
334 if (this_instance < get_instance(nextdev->name) &&
335 (!(curdev->flags & PCAP_IF_LOOPBACK) ||
336 (nextdev->flags & PCAP_IF_LOOPBACK))) {
337 /*
338 * Yes - we should put the new entry
339 * before "nextdev", i.e. after "prevdev".
340 */
341 break;
342 }
343
344 prevdev = nextdev;
345 }
346
347 /*
348 * Insert before "nextdev".
349 */
350 curdev->next = nextdev;
351
352 /*
353 * Insert after "prevdev" - unless "prevdev" is null,
354 * in which case this is the first interface.
355 */
356 if (prevdev == NULL) {
357 /*
358 * This is the first interface. Pass back a
359 * pointer to it, and put "curdev" before
360 * "nextdev".
361 */
362 *alldevs = curdev;
363 } else
364 prevdev->next = curdev;
365 }
366
367 *curdev_ret = curdev;
368 return (0);
369 }
370
371 /*
372 * XXX - on FreeBSDs that support it, should it get the sysctl named
373 * "dev.{adapter family name}.{adapter unit}.%desc" to get a description
374 * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
375 * with my Cisco 350 card, so the name isn't entirely descriptive. The
376 * "dev.an.0.%pnpinfo" has a better description, although one might argue
377 * that the problem is really a driver bug - if it can find out that it's
378 * a Cisco 340 or 350, rather than an old Aironet card, it should use
379 * that in the description.
380 *
381 * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
382 * and OpenBSD let you get a description, but it's not generated by the OS,
383 * it's set with another ioctl that ifconfig supports; we use that to get
384 * a description in FreeBSD and OpenBSD, but if there is no such
385 * description available, it still might be nice to get some description
386 * string based on the device type or something such as that.
387 *
388 * In OS X, the System Configuration framework can apparently return
389 * names in 10.4 and later.
390 *
391 * It also appears that freedesktop.org's HAL offers an "info.product"
392 * string, but the HAL specification says it "should not be used in any
393 * UI" and "subsystem/capability specific properties" should be used
394 * instead and, in any case, I think HAL is being deprecated in
395 * favor of other stuff such as DeviceKit. DeviceKit doesn't appear
396 * to have any obvious product information for devices, but maybe
397 * I haven't looked hard enough.
398 *
399 * Using the System Configuration framework, or HAL, or DeviceKit, or
400 * whatever, would require that libpcap applications be linked with
401 * the frameworks/libraries in question. That shouldn't be a problem
402 * for programs linking with the shared version of libpcap (unless
403 * you're running on AIX - which I think is the only UN*X that doesn't
404 * support linking a shared library with other libraries on which it
405 * depends, and having an executable linked only with the first shared
406 * library automatically pick up the other libraries when started -
407 * and using HAL or whatever). Programs linked with the static
408 * version of libpcap would have to use pcap-config with the --static
409 * flag in order to get the right linker flags in order to pick up
410 * the additional libraries/frameworks; those programs need that anyway
411 * for libpcap 1.1 and beyond on Linux, as, by default, it requires
412 * -lnl.
413 *
414 * Do any other UN*Xes, or desktop environments support getting a
415 * description?
416 */
417 int
418 add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
419 struct sockaddr *addr, size_t addr_size,
420 struct sockaddr *netmask, size_t netmask_size,
421 struct sockaddr *broadaddr, size_t broadaddr_size,
422 struct sockaddr *dstaddr, size_t dstaddr_size,
423 char *errbuf)
424 {
425 pcap_if_t *curdev;
426 char *description = NULL;
427 pcap_addr_t *curaddr, *prevaddr, *nextaddr;
428 #ifdef SIOCGIFDESCR
429 int s;
430 struct ifreq ifrdesc;
431 #ifndef IFDESCRSIZE
432 size_t descrlen = 64;
433 #else
434 size_t descrlen = IFDESCRSIZE;
435 #endif /* IFDESCRSIZE */
436 #endif /* SIOCGIFDESCR */
437
438 #ifdef SIOCGIFDESCR
439 /*
440 * Get the description for the interface.
441 */
442 memset(&ifrdesc, 0, sizeof ifrdesc);
443 strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
444 s = socket(AF_INET, SOCK_DGRAM, 0);
445 if (s >= 0) {
446 #ifdef __FreeBSD__
447 /*
448 * On FreeBSD, if the buffer isn't big enough for the
449 * description, the ioctl succeeds, but the description
450 * isn't copied, ifr_buffer.length is set to the description
451 * length, and ifr_buffer.buffer is set to NULL.
452 */
453 for (;;) {
454 free(description);
455 if ((description = malloc(descrlen)) != NULL) {
456 ifrdesc.ifr_buffer.buffer = description;
457 ifrdesc.ifr_buffer.length = descrlen;
458 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
459 if (ifrdesc.ifr_buffer.buffer ==
460 description)
461 break;
462 else
463 descrlen = ifrdesc.ifr_buffer.length;
464 } else {
465 /*
466 * Failed to get interface description.
467 */
468 free(description);
469 description = NULL;
470 break;
471 }
472 } else
473 break;
474 }
475 #else /* __FreeBSD__ */
476 /*
477 * The only other OS that currently supports
478 * SIOCGIFDESCR is OpenBSD, and it has no way
479 * to get the description length - it's clamped
480 * to a maximum of IFDESCRSIZE.
481 */
482 if ((description = malloc(descrlen)) != NULL) {
483 ifrdesc.ifr_data = (caddr_t)description;
484 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
485 /*
486 * Failed to get interface description.
487 */
488 free(description);
489 description = NULL;
490 }
491 }
492 #endif /* __FreeBSD__ */
493 close(s);
494 if (description != NULL && strlen(description) == 0) {
495 free(description);
496 description = NULL;
497 }
498 }
499 #endif /* SIOCGIFDESCR */
500
501 if (add_or_find_if(&curdev, alldevs, name, flags, description,
502 errbuf) == -1) {
503 free(description);
504 /*
505 * Error - give up.
506 */
507 return (-1);
508 }
509 free(description);
510 if (curdev == NULL) {
511 /*
512 * Device wasn't added because it can't be opened.
513 * Not a fatal error.
514 */
515 return (0);
516 }
517
518 /*
519 * "curdev" is an entry for this interface; add an entry for this
520 * address to its list of addresses.
521 *
522 * Allocate the new entry and fill it in.
523 */
524 curaddr = malloc(sizeof(pcap_addr_t));
525 if (curaddr == NULL) {
526 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
527 "malloc: %s", pcap_strerror(errno));
528 return (-1);
529 }
530
531 curaddr->next = NULL;
532 if (addr != NULL) {
533 curaddr->addr = dup_sockaddr(addr, addr_size);
534 if (curaddr->addr == NULL) {
535 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
536 "malloc: %s", pcap_strerror(errno));
537 free(curaddr);
538 return (-1);
539 }
540 } else
541 curaddr->addr = NULL;
542
543 if (netmask != NULL) {
544 curaddr->netmask = dup_sockaddr(netmask, netmask_size);
545 if (curaddr->netmask == NULL) {
546 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
547 "malloc: %s", pcap_strerror(errno));
548 if (curaddr->addr != NULL)
549 free(curaddr->addr);
550 free(curaddr);
551 return (-1);
552 }
553 } else
554 curaddr->netmask = NULL;
555
556 if (broadaddr != NULL) {
557 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
558 if (curaddr->broadaddr == NULL) {
559 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
560 "malloc: %s", pcap_strerror(errno));
561 if (curaddr->netmask != NULL)
562 free(curaddr->netmask);
563 if (curaddr->addr != NULL)
564 free(curaddr->addr);
565 free(curaddr);
566 return (-1);
567 }
568 } else
569 curaddr->broadaddr = NULL;
570
571 if (dstaddr != NULL) {
572 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
573 if (curaddr->dstaddr == NULL) {
574 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
575 "malloc: %s", pcap_strerror(errno));
576 if (curaddr->broadaddr != NULL)
577 free(curaddr->broadaddr);
578 if (curaddr->netmask != NULL)
579 free(curaddr->netmask);
580 if (curaddr->addr != NULL)
581 free(curaddr->addr);
582 free(curaddr);
583 return (-1);
584 }
585 } else
586 curaddr->dstaddr = NULL;
587
588 /*
589 * Find the end of the list of addresses.
590 */
591 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
592 nextaddr = prevaddr->next;
593 if (nextaddr == NULL) {
594 /*
595 * This is the end of the list.
596 */
597 break;
598 }
599 }
600
601 if (prevaddr == NULL) {
602 /*
603 * The list was empty; this is the first member.
604 */
605 curdev->addresses = curaddr;
606 } else {
607 /*
608 * "prevaddr" is the last member of the list; append
609 * this member to it.
610 */
611 prevaddr->next = curaddr;
612 }
613
614 return (0);
615 }
616
617 int
618 pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
619 const char *description, char *errbuf)
620 {
621 pcap_if_t *curdev;
622
623 return (add_or_find_if(&curdev, devlist, name, flags, description,
624 errbuf));
625 }
626
627
628 /*
629 * Free a list of interfaces.
630 */
631 void
632 pcap_freealldevs(pcap_if_t *alldevs)
633 {
634 pcap_if_t *curdev, *nextdev;
635 pcap_addr_t *curaddr, *nextaddr;
636
637 for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
638 nextdev = curdev->next;
639
640 /*
641 * Free all addresses.
642 */
643 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
644 nextaddr = curaddr->next;
645 if (curaddr->addr)
646 free(curaddr->addr);
647 if (curaddr->netmask)
648 free(curaddr->netmask);
649 if (curaddr->broadaddr)
650 free(curaddr->broadaddr);
651 if (curaddr->dstaddr)
652 free(curaddr->dstaddr);
653 free(curaddr);
654 }
655
656 /*
657 * Free the name string.
658 */
659 free(curdev->name);
660
661 /*
662 * Free the description string, if any.
663 */
664 if (curdev->description != NULL)
665 free(curdev->description);
666
667 /*
668 * Free the interface.
669 */
670 free(curdev);
671 }
672 }
673
674 #if !defined(WIN32) && !defined(MSDOS)
675
676 /*
677 * Return the name of a network interface attached to the system, or NULL
678 * if none can be found. The interface must be configured up; the
679 * lowest unit number is preferred; loopback is ignored.
680 */
681 char *
682 pcap_lookupdev(errbuf)
683 register char *errbuf;
684 {
685 pcap_if_t *alldevs;
686 /* for old BSD systems, including bsdi3 */
687 #ifndef IF_NAMESIZE
688 #define IF_NAMESIZE IFNAMSIZ
689 #endif
690 static char device[IF_NAMESIZE + 1];
691 char *ret;
692
693 if (pcap_findalldevs(&alldevs, errbuf) == -1)
694 return (NULL);
695
696 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
697 /*
698 * There are no devices on the list, or the first device
699 * on the list is a loopback device, which means there
700 * are no non-loopback devices on the list. This means
701 * we can't return any device.
702 *
703 * XXX - why not return a loopback device? If we can't
704 * capture on it, it won't be on the list, and if it's
705 * on the list, there aren't any non-loopback devices,
706 * so why not just supply it as the default device?
707 */
708 (void)strlcpy(errbuf, "no suitable device found",
709 PCAP_ERRBUF_SIZE);
710 ret = NULL;
711 } else {
712 /*
713 * Return the name of the first device on the list.
714 */
715 (void)strlcpy(device, alldevs->name, sizeof(device));
716 ret = device;
717 }
718
719 pcap_freealldevs(alldevs);
720 return (ret);
721 }
722
723 int
724 pcap_lookupnet(device, netp, maskp, errbuf)
725 register const char *device;
726 register bpf_u_int32 *netp, *maskp;
727 register char *errbuf;
728 {
729 register int fd;
730 register struct sockaddr_in *sin4;
731 struct ifreq ifr;
732
733 /*
734 * The pseudo-device "any" listens on all interfaces and therefore
735 * has the network address and -mask "0.0.0.0" therefore catching
736 * all traffic. Using NULL for the interface is the same as "any".
737 */
738 if (!device || strcmp(device, "any") == 0
739 #ifdef HAVE_DAG_API
740 || strstr(device, "dag") != NULL
741 #endif
742 #ifdef HAVE_SEPTEL_API
743 || strstr(device, "septel") != NULL
744 #endif
745 #ifdef PCAP_SUPPORT_BT
746 || strstr(device, "bluetooth") != NULL
747 #endif
748 #ifdef PCAP_SUPPORT_USB
749 || strstr(device, "usbmon") != NULL
750 #endif
751 #ifdef HAVE_SNF_API
752 || strstr(device, "snf") != NULL
753 #endif
754 ) {
755 *netp = *maskp = 0;
756 return 0;
757 }
758
759 fd = socket(AF_INET, SOCK_DGRAM, 0);
760 if (fd < 0) {
761 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
762 pcap_strerror(errno));
763 return (-1);
764 }
765 memset(&ifr, 0, sizeof(ifr));
766 #ifdef linux
767 /* XXX Work around Linux kernel bug */
768 ifr.ifr_addr.sa_family = AF_INET;
769 #endif
770 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
771 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
772 if (errno == EADDRNOTAVAIL) {
773 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
774 "%s: no IPv4 address assigned", device);
775 } else {
776 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
777 "SIOCGIFADDR: %s: %s",
778 device, pcap_strerror(errno));
779 }
780 (void)close(fd);
781 return (-1);
782 }
783 sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
784 *netp = sin4->sin_addr.s_addr;
785 memset(&ifr, 0, sizeof(ifr));
786 #ifdef linux
787 /* XXX Work around Linux kernel bug */
788 ifr.ifr_addr.sa_family = AF_INET;
789 #endif
790 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
791 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
792 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
793 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
794 (void)close(fd);
795 return (-1);
796 }
797 (void)close(fd);
798 *maskp = sin4->sin_addr.s_addr;
799 if (*maskp == 0) {
800 if (IN_CLASSA(*netp))
801 *maskp = IN_CLASSA_NET;
802 else if (IN_CLASSB(*netp))
803 *maskp = IN_CLASSB_NET;
804 else if (IN_CLASSC(*netp))
805 *maskp = IN_CLASSC_NET;
806 else {
807 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
808 "inet class for 0x%x unknown", *netp);
809 return (-1);
810 }
811 }
812 *netp &= *maskp;
813 return (0);
814 }
815
816 #elif defined(WIN32)
817
818 /*
819 * Return the name of a network interface attached to the system, or NULL
820 * if none can be found. The interface must be configured up; the
821 * lowest unit number is preferred; loopback is ignored.
822 */
823 char *
824 pcap_lookupdev(errbuf)
825 register char *errbuf;
826 {
827 DWORD dwVersion;
828 DWORD dwWindowsMajorVersion;
829 dwVersion = GetVersion(); /* get the OS version */
830 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
831
832 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
833 /*
834 * Windows 95, 98, ME.
835 */
836 ULONG NameLength = 8192;
837 static char AdaptersName[8192];
838
839 if (PacketGetAdapterNames(AdaptersName,&NameLength) )
840 return (AdaptersName);
841 else
842 return NULL;
843 } else {
844 /*
845 * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
846 */
847 ULONG NameLength = 8192;
848 static WCHAR AdaptersName[8192];
849 char *tAstr;
850 WCHAR *tUstr;
851 WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
852 int NAdapts = 0;
853
854 if(TAdaptersName == NULL)
855 {
856 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
857 return NULL;
858 }
859
860 if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
861 {
862 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
863 "PacketGetAdapterNames: %s",
864 pcap_win32strerror());
865 free(TAdaptersName);
866 return NULL;
867 }
868
869
870 tAstr = (char*)TAdaptersName;
871 tUstr = (WCHAR*)AdaptersName;
872
873 /*
874 * Convert and copy the device names
875 */
876 while(sscanf(tAstr, "%S", tUstr) > 0)
877 {
878 tAstr += strlen(tAstr) + 1;
879 tUstr += wcslen(tUstr) + 1;
880 NAdapts ++;
881 }
882
883 tAstr++;
884 *tUstr = 0;
885 tUstr++;
886
887 /*
888 * Copy the descriptions
889 */
890 while(NAdapts--)
891 {
892 char* tmp = (char*)tUstr;
893 strcpy(tmp, tAstr);
894 tmp += strlen(tAstr) + 1;
895 tUstr = (WCHAR*)tmp;
896 tAstr += strlen(tAstr) + 1;
897 }
898
899 free(TAdaptersName);
900 return (char *)(AdaptersName);
901 }
902 }
903
904
905 int
906 pcap_lookupnet(device, netp, maskp, errbuf)
907 register const char *device;
908 register bpf_u_int32 *netp, *maskp;
909 register char *errbuf;
910 {
911 /*
912 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
913 * in order to skip non IPv4 (i.e. IPv6 addresses)
914 */
915 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
916 LONG if_addr_size = 1;
917 struct sockaddr_in *t_addr;
918 unsigned int i;
919
920 if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
921 *netp = *maskp = 0;
922 return (0);
923 }
924
925 for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
926 {
927 if(if_addrs[i].IPAddress.ss_family == AF_INET)
928 {
929 t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
930 *netp = t_addr->sin_addr.S_un.S_addr;
931 t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
932 *maskp = t_addr->sin_addr.S_un.S_addr;
933
934 *netp &= *maskp;
935 return (0);
936 }
937
938 }
939
940 *netp = *maskp = 0;
941 return (0);
942 }
943
944 #endif /* !WIN32 && !MSDOS */