]> The Tcpdump Group git mirrors - libpcap/commitdiff
Add an error for "you don't have permission to open that device", as
authorguy <guy>
Wed, 9 Apr 2008 19:58:02 +0000 (19:58 +0000)
committerguy <guy>
Wed, 9 Apr 2008 19:58:02 +0000 (19:58 +0000)
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
pcap-dlpi.c
pcap-libdlpi.c
pcap-linux.c
pcap.c
pcap/pcap.h
pcap_activate.3pcap

index 5043434a4f52f5a4775338866cc7bdb6de9d5ef4..2fc0d727a0ab3835ebba9a6ef2757b75858c913f 100644 (file)
@@ -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;
                                }
index 8301c37c6f6f476f6787269866d7c7d881e58051..29aae807ae17520a1a40ddfe991d4358334d986d 100644 (file)
@@ -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);
index d1df5ba223e32c75f507fd6731f8ed01b67f1b07..9002984767b5345deb9d31f7d2f02014c84b5b3a 100644 (file)
@@ -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);
 }
 
 /*
index e11f6011e349b39369a69b69527dc5a47bc025cc..55e5a26e74b4b2d54f526d38e6c85585d2d3d644 100644 (file)
@@ -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 6c4de05bc56beb8246301ff24f618eef73ebdcbe..7494c32d07f1324f3efad22d28045219415861be 100644 (file)
--- 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);
index 5dbc047f5d048fabc2c9c737a3832d8618fb6dd8..9135832ece7cfe0fee9884af770cfe7836e6c7d0 100644 (file)
@@ -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 *);
index 94d7330b3da6efc8f086d5a49786bb356568996f..43bad0335b70d117acc38cc6586dd14117699f9b 100644 (file)
@@ -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