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).
This commit is contained in:
parent
745e497e4c
commit
216c64a7ce
27
pcap-bpf.c
27
pcap-bpf.c
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -195,14 +195,19 @@ bpf_open(pcap_t *p)
|
||||||
* already exist.
|
* already exist.
|
||||||
*/
|
*/
|
||||||
if (bpf_load(p->errbuf) == -1)
|
if (bpf_load(p->errbuf) == -1)
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CLONING_BPF
|
#ifdef HAVE_CLONING_BPF
|
||||||
if ((fd = open(device, O_RDWR)) == -1 &&
|
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,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"(cannot open device) %s: %s", device, pcap_strerror(errno));
|
"(cannot open device) %s: %s", device, pcap_strerror(errno));
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* Go through all the minors and find one that isn't in use.
|
* 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
|
* 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",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "(no devices found) %s: %s",
|
||||||
device, pcap_strerror(errno));
|
device, pcap_strerror(errno));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (fd);
|
return (fd);
|
||||||
|
@ -396,7 +406,7 @@ pcap_can_set_rfmon_bpf(pcap_t *p)
|
||||||
*/
|
*/
|
||||||
fd = bpf_open(p);
|
fd = bpf_open(p);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return (PCAP_ERROR);
|
return (fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now bind to the device.
|
* Now bind to the device.
|
||||||
|
@ -972,6 +982,7 @@ check_setif_failure(pcap_t *p, int error)
|
||||||
* exist.
|
* exist.
|
||||||
*/
|
*/
|
||||||
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
|
strcpy(p->errbuf, "");
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* The underlying "enN" device
|
* The underlying "enN" device
|
||||||
|
@ -993,6 +1004,7 @@ check_setif_failure(pcap_t *p, int error)
|
||||||
* just report "no such device".
|
* just report "no such device".
|
||||||
*/
|
*/
|
||||||
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
|
strcpy(p->errbuf, "");
|
||||||
}
|
}
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
@ -1000,6 +1012,7 @@ check_setif_failure(pcap_t *p, int error)
|
||||||
/*
|
/*
|
||||||
* No such device.
|
* No such device.
|
||||||
*/
|
*/
|
||||||
|
strcpy(p->errbuf, "");
|
||||||
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
return (PCAP_ERROR_NO_SUCH_DEVICE);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -1040,7 +1053,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||||
|
|
||||||
fd = bpf_open(p);
|
fd = bpf_open(p);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
err = PCAP_ERROR;
|
err = fd;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1117,6 +1130,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||||
* exist.
|
* exist.
|
||||||
*/
|
*/
|
||||||
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
|
strcpy(p->errbuf, "");
|
||||||
} else
|
} else
|
||||||
err = PCAP_ERROR_RFMON_NOTSUP;
|
err = PCAP_ERROR_RFMON_NOTSUP;
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
|
@ -1127,6 +1141,7 @@ pcap_activate_bpf(pcap_t *p)
|
||||||
* report "no such device".
|
* report "no such device".
|
||||||
*/
|
*/
|
||||||
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
|
strcpy(p->errbuf, "");
|
||||||
}
|
}
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
97
pcap-dlpi.c
97
pcap-dlpi.c
|
@ -70,7 +70,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -342,13 +342,7 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
#ifndef HAVE_DEV_DLPI
|
#ifndef HAVE_DEV_DLPI
|
||||||
char dname2[100];
|
char dname2[100];
|
||||||
#endif
|
#endif
|
||||||
|
int err = PCAP_ERROR;
|
||||||
if (p->opt.rfmon) {
|
|
||||||
/*
|
|
||||||
* No monitor mode on any platforms that support DLPI.
|
|
||||||
*/
|
|
||||||
return (PCAP_ERROR_RFMON_NOTSUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
p->fd = -1; /* indicate that it hasn't been opened yet */
|
p->fd = -1; /* indicate that it hasn't been opened yet */
|
||||||
p->send_fd = -1;
|
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.
|
* chop off the unit number, so "dname" is just a device type name.
|
||||||
*/
|
*/
|
||||||
cp = split_dname(dname, &ppa, p->errbuf);
|
cp = split_dname(dname, &ppa, p->errbuf);
|
||||||
if (cp == NULL)
|
if (cp == NULL) {
|
||||||
|
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
goto bad;
|
goto bad;
|
||||||
|
}
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -385,6 +381,8 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
*/
|
*/
|
||||||
cp = "/dev/dlpi";
|
cp = "/dev/dlpi";
|
||||||
if ((p->fd = open(cp, O_RDWR)) < 0) {
|
if ((p->fd = open(cp, O_RDWR)) < 0) {
|
||||||
|
if (errno == EPERM || errno == EACCES)
|
||||||
|
err = PCAP_ERROR_PERM_DENIED;
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"%s: %s", cp, pcap_strerror(errno));
|
"%s: %s", cp, pcap_strerror(errno));
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@ -410,8 +408,10 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
* table for the specified device type name and unit number.
|
* table for the specified device type name and unit number.
|
||||||
*/
|
*/
|
||||||
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
|
ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
|
||||||
if (ppa < 0)
|
if (ppa < 0) {
|
||||||
|
err = ppa;
|
||||||
goto bad;
|
goto bad;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* If the device name begins with "/", assume it begins with
|
* If the device name begins with "/", assume it begins with
|
||||||
|
@ -430,8 +430,10 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
* type name.
|
* type name.
|
||||||
*/
|
*/
|
||||||
cp = split_dname(dname, &ppa, p->errbuf);
|
cp = split_dname(dname, &ppa, p->errbuf);
|
||||||
if (cp == NULL)
|
if (cp == NULL) {
|
||||||
|
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
goto bad;
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make a copy of the device pathname, and then remove the unit
|
* 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 */
|
/* Try again with unit number */
|
||||||
if ((p->fd = open(dname2, O_RDWR)) < 0) {
|
if ((p->fd = open(dname2, O_RDWR)) < 0) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
|
err = PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We just report "No DLPI device found"
|
* We provide an error message even
|
||||||
* with the device name, so people don't
|
* for this error, for diagnostic
|
||||||
* get confused and think, for example,
|
* 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"
|
* that if they can't capture on "lo0"
|
||||||
* on Solaris the fix is to change libpcap
|
* on Solaris the fix is to change libpcap
|
||||||
* (or the application that uses it) to
|
* (or the application that uses it) to
|
||||||
|
@ -469,6 +479,8 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
||||||
"%s: No DLPI device found", p->opt.source);
|
"%s: No DLPI device found", p->opt.source);
|
||||||
} else {
|
} else {
|
||||||
|
if (errno == EACCES)
|
||||||
|
err = PCAP_ERROR_PERM_DENIED;
|
||||||
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
|
||||||
dname2, pcap_strerror(errno));
|
dname2, pcap_strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -491,7 +503,8 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
isatm = 1;
|
isatm = 1;
|
||||||
#endif
|
#endif
|
||||||
if (infop->dl_provider_style == DL_STYLE2) {
|
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;
|
goto bad;
|
||||||
#ifdef DL_HP_RAWDLS
|
#ifdef DL_HP_RAWDLS
|
||||||
if (p->send_fd >= 0) {
|
if (p->send_fd >= 0) {
|
||||||
|
@ -501,6 +514,15 @@ pcap_activate_dlpi(pcap_t *p)
|
||||||
#endif
|
#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
|
#ifdef HAVE_DLPI_PASSIVE
|
||||||
/*
|
/*
|
||||||
* Enable Passive mode to be able to capture on aggregated link.
|
* Enable Passive mode to be able to capture on aggregated link.
|
||||||
|
@ -732,7 +754,7 @@ bad:
|
||||||
close(p->fd);
|
close(p->fd);
|
||||||
if (p->send_fd >= 0)
|
if (p->send_fd >= 0)
|
||||||
close(p->send_fd);
|
close(p->send_fd);
|
||||||
return (PCAP_ERROR);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -788,10 +810,13 @@ static int
|
||||||
dl_doattach(int fd, int ppa, char *ebuf)
|
dl_doattach(int fd, int ppa, char *ebuf)
|
||||||
{
|
{
|
||||||
bpf_u_int32 buf[MAXDLBUF];
|
bpf_u_int32 buf[MAXDLBUF];
|
||||||
|
int err;
|
||||||
|
|
||||||
if (dlattachreq(fd, ppa, ebuf) < 0 ||
|
if (dlattachreq(fd, ppa, ebuf) < 0)
|
||||||
dlokack(fd, "attach", (char *)buf, ebuf) < 0)
|
return (PCAP_ERROR);
|
||||||
return (-1);
|
err = dlokack(fd, "attach", (char *)buf, ebuf);
|
||||||
|
if (err < 0)
|
||||||
|
return (err);
|
||||||
return (0);
|
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) {
|
if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
|
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
|
||||||
what, pcap_strerror(errno));
|
what, pcap_strerror(errno));
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
dlp = (union DL_primitives *) ctl.buf;
|
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,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"recv_ack: %s: UNIX error - %s",
|
"recv_ack: %s: UNIX error - %s",
|
||||||
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
|
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
|
||||||
|
if (dlp->error_ack.dl_unix_errno == EACCES)
|
||||||
|
return (PCAP_ERROR_PERM_DENIED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
|
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
|
||||||
what, dlstrerror(dlp->error_ack.dl_errno));
|
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;
|
break;
|
||||||
}
|
}
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"recv_ack: %s: Unexpected primitive ack %s",
|
"recv_ack: %s: Unexpected primitive ack %s",
|
||||||
what, dlprim(dlp->dl_primitive));
|
what, dlprim(dlp->dl_primitive));
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctl.len < size) {
|
if (ctl.len < size) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"recv_ack: %s: Ack too small (%d < %d)",
|
"recv_ack: %s: Ack too small (%d < %d)",
|
||||||
what, ctl.len, size);
|
what, ctl.len, size);
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
return (ctl.len);
|
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));
|
memset((char *)buf, 0, sizeof(buf));
|
||||||
if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0)
|
if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0)
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
|
|
||||||
ctl.maxlen = DL_HP_PPA_ACK_SIZE;
|
ctl.maxlen = DL_HP_PPA_ACK_SIZE;
|
||||||
ctl.len = 0;
|
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) {
|
if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
dlp = (dl_hp_ppa_ack_t *)ctl.buf;
|
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,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
|
"get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
|
||||||
(bpf_u_int32)dlp->dl_primitive);
|
(bpf_u_int32)dlp->dl_primitive);
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
|
if (ctl.len < DL_HP_PPA_ACK_SIZE) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
|
"get_dlpi_ppa: hpppa ack too small (%d < %lu)",
|
||||||
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
|
ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate buffer */
|
/* allocate buffer */
|
||||||
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
|
if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
|
"get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
ctl.maxlen = dlp->dl_length;
|
ctl.maxlen = dlp->dl_length;
|
||||||
ctl.len = 0;
|
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,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
"get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
|
||||||
free(ppa_data_buf);
|
free(ppa_data_buf);
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
if (ctl.len < dlp->dl_length) {
|
if (ctl.len < dlp->dl_length) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"get_dlpi_ppa: hpppa ack too small (%d < %d)",
|
"get_dlpi_ppa: hpppa ack too small (%d < %d)",
|
||||||
ctl.len, dlp->dl_length);
|
ctl.len, dlp->dl_length);
|
||||||
free(ppa_data_buf);
|
free(ppa_data_buf);
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
ap = (dl_hp_ppa_ack_t *)buf;
|
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) {
|
if (stat(dname, &statbuf) < 0) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
|
snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
|
||||||
dname, pcap_strerror(errno));
|
dname, pcap_strerror(errno));
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
majdev = major(statbuf.st_rdev);
|
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) {
|
if (i == ap->dl_count) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"can't find /dev/dlpi PPA for %s%d", device, unit);
|
"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) {
|
if (ip->dl_hdw_state == HDW_DEAD) {
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
"%s%d: hardware state: DOWN\n", device, unit);
|
"%s%d: hardware state: DOWN\n", device, unit);
|
||||||
free(ppa_data_buf);
|
free(ppa_data_buf);
|
||||||
return (-1);
|
return (PCAP_ERROR);
|
||||||
}
|
}
|
||||||
ppa = ip->dl_ppa;
|
ppa = ip->dl_ppa;
|
||||||
free(ppa_data_buf);
|
free(ppa_data_buf);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -102,13 +102,7 @@ pcap_activate_libdlpi(pcap_t *p)
|
||||||
int retv;
|
int retv;
|
||||||
dlpi_handle_t dh;
|
dlpi_handle_t dh;
|
||||||
dlpi_info_t dlinfo;
|
dlpi_info_t dlinfo;
|
||||||
|
int err = PCAP_ERROR;
|
||||||
if (p->opt.rfmon) {
|
|
||||||
/*
|
|
||||||
* No monitor mode on any platforms that support DLPI.
|
|
||||||
*/
|
|
||||||
return (PCAP_ERROR_RFMON_NOTSUP);
|
|
||||||
}
|
|
||||||
|
|
||||||
p->fd = -1; /* indicate that it hasn't been opened yet */
|
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);
|
retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE);
|
||||||
if (retv != DLPI_SUCCESS) {
|
if (retv != DLPI_SUCCESS) {
|
||||||
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv, p->errbuf);
|
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
|
||||||
goto bad;
|
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;
|
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. */
|
/* Bind with DLPI_ANY_SAP. */
|
||||||
if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
|
if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) {
|
||||||
pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
|
pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf);
|
||||||
|
@ -211,7 +219,7 @@ bad:
|
||||||
if (p->dlt_list != NULL)
|
if (p->dlt_list != NULL)
|
||||||
free(p->dlt_list);
|
free(p->dlt_list);
|
||||||
dlpi_close(p->dlpi_hd);
|
dlpi_close(p->dlpi_hd);
|
||||||
return (PCAP_ERROR);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
14
pcap-linux.c
14
pcap-linux.c
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
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
|
#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);
|
static int iface_get_arptype(int fd, const char *device, char *ebuf);
|
||||||
#ifdef HAVE_PF_PACKET_SOCKETS
|
#ifdef HAVE_PF_PACKET_SOCKETS
|
||||||
static int iface_bind(int fd, int ifindex, char *ebuf);
|
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,
|
static int enter_rfmon_mode_wext(pcap_t *handle, int sock_fd,
|
||||||
const char *device);
|
const char *device);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2223,7 +2223,7 @@ iface_bind(int fd, int ifindex, char *ebuf)
|
||||||
* if the device doesn't even exist.
|
* if the device doesn't even exist.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
has_wext(int sock_fd, const char *device)
|
has_wext(int sock_fd, const char *device, char *ebuf)
|
||||||
{
|
{
|
||||||
#ifdef IW_MODE_MONITOR
|
#ifdef IW_MODE_MONITOR
|
||||||
struct iwreq ireq;
|
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;
|
ireq.ifr_ifrn.ifrn_name[sizeof ireq.ifr_ifrn.ifrn_name - 1] = 0;
|
||||||
if (ioctl(sock_fd, SIOCGIWNAME, &ireq) >= 0)
|
if (ioctl(sock_fd, SIOCGIWNAME, &ireq) >= 0)
|
||||||
return 1; /* yes */
|
return 1; /* yes */
|
||||||
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
|
"%s: SIOCGIWPRIV: %s", device, pcap_strerror(errno));
|
||||||
if (errno == ENODEV)
|
if (errno == ENODEV)
|
||||||
return PCAP_ERROR_NO_SUCH_DEVICE;
|
return PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
#endif
|
#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?
|
* Does this device *support* the Wireless Extensions?
|
||||||
*/
|
*/
|
||||||
err = has_wext(sock_fd, device);
|
err = has_wext(sock_fd, device, handle->errbuf);
|
||||||
if (err <= 0)
|
if (err <= 0)
|
||||||
return err; /* either it doesn't or the device doesn't even exist */
|
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));
|
strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
|
||||||
|
|
||||||
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
|
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
|
||||||
|
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
||||||
|
"SIOCGIFHWADDR: %s", pcap_strerror(errno));
|
||||||
if (errno == ENODEV) {
|
if (errno == ENODEV) {
|
||||||
/*
|
/*
|
||||||
* No such device.
|
* No such device.
|
||||||
*/
|
*/
|
||||||
return PCAP_ERROR_NO_SUCH_DEVICE;
|
return PCAP_ERROR_NO_SUCH_DEVICE;
|
||||||
}
|
}
|
||||||
snprintf(ebuf, PCAP_ERRBUF_SIZE,
|
|
||||||
"SIOCGIFHWADDR: %s", pcap_strerror(errno));
|
|
||||||
return PCAP_ERROR;
|
return PCAP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
pcap.c
25
pcap.c
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static const char rcsid[] _U_ =
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#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_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
|
||||||
{
|
{
|
||||||
pcap_t *p;
|
pcap_t *p;
|
||||||
|
int err;
|
||||||
|
|
||||||
p = pcap_create(source, errbuf);
|
p = pcap_create(source, errbuf);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if (pcap_set_snaplen(p, snaplen))
|
err = pcap_set_snaplen(p, snaplen);
|
||||||
|
if (err < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (pcap_set_promisc(p, promisc))
|
err = pcap_set_promisc(p, promisc);
|
||||||
|
if (err < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (pcap_set_timeout(p, to_ms))
|
err = pcap_set_timeout(p, to_ms);
|
||||||
|
if (err < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
/*
|
/*
|
||||||
* Mark this as opened with pcap_open_live(), so that, for
|
* 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.
|
* the adapter is in monitor mode or not.
|
||||||
*/
|
*/
|
||||||
p->oldstyle = 1;
|
p->oldstyle = 1;
|
||||||
if (pcap_activate(p))
|
err = pcap_activate(p);
|
||||||
|
if (err < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
return (p);
|
return (p);
|
||||||
fail:
|
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);
|
pcap_close(p);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
@ -912,6 +922,9 @@ pcap_errtostr(int errnum)
|
||||||
|
|
||||||
case PCAP_ERROR_NOT_RFMON:
|
case PCAP_ERROR_NOT_RFMON:
|
||||||
return ("That operation is supported only in monitor mode");
|
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);
|
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
|
||||||
return(ebuf);
|
return(ebuf);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* 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
|
#ifndef lib_pcap_pcap_h
|
||||||
|
@ -226,7 +226,7 @@ struct pcap_addr {
|
||||||
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
||||||
const u_char *);
|
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 -1 /* generic error code */
|
||||||
#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
|
#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_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_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_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_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 *);
|
char *pcap_lookupdev(char *);
|
||||||
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||||
|
|
|
@ -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
|
.\" Copyright (c) 1994, 1996, 1997
|
||||||
.\" The Regents of the University of California. All rights reserved.
|
.\" The Regents of the University of California. All rights reserved.
|
||||||
|
@ -43,7 +43,10 @@ returns 0 on success,
|
||||||
.B PCAP_ERROR_ACTIVATED
|
.B PCAP_ERROR_ACTIVATED
|
||||||
if the handle has already been activated,
|
if the handle has already been activated,
|
||||||
.B PCAP_ERROR_NO_SUCH_DEVICE
|
.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
|
.B PCAP_ERROR_RFMON_NOTSUP
|
||||||
if monitor mode was specified but the capture source doesn't support
|
if monitor mode was specified but the capture source doesn't support
|
||||||
monitor mode, and
|
monitor mode, and
|
||||||
|
|
Reference in New Issue