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).
*/
#ifndef lint
static const char rcsid[] _U_ =
*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.99.2.8 2008-04-09 19:58:34 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.99.2.9 2008-04-09 21:26:37 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif
#ifdef HAVE_CONFIG_H
static int
pcap_activate_bpf(pcap_t *p)
{
static int
pcap_activate_bpf(pcap_t *p)
{
int fd;
struct ifreq ifr;
struct bpf_version bv;
int fd;
struct ifreq ifr;
struct bpf_version bv;
fd = bpf_open(p);
if (fd < 0) {
fd = bpf_open(p);
if (fd < 0) {
if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
pcap_strerror(errno));
if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
pcap_strerror(errno));
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");
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");
/*
* 10.3 (Darwin 7.x) or earlier.
*/
/*
* 10.3 (Darwin 7.x) or earlier.
*/
- err = PCAP_ERROR_RFMON_NOTSUP;
+ status = PCAP_ERROR_RFMON_NOTSUP;
goto bad;
}
if (osinfo.release[0] == '8' &&
goto bad;
}
if (osinfo.release[0] == '8' &&
* device doesn't
* exist.
*/
* device doesn't
* exist.
*/
- err = PCAP_ERROR_NO_SUCH_DEVICE;
+ status = PCAP_ERROR_NO_SUCH_DEVICE;
strcpy(p->errbuf, "");
} else
strcpy(p->errbuf, "");
} else
- err = PCAP_ERROR_RFMON_NOTSUP;
+ status = PCAP_ERROR_RFMON_NOTSUP;
close(sockfd);
} else {
/*
close(sockfd);
} else {
/*
* the device exists, so just
* report "no such device".
*/
* 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;
strcpy(p->errbuf, "");
}
goto bad;
(void)snprintf(p->errbuf,
PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
(void)snprintf(p->errbuf,
PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
goto bad;
}
strcpy(wltdev, "wlt");
goto bad;
}
strcpy(wltdev, "wlt");
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSBLEN: %s: %s", p->opt.source,
pcap_strerror(errno));
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSBLEN: %s: %s", p->opt.source,
pcap_strerror(errno));
(void)strncpy(ifr.ifr_name, p->opt.source,
sizeof(ifr.ifr_name));
if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
(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);
break; /* that size worked; we're done */
if (errno != ENOBUFS) {
break; /* that size worked; we're done */
if (errno != ENOBUFS) {
- err = check_setif_failure(p, errno);
+ status = check_setif_failure(p, errno);
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSBLEN: %s: No buffer size worked",
p->opt.source);
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSBLEN: %s: No buffer size worked",
p->opt.source);
if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
pcap_strerror(errno));
if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
pcap_strerror(errno));
*/
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
v);
*/
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
v);
* not fatal; we just don't get to use the feature later.
*/
if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) {
* not fatal; we just don't get to use the feature later.
*/
if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) {
goto bad;
}
p->dlt_count = bdl.bfl_len;
goto bad;
}
p->dlt_count = bdl.bfl_len;
* link-layer types, so they
* can't have it.
*/
* link-layer types, so they
* can't have it.
*/
- err = PCAP_ERROR_RFMON_NOTSUP;
+ status = PCAP_ERROR_RFMON_NOTSUP;
/*
* Try to put the interface into monitor mode.
*/
/*
* Try to put the interface into monitor mode.
*/
- err = monitor_mode(p, 1);
- if (err != 0) {
+ status = monitor_mode(p, 1);
+ if (status != 0) {
if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSHDRCMPLT: %s", pcap_strerror(errno));
if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
(void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"BIOCSHDRCMPLT: %s", pcap_strerror(errno));
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
pcap_strerror(errno));
if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSRTIMEOUT: %s",
pcap_strerror(errno));
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
pcap_strerror(errno));
if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
pcap_strerror(errno));
goto bad;
}
#endif /* BIOCIMMEDIATE */
goto bad;
}
#endif /* BIOCIMMEDIATE */
if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
pcap_strerror(errno));
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));
}
}
if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
pcap_strerror(errno));
goto bad;
}
p->bufsize = v;
goto bad;
}
p->bufsize = v;
if (p->buffer == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
if (p->buffer == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
pcap_strerror(errno));
if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
pcap_strerror(errno));
p->stats_op = pcap_stats_bpf;
p->close_op = pcap_close_bpf;
p->stats_op = pcap_stats_bpf;
p->close_op = pcap_close_bpf;
bad:
(void)close(fd);
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
}
bad:
(void)close(fd);
if (p->buffer != NULL) {
free(p->buffer);
p->buffer = NULL;
}
#ifndef lint
static const char rcsid[] _U_ =
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.116.2.7 2008-04-09 19:58:34 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.116.2.8 2008-04-09 21:26:37 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif
#ifdef HAVE_CONFIG_H
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
+ int status = PCAP_ERROR;
p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1;
p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1;
*/
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
*/
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
- err = PCAP_ERROR_NO_SUCH_DEVICE;
+ status = PCAP_ERROR_NO_SUCH_DEVICE;
cp = "/dev/dlpi";
if ((p->fd = open(cp, O_RDWR)) < 0) {
if (errno == EPERM || errno == EACCES)
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;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: %s", cp, pcap_strerror(errno));
goto bad;
*/
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
if (ppa < 0) {
*/
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
if (ppa < 0) {
*/
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
*/
cp = split_dname(dname, &ppa, p->errbuf);
if (cp == NULL) {
- err = PCAP_ERROR_NO_SUCH_DEVICE;
+ status = PCAP_ERROR_NO_SUCH_DEVICE;
/* Try again with unit number */
if ((p->fd = open(dname2, O_RDWR)) < 0) {
if (errno == ENOENT) {
/* 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
/*
* We provide an error message even
"%s: No DLPI device found", p->opt.source);
} else {
if (errno == EACCES)
"%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));
}
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
}
isatm = 1;
#endif
if (infop->dl_provider_style == DL_STYLE2) {
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) {
goto bad;
#ifdef DL_HP_RAWDLS
if (p->send_fd >= 0) {
* This device exists, but we don't support monitor mode
* any platforms that support DLPI.
*/
* 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;
#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)
#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);
dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
if (p->opt.promisc)
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);
release = get_release(&osmajor, &osminor, &osmicro);
if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
getenv("BUFMOD_FIXED") == NULL) {
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.",
if (pcap_alloc_databuf(p) != 0)
goto bad;
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.
/*
* "p->fd" is an FD for a STREAMS device, so "select()" and
* "poll()" should work on it.
p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_dlpi;
p->stats_op = pcap_stats_dlpi;
p->close_op = pcap_close_dlpi;
bad:
if (p->fd >= 0)
close(p->fd);
if (p->send_fd >= 0)
close(p->send_fd);
bad:
if (p->fd >= 0)
close(p->fd);
if (p->send_fd >= 0)
close(p->send_fd);
#ifndef lint
static const char rcsid[] _U_ =
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.129.2.15 2008-04-09 19:58:35 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.129.2.16 2008-04-09 21:26:37 guy Exp $ (LBL)";
pcap_activate_linux(pcap_t *handle)
{
const char *device;
pcap_activate_linux(pcap_t *handle)
{
const char *device;
int activate_ok = 0;
device = handle->opt.source;
int activate_ok = 0;
device = handle->opt.source;
/* Just a warning. */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Promiscuous mode not supported on the \"any\" device");
/* Just a warning. */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Promiscuous mode not supported on the \"any\" device");
+ status = PCAP_WARNING_PROMISC_NOTSUP;
* trying both methods with the newer method preferred.
*/
* 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.
activate_ok = 1;
/*
* Try to use memory-mapped access.
if (activate_mmap(handle) == 1)
return 0; /* we succeeded; nothing more to do */
}
if (activate_mmap(handle) == 1)
return 0; /* we succeeded; nothing more to do */
}
+ else if (status == 0) {
/* Non-fatal error; try old way */
/* Non-fatal error; try old way */
- if ((err = activate_old(handle)) == 1)
+ if ((status = activate_old(handle)) == 1)
activate_ok = 1;
}
if (!activate_ok) {
activate_ok = 1;
}
if (!activate_ok) {
sizeof(handle->opt.buffer_size)) == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SO_RCVBUF: %s", pcap_strerror(errno));
sizeof(handle->opt.buffer_size)) == -1) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SO_RCVBUF: %s", pcap_strerror(errno));
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
*/
handle->selectable_fd = handle->fd;
*/
handle->selectable_fd = handle->fd;
free(handle->md.device);
handle->md.device = NULL;
}
free(handle->md.device);
handle->md.device = NULL;
}
#ifndef lint
static const char rcsid[] _U_ =
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.112.2.5 2008-04-09 19:58:35 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.112.2.6 2008-04-09 21:26:37 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif
#ifdef HAVE_CONFIG_H
int
pcap_activate(pcap_t *p)
{
int
pcap_activate(pcap_t *p)
{
- err = p->activate_op(p);
- if (err == 0)
+ status = p->activate_op(p);
+ if (status >= 0)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* 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.4.2.4 2008-04-09 19:58:35 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.5 2008-04-09 21:26:37 guy Exp $ (LBL)
*/
#ifndef lib_pcap_pcap_h
*/
#ifndef lib_pcap_pcap_h
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
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 */
#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 */
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
#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 *);
char *pcap_lookupdev(char *);
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
-.\" @(#) $Header: /tcpdump/master/libpcap/pcap_activate.3pcap,v 1.1.2.3 2008-04-09 20:20:59 guy Exp $
+.\" @(#) $Header: /tcpdump/master/libpcap/pcap_activate.3pcap,v 1.1.2.4 2008-04-09 21:26:37 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
being in effect.
.SH RETURN VALUE
.B pcap_activate()
being in effect.
.SH RETURN VALUE
.B pcap_activate()
+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
.B PCAP_ERROR_ACTIVATED
if the handle has already been activated,
.B PCAP_ERROR_NO_SUCH_DEVICE
.B PCAP_ERROR
if an error occurred.
If
.B PCAP_ERROR
if an error occurred.
If
.B PCAP_ERROR
is returned,
.B pcap_geterr()
.B PCAP_ERROR
is returned,
.B pcap_geterr()
.B pcap_perror()
may be called with
.I p
.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.
-.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,
or
.B PCAP_ERROR_PERM_DENIED
is returned,
.B pcap_perror()
may be called with
.I p
.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.