From 216c64a7ceaa12e96df1c45f90c943d2d958a9cc Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 9 Apr 2008 19:58:02 +0000 Subject: [PATCH] Add an error for "you don't have permission to open that device", as that often means "sorry, this platform requires you to run as root or to somehow tweak the system to give you capture privileges", and applications might want to explain that in a way that does a better job of letting the user know what they have to do. Try to return or PCAP_ERROR_PERM_DENIED for open errors, rather than just returning PCAP_ERROR, so that the application can, if it chooses, try to explain the error better (as those two errors are the ones that don't mean "there's probably some obscure OS or libpcap problem", but mean, instead, "you made an error" or "you need to get permission to capture"). Check for monitor mode *after* checking whether the device exists in the first place; a non-existent device doesn't support monitor mode, but that's because it doesn't, well, exist, and the latter would be a more meaningful error. Have pcap_open_live() supply an error message for return values other than PCAP_ERROR, PCAP_ERROR_NO_SUCH_DEVICE, and PCAP_ERROR_PERM_DENIED - those all supply error strings (PCAP_ERROR because it's for various OS problems that might require debugging, and the other two because there might be multiple causes). --- pcap-bpf.c | 27 ++++++++++--- pcap-dlpi.c | 97 ++++++++++++++++++++++++++++++--------------- pcap-libdlpi.c | 30 +++++++++----- pcap-linux.c | 14 ++++--- pcap.c | 25 +++++++++--- pcap/pcap.h | 5 ++- pcap_activate.3pcap | 7 +++- 7 files changed, 139 insertions(+), 66 deletions(-) diff --git a/pcap-bpf.c b/pcap-bpf.c index 5043434..2fc0d72 100644 --- a/pcap-bpf.c +++ b/pcap-bpf.c @@ -20,7 +20,7 @@ */ #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 @@ -195,14 +195,19 @@ bpf_open(pcap_t *p) * 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. @@ -231,9 +236,14 @@ bpf_open(pcap_t *p) /* * 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); @@ -396,7 +406,7 @@ pcap_can_set_rfmon_bpf(pcap_t *p) */ fd = bpf_open(p); if (fd < 0) - return (PCAP_ERROR); + return (fd); /* * Now bind to the device. @@ -972,6 +982,7 @@ check_setif_failure(pcap_t *p, int error) * exist. */ err = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); } else { /* * The underlying "enN" device @@ -993,6 +1004,7 @@ check_setif_failure(pcap_t *p, int error) * just report "no such device". */ err = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); } return (err); } @@ -1000,6 +1012,7 @@ check_setif_failure(pcap_t *p, int error) /* * No such device. */ + strcpy(p->errbuf, ""); return (PCAP_ERROR_NO_SUCH_DEVICE); } else { /* @@ -1040,7 +1053,7 @@ pcap_activate_bpf(pcap_t *p) fd = bpf_open(p); if (fd < 0) { - err = PCAP_ERROR; + err = fd; goto bad; } @@ -1117,6 +1130,7 @@ pcap_activate_bpf(pcap_t *p) * exist. */ err = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); } else err = PCAP_ERROR_RFMON_NOTSUP; close(sockfd); @@ -1127,6 +1141,7 @@ pcap_activate_bpf(pcap_t *p) * report "no such device". */ err = PCAP_ERROR_NO_SUCH_DEVICE; + strcpy(p->errbuf, ""); } goto bad; } diff --git a/pcap-dlpi.c b/pcap-dlpi.c index 8301c37..29aae80 100644 --- a/pcap-dlpi.c +++ b/pcap-dlpi.c @@ -70,7 +70,7 @@ #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 @@ -342,13 +342,7 @@ pcap_activate_dlpi(pcap_t *p) #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; @@ -368,8 +362,10 @@ pcap_activate_dlpi(pcap_t *p) * 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'; /* @@ -385,6 +381,8 @@ 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; snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", cp, pcap_strerror(errno)); goto bad; @@ -410,8 +408,10 @@ pcap_activate_dlpi(pcap_t *p) * 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 @@ -430,8 +430,10 @@ pcap_activate_dlpi(pcap_t *p) * 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 @@ -451,10 +453,18 @@ 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; + /* - * 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 @@ -469,6 +479,8 @@ pcap_activate_dlpi(pcap_t *p) 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)); } @@ -491,7 +503,8 @@ pcap_activate_dlpi(pcap_t *p) 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) { @@ -501,6 +514,15 @@ pcap_activate_dlpi(pcap_t *p) #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. @@ -732,7 +754,7 @@ bad: close(p->fd); if (p->send_fd >= 0) close(p->send_fd); - return (PCAP_ERROR); + return (err); } /* @@ -788,10 +810,13 @@ static int 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); } @@ -931,7 +956,7 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror 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; @@ -955,27 +980,33 @@ recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror 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); } @@ -1401,7 +1432,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit, 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; @@ -1424,7 +1455,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit, 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; @@ -1432,21 +1463,21 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit, 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; @@ -1456,14 +1487,14 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit, 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; @@ -1520,7 +1551,7 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit, 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); @@ -1537,13 +1568,13 @@ get_dlpi_ppa(register int fd, register const char *device, register int unit, 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); diff --git a/pcap-libdlpi.c b/pcap-libdlpi.c index d1df5ba..9002984 100644 --- a/pcap-libdlpi.c +++ b/pcap-libdlpi.c @@ -26,7 +26,7 @@ #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 @@ -102,13 +102,7 @@ pcap_activate_libdlpi(pcap_t *p) 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 */ @@ -119,11 +113,25 @@ pcap_activate_libdlpi(pcap_t *p) */ 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); @@ -211,7 +219,7 @@ bad: if (p->dlt_list != NULL) free(p->dlt_list); dlpi_close(p->dlpi_hd); - return (PCAP_ERROR); + return (err); } /* diff --git a/pcap-linux.c b/pcap-linux.c index e11f601..55e5a26 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -34,7 +34,7 @@ #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 /* @@ -258,7 +258,7 @@ static int iface_get_mtu(int fd, const char *device, char *ebuf); 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 @@ -2223,7 +2223,7 @@ iface_bind(int fd, int ifindex, char *ebuf) * 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; @@ -2233,6 +2233,8 @@ has_wext(int sock_fd, const char *device) 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 @@ -2296,7 +2298,7 @@ enter_rfmon_mode_wext(pcap_t *handle, int sock_fd, const char *device) /* * 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 */ /* @@ -3027,14 +3029,14 @@ iface_get_arptype(int fd, const char *device, char *ebuf) 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; } diff --git a/pcap.c b/pcap.c index 6c4de05..7494c32 100644 --- a/pcap.c +++ b/pcap.c @@ -33,7 +33,7 @@ #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 @@ -223,15 +223,19 @@ pcap_t * 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 @@ -244,11 +248,17 @@ pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *er * 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); } @@ -912,6 +922,9 @@ pcap_errtostr(int errnum) 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); diff --git a/pcap/pcap.h b/pcap/pcap.h index 5dbc047..9135832 100644 --- a/pcap/pcap.h +++ b/pcap/pcap.h @@ -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.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 @@ -226,7 +226,7 @@ struct pcap_addr { 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 */ @@ -234,6 +234,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, #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 *); diff --git a/pcap_activate.3pcap b/pcap_activate.3pcap index 94d7330..43bad03 100644 --- a/pcap_activate.3pcap +++ b/pcap_activate.3pcap @@ -1,4 +1,4 @@ -.\" @(#) $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. @@ -43,7 +43,10 @@ returns 0 on success, .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