Provide a suggestion for PCAP_ERROR_PERM_DENIED and
PCAP_ERROR_PROMISC_PERM_DENIED; the suggestion may be nothing more than
"you might require root permission", but at least it's something.
Note also what we were trying to do, to indicate that the problem might
be that you need root permission to set promiscuous mode even if you
don't need it to capture, or that you need CAP_NET_ADMIN permission to
change the time stamp mode of an adapter on Linux even though you don't
need it to capture. (The latter was done as per the discussion in issue
and that triggered the same double-free bug that failing to set up the
memory-mapped ring buffer caused in issue #1054.)
(cherry picked from commit
92c547194ffa85c89b579658f1cc752fad98666f)
((errno != EACCES && errno != ENOENT) ||
(fd = open(cloning_device, O_RDONLY)) == -1)) {
if (errno != ENOENT) {
((errno != EACCES && errno != ENOENT) ||
(fd = open(cloning_device, O_RDONLY)) == -1)) {
if (errno != ENOENT) {
fd = PCAP_ERROR_PERM_DENIED;
fd = PCAP_ERROR_PERM_DENIED;
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed - root privileges may be required",
+ cloning_device);
+ } else {
- pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
- errno, "(cannot open device) %s", cloning_device);
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "(cannot open device) %s", cloning_device);
+ }
return (fd);
}
no_cloning_bpf = 1;
return (fd);
}
no_cloning_bpf = 1;
* if any.
*/
fd = PCAP_ERROR_PERM_DENIED;
* if any.
*/
fd = PCAP_ERROR_PERM_DENIED;
- pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
- errno, "(cannot open BPF device) %s", device);
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed - root privileges may be required",
+ device);
*/
if (errno == ENOENT)
ret = PCAP_ERROR_NO_SUCH_DEVICE;
*/
if (errno == ENOENT)
ret = PCAP_ERROR_NO_SUCH_DEVICE;
- else if (errno == EPERM || errno == EACCES)
+ else if (errno == EPERM || errno == EACCES) {
ret = PCAP_ERROR_PERM_DENIED;
ret = PCAP_ERROR_PERM_DENIED;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed with %s - additional privileges may be required",
+ device, (errno == EPERM) ? "EPERM" : "EACCES");
+ } else {
- pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
- errno, "dag_config_init %s", device);
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "dag_config_init %s", device);
+ }
static int dlpromiscon(pcap_t *, bpf_u_int32);
static int dlbindreq(int, bpf_u_int32, char *);
static int dlbindack(int, char *, char *, int *);
static int dlpromiscon(pcap_t *, bpf_u_int32);
static int dlbindreq(int, bpf_u_int32, char *);
static int dlbindack(int, char *, char *, int *);
-static int dlokack(int, const char *, char *, char *);
+static int dlokack(int, const char *, char *, char *, int *);
static int dlinforeq(int, char *);
static int dlinfoack(int, char *, char *);
static int dlinforeq(int, char *);
static int dlinfoack(int, char *, char *);
*/
cp = "/dev/dlpi";
if ((fd = open(cp, O_RDWR)) < 0) {
*/
cp = "/dev/dlpi";
if ((fd = open(cp, O_RDWR)) < 0) {
- if (errno == EPERM || errno == EACCES)
+ if (errno == EPERM || errno == EACCES) {
status = PCAP_ERROR_PERM_DENIED;
status = PCAP_ERROR_PERM_DENIED;
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed with %s - root privilege may be required",
+ cp, (errno == EPERM) ? "EPERM" : "EACCES");
+ } else {
- pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
- errno, "%s", cp);
+ pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ errno, "Attempt to open %s failed", cp);
+ }
/* Try device without unit number */
if ((fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
/* Try device without unit number */
if ((fd = open(dname, O_RDWR)) < 0) {
if (errno != ENOENT) {
- if (errno == EPERM || errno == EACCES)
+ if (errno == EPERM || errno == EACCES) {
status = PCAP_ERROR_PERM_DENIED;
status = PCAP_ERROR_PERM_DENIED;
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed with %s - root privilege may be required",
+ dname,
+ (errno == EPERM) ? "EPERM" : "EACCES");
+ } else {
- pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
- errno, "%s", dname);
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Attempt to open %s failed", dname);
+ }
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", name);
} else {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"%s: No DLPI device found", name);
} else {
- if (errno == EPERM || errno == EACCES)
+ if (errno == EPERM || errno == EACCES) {
status = PCAP_ERROR_PERM_DENIED;
status = PCAP_ERROR_PERM_DENIED;
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed with %s - root privilege may be required",
+ dname2,
+ (errno == EPERM) ? "EPERM" : "EACCES");
+ } else {
- pcap_fmt_errmsg_for_errno(errbuf,
- PCAP_ERRBUF_SIZE, errno, "%s", dname2);
+ pcap_fmt_errmsg_for_errno(errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "Attempt to open %s failed",
+ dname2);
+ }
if (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf) < 0)
return (PCAP_ERROR);
if (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf) < 0)
return (PCAP_ERROR);
- err = dlokack(fd, "attach", (char *)buf, ebuf);
+ err = dlokack(fd, "attach", (char *)buf, ebuf, NULL);
if (err < 0)
return (err);
return (0);
if (err < 0)
return (err);
return (0);
dl_promiscon_req_t req;
bpf_u_int32 buf[MAXDLBUF];
int err;
dl_promiscon_req_t req;
bpf_u_int32 buf[MAXDLBUF];
int err;
req.dl_primitive = DL_PROMISCON_REQ;
req.dl_level = level;
req.dl_primitive = DL_PROMISCON_REQ;
req.dl_level = level;
p->errbuf) < 0)
return (PCAP_ERROR);
err = dlokack(p->fd, "promiscon" STRINGIFY(level), (char *)buf,
p->errbuf) < 0)
return (PCAP_ERROR);
err = dlokack(p->fd, "promiscon" STRINGIFY(level), (char *)buf,
- p->errbuf);
- if (err < 0)
+ p->errbuf, &uerror);
+ if (err < 0) {
+ if (err == PCAP_ERROR_PERM_DENIED) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to set promiscuous mode failed with %s - root privilege may be required",
+ (uerror == EPERM) ? "EPERM" : "EACCES");
+ err = PCAP_ERROR_PROMISC_PERM_DENIED;
+ }
-dlokack(int fd, const char *what, char *bufp, char *ebuf)
+dlokack(int fd, const char *what, char *bufp, char *ebuf, int *uerror)
- return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL));
+ return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, uerror));
req.dl_primitive = DL_PASSIVE_REQ;
if (send_request(fd, (char *)&req, sizeof(req), "dlpassive", ebuf) == 0)
req.dl_primitive = DL_PASSIVE_REQ;
if (send_request(fd, (char *)&req, sizeof(req), "dlpassive", ebuf) == 0)
- (void) dlokack(fd, "dlpassive", (char *)buf, ebuf);
+ (void) dlokack(fd, "dlpassive", (char *)buf, ebuf, NULL);
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
status = PCAP_ERROR_NO_SUCH_DEVICE;
else if (retv == DL_SYSERR &&
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
status = PCAP_ERROR_NO_SUCH_DEVICE;
else if (retv == DL_SYSERR &&
- (errno == EPERM || errno == EACCES))
+ (errno == EPERM || errno == EACCES)) {
status = PCAP_ERROR_PERM_DENIED;
status = PCAP_ERROR_PERM_DENIED;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open DLPI device failed with %s - root privilege may be required",
+ (errno == EPERM) ? "EPERM" : "EACCES");
+ } else {
- pcap_libdlpi_err(p->opt.device, "dlpi_open", retv,
- p->errbuf);
+ pcap_libdlpi_err(p->opt.device, "dlpi_open", retv,
+ p->errbuf);
+ }
return (status);
}
pd->dlpi_hd = dh;
return (status);
}
pd->dlpi_hd = dh;
retv = dlpi_promiscon(pd->dlpi_hd, level);
if (retv != DLPI_SUCCESS) {
if (retv == DL_SYSERR &&
retv = dlpi_promiscon(pd->dlpi_hd, level);
if (retv != DLPI_SUCCESS) {
if (retv == DL_SYSERR &&
- (errno == EPERM || errno == EACCES))
- err = PCAP_ERROR_PERM_DENIED;
- else
+ (errno == EPERM || errno == EACCES)) {
+ if (level == DL_PROMISC_PHYS) {
+ err = PCAP_ERROR_PROMISC_PERM_DENIED;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to set promiscuous mode failed with %s - root privilege may be required",
+ (errno == EPERM) ? "EPERM" : "EACCES");
+ } else {
+ err = PCAP_ERROR_PERM_DENIED;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to set %s mode failed with %s - root privilege may be required",
+ (level == DL_PROMISC_MULTI) ? "multicast" : "SAP promiscuous",
+ (errno == EPERM) ? "EPERM" : "EACCES");
+ }
+ } else {
- pcap_libdlpi_err(p->opt.device, "dlpi_promiscon" STRINGIFY(level),
- retv, p->errbuf);
+ pcap_libdlpi_err(p->opt.device,
+ "dlpi_promiscon" STRINGIFY(level),
+ retv, p->errbuf);
+ }
return (err);
}
return (0);
return (err);
}
return (0);
* socket.
*/
status = PCAP_ERROR_PERM_DENIED;
* socket.
*/
status = PCAP_ERROR_PERM_DENIED;
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to create packet socket failed - CAP_NET_RAW may be required");
} else {
/*
* Other error.
} else {
/*
* Other error.
pcap_strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
ifr.ifr_data = (void *)&hwconfig;
pcap_strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
ifr.ifr_data = (void *)&hwconfig;
+ /*
+ * This may require CAP_NET_ADMIN.
+ */
if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) {
switch (errno) {
if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) {
switch (errno) {
* try requesting hardware time stamps.
*/
*status = PCAP_ERROR_PERM_DENIED;
* try requesting hardware time stamps.
*/
*status = PCAP_ERROR_PERM_DENIED;
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to set hardware timestamp failed - CAP_NET_ADMIN may be required");
return -1;
case EOPNOTSUPP:
return -1;
case EOPNOTSUPP:
/*
* There is, but we don't have permission to
* use it.
/*
* There is, but we don't have permission to
* use it.
+ *
+ * XXX - we currently get ERROR_BAD_UNIT if the
+ * user says "no" to the UAC prompt.
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The helper program for \"Admin-only Mode\" must be allowed to make changes to your device");
return (PCAP_ERROR_PERM_DENIED);
default:
return (PCAP_ERROR_PERM_DENIED);
default:
if (fd < 0 && errno == EACCES)
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
if (fd < 0 && errno == EACCES)
p->fd = fd = open(dev, O_RDONLY);
if (fd < 0) {
err = PCAP_ERROR_PERM_DENIED;
err = PCAP_ERROR_PERM_DENIED;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed with EACCES - root privileges may be required",
+ dev);
+ } else {
- pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
- errno, "%s", dev);
+ pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
+ errno, "%s", dev);
+ }
/*
* We didn't have permission to open it.
*/
/*
* We didn't have permission to open it.
*/
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "Attempt to open %s failed with EACCES - root privileges may be required",
+ full_path);
return PCAP_ERROR_PERM_DENIED;
default:
return PCAP_ERROR_PERM_DENIED;
default: