dect
/
libpcap
Archived
13
0
Fork 0

If we have "/proc/net/dev", and don't have <ifaddrs.h> (i.e., don't have

"getifaddrs()"), after processing the list returned by SIOCGIFCONF, scan
"/proc/net/dev" for interface names, and add to the list of interfaces
entries for those interfaces, with no associated addresses (if the
interfaces were already added, with addresses, from the list returned by
SIOCGIFCONF, they won't get added again).

Clean up the error handling a bit.
This commit is contained in:
guy 2001-10-09 05:43:19 +00:00
parent 5a85948f80
commit 519b0b5a59
4 changed files with 217 additions and 73 deletions

View File

@ -66,6 +66,9 @@
/* if if_packet.h has tpacket_stats defined */
#undef HAVE_TPACKET_STATS
/* define if you have a /proc/net/dev */
#undef HAVE_PROC_NET_DEV
/* define on AIX to get certain functions */
#undef _SUN

49
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# From configure.in Revision: 1.90
# From configure.in Revision: 1.91
@ -1750,6 +1750,21 @@ null)
esac
echo $ac_n "checking whether we have /proc/net/dev""... $ac_c" 1>&6
echo "configure:1755: checking whether we have /proc/net/dev" >&5
if test -r /proc/net/dev ; then
ac_cv_lbl_proc_net_dev=yes
else
ac_cv_lbl_proc_net_dev=no
fi
if test $ac_cv_lbl_proc_net_dev = yes; then
cat >> confdefs.h <<\EOF
#define HAVE_PROC_NET_DEV 1
EOF
fi
echo "$ac_t""$ac_cv_lbl_proc_net_dev" 1>&6
# Check whether --with-flex or --without-flex was given.
if test "${with_flex+set}" = set; then
withval="$with_flex"
@ -1770,7 +1785,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1774: checking for $ac_word" >&5
echo "configure:1789: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_V_LEX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1804,7 +1819,7 @@ test -n "$V_LEX" || V_LEX="lex"
if test "$V_LEX" = flex ; then
# The -V flag was added in 2.4
echo $ac_n "checking for flex 2.4 or higher""... $ac_c" 1>&6
echo "configure:1808: checking for flex 2.4 or higher" >&5
echo "configure:1823: checking for flex 2.4 or higher" >&5
if eval "test \"`echo '$''{'ac_cv_lbl_flex_v24'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1830,7 +1845,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1834: checking for $ac_word" >&5
echo "configure:1849: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_V_YACC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1877,7 +1892,7 @@ if test "$V_LEX" = lex ; then
# Some versions of lex can't handle the definitions section of scanner.l .
# Try lexing it and complain if it can't deal.
echo $ac_n "checking for capable lex""... $ac_c" 1>&6
echo "configure:1881: checking for capable lex" >&5
echo "configure:1896: checking for capable lex" >&5
if eval "test \"`echo '$''{'tcpdump_cv_capable_lex'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -1928,19 +1943,19 @@ EOF
sinix*)
echo $ac_n "checking if SINIX compiler defines sinix""... $ac_c" 1>&6
echo "configure:1932: checking if SINIX compiler defines sinix" >&5
echo "configure:1947: checking if SINIX compiler defines sinix" >&5
if eval "test \"`echo '$''{'ac_cv_cc_sinix_defined'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1937 "configure"
#line 1952 "configure"
#include "confdefs.h"
int main() {
int i = sinix;
; return 0; }
EOF
if { (eval echo configure:1944: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:1959: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_cc_sinix_defined=yes
else
@ -1972,7 +1987,7 @@ esac
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1976: checking for $ac_word" >&5
echo "configure:1991: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2040,12 +2055,12 @@ EOF
fi
echo $ac_n "checking if sockaddr struct has sa_len member""... $ac_c" 1>&6
echo "configure:2044: checking if sockaddr struct has sa_len member" >&5
echo "configure:2059: checking if sockaddr struct has sa_len member" >&5
if eval "test \"`echo '$''{'ac_cv_lbl_sockaddr_has_sa_len'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2049 "configure"
#line 2064 "configure"
#include "confdefs.h"
# include <sys/types.h>
@ -2054,7 +2069,7 @@ int main() {
u_int i = sizeof(((struct sockaddr *)0)->sa_len)
; return 0; }
EOF
if { (eval echo configure:2058: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:2073: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_lbl_sockaddr_has_sa_len=yes
else
@ -2075,12 +2090,12 @@ EOF
fi
echo $ac_n "checking if dl_hp_ppa_info_t struct has dl_module_id_1 member""... $ac_c" 1>&6
echo "configure:2079: checking if dl_hp_ppa_info_t struct has dl_module_id_1 member" >&5
echo "configure:2094: checking if dl_hp_ppa_info_t struct has dl_module_id_1 member" >&5
if eval "test \"`echo '$''{'ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2084 "configure"
#line 2099 "configure"
#include "confdefs.h"
# include <sys/types.h>
@ -2090,7 +2105,7 @@ int main() {
u_int i = sizeof(((dl_hp_ppa_info_t *)0)->dl_module_id_1)
; return 0; }
EOF
if { (eval echo configure:2094: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
if { (eval echo configure:2109: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_lbl_dl_hp_ppa_info_t_has_dl_module_id_1=yes
else
@ -2111,7 +2126,7 @@ EOF
fi
echo $ac_n "checking if unaligned accesses fail""... $ac_c" 1>&6
echo "configure:2115: checking if unaligned accesses fail" >&5
echo "configure:2130: checking if unaligned accesses fail" >&5
if eval "test \"`echo '$''{'ac_cv_lbl_unaligned_fail'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@ -2196,7 +2211,7 @@ ln -s ${srcdir}/bpf/net net
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:2200: checking for a BSD compatible install" >&5
echo "configure:2215: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6

View File

@ -1,4 +1,4 @@
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.90 2001-10-09 03:53:38 guy Exp $ (LBL)
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.91 2001-10-09 05:43:20 guy Exp $ (LBL)
dnl
dnl Copyright (c) 1994, 1995, 1996, 1997
dnl The Regents of the University of California. All rights reserved.
@ -6,7 +6,7 @@ dnl
dnl Process this file with autoconf to produce a configure script.
dnl
AC_REVISION($Revision: 1.90 $)
AC_REVISION($Revision: 1.91 $)
AC_INIT(pcap.c)
AC_CANONICAL_SYSTEM
@ -142,6 +142,17 @@ null)
esac
AC_MSG_CHECKING(whether we have /proc/net/dev)
if test -r /proc/net/dev ; then
ac_cv_lbl_proc_net_dev=yes
else
ac_cv_lbl_proc_net_dev=no
fi
if test $ac_cv_lbl_proc_net_dev = yes; then
AC_DEFINE(HAVE_PROC_NET_DEV, 1, [define if you have a /proc/net/dev])
fi
AC_MSG_RESULT($ac_cv_lbl_proc_net_dev)
AC_LBL_LEX_AND_YACC(V_LEX, V_YACC, pcap_)
if test "$V_LEX" = lex ; then
# Some versions of lex can't handle the definitions section of scanner.l .

223
inet.c
View File

@ -34,7 +34,7 @@
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.40 2001-10-09 03:53:38 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.41 2001-10-09 05:43:20 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -412,11 +412,11 @@ add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
}
static int
pcap_addanydev(pcap_if_t **devlist, char *errbuf)
pcap_add_if(pcap_if_t **devlist, char *name, u_int flags, char *errbuf)
{
pcap_if_t *curdev;
return (add_or_find_if(&curdev, devlist, "any", 0, errbuf));
return (add_or_find_if(&curdev, devlist, name, flags, errbuf));
}
/*
@ -438,6 +438,17 @@ pcap_findalldevs(alldevsp, errbuf)
/*
* Get the list of interface addresses.
*
* Note: this won't return information about interfaces
* with no addresses; are there any such interfaces
* that would be capable of receiving packets?
* (Interfaces incapable of receiving packets aren't
* very interesting from libpcap's point of view.)
*
* LAN interfaces will probably have link-layer
* addresses; I don't know whether all implementations
* of "getifaddrs()" now, or in the future, will return
* those.
*/
if (getifaddrs(&ifap) != 0) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
@ -477,14 +488,6 @@ pcap_findalldevs(alldevsp, errbuf)
if (add_addr_to_iflist(&devlist, ifa->ifa_name,
ifa->ifa_flags, ifa->ifa_addr, ifa->ifa_netmask,
broadaddr, dstaddr, errbuf) < 0) {
/*
* Oops, we had a fatal error.
* Free the list we've been constructing, and fail.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
ret = -1;
break;
}
@ -497,16 +500,17 @@ pcap_findalldevs(alldevsp, errbuf)
* We haven't had any errors yet; add the "any" device,
* if we can open it.
*/
if (pcap_addanydev(&devlist, errbuf) < 0) {
/*
* Oops, we had a fatal error.
* Free the list we've been constructing, and fail.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
return (-1);
if (pcap_add_if(&devlist, "any", 0, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}
@ -528,6 +532,14 @@ pcap_findalldevs(alldevsp, errbuf)
unsigned buf_size;
struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
struct sockaddr *netmask, *broadaddr, *dstaddr;
#ifdef HAVE_PROC_NET_DEV
FILE *proc_net_f;
char linebuf[512];
int i;
unsigned char *p;
char name[512]; /* XXX - pick a size */
char *q, *saveq;
#endif
int ret = 0;
/*
@ -556,6 +568,7 @@ pcap_findalldevs(alldevsp, errbuf)
if (buf == NULL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
(void)close(fd);
return (-1);
}
@ -566,7 +579,7 @@ pcap_findalldevs(alldevsp, errbuf)
&& errno != EINVAL) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFCONF: %s", pcap_strerror(errno));
close(fd);
(void)close(fd);
free(buf);
return (-1);
}
@ -600,10 +613,6 @@ pcap_findalldevs(alldevsp, errbuf)
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
ret = -1;
break;
}
@ -629,10 +638,6 @@ pcap_findalldevs(alldevsp, errbuf)
(int)sizeof(ifrnetmask.ifr_name),
ifrnetmask.ifr_name,
pcap_strerror(errno));
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
ret = -1;
break;
}
@ -661,10 +666,6 @@ pcap_findalldevs(alldevsp, errbuf)
(int)sizeof(ifrbroadaddr.ifr_name),
ifrbroadaddr.ifr_name,
pcap_strerror(errno));
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
ret = -1;
break;
}
@ -700,10 +701,6 @@ pcap_findalldevs(alldevsp, errbuf)
(int)sizeof(ifrdstaddr.ifr_name),
ifrdstaddr.ifr_name,
pcap_strerror(errno));
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
ret = -1;
break;
}
@ -718,37 +715,155 @@ pcap_findalldevs(alldevsp, errbuf)
if (add_addr_to_iflist(&devlist, ifrp->ifr_name,
ifrflags.ifr_flags, &ifrp->ifr_addr,
netmask, broadaddr, dstaddr, errbuf) < 0) {
/*
* Oops, we had a fatal error.
* Free the list we've been constructing, and fail.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
ret = -1;
break;
}
}
free(buf);
#ifdef HAVE_PROC_NET_DEV
/*
* OK, now read "/proc/net/dev", and add to the list of
* interfaces all interfaces listed there that we don't
* already have.
*
* We don't bother getting any addresses for them;
* it appears you can't use SIOCGIFADDR to get
* IPv6 addresses for interfaces, and, although some
* other types of addresses can be fetched with
* SIOCGIFADDR, we don't bother with them for now.
*
* We also don't fail if we couldn't open "/proc/net/dev";
* we just return the interfaces we've already found.
*/
proc_net_f = fopen("/proc/net/dev", "r");
if (proc_net_f != NULL) {
/*
* Skip the first two lines - they're headers.
*/
for (i = 0; i < 2; i++) {
if (fgets(linebuf, sizeof linebuf, proc_net_f) == NULL) {
if (ferror(proc_net_f)) {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"Error reading /proc/net/dev: %s",
pcap_strerror(errno));
} else {
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"EOF reading header line %d of /proc/net/dev: %s",
i + 1, pcap_strerror(errno));
}
ret = -1;
break;
}
}
/*
* Now read the rest of the lines.
*/
while (ret != -1 &&
fgets(linebuf, sizeof linebuf, proc_net_f) != NULL) {
p = &linebuf[0];
/*
* Skip leading white space.
*/
while (*p != '\0' && isspace(*p))
p++;
if (*p == '\0' || *p == '\n')
continue; /* blank line */
/*
* Get the interface name.
*/
q = &name[0];
while (*p != '\0' && !isspace(*p)) {
if (*p == ':') {
/*
* This could be the separator
* between a name and an alias
* number, or it could be the
* separator between a name with
* no alias number and the next
* field.
* If there's a colon after digits,
* it separates the name and the alias
* number, otherwise it separates the
* name and the next field.
*/
saveq = q;
while (isdigit(*p))
*q++ = *p++;
if (*p != ':') {
/*
* That was the next field,
* not the alias number.
*/
q = saveq;
}
break;
} else
*q++ = *p++;
}
*q = '\0';
/*
* Get the flags for this interface, and skip it if
* it's not up.
*/
strncpy(ifrflags.ifr_name, name,
sizeof(ifrflags.ifr_name));
if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
if (errno == ENXIO)
continue;
(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
"SIOCGIFFLAGS: %.*s: %s",
(int)sizeof(ifrflags.ifr_name),
ifrflags.ifr_name,
pcap_strerror(errno));
ret = -1;
break;
}
if (!(ifrflags.ifr_flags & IFF_UP))
continue;
/*
* Add an entry for this interface, with no addresses.
*/
if (pcap_add_if(&devlist, name, ifrflags.ifr_flags,
errbuf) == -1) {
/*
* Failure.
*/
ret = -1;
break;
}
}
(void)fclose(proc_net_f);
}
#endif
(void)close(fd);
free(buf);
if (ret != -1) {
/*
* We haven't had any errors yet; add the "any" device,
* if we can open it.
*/
if (pcap_addanydev(&devlist, errbuf) < 0) {
if (pcap_add_if(&devlist, "any", 0, errbuf) < 0) {
/*
* Oops, we had a fatal error.
* Free the list we've been constructing, and fail.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
return (-1);
ret = -1;
}
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.
*/
if (devlist != NULL) {
pcap_freealldevs(devlist);
devlist = NULL;
}
}