dect
/
libpcap
Archived
10
0
Fork 0

Add some PCAP_WARNING return values for "success, but you might want to

know that..."; currently, only pcap_activate() returns them, but we
might want some more warning returns for some other calls, such as the
ones that set filters.  It's a little cleaner than "clear out the error
message buffer and, if it's not empty after a successful return, it has
a warning", and a little cleaner than spewing a warning to the standard
error (as that might not be visible to the user if they're running a GUI
application).
master
guy 15 years ago
parent 0bee352573
commit a590c21380
  1. 57
      pcap-bpf.c
  2. 42
      pcap-dlpi.c
  3. 19
      pcap-linux.c
  4. 10
      pcap.c
  5. 17
      pcap/pcap.h
  6. 23
      pcap_activate.3pcap

@ -20,7 +20,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.107 2008-04-09 19:58:02 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.108 2008-04-09 21:26:12 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -1028,7 +1028,7 @@ check_setif_failure(pcap_t *p, int error)
static int
pcap_activate_bpf(pcap_t *p)
{
int err;
int status = 0;
int fd;
struct ifreq ifr;
struct bpf_version bv;
@ -1053,7 +1053,7 @@ pcap_activate_bpf(pcap_t *p)
fd = bpf_open(p);
if (fd < 0) {
err = fd;
status = fd;
goto bad;
}
@ -1062,14 +1062,14 @@ pcap_activate_bpf(pcap_t *p)
if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
if (bv.bv_major != BPF_MAJOR_VERSION ||
bv.bv_minor < BPF_MINOR_VERSION) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"kernel bpf filter out of date");
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
@ -1102,7 +1102,7 @@ pcap_activate_bpf(pcap_t *p)
/*
* 10.3 (Darwin 7.x) or earlier.
*/
err = PCAP_ERROR_RFMON_NOTSUP;
status = PCAP_ERROR_RFMON_NOTSUP;
goto bad;
}
if (osinfo.release[0] == '8' &&
@ -1129,10 +1129,10 @@ pcap_activate_bpf(pcap_t *p)
* device doesn't
* exist.
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
status = PCAP_ERROR_NO_SUCH_DEVICE;
strcpy(p->errbuf, "");
} else
err = PCAP_ERROR_RFMON_NOTSUP;
status = PCAP_ERROR_RFMON_NOTSUP;
close(sockfd);
} else {
/*
@ -1140,7 +1140,7 @@ pcap_activate_bpf(pcap_t *p)
* the device exists, so just
* report "no such device".
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
status = PCAP_ERROR_NO_SUCH_DEVICE;
strcpy(p->errbuf, "");
}
goto bad;
@ -1150,7 +1150,7 @@ pcap_activate_bpf(pcap_t *p)
(void)snprintf(p->errbuf,
PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
strcpy(wltdev, "wlt");
@ -1177,7 +1177,7 @@ pcap_activate_bpf(pcap_t *p)
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSBLEN: %s: %s", p->opt.source,
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
@ -1187,7 +1187,7 @@ pcap_activate_bpf(pcap_t *p)
(void)strncpy(ifr.ifr_name, p->opt.source,
sizeof(ifr.ifr_name));
if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
err = check_setif_failure(p, errno);
status = check_setif_failure(p, errno);
goto bad;
}
} else {
@ -1217,7 +1217,7 @@ pcap_activate_bpf(pcap_t *p)
break; /* that size worked; we're done */
if (errno != ENOBUFS) {
err = check_setif_failure(p, errno);
status = check_setif_failure(p, errno);
goto bad;
}
}
@ -1226,7 +1226,7 @@ pcap_activate_bpf(pcap_t *p)
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSBLEN: %s: No buffer size worked",
p->opt.source);
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
}
@ -1235,7 +1235,7 @@ pcap_activate_bpf(pcap_t *p)
if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
@ -1268,7 +1268,7 @@ pcap_activate_bpf(pcap_t *p)
*/
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
v);
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
#endif
@ -1301,7 +1301,7 @@ pcap_activate_bpf(pcap_t *p)
* not fatal; we just don't get to use the feature later.
*/
if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) {
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
p->dlt_count = bdl.bfl_len;
@ -1386,7 +1386,7 @@ pcap_activate_bpf(pcap_t *p)
* link-layer types, so they
* can't have it.
*/
err = PCAP_ERROR_RFMON_NOTSUP;
status = PCAP_ERROR_RFMON_NOTSUP;
goto bad;
}
}
@ -1401,8 +1401,8 @@ pcap_activate_bpf(pcap_t *p)
/*
* Try to put the interface into monitor mode.
*/
err = monitor_mode(p, 1);
if (err != 0) {
status = monitor_mode(p, 1);
if (status != 0) {
/*
* We failed.
*/
@ -1479,7 +1479,7 @@ pcap_activate_bpf(pcap_t *p)
if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSHDRCMPLT: %s", pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
#endif
@ -1496,7 +1496,7 @@ pcap_activate_bpf(pcap_t *p)
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
}
@ -1553,7 +1553,7 @@ pcap_activate_bpf(pcap_t *p)
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
#endif /* BIOCIMMEDIATE */
@ -1564,13 +1564,14 @@ pcap_activate_bpf(pcap_t *p)
if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
pcap_strerror(errno));
status = PCAP_WARNING_PROMISC_NOTSUP;
}
}
if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
p->bufsize = v;
@ -1578,7 +1579,7 @@ pcap_activate_bpf(pcap_t *p)
if (p->buffer == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
#ifdef _AIX
@ -1606,7 +1607,7 @@ pcap_activate_bpf(pcap_t *p)
if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto bad;
}
@ -1668,14 +1669,14 @@ pcap_activate_bpf(pcap_t *p)
p->stats_op = pcap_stats_bpf;
p->close_op = pcap_close_bpf;
return (0);
return (status);
bad:
(void)close(fd);
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
}
return (err);
return (status);
}
int

@ -70,7 +70,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.123 2008-04-09 19:58:02 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.124 2008-04-09 21:26:12 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -342,7 +342,7 @@ pcap_activate_dlpi(pcap_t *p)
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
int err = PCAP_ERROR;
int status = PCAP_ERROR;
p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1;
@ -363,7 +363,7 @@ pcap_activate_dlpi(pcap_t *p)
*/
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
err = PCAP_ERROR_NO_SUCH_DEVICE;
status = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
}
*cp = '\0';
@ -382,7 +382,7 @@ pcap_activate_dlpi(pcap_t *p)
cp = "/dev/dlpi";
if ((p->fd = open(cp, O_RDWR)) < 0) {
if (errno == EPERM || errno == EACCES)
err = PCAP_ERROR_PERM_DENIED;
status = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: %s", cp, pcap_strerror(errno));
goto bad;
@ -409,7 +409,7 @@ pcap_activate_dlpi(pcap_t *p)
*/
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
if (ppa < 0) {
err = ppa;
status = ppa;
goto bad;
}
#else
@ -431,7 +431,7 @@ pcap_activate_dlpi(pcap_t *p)
*/
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
err = PCAP_ERROR_NO_SUCH_DEVICE;
status = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
}
@ -453,7 +453,7 @@ pcap_activate_dlpi(pcap_t *p)
/* Try again with unit number */
if ((p->fd = open(dname2, O_RDWR)) < 0) {
if (errno == ENOENT) {
err = PCAP_ERROR_NO_SUCH_DEVICE;
status = PCAP_ERROR_NO_SUCH_DEVICE;
/*
* We provide an error message even
@ -480,7 +480,7 @@ pcap_activate_dlpi(pcap_t *p)
"%s: No DLPI device found", p->opt.source);
} else {
if (errno == EACCES)
err = PCAP_ERROR_PERM_DENIED;
status = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
}
@ -503,8 +503,8 @@ pcap_activate_dlpi(pcap_t *p)
isatm = 1;
#endif
if (infop->dl_provider_style == DL_STYLE2) {
err = dl_doattach(p->fd, ppa, p->errbuf);
if (err < 0)
status = dl_doattach(p->fd, ppa, p->errbuf);
if (status < 0)
goto bad;
#ifdef DL_HP_RAWDLS
if (p->send_fd >= 0) {
@ -519,7 +519,7 @@ pcap_activate_dlpi(pcap_t *p)
* This device exists, but we don't support monitor mode
* any platforms that support DLPI.
*/
err = PCAP_ERROR_RFMON_NOTSUP;
status = PCAP_ERROR_RFMON_NOTSUP;
goto bad;
}
@ -615,9 +615,7 @@ pcap_activate_dlpi(pcap_t *p)
#if !defined(__hpux) && !defined(sinix)
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
fprintf(stderr,
"WARNING: DL_PROMISC_MULTI failed (%s)\n",
p->errbuf);
status = PCAP_WARNING;
#endif
}
/*
@ -637,8 +635,7 @@ pcap_activate_dlpi(pcap_t *p)
dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
if (p->opt.promisc)
fprintf(stderr,
"WARNING: DL_PROMISC_SAP failed (%s)\n", p->errbuf);
status = PCAP_WARNING;
else
goto bad;
}
@ -706,10 +703,11 @@ pcap_activate_dlpi(pcap_t *p)
release = get_release(&osmajor, &osminor, &osmicro);
if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
getenv("BUFMOD_FIXED") == NULL) {
fprintf(stderr,
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.\n",
snprintf(p->errbuf,
"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.",
release);
ss = 0;
status = PCAP_WARNING;
}
#endif
@ -732,6 +730,10 @@ pcap_activate_dlpi(pcap_t *p)
if (pcap_alloc_databuf(p) != 0)
goto bad;
/* Success - but perhaps with a warning */
if (status < 0)
status = 0;
/*
* "p->fd" is an FD for a STREAMS device, so "select()" and
* "poll()" should work on it.
@ -748,13 +750,13 @@ pcap_activate_dlpi(pcap_t *p)
p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_dlpi;
return (0);
return (status);
bad:
if (p->fd >= 0)
close(p->fd);
if (p->send_fd >= 0)
close(p->send_fd);
return (err);
return (status);
}
/*

@ -34,7 +34,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.144 2008-04-09 19:58:02 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.145 2008-04-09 21:26:12 guy Exp $ (LBL)";
#endif
/*
@ -486,7 +486,7 @@ static int
pcap_activate_linux(pcap_t *handle)
{
const char *device;
int err;
int status = 0;
int activate_ok = 0;
device = handle->opt.source;
@ -513,6 +513,7 @@ pcap_activate_linux(pcap_t *handle)
/* Just a warning. */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Promiscuous mode not supported on the \"any\" device");
status = PCAP_WARNING_PROMISC_NOTSUP;
}
} else
@ -534,7 +535,7 @@ pcap_activate_linux(pcap_t *handle)
* trying both methods with the newer method preferred.
*/
if ((err = activate_new(handle)) == 1) {
if ((status = activate_new(handle)) == 1) {
activate_ok = 1;
/*
* Try to use memory-mapped access.
@ -542,9 +543,9 @@ pcap_activate_linux(pcap_t *handle)
if (activate_mmap(handle) == 1)
return 0; /* we succeeded; nothing more to do */
}
else if (err == 0) {
else if (status == 0) {
/* Non-fatal error; try old way */
if ((err = activate_old(handle)) == 1)
if ((status = activate_old(handle)) == 1)
activate_ok = 1;
}
if (!activate_ok) {
@ -565,7 +566,7 @@ pcap_activate_linux(pcap_t *handle)
sizeof(handle->opt.buffer_size)) == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SO_RCVBUF: %s", pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto fail;
}
}
@ -576,7 +577,7 @@ pcap_activate_linux(pcap_t *handle)
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
err = PCAP_ERROR;
status = PCAP_ERROR;
goto fail;
}
@ -586,7 +587,7 @@ pcap_activate_linux(pcap_t *handle)
*/
handle->selectable_fd = handle->fd;
return 0;
return status;
fail:
close(handle->fd);
@ -594,7 +595,7 @@ fail:
free(handle->md.device);
handle->md.device = NULL;
}
return err;
return status;
}
/*

@ -33,7 +33,7 @@
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.117 2008-04-09 19:58:02 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.118 2008-04-09 21:26:12 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@ -211,12 +211,12 @@ pcap_set_buffer_size(pcap_t *p, int buffer_size)
int
pcap_activate(pcap_t *p)
{
int err;
int status;
err = p->activate_op(p);
if (err == 0)
status = p->activate_op(p);
if (status >= 0)
p->activated = 1;
return (err);
return (status);
}
pcap_t *

@ -31,7 +31,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.8 2008-04-09 19:58:02 guy Exp $ (LBL)
* @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.9 2008-04-09 21:26:12 guy Exp $ (LBL)
*/
#ifndef lib_pcap_pcap_h
@ -226,7 +226,12 @@ struct pcap_addr {
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
/* list of known error codes for pcap API */
/*
* Error codes for the pcap API.
* These will all be negative, so you can check for the success or
* failure of a call that returns these codes by checking for a
* negative value.
*/
#define PCAP_ERROR -1 /* generic error code */
#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
@ -236,6 +241,14 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
/*
* Warning codes for the pcap API.
* These will all be positive and non-zero, so they won't look like
* errors.
*/
#define PCAP_WARNING 1 /* generic warning code */
#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
char *pcap_lookupdev(char *);
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);

@ -1,4 +1,4 @@
.\" @(#) $Header: /tcpdump/master/libpcap/pcap_activate.3pcap,v 1.3 2008-04-09 20:20:17 guy Exp $
.\" @(#) $Header: /tcpdump/master/libpcap/pcap_activate.3pcap,v 1.4 2008-04-09 21:26:12 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
@ -39,7 +39,12 @@ at packets on the network, with the options that were set on the handle
being in effect.
.SH RETURN VALUE
.B pcap_activate()
returns 0 on success,
returns 0 on success without warnings,
.B PCAP_WARNING_PROMISC_NOTSUP
on success on a device that doesn't support promiscuous mode if
promiscuous mode was requested,
.B PCAP_WARNING
on success with any other warning,
.B PCAP_ERROR_ACTIVATED
if the handle has already been activated,
.B PCAP_ERROR_NO_SUCH_DEVICE
@ -53,6 +58,8 @@ monitor mode, and
.B PCAP_ERROR
if an error occurred.
If
.B PCAP_WARNING
or
.B PCAP_ERROR
is returned,
.B pcap_geterr()
@ -60,9 +67,11 @@ or
.B pcap_perror()
may be called with
.I p
as an argument to fetch or display the error text.
as an argument to fetch or display a message describing the warning or
error.
If
.B PCAP_ERROR_NO_SUCH_DEVICE
.BR PCAP_WARNING_PROMISC_NOTSUP ,
.BR PCAP_ERROR_NO_SUCH_DEVICE ,
or
.B PCAP_ERROR_PERM_DENIED
is returned,
@ -71,8 +80,8 @@ or
.B pcap_perror()
may be called with
.I p
as an argument to fetch or display an error message giving additional
details about the error that might be useful for debugging the error if
it's unexpected.
as an argument to fetch or display an message giving additional details
about the problem that might be useful for debugging the problem if it's
unexpected.
.SH SEE ALSO
pcap(3PCAP)