]> The Tcpdump Group git mirrors - libpcap/blob - inet.c
Pull the code to add an address to an interface into a routine.
[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 #ifdef SIOCGIFDESCR
428 int s;
429 struct ifreq ifrdesc;
430 #ifndef IFDESCRSIZE
431 size_t descrlen = 64;
432 #else
433 size_t descrlen = IFDESCRSIZE;
434 #endif /* IFDESCRSIZE */
435 #endif /* SIOCGIFDESCR */
436
437 #ifdef SIOCGIFDESCR
438 /*
439 * Get the description for the interface.
440 */
441 memset(&ifrdesc, 0, sizeof ifrdesc);
442 strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
443 s = socket(AF_INET, SOCK_DGRAM, 0);
444 if (s >= 0) {
445 #ifdef __FreeBSD__
446 /*
447 * On FreeBSD, if the buffer isn't big enough for the
448 * description, the ioctl succeeds, but the description
449 * isn't copied, ifr_buffer.length is set to the description
450 * length, and ifr_buffer.buffer is set to NULL.
451 */
452 for (;;) {
453 free(description);
454 if ((description = malloc(descrlen)) != NULL) {
455 ifrdesc.ifr_buffer.buffer = description;
456 ifrdesc.ifr_buffer.length = descrlen;
457 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
458 if (ifrdesc.ifr_buffer.buffer ==
459 description)
460 break;
461 else
462 descrlen = ifrdesc.ifr_buffer.length;
463 } else {
464 /*
465 * Failed to get interface description.
466 */
467 free(description);
468 description = NULL;
469 break;
470 }
471 } else
472 break;
473 }
474 #else /* __FreeBSD__ */
475 /*
476 * The only other OS that currently supports
477 * SIOCGIFDESCR is OpenBSD, and it has no way
478 * to get the description length - it's clamped
479 * to a maximum of IFDESCRSIZE.
480 */
481 if ((description = malloc(descrlen)) != NULL) {
482 ifrdesc.ifr_data = (caddr_t)description;
483 if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
484 /*
485 * Failed to get interface description.
486 */
487 free(description);
488 description = NULL;
489 }
490 }
491 #endif /* __FreeBSD__ */
492 close(s);
493 if (description != NULL && strlen(description) == 0) {
494 free(description);
495 description = NULL;
496 }
497 }
498 #endif /* SIOCGIFDESCR */
499
500 if (add_or_find_if(&curdev, alldevs, name, flags, description,
501 errbuf) == -1) {
502 free(description);
503 /*
504 * Error - give up.
505 */
506 return (-1);
507 }
508 free(description);
509 if (curdev == NULL) {
510 /*
511 * Device wasn't added because it can't be opened.
512 * Not a fatal error.
513 */
514 return (0);
515 }
516
517 /*
518 * "curdev" is an entry for this interface; add an entry for this
519 * address to its list of addresses.
520 *
521 * Allocate the new entry and fill it in.
522 */
523 return (add_addr_to_dev(curdev, addr, addr_size, netmask, netmask_size,
524 broadaddr, broadaddr_size, dstaddr, dstaddr_size, errbuf));
525 }
526
527 /*
528 * Add an entry to the list of addresses for an interface.
529 * "curdev" is the entry for that interface.
530 * If this is the first IP address added to the interface, move it
531 * in the list as appropriate.
532 */
533 int
534 add_addr_to_dev(pcap_if_t *curdev,
535 struct sockaddr *addr, size_t addr_size,
536 struct sockaddr *netmask, size_t netmask_size,
537 struct sockaddr *broadaddr, size_t broadaddr_size,
538 struct sockaddr *dstaddr, size_t dstaddr_size,
539 char *errbuf)
540 {
541 pcap_addr_t *curaddr, *prevaddr, *nextaddr;
542
543 curaddr = malloc(sizeof(pcap_addr_t));
544 if (curaddr == NULL) {
545 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
546 "malloc: %s", pcap_strerror(errno));
547 return (-1);
548 }
549
550 curaddr->next = NULL;
551 if (addr != NULL) {
552 curaddr->addr = dup_sockaddr(addr, addr_size);
553 if (curaddr->addr == NULL) {
554 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
555 "malloc: %s", pcap_strerror(errno));
556 free(curaddr);
557 return (-1);
558 }
559 } else
560 curaddr->addr = NULL;
561
562 if (netmask != NULL) {
563 curaddr->netmask = dup_sockaddr(netmask, netmask_size);
564 if (curaddr->netmask == NULL) {
565 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
566 "malloc: %s", pcap_strerror(errno));
567 if (curaddr->addr != NULL)
568 free(curaddr->addr);
569 free(curaddr);
570 return (-1);
571 }
572 } else
573 curaddr->netmask = NULL;
574
575 if (broadaddr != NULL) {
576 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
577 if (curaddr->broadaddr == NULL) {
578 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
579 "malloc: %s", pcap_strerror(errno));
580 if (curaddr->netmask != NULL)
581 free(curaddr->netmask);
582 if (curaddr->addr != NULL)
583 free(curaddr->addr);
584 free(curaddr);
585 return (-1);
586 }
587 } else
588 curaddr->broadaddr = NULL;
589
590 if (dstaddr != NULL) {
591 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
592 if (curaddr->dstaddr == NULL) {
593 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
594 "malloc: %s", pcap_strerror(errno));
595 if (curaddr->broadaddr != NULL)
596 free(curaddr->broadaddr);
597 if (curaddr->netmask != NULL)
598 free(curaddr->netmask);
599 if (curaddr->addr != NULL)
600 free(curaddr->addr);
601 free(curaddr);
602 return (-1);
603 }
604 } else
605 curaddr->dstaddr = NULL;
606
607 /*
608 * Find the end of the list of addresses.
609 */
610 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
611 nextaddr = prevaddr->next;
612 if (nextaddr == NULL) {
613 /*
614 * This is the end of the list.
615 */
616 break;
617 }
618 }
619
620 if (prevaddr == NULL) {
621 /*
622 * The list was empty; this is the first member.
623 */
624 curdev->addresses = curaddr;
625 } else {
626 /*
627 * "prevaddr" is the last member of the list; append
628 * this member to it.
629 */
630 prevaddr->next = curaddr;
631 }
632
633 return (0);
634 }
635
636 int
637 pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
638 const char *description, char *errbuf)
639 {
640 pcap_if_t *curdev;
641
642 return (add_or_find_if(&curdev, devlist, name, flags, description,
643 errbuf));
644 }
645
646
647 /*
648 * Free a list of interfaces.
649 */
650 void
651 pcap_freealldevs(pcap_if_t *alldevs)
652 {
653 pcap_if_t *curdev, *nextdev;
654 pcap_addr_t *curaddr, *nextaddr;
655
656 for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
657 nextdev = curdev->next;
658
659 /*
660 * Free all addresses.
661 */
662 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
663 nextaddr = curaddr->next;
664 if (curaddr->addr)
665 free(curaddr->addr);
666 if (curaddr->netmask)
667 free(curaddr->netmask);
668 if (curaddr->broadaddr)
669 free(curaddr->broadaddr);
670 if (curaddr->dstaddr)
671 free(curaddr->dstaddr);
672 free(curaddr);
673 }
674
675 /*
676 * Free the name string.
677 */
678 free(curdev->name);
679
680 /*
681 * Free the description string, if any.
682 */
683 if (curdev->description != NULL)
684 free(curdev->description);
685
686 /*
687 * Free the interface.
688 */
689 free(curdev);
690 }
691 }
692
693 #if !defined(WIN32) && !defined(MSDOS)
694
695 /*
696 * Return the name of a network interface attached to the system, or NULL
697 * if none can be found. The interface must be configured up; the
698 * lowest unit number is preferred; loopback is ignored.
699 */
700 char *
701 pcap_lookupdev(errbuf)
702 register char *errbuf;
703 {
704 pcap_if_t *alldevs;
705 /* for old BSD systems, including bsdi3 */
706 #ifndef IF_NAMESIZE
707 #define IF_NAMESIZE IFNAMSIZ
708 #endif
709 static char device[IF_NAMESIZE + 1];
710 char *ret;
711
712 if (pcap_findalldevs(&alldevs, errbuf) == -1)
713 return (NULL);
714
715 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
716 /*
717 * There are no devices on the list, or the first device
718 * on the list is a loopback device, which means there
719 * are no non-loopback devices on the list. This means
720 * we can't return any device.
721 *
722 * XXX - why not return a loopback device? If we can't
723 * capture on it, it won't be on the list, and if it's
724 * on the list, there aren't any non-loopback devices,
725 * so why not just supply it as the default device?
726 */
727 (void)strlcpy(errbuf, "no suitable device found",
728 PCAP_ERRBUF_SIZE);
729 ret = NULL;
730 } else {
731 /*
732 * Return the name of the first device on the list.
733 */
734 (void)strlcpy(device, alldevs->name, sizeof(device));
735 ret = device;
736 }
737
738 pcap_freealldevs(alldevs);
739 return (ret);
740 }
741
742 int
743 pcap_lookupnet(device, netp, maskp, errbuf)
744 register const char *device;
745 register bpf_u_int32 *netp, *maskp;
746 register char *errbuf;
747 {
748 register int fd;
749 register struct sockaddr_in *sin4;
750 struct ifreq ifr;
751
752 /*
753 * The pseudo-device "any" listens on all interfaces and therefore
754 * has the network address and -mask "0.0.0.0" therefore catching
755 * all traffic. Using NULL for the interface is the same as "any".
756 */
757 if (!device || strcmp(device, "any") == 0
758 #ifdef HAVE_DAG_API
759 || strstr(device, "dag") != NULL
760 #endif
761 #ifdef HAVE_SEPTEL_API
762 || strstr(device, "septel") != NULL
763 #endif
764 #ifdef PCAP_SUPPORT_BT
765 || strstr(device, "bluetooth") != NULL
766 #endif
767 #ifdef PCAP_SUPPORT_USB
768 || strstr(device, "usbmon") != NULL
769 #endif
770 #ifdef HAVE_SNF_API
771 || strstr(device, "snf") != NULL
772 #endif
773 ) {
774 *netp = *maskp = 0;
775 return 0;
776 }
777
778 fd = socket(AF_INET, SOCK_DGRAM, 0);
779 if (fd < 0) {
780 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
781 pcap_strerror(errno));
782 return (-1);
783 }
784 memset(&ifr, 0, sizeof(ifr));
785 #ifdef linux
786 /* XXX Work around Linux kernel bug */
787 ifr.ifr_addr.sa_family = AF_INET;
788 #endif
789 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
790 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
791 if (errno == EADDRNOTAVAIL) {
792 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
793 "%s: no IPv4 address assigned", device);
794 } else {
795 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
796 "SIOCGIFADDR: %s: %s",
797 device, pcap_strerror(errno));
798 }
799 (void)close(fd);
800 return (-1);
801 }
802 sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
803 *netp = sin4->sin_addr.s_addr;
804 memset(&ifr, 0, sizeof(ifr));
805 #ifdef linux
806 /* XXX Work around Linux kernel bug */
807 ifr.ifr_addr.sa_family = AF_INET;
808 #endif
809 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
810 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
811 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
812 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
813 (void)close(fd);
814 return (-1);
815 }
816 (void)close(fd);
817 *maskp = sin4->sin_addr.s_addr;
818 if (*maskp == 0) {
819 if (IN_CLASSA(*netp))
820 *maskp = IN_CLASSA_NET;
821 else if (IN_CLASSB(*netp))
822 *maskp = IN_CLASSB_NET;
823 else if (IN_CLASSC(*netp))
824 *maskp = IN_CLASSC_NET;
825 else {
826 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
827 "inet class for 0x%x unknown", *netp);
828 return (-1);
829 }
830 }
831 *netp &= *maskp;
832 return (0);
833 }
834
835 #elif defined(WIN32)
836
837 /*
838 * Return the name of a network interface attached to the system, or NULL
839 * if none can be found. The interface must be configured up; the
840 * lowest unit number is preferred; loopback is ignored.
841 */
842 char *
843 pcap_lookupdev(errbuf)
844 register char *errbuf;
845 {
846 DWORD dwVersion;
847 DWORD dwWindowsMajorVersion;
848 dwVersion = GetVersion(); /* get the OS version */
849 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
850
851 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
852 /*
853 * Windows 95, 98, ME.
854 */
855 ULONG NameLength = 8192;
856 static char AdaptersName[8192];
857
858 if (PacketGetAdapterNames(AdaptersName,&NameLength) )
859 return (AdaptersName);
860 else
861 return NULL;
862 } else {
863 /*
864 * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
865 */
866 ULONG NameLength = 8192;
867 static WCHAR AdaptersName[8192];
868 char *tAstr;
869 WCHAR *tUstr;
870 WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
871 int NAdapts = 0;
872
873 if(TAdaptersName == NULL)
874 {
875 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
876 return NULL;
877 }
878
879 if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
880 {
881 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
882 "PacketGetAdapterNames: %s",
883 pcap_win32strerror());
884 free(TAdaptersName);
885 return NULL;
886 }
887
888
889 tAstr = (char*)TAdaptersName;
890 tUstr = (WCHAR*)AdaptersName;
891
892 /*
893 * Convert and copy the device names
894 */
895 while(sscanf(tAstr, "%S", tUstr) > 0)
896 {
897 tAstr += strlen(tAstr) + 1;
898 tUstr += wcslen(tUstr) + 1;
899 NAdapts ++;
900 }
901
902 tAstr++;
903 *tUstr = 0;
904 tUstr++;
905
906 /*
907 * Copy the descriptions
908 */
909 while(NAdapts--)
910 {
911 char* tmp = (char*)tUstr;
912 strcpy(tmp, tAstr);
913 tmp += strlen(tAstr) + 1;
914 tUstr = (WCHAR*)tmp;
915 tAstr += strlen(tAstr) + 1;
916 }
917
918 free(TAdaptersName);
919 return (char *)(AdaptersName);
920 }
921 }
922
923
924 int
925 pcap_lookupnet(device, netp, maskp, errbuf)
926 register const char *device;
927 register bpf_u_int32 *netp, *maskp;
928 register char *errbuf;
929 {
930 /*
931 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
932 * in order to skip non IPv4 (i.e. IPv6 addresses)
933 */
934 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
935 LONG if_addr_size = 1;
936 struct sockaddr_in *t_addr;
937 unsigned int i;
938
939 if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
940 *netp = *maskp = 0;
941 return (0);
942 }
943
944 for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
945 {
946 if(if_addrs[i].IPAddress.ss_family == AF_INET)
947 {
948 t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
949 *netp = t_addr->sin_addr.S_un.S_addr;
950 t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
951 *maskp = t_addr->sin_addr.S_un.S_addr;
952
953 *netp &= *maskp;
954 return (0);
955 }
956
957 }
958
959 *netp = *maskp = 0;
960 return (0);
961 }
962
963 #endif /* !WIN32 && !MSDOS */