*/
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.106 2008-04-06 22:15:03 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.107 2008-04-09 19:58:02 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
* already exist.
*/
if (bpf_load(p->errbuf) == -1)
- return (-1);
+ return (PCAP_ERROR);
#endif
#ifdef HAVE_CLONING_BPF
if ((fd = open(device, O_RDWR)) == -1 &&
- (errno != EACCES || (fd = open(device, O_RDONLY)) == -1))
+ (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) {
+ if (errno == EACCES)
+ fd = PCAP_ERROR_PERM_DENIED;
+ else
+ fd = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"(cannot open device) %s: %s", device, pcap_strerror(errno));
+ }
#else
/*
* Go through all the minors and find one that isn't in use.
/*
* XXX better message for all minors used
*/
- if (fd < 0)
+ if (fd < 0) {
+ if (errno == EACCES)
+ fd = PCAP_ERROR_PERM_DENIED;
+ else
+ fd = PCAP_ERROR;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
device, pcap_strerror(errno));
+ }
#endif
return (fd);
*/
fd = bpf_open(p);
if (fd < 0)
- return (PCAP_ERROR);
+ return (fd);
/*
* Now bind to the device.
* exist.
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
+ strcpy(p->errbuf, "");
} else {
/*
* The underlying "enN" device
* just report "no such device".
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
+ strcpy(p->errbuf, "");
}
return (err);
}
/*
* No such device.
*/
+ strcpy(p->errbuf, "");
return (PCAP_ERROR_NO_SUCH_DEVICE);
} else {
/*
fd = bpf_open(p);
if (fd < 0) {
- err = PCAP_ERROR;
+ err = fd;
goto bad;
}
* exist.
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
+ strcpy(p->errbuf, "");
} else
err = PCAP_ERROR_RFMON_NOTSUP;
close(sockfd);
* report "no such device".
*/
err = PCAP_ERROR_NO_SUCH_DEVICE;
+ strcpy(p->errbuf, "");
}
goto bad;
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.122 2008-04-05 05:25:38 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.123 2008-04-09 19:58:02 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#ifndef HAVE_DEV_DLPI
char dname2[100];
#endif
-
- if (p->opt.rfmon) {
- /*
- * No monitor mode on any platforms that support DLPI.
- */
- return (PCAP_ERROR_RFMON_NOTSUP);
- }
+ int err = PCAP_ERROR;
p->fd = -1; /* indicate that it hasn't been opened yet */
p->send_fd = -1;
* chop off the unit number, so "dname" is just a device type name.
*/
cp = split_dname(dname, &ppa, p->errbuf);
- if (cp == NULL)
+ if (cp == NULL) {
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
+ }
*cp = '\0';
/*
*/
cp = "/dev/dlpi";
if ((p->fd = open(cp, O_RDWR)) < 0) {
+ if (errno == EPERM || errno == EACCES)
+ err = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: %s", cp, pcap_strerror(errno));
goto bad;
* table for the specified device type name and unit number.
*/
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
- if (ppa < 0)
+ if (ppa < 0) {
+ err = ppa;
goto bad;
+ }
#else
/*
* If the device name begins with "/", assume it begins with
* type name.
*/
cp = split_dname(dname, &ppa, p->errbuf);
- if (cp == NULL)
+ if (cp == NULL) {
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
goto bad;
+ }
/*
* Make a copy of the device pathname, and then remove the unit
/* Try again with unit number */
if ((p->fd = open(dname2, O_RDWR)) < 0) {
if (errno == ENOENT) {
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
+
/*
- * We just report "No DLPI device found"
- * with the device name, so people don't
- * get confused and think, for example,
+ * We provide an error message even
+ * for this error, for diagnostic
+ * purposes (so that, for example,
+ * the app can show the message if the
+ * user requests it).
+ *
+ * In it, we just report "No DLPI device
+ * found" with the device name, so people
+ * don't get confused and think, for example,
* that if they can't capture on "lo0"
* on Solaris the fix is to change libpcap
* (or the application that uses it) to
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", p->opt.source);
} else {
+ if (errno == EACCES)
+ err = PCAP_ERROR_PERM_DENIED;
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
dname2, pcap_strerror(errno));
}
isatm = 1;
#endif
if (infop->dl_provider_style == DL_STYLE2) {
- if (dl_doattach(p->fd, ppa, p->errbuf) < 0)
+ err = dl_doattach(p->fd, ppa, p->errbuf);
+ if (err < 0)
goto bad;
#ifdef DL_HP_RAWDLS
if (p->send_fd >= 0) {
#endif
}
+ if (p->opt.rfmon) {
+ /*
+ * This device exists, but we don't support monitor mode
+ * any platforms that support DLPI.
+ */
+ err = PCAP_ERROR_RFMON_NOTSUP;
+ goto bad;
+ }
+
#ifdef HAVE_DLPI_PASSIVE
/*
* Enable Passive mode to be able to capture on aggregated link.
close(p->fd);
if (p->send_fd >= 0)
close(p->send_fd);
- return (PCAP_ERROR);
+ return (err);
}
/*
dl_doattach(int fd, int ppa, char *ebuf)
{
bpf_u_int32 buf[MAXDLBUF];
+ int err;
- if (dlattachreq(fd, ppa, ebuf) < 0 ||
- dlokack(fd, "attach", (char *)buf, ebuf) < 0)
- return (-1);
+ if (dlattachreq(fd, ppa, ebuf) < 0)
+ return (PCAP_ERROR);
+ err = dlokack(fd, "attach", (char *)buf, ebuf);
+ if (err < 0)
+ return (err);
return (0);
}
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
what, pcap_strerror(errno));
- return (-1);
+ return (PCAP_ERROR);
}
dlp = (union DL_primitives *) ctl.buf;
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: UNIX error - %s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
+ if (dlp->error_ack.dl_unix_errno == EACCES)
+ return (PCAP_ERROR_PERM_DENIED);
break;
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
what, dlstrerror(dlp->error_ack.dl_errno));
+ if (dlp->error_ack.dl_errno == DL_BADPPA)
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+ else if (dlp->error_ack.dl_errno == DL_ACCESS)
+ return (PCAP_ERROR_PERM_DENIED);
break;
}
- return (-1);
+ return (PCAP_ERROR);
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Unexpected primitive ack %s",
what, dlprim(dlp->dl_primitive));
- return (-1);
+ return (PCAP_ERROR);
}
if (ctl.len < size) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Ack too small (%d < %d)",
what, ctl.len, size);
- return (-1);
+ return (PCAP_ERROR);
}
return (ctl.len);
}
memset((char *)buf, 0, sizeof(buf));
if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0)
- return (-1);
+ return (PCAP_ERROR);
ctl.maxlen = DL_HP_PPA_ACK_SIZE;
ctl.len = 0;
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
- return (-1);
+ return (PCAP_ERROR);
}
dlp = (dl_hp_ppa_ack_t *)ctl.buf;
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
(bpf_u_int32)dlp->dl_primitive);
- return (-1);
+ return (PCAP_ERROR);
}
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
- return (-1);
+ return (PCAP_ERROR);
}
/* allocate buffer */
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
- return (-1);
+ return (PCAP_ERROR);
}
ctl.maxlen = dlp->dl_length;
ctl.len = 0;
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
free(ppa_data_buf);
- return (-1);
+ return (PCAP_ERROR);
}
if (ctl.len < dlp->dl_length) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"get_dlpi_ppa: hpppa ack too small (%d < %d)",
ctl.len, dlp->dl_length);
free(ppa_data_buf);
- return (-1);
+ return (PCAP_ERROR);
}
ap = (dl_hp_ppa_ack_t *)buf;
if (stat(dname, &statbuf) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
dname, pcap_strerror(errno));
- return (-1);
+ return (PCAP_ERROR);
}
majdev = major(statbuf.st_rdev);
if (i == ap->dl_count) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"can't find /dev/dlpi PPA for %s%d", device, unit);
- return (-1);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
}
if (ip->dl_hdw_state == HDW_DEAD) {
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"%s%d: hardware state: DOWN\n", device, unit);
free(ppa_data_buf);
- return (-1);
+ return (PCAP_ERROR);
}
ppa = ip->dl_ppa;
free(ppa_data_buf);
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.4 2008-04-04 19:37:45 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-libdlpi.c,v 1.5 2008-04-09 19:58:02 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
int retv;
dlpi_handle_t dh;
dlpi_info_t dlinfo;
-
- if (p->opt.rfmon) {
- /*
- * No monitor mode on any platforms that support DLPI.
- */
- return (PCAP_ERROR_RFMON_NOTSUP);
- }
+ int err = PCAP_ERROR;
p->fd = -1; /* indicate that it hasn't been opened yet */
*/
retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
if (retv != DLPI_SUCCESS) {
- pcap_libdlpi_err(p->opt.source, "dlpi_open", retv, p->errbuf);
- goto bad;
+ if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
+ else if (retv == DLPI_SYSERR && errno == EACCES)
+ err = PCAP_ERROR_PERM_DENIED;
+ pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
+ p->errbuf);
+ return (err);
}
p->dlpi_hd = dh;
+ if (p->opt.rfmon) {
+ /*
+ * This device exists, but we don't support monitor mode
+ * any platforms that support DLPI.
+ */
+ err = PCAP_ERROR_RFMON_NOTSUP;
+ goto bad;
+ }
+
/* Bind with DLPI_ANY_SAP. */
if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
if (p->dlt_list != NULL)
free(p->dlt_list);
dlpi_close(p->dlpi_hd);
- return (PCAP_ERROR);
+ return (err);
}
/*
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.143 2008-04-07 03:57:32 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.144 2008-04-09 19:58:02 guy Exp $ (LBL)";
#endif
/*
static int iface_get_arptype(int fd, const char *device, char *ebuf);
#ifdef HAVE_PF_PACKET_SOCKETS
static int iface_bind(int fd, int ifindex, char *ebuf);
-static int has_wext(int sock_fd, const char *device);
+static int has_wext(int sock_fd, const char *device, char *ebuf);
static int enter_rfmon_mode_wext(pcap_t *handle, int sock_fd,
const char *device);
#endif
* if the device doesn't even exist.
*/
static int
-has_wext(int sock_fd, const char *device)
+has_wext(int sock_fd, const char *device, char *ebuf)
{
#ifdef IW_MODE_MONITOR
struct iwreq ireq;
ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
if (ioctl(sock_fd, SIOCGIWNAME, &ireq) >= 0)
return 1; /* yes */
+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "%s: SIOCGIWPRIV: %s", device, pcap_strerror(errno));
if (errno == ENODEV)
return PCAP_ERROR_NO_SUCH_DEVICE;
#endif
/*
* Does this device *support* the Wireless Extensions?
*/
- err = has_wext(sock_fd, device);
+ err = has_wext(sock_fd, device, handle->errbuf);
if (err <= 0)
return err; /* either it doesn't or the device doesn't even exist */
/*
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFHWADDR: %s", pcap_strerror(errno));
if (errno == ENODEV) {
/*
* No such device.
*/
return PCAP_ERROR_NO_SUCH_DEVICE;
}
- snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "SIOCGIFHWADDR: %s", pcap_strerror(errno));
return PCAP_ERROR;
}
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.116 2008-04-06 19:55:32 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.117 2008-04-09 19:58:02 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
{
pcap_t *p;
+ int err;
p = pcap_create(source, errbuf);
if (p == NULL)
return (NULL);
- if (pcap_set_snaplen(p, snaplen))
+ err = pcap_set_snaplen(p, snaplen);
+ if (err < 0)
goto fail;
- if (pcap_set_promisc(p, promisc))
+ err = pcap_set_promisc(p, promisc);
+ if (err < 0)
goto fail;
- if (pcap_set_timeout(p, to_ms))
+ err = pcap_set_timeout(p, to_ms);
+ if (err < 0)
goto fail;
/*
* Mark this as opened with pcap_open_live(), so that, for
* the adapter is in monitor mode or not.
*/
p->oldstyle = 1;
- if (pcap_activate(p))
+ err = pcap_activate(p);
+ if (err < 0)
goto fail;
return (p);
fail:
- strncpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
+ if (err == PCAP_ERROR || err == PCAP_ERROR_NO_SUCH_DEVICE ||
+ err == PCAP_ERROR_PERM_DENIED)
+ strlcpy(errbuf, p->errbuf, PCAP_ERRBUF_SIZE);
+ else
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
+ pcap_errtostr(err));
pcap_close(p);
return (NULL);
}
case PCAP_ERROR_NOT_RFMON:
return ("That operation is supported only in monitor mode");
+
+ case PCAP_ERROR_PERM_DENIED:
+ return ("You don't have permission to capture on that device");
}
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf);
* 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.7 2008-04-06 19:55:33 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.8 2008-04-09 19:58:02 guy Exp $ (LBL)
*/
#ifndef lib_pcap_pcap_h
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
const u_char *);
-/* list of known error code for pcap API */
+/* list of known error codes for pcap API */
#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_NO_SUCH_DEVICE -5 /* no such device exists */
#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
+#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
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 2008-04-06 02:53:21 guy Exp $
+.\" @(#) $Header: /tcpdump/master/libpcap/pcap_activate.3pcap,v 1.2 2008-04-09 19:58:02 guy Exp $
.\"
.\" Copyright (c) 1994, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
.B PCAP_ERROR_ACTIVATED
if the handle has already been activated,
.B PCAP_ERROR_NO_SUCH_DEVICE
-if the capture source specified when the handle was created doesn't exist,
+if the capture source specified when the handle was created doesn't
+exist,
+.B PCAP_ERROR_PERM_DENIED
+if the process doesn't have permission to open the capture source,
.B PCAP_ERROR_RFMON_NOTSUP
if monitor mode was specified but the capture source doesn't support
monitor mode, and