]> The Tcpdump Group git mirrors - libpcap/blob - inet.c
If we have "/proc/net/dev", and don't have <ifaddrs.h> (i.e., don't have
[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 #ifndef lint
36 static const char rcsid[] =
37 "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.41 2001-10-09 05:43:20 guy Exp $ (LBL)";
38 #endif
39
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44 #include <sys/param.h>
45 #include <sys/file.h>
46 #include <sys/ioctl.h>
47 #include <sys/socket.h>
48 #ifdef HAVE_SYS_SOCKIO_H
49 #include <sys/sockio.h>
50 #endif
51 #include <sys/time.h> /* concession to AIX */
52
53 struct mbuf;
54 struct rtentry;
55 #include <net/if.h>
56 #include <netinet/in.h>
57
58 #include <ctype.h>
59 #include <errno.h>
60 #include <memory.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <string.h>
64 #include <unistd.h>
65 #ifdef HAVE_LIMITS_H
66 #include <limits.h>
67 #else
68 #define INT_MAX 2147483647
69 #endif
70 #ifdef HAVE_IFADDRS_H
71 #include <ifaddrs.h>
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 /*
89 * This is fun.
90 *
91 * In older BSD systems, socket addresses were fixed-length, and
92 * "sizeof (struct sockaddr)" gave the size of the structure.
93 * All addresses fit within a "struct sockaddr".
94 *
95 * In newer BSD systems, the socket address is variable-length, and
96 * there's an "sa_len" field giving the length of the structure;
97 * this allows socket addresses to be longer than 2 bytes of family
98 * and 14 bytes of data.
99 *
100 * Some commercial UNIXes use the old BSD scheme, and some might use
101 * the new BSD scheme.
102 *
103 * GNU libc uses neither scheme, but has an "SA_LEN()" macro that
104 * determines the size based on the address family.
105 */
106 #ifndef SA_LEN
107 #ifdef HAVE_SOCKADDR_SA_LEN
108 #define SA_LEN(addr) ((addr)->sa_len)
109 #else /* HAVE_SOCKADDR_SA_LEN */
110 #define SA_LEN(addr) (sizeof (struct sockaddr))
111 #endif /* HAVE_SOCKADDR_SA_LEN */
112 #endif /* SA_LEN */
113
114 static struct sockaddr *
115 dup_sockaddr(struct sockaddr *sa)
116 {
117 struct sockaddr *newsa;
118 unsigned int size;
119
120 size = SA_LEN(sa);
121 if ((newsa = malloc(size)) == NULL)
122 return (NULL);
123 return (memcpy(newsa, sa, size));
124 }
125
126 static int
127 get_instance(char *name)
128 {
129 char *cp, *endcp;
130 int n;
131
132 if (strcmp(name, "any") == 0) {
133 /*
134 * Give the "any" device an artificially high instance
135 * number, so it shows up after all other non-loopback
136 * interfaces.
137 */
138 return INT_MAX;
139 }
140
141 endcp = name + strlen(name);
142 for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
143 continue;
144
145 if (isdigit((unsigned char)*cp))
146 n = atoi(cp);
147 else
148 n = 0;
149 return (n);
150 }
151
152 static int
153 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name,
154 u_int flags, char *errbuf)
155 {
156 pcap_t *p;
157 pcap_if_t *curdev, *prevdev, *nextdev;
158 int this_instance;
159
160 /*
161 * Can we open this interface for live capture?
162 */
163 p = pcap_open_live(name, 68, 0, 0, errbuf);
164 if (p == NULL) {
165 /*
166 * No. Don't bother including it.
167 * Don't treat this as an error, though.
168 */
169 *curdev_ret = NULL;
170 return (0);
171 }
172 pcap_close(p);
173
174 /*
175 * Is there already an entry in the list for this interface?
176 */
177 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
178 if (strcmp(name, curdev->name) == 0)
179 break; /* yes, we found it */
180 }
181 if (curdev == NULL) {
182 /*
183 * No, we didn't find it.
184 * Allocate a new entry.
185 */
186 curdev = malloc(sizeof(pcap_if_t));
187 if (curdev == NULL) {
188 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
189 "malloc: %s", pcap_strerror(errno));
190 return (-1);
191 }
192
193 /*
194 * Fill in the entry.
195 */
196 curdev->next = NULL;
197 curdev->name = malloc(strlen(name) + 1);
198 strcpy(curdev->name, name);
199 curdev->description = NULL; /* not available */
200 curdev->addresses = NULL; /* list starts out as empty */
201 curdev->is_loopback = ISLOOPBACK(name, flags);
202
203 /*
204 * Add it to the list, in the appropriate location.
205 * First, get the instance number of this interface.
206 */
207 this_instance = get_instance(name);
208
209 /*
210 * Now look for the last interface with an instance number
211 * less than or equal to the new interface's instance
212 * number - except that non-loopback interfaces are
213 * arbitrarily treated as having interface numbers less
214 * than those of loopback interfaces, so the loopback
215 * interfaces are put at the end of the list.
216 *
217 * We start with "prevdev" being NULL, meaning we're before
218 * the first element in the list.
219 */
220 prevdev = NULL;
221 for (;;) {
222 /*
223 * Get the interface after this one.
224 */
225 if (prevdev == NULL) {
226 /*
227 * The next element is the first element.
228 */
229 nextdev = *alldevs;
230 } else
231 nextdev = prevdev->next;
232
233 /*
234 * Are we at the end of the list?
235 */
236 if (nextdev == NULL) {
237 /*
238 * Yes - we have to put the new entry
239 * after "prevdev".
240 */
241 break;
242 }
243
244 /*
245 * Is the new interface a non-loopback interface
246 * and the next interface a loopback interface?
247 */
248 if (!curdev->is_loopback && nextdev->is_loopback) {
249 /*
250 * Yes, we should put the new entry
251 * before "nextdev", i.e. after "prevdev".
252 */
253 break;
254 }
255
256 /*
257 * Is the new interface's instance number less
258 * than the next interface's instance number,
259 * and is it the case that the new interface is a
260 * non-loopback interface or the next interface is
261 * a loopback interface?
262 *
263 * (The goal of both loopback tests is to make
264 * sure that we never put a loopback interface
265 * before any non-loopback interface and that we
266 * always put a non-loopback interface before all
267 * loopback interfaces.)
268 */
269 if (this_instance < get_instance(nextdev->name) &&
270 (!curdev->is_loopback || nextdev->is_loopback)) {
271 /*
272 * Yes - we should put the new entry
273 * before "nextdev", i.e. after "prevdev".
274 */
275 break;
276 }
277
278 prevdev = nextdev;
279 }
280
281 /*
282 * Insert before "nextdev".
283 */
284 curdev->next = nextdev;
285
286 /*
287 * Insert after "prevdev" - unless "prevdev" is null,
288 * in which case this is the first interface.
289 */
290 if (prevdev == NULL) {
291 /*
292 * This is the first interface. Pass back a
293 * pointer to it, and put "curdev" before
294 * "nextdev".
295 */
296 *alldevs = curdev;
297 } else
298 prevdev->next = curdev;
299 }
300
301 *curdev_ret = curdev;
302 return (0);
303 }
304
305 static int
306 add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
307 struct sockaddr *addr, struct sockaddr *netmask,
308 struct sockaddr *broadaddr, struct sockaddr *dstaddr, char *errbuf)
309 {
310 pcap_if_t *curdev;
311 pcap_addr_t *curaddr, *prevaddr, *nextaddr;
312
313 if (add_or_find_if(&curdev, alldevs, name, flags, errbuf) == -1) {
314 /*
315 * Error - give up.
316 */
317 return (-1);
318 }
319 if (curdev == NULL) {
320 /*
321 * Device wasn't added because it can't be opened.
322 * Not a fatal error.
323 */
324 return (0);
325 }
326
327 /*
328 * "curdev" is an entry for this interface; add an entry for this
329 * address to its list of addresses.
330 *
331 * Allocate the new entry and fill it in.
332 */
333 curaddr = malloc(sizeof(pcap_addr_t));
334 if (curaddr == NULL) {
335 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
336 "malloc: %s", pcap_strerror(errno));
337 return (-1);
338 }
339
340 curaddr->next = NULL;
341 if (addr != NULL) {
342 curaddr->addr = dup_sockaddr(addr);
343 if (curaddr->addr == NULL) {
344 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
345 "malloc: %s", pcap_strerror(errno));
346 free(curaddr);
347 return (-1);
348 }
349 } else
350 curaddr->addr = NULL;
351
352 if (netmask != NULL) {
353 curaddr->netmask = dup_sockaddr(netmask);
354 if (curaddr->netmask == NULL) {
355 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
356 "malloc: %s", pcap_strerror(errno));
357 free(curaddr);
358 return (-1);
359 }
360 } else
361 curaddr->netmask = NULL;
362
363 if (broadaddr != NULL) {
364 curaddr->broadaddr = dup_sockaddr(broadaddr);
365 if (curaddr->broadaddr == NULL) {
366 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
367 "malloc: %s", pcap_strerror(errno));
368 free(curaddr);
369 return (-1);
370 }
371 } else
372 curaddr->broadaddr = NULL;
373
374 if (dstaddr != NULL) {
375 curaddr->dstaddr = dup_sockaddr(dstaddr);
376 if (curaddr->dstaddr == NULL) {
377 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
378 "malloc: %s", pcap_strerror(errno));
379 free(curaddr);
380 return (-1);
381 }
382 } else
383 curaddr->dstaddr = NULL;
384
385 /*
386 * Find the end of the list of addresses.
387 */
388 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
389 nextaddr = prevaddr->next;
390 if (nextaddr == NULL) {
391 /*
392 * This is the end of the list.
393 */
394 break;
395 }
396 }
397
398 if (prevaddr == NULL) {
399 /*
400 * The list was empty; this is the first member.
401 */
402 curdev->addresses = curaddr;
403 } else {
404 /*
405 * "prevaddr" is the last member of the list; append
406 * this member to it.
407 */
408 prevaddr->next = curaddr;
409 }
410
411 return (0);
412 }
413
414 static int
415 pcap_add_if(pcap_if_t **devlist, char *name, u_int flags, char *errbuf)
416 {
417 pcap_if_t *curdev;
418
419 return (add_or_find_if(&curdev, devlist, name, flags, errbuf));
420 }
421
422 /*
423 * Get a list of all interfaces that are up and that we can open.
424 * Returns -1 on error, 0 otherwise.
425 * The list, as returned through "alldevsp", may be null if no interfaces
426 * were up and could be opened.
427 */
428 #ifdef HAVE_IFADDRS_H
429 int
430 pcap_findalldevs(alldevsp, errbuf)
431 pcap_if_t **alldevsp;
432 register char *errbuf;
433 {
434 pcap_if_t *devlist = NULL;
435 struct ifaddrs *ifap, *ifa;
436 struct sockaddr *broadaddr, *dstaddr;
437 int ret = 0;
438
439 /*
440 * Get the list of interface addresses.
441 *
442 * Note: this won't return information about interfaces
443 * with no addresses; are there any such interfaces
444 * that would be capable of receiving packets?
445 * (Interfaces incapable of receiving packets aren't
446 * very interesting from libpcap's point of view.)
447 *
448 * LAN interfaces will probably have link-layer
449 * addresses; I don't know whether all implementations
450 * of "getifaddrs()" now, or in the future, will return
451 * those.
452 */
453 if (getifaddrs(&ifap) != 0) {
454 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
455 "getifaddrs: %s", pcap_strerror(errno));
456 return (-1);
457 }
458 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
459 /*
460 * Is this interface up?
461 */
462 if (!(ifa->ifa_flags & IFF_UP)) {
463 /*
464 * No, so don't add it to the list.
465 */
466 continue;
467 }
468
469 /*
470 * "ifa_broadaddr" may be non-null even on
471 * non-broadcast interfaces; "ifa_dstaddr"
472 * was, on at least one FreeBSD 4.1 system,
473 * non-null on a non-point-to-point
474 * interface.
475 */
476 if (ifa->ifa_flags & IFF_BROADCAST)
477 broadaddr = ifa->ifa_broadaddr;
478 else
479 broadaddr = NULL;
480 if (ifa->ifa_flags & IFF_POINTOPOINT)
481 dstaddr = ifa->ifa_dstaddr;
482 else
483 dstaddr = NULL;
484
485 /*
486 * Add information for this address to the list.
487 */
488 if (add_addr_to_iflist(&devlist, ifa->ifa_name,
489 ifa->ifa_flags, ifa->ifa_addr, ifa->ifa_netmask,
490 broadaddr, dstaddr, errbuf) < 0) {
491 ret = -1;
492 break;
493 }
494 }
495
496 freeifaddrs(ifap);
497
498 if (ret != -1) {
499 /*
500 * We haven't had any errors yet; add the "any" device,
501 * if we can open it.
502 */
503 if (pcap_add_if(&devlist, "any", 0, errbuf) < 0)
504 ret = -1;
505 }
506
507 if (ret == -1) {
508 /*
509 * We had an error; free the list we've been constructing.
510 */
511 if (devlist != NULL) {
512 pcap_freealldevs(devlist);
513 devlist = NULL;
514 }
515 }
516
517 *alldevsp = devlist;
518 return (ret);
519 }
520 #else /* HAVE_IFADDRS_H */
521 int
522 pcap_findalldevs(alldevsp, errbuf)
523 pcap_if_t **alldevsp;
524 register char *errbuf;
525 {
526 pcap_if_t *devlist = NULL;
527 register int fd;
528 register struct ifreq *ifrp, *ifend, *ifnext;
529 int n;
530 struct ifconf ifc;
531 char *buf = NULL;
532 unsigned buf_size;
533 struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
534 struct sockaddr *netmask, *broadaddr, *dstaddr;
535 #ifdef HAVE_PROC_NET_DEV
536 FILE *proc_net_f;
537 char linebuf[512];
538 int i;
539 unsigned char *p;
540 char name[512]; /* XXX - pick a size */
541 char *q, *saveq;
542 #endif
543 int ret = 0;
544
545 /*
546 * Create a socket from which to fetch the list of interfaces.
547 *
548 * XXX - on Linux, SIOCGIFCONF reports only interfaces with
549 * IPv4 addresses; you need to read "/proc/net/dev" to get
550 * the names of all the interfaces.
551 */
552 fd = socket(AF_INET, SOCK_DGRAM, 0);
553 if (fd < 0) {
554 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
555 "socket: %s", pcap_strerror(errno));
556 return (-1);
557 }
558
559 /*
560 * Start with an 8K buffer, and keep growing the buffer until
561 * we get the entire interface list or fail to get it for some
562 * reason other than EINVAL (which is presumed here to mean
563 * "buffer is too small").
564 */
565 buf_size = 8192;
566 for (;;) {
567 buf = malloc(buf_size);
568 if (buf == NULL) {
569 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
570 "malloc: %s", pcap_strerror(errno));
571 (void)close(fd);
572 return (-1);
573 }
574
575 ifc.ifc_len = buf_size;
576 ifc.ifc_buf = buf;
577 memset(buf, 0, buf_size);
578 if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0
579 && errno != EINVAL) {
580 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
581 "SIOCGIFCONF: %s", pcap_strerror(errno));
582 (void)close(fd);
583 free(buf);
584 return (-1);
585 }
586 if (ifc.ifc_len < buf_size)
587 break;
588 free(buf);
589 buf_size *= 2;
590 }
591
592 ifrp = (struct ifreq *)buf;
593 ifend = (struct ifreq *)(buf + ifc.ifc_len);
594
595 for (; ifrp < ifend; ifrp = ifnext) {
596 n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name);
597 if (n < sizeof(*ifrp))
598 ifnext = ifrp + 1;
599 else
600 ifnext = (struct ifreq *)((char *)ifrp + n);
601
602 /*
603 * Get the flags for this interface, and skip it if it's
604 * not up.
605 */
606 strncpy(ifrflags.ifr_name, ifrp->ifr_name,
607 sizeof(ifrflags.ifr_name));
608 if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
609 if (errno == ENXIO)
610 continue;
611 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
612 "SIOCGIFFLAGS: %.*s: %s",
613 (int)sizeof(ifrflags.ifr_name),
614 ifrflags.ifr_name,
615 pcap_strerror(errno));
616 ret = -1;
617 break;
618 }
619 if (!(ifrflags.ifr_flags & IFF_UP))
620 continue;
621
622 /*
623 * Get the netmask for this address on this interface.
624 */
625 strncpy(ifrnetmask.ifr_name, ifrp->ifr_name,
626 sizeof(ifrnetmask.ifr_name));
627 memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr,
628 sizeof(ifrnetmask.ifr_addr));
629 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) {
630 if (errno == EADDRNOTAVAIL) {
631 /*
632 * Not available.
633 */
634 netmask = NULL;
635 } else {
636 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
637 "SIOCGIFNETMASK: %.*s: %s",
638 (int)sizeof(ifrnetmask.ifr_name),
639 ifrnetmask.ifr_name,
640 pcap_strerror(errno));
641 ret = -1;
642 break;
643 }
644 } else
645 netmask = &ifrnetmask.ifr_addr;
646
647 /*
648 * Get the broadcast address for this address on this
649 * interface (if any).
650 */
651 if (ifrflags.ifr_flags & IFF_BROADCAST) {
652 strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name,
653 sizeof(ifrbroadaddr.ifr_name));
654 memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr,
655 sizeof(ifrbroadaddr.ifr_addr));
656 if (ioctl(fd, SIOCGIFBRDADDR,
657 (char *)&ifrbroadaddr) < 0) {
658 if (errno == EADDRNOTAVAIL) {
659 /*
660 * Not available.
661 */
662 broadaddr = NULL;
663 } else {
664 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
665 "SIOCGIFBRDADDR: %.*s: %s",
666 (int)sizeof(ifrbroadaddr.ifr_name),
667 ifrbroadaddr.ifr_name,
668 pcap_strerror(errno));
669 ret = -1;
670 break;
671 }
672 } else
673 broadaddr = &ifrbroadaddr.ifr_broadaddr;
674 } else {
675 /*
676 * Not a broadcast interface, so no broadcast
677 * address.
678 */
679 broadaddr = NULL;
680 }
681
682 /*
683 * Get the destination address for this address on this
684 * interface (if any).
685 */
686 if (ifrflags.ifr_flags & IFF_POINTOPOINT) {
687 strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name,
688 sizeof(ifrdstaddr.ifr_name));
689 memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr,
690 sizeof(ifrdstaddr.ifr_addr));
691 if (ioctl(fd, SIOCGIFDSTADDR,
692 (char *)&ifrdstaddr) < 0) {
693 if (errno == EADDRNOTAVAIL) {
694 /*
695 * Not available.
696 */
697 dstaddr = NULL;
698 } else {
699 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
700 "SIOCGIFDSTADDR: %.*s: %s",
701 (int)sizeof(ifrdstaddr.ifr_name),
702 ifrdstaddr.ifr_name,
703 pcap_strerror(errno));
704 ret = -1;
705 break;
706 }
707 } else
708 dstaddr = &ifrdstaddr.ifr_dstaddr;
709 } else
710 dstaddr = NULL;
711
712 /*
713 * Add information for this address to the list.
714 */
715 if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
716 ifrflags.ifr_flags, &ifrp->ifr_addr,
717 netmask, broadaddr, dstaddr, errbuf) < 0) {
718 ret = -1;
719 break;
720 }
721 }
722 free(buf);
723
724 #ifdef HAVE_PROC_NET_DEV
725 /*
726 * OK, now read "/proc/net/dev", and add to the list of
727 * interfaces all interfaces listed there that we don't
728 * already have.
729 *
730 * We don't bother getting any addresses for them;
731 * it appears you can't use SIOCGIFADDR to get
732 * IPv6 addresses for interfaces, and, although some
733 * other types of addresses can be fetched with
734 * SIOCGIFADDR, we don't bother with them for now.
735 *
736 * We also don't fail if we couldn't open "/proc/net/dev";
737 * we just return the interfaces we've already found.
738 */
739 proc_net_f = fopen("/proc/net/dev", "r");
740 if (proc_net_f != NULL) {
741 /*
742 * Skip the first two lines - they're headers.
743 */
744 for (i = 0; i < 2; i++) {
745 if (fgets(linebuf, sizeof linebuf, proc_net_f) == NULL) {
746 if (ferror(proc_net_f)) {
747 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
748 "Error reading /proc/net/dev: %s",
749 pcap_strerror(errno));
750 } else {
751 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
752 "EOF reading header line %d of /proc/net/dev: %s",
753 i + 1, pcap_strerror(errno));
754 }
755 ret = -1;
756 break;
757 }
758 }
759
760 /*
761 * Now read the rest of the lines.
762 */
763 while (ret != -1 &&
764 fgets(linebuf, sizeof linebuf, proc_net_f) != NULL) {
765 p = &linebuf[0];
766
767 /*
768 * Skip leading white space.
769 */
770 while (*p != '\0' && isspace(*p))
771 p++;
772 if (*p == '\0' || *p == '\n')
773 continue; /* blank line */
774
775 /*
776 * Get the interface name.
777 */
778 q = &name[0];
779 while (*p != '\0' && !isspace(*p)) {
780 if (*p == ':') {
781 /*
782 * This could be the separator
783 * between a name and an alias
784 * number, or it could be the
785 * separator between a name with
786 * no alias number and the next
787 * field.
788 * If there's a colon after digits,
789 * it separates the name and the alias
790 * number, otherwise it separates the
791 * name and the next field.
792 */
793 saveq = q;
794 while (isdigit(*p))
795 *q++ = *p++;
796 if (*p != ':') {
797 /*
798 * That was the next field,
799 * not the alias number.
800 */
801 q = saveq;
802 }
803 break;
804 } else
805 *q++ = *p++;
806 }
807 *q = '\0';
808
809 /*
810 * Get the flags for this interface, and skip it if
811 * it's not up.
812 */
813 strncpy(ifrflags.ifr_name, name,
814 sizeof(ifrflags.ifr_name));
815 if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
816 if (errno == ENXIO)
817 continue;
818 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
819 "SIOCGIFFLAGS: %.*s: %s",
820 (int)sizeof(ifrflags.ifr_name),
821 ifrflags.ifr_name,
822 pcap_strerror(errno));
823 ret = -1;
824 break;
825 }
826 if (!(ifrflags.ifr_flags & IFF_UP))
827 continue;
828
829 /*
830 * Add an entry for this interface, with no addresses.
831 */
832 if (pcap_add_if(&devlist, name, ifrflags.ifr_flags,
833 errbuf) == -1) {
834 /*
835 * Failure.
836 */
837 ret = -1;
838 break;
839 }
840 }
841 (void)fclose(proc_net_f);
842 }
843 #endif
844
845 (void)close(fd);
846
847 if (ret != -1) {
848 /*
849 * We haven't had any errors yet; add the "any" device,
850 * if we can open it.
851 */
852 if (pcap_add_if(&devlist, "any", 0, errbuf) < 0) {
853 /*
854 * Oops, we had a fatal error.
855 */
856 ret = -1;
857 }
858 }
859
860 if (ret == -1) {
861 /*
862 * We had an error; free the list we've been constructing.
863 */
864 if (devlist != NULL) {
865 pcap_freealldevs(devlist);
866 devlist = NULL;
867 }
868 }
869
870 *alldevsp = devlist;
871 return (ret);
872 }
873 #endif /* HAVE_IFADDRS_H */
874
875 /*
876 * Free a list of interfaces.
877 */
878 void
879 pcap_freealldevs(pcap_if_t *alldevs)
880 {
881 pcap_if_t *curdev, *nextdev;
882 pcap_addr_t *curaddr, *nextaddr;
883
884 for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
885 nextdev = curdev->next;
886
887 /*
888 * Free all addresses.
889 */
890 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
891 nextaddr = curaddr->next;
892 if (curaddr->addr)
893 free(curaddr->addr);
894 if (curaddr->netmask)
895 free(curaddr->netmask);
896 if (curaddr->broadaddr)
897 free(curaddr->broadaddr);
898 if (curaddr->dstaddr)
899 free(curaddr->dstaddr);
900 free(curaddr);
901 }
902
903 /*
904 * Free the name string.
905 */
906 free(curdev->name);
907
908 /*
909 * Free the description string, if any.
910 */
911 if (curdev->description != NULL)
912 free(curdev->description);
913
914 /*
915 * Free the interface.
916 */
917 free(curdev);
918 }
919 }
920
921 /*
922 * Return the name of a network interface attached to the system, or NULL
923 * if none can be found. The interface must be configured up; the
924 * lowest unit number is preferred; loopback is ignored.
925 */
926 char *
927 pcap_lookupdev(errbuf)
928 register char *errbuf;
929 {
930 pcap_if_t *alldevs;
931 /* for old BSD systems, including bsdi3 */
932 #ifndef IF_NAMESIZE
933 #define IF_NAMESIZE IFNAMSIZ
934 #endif
935 static char device[IF_NAMESIZE + 1];
936 char *ret;
937
938 if (pcap_findalldevs(&alldevs, errbuf) == -1)
939 return (NULL);
940
941 if (alldevs == NULL || alldevs->is_loopback) {
942 /*
943 * There are no devices on the list, or the first device
944 * on the list is a loopback device, which means there
945 * are no non-loopback devices on the list. This means
946 * we can't return any device.
947 *
948 * XXX - why not return a loopback device? If we can't
949 * capture on it, it won't be on the list, and if it's
950 * on the list, there aren't any non-loopback devices,
951 * so why not just supply it as the default device?
952 */
953 (void)strlcpy(errbuf, "no suitable device found",
954 PCAP_ERRBUF_SIZE);
955 ret = NULL;
956 } else {
957 /*
958 * Return the name of the first device on the list.
959 */
960 (void)strlcpy(device, alldevs->name, sizeof(device));
961 ret = device;
962 }
963
964 pcap_freealldevs(alldevs);
965 return (ret);
966 }
967
968 int
969 pcap_lookupnet(device, netp, maskp, errbuf)
970 register char *device;
971 register bpf_u_int32 *netp, *maskp;
972 register char *errbuf;
973 {
974 register int fd;
975 register struct sockaddr_in *sin;
976 struct ifreq ifr;
977
978 /*
979 * The pseudo-device "any" listens on all interfaces and therefore
980 * has the network address and -mask "0.0.0.0" therefore catching
981 * all traffic. Using NULL for the interface is the same as "any".
982 */
983 if (!device || strcmp(device, "any") == 0) {
984 *netp = *maskp = 0;
985 return 0;
986 }
987
988 fd = socket(AF_INET, SOCK_DGRAM, 0);
989 if (fd < 0) {
990 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
991 pcap_strerror(errno));
992 return (-1);
993 }
994 memset(&ifr, 0, sizeof(ifr));
995 #ifdef linux
996 /* XXX Work around Linux kernel bug */
997 ifr.ifr_addr.sa_family = AF_INET;
998 #endif
999 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
1000 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
1001 if (errno == EADDRNOTAVAIL) {
1002 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
1003 "%s: no IPv4 address assigned", device);
1004 } else {
1005 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
1006 "SIOCGIFADDR: %s: %s",
1007 device, pcap_strerror(errno));
1008 }
1009 (void)close(fd);
1010 return (-1);
1011 }
1012 sin = (struct sockaddr_in *)&ifr.ifr_addr;
1013 *netp = sin->sin_addr.s_addr;
1014 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
1015 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
1016 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
1017 (void)close(fd);
1018 return (-1);
1019 }
1020 (void)close(fd);
1021 *maskp = sin->sin_addr.s_addr;
1022 if (*maskp == 0) {
1023 if (IN_CLASSA(*netp))
1024 *maskp = IN_CLASSA_NET;
1025 else if (IN_CLASSB(*netp))
1026 *maskp = IN_CLASSB_NET;
1027 else if (IN_CLASSC(*netp))
1028 *maskp = IN_CLASSC_NET;
1029 else {
1030 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
1031 "inet class for 0x%x unknown", *netp);
1032 return (-1);
1033 }
1034 }
1035 *netp &= *maskp;
1036 return (0);
1037 }