Return PCAP_ERROR_PROMISC_PERM_DENIED if you have permission to open the
DLPI device but don't have permission to put the interface in promiscuous mode; some systems using DLPI work that way. Change the libdlpi code to return a warning if you *are* using physical promiscuous mode and you fail to turn on SAP promiscuous mode, not if you *aren't* using physical promiscuous mode and you fail to turn on SAP promiscuous mode; that matches with the no-libdlpi code does, and matches what the comment says. Pull dlattachreq up into dl_doattach().
This commit is contained in:
parent
b26d8d2aa8
commit
74b7b4259f
76
pcap-dlpi.c
76
pcap-dlpi.c
|
@ -143,10 +143,9 @@ static int dl_doattach(int, int, char *);
|
|||
#ifdef DL_HP_RAWDLS
|
||||
static int dl_dohpuxbind(int, char *);
|
||||
#endif
|
||||
static int dlattachreq(int, bpf_u_int32, char *);
|
||||
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 dlpromisconreq(int, bpf_u_int32, char *);
|
||||
static int dlokack(int, const char *, char *, char *);
|
||||
static int dlinforeq(int, char *);
|
||||
static int dlinfoack(int, char *, char *);
|
||||
|
@ -610,9 +609,12 @@ pcap_activate_dlpi(pcap_t *p)
|
|||
/*
|
||||
** Enable promiscuous (not necessary on send FD)
|
||||
*/
|
||||
if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
|
||||
dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
|
||||
status = dlpromiscon(p, DL_PROMISC_PHYS);
|
||||
if (status < 0) {
|
||||
if (status == PCAP_ERROR_PERM_DENIED)
|
||||
status = PCAP_ERROR_PROMISC_PERM_DENIED;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
** Try to enable multicast (you would have thought
|
||||
|
@ -620,8 +622,8 @@ pcap_activate_dlpi(pcap_t *p)
|
|||
** HP-UX or SINIX) (Not necessary on send FD)
|
||||
*/
|
||||
#if !defined(__hpux) && !defined(sinix)
|
||||
if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
|
||||
dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
|
||||
status = dlpromiscon(p, DL_PROMISC_MULTI);
|
||||
if (status < 0)
|
||||
status = PCAP_WARNING;
|
||||
#endif
|
||||
}
|
||||
|
@ -636,16 +638,21 @@ pcap_activate_dlpi(pcap_t *p)
|
|||
!p->opt.promisc &&
|
||||
#endif
|
||||
#ifdef HAVE_SOLARIS
|
||||
!isatm &&
|
||||
!isatm
|
||||
#endif
|
||||
(dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
|
||||
dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
|
||||
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
|
||||
) {
|
||||
status = dlpromiscon(p, DL_PROMISC_SAP);
|
||||
if (status < 0) {
|
||||
/*
|
||||
* Not fatal, since the DL_PROMISC_PHYS mode worked.
|
||||
* Report it as a warning, however.
|
||||
*/
|
||||
if (p->opt.promisc)
|
||||
status = PCAP_WARNING;
|
||||
else
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
#endif /* sinix */
|
||||
|
||||
/*
|
||||
|
@ -815,11 +822,15 @@ split_dname(char *device, int *unitp, char *ebuf)
|
|||
static int
|
||||
dl_doattach(int fd, int ppa, char *ebuf)
|
||||
{
|
||||
dl_attach_req_t req;
|
||||
bpf_u_int32 buf[MAXDLBUF];
|
||||
int err;
|
||||
|
||||
if (dlattachreq(fd, ppa, ebuf) < 0)
|
||||
req.dl_primitive = DL_ATTACH_REQ;
|
||||
req.dl_ppa = ppa;
|
||||
if (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf) < 0)
|
||||
return (PCAP_ERROR);
|
||||
|
||||
err = dlokack(fd, "attach", (char *)buf, ebuf);
|
||||
if (err < 0)
|
||||
return (err);
|
||||
|
@ -877,6 +888,27 @@ dl_dohpuxbind(int fd, char *ebuf)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define STRINGIFY(n) #n
|
||||
|
||||
static int
|
||||
dlpromiscon(pcap_t *p, bpf_u_int32 level)
|
||||
{
|
||||
dl_promiscon_req_t req;
|
||||
bpf_u_int32 buf[MAXDLBUF];
|
||||
int err;
|
||||
|
||||
req.dl_primitive = DL_PROMISCON_REQ;
|
||||
req.dl_level = level;
|
||||
if (send_request(p->fd, (char *)&req, sizeof(req), "promiscon",
|
||||
p->errbuf) < 0)
|
||||
return (PCAP_ERROR);
|
||||
err = dlokack(p->fd, "promiscon" STRINGIFY(level), (char *)buf,
|
||||
p->errbuf);
|
||||
if (err < 0)
|
||||
return (err);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
|
||||
{
|
||||
|
@ -1221,17 +1253,6 @@ dlprim(bpf_u_int32 prim)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf)
|
||||
{
|
||||
dl_attach_req_t req;
|
||||
|
||||
req.dl_primitive = DL_ATTACH_REQ;
|
||||
req.dl_ppa = ppa;
|
||||
|
||||
return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));
|
||||
}
|
||||
|
||||
static int
|
||||
dlbindreq(int fd, bpf_u_int32 sap, char *ebuf)
|
||||
{
|
||||
|
@ -1259,17 +1280,6 @@ dlbindack(int fd, char *bufp, char *ebuf, int *uerror)
|
|||
return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror));
|
||||
}
|
||||
|
||||
static int
|
||||
dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf)
|
||||
{
|
||||
dl_promiscon_req_t req;
|
||||
|
||||
req.dl_primitive = DL_PROMISCON_REQ;
|
||||
req.dl_level = level;
|
||||
|
||||
return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));
|
||||
}
|
||||
|
||||
static int
|
||||
dlokack(int fd, const char *what, char *bufp, char *ebuf)
|
||||
{
|
||||
|
|
|
@ -49,6 +49,7 @@ static const char rcsid[] _U_ =
|
|||
#include "dlpisubs.h"
|
||||
|
||||
/* Forwards. */
|
||||
static int dlpromiscon(pcap_t *, bpf_u_int32);
|
||||
static int pcap_read_libdlpi(pcap_t *, int, pcap_handler, u_char *);
|
||||
static int pcap_inject_libdlpi(pcap_t *, const void *, size_t);
|
||||
static void pcap_close_libdlpi(pcap_t *);
|
||||
|
@ -139,36 +140,45 @@ pcap_activate_libdlpi(pcap_t *p)
|
|||
|
||||
/* Enable promiscuous mode. */
|
||||
if (p->opt.promisc) {
|
||||
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
|
||||
if (retv != DLPI_SUCCESS) {
|
||||
pcap_libdlpi_err(p->opt.source,
|
||||
"dlpi_promisc(PHYSICAL)", retv, p->errbuf);
|
||||
err = dlpromiscon(p, DL_PROMISC_PHYS);
|
||||
if (err < 0) {
|
||||
/*
|
||||
* "You don't have permission to capture on
|
||||
* this device" and "you don't have permission
|
||||
* to capture in promiscuous mode on this
|
||||
* device" are different; let the user know,
|
||||
* so if they can't get permission to
|
||||
* capture in promiscuous mode, they can at
|
||||
* least try to capture in non-promiscuous
|
||||
* mode.
|
||||
*
|
||||
* XXX - you might have to capture in
|
||||
* promiscuous mode to see outgoing packets.
|
||||
*/
|
||||
if (err == PCAP_ERROR_PERM_DENIED)
|
||||
err = PCAP_ERROR_PROMISC_PERM_DENIED;
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
/* Try to enable multicast. */
|
||||
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
|
||||
if (retv != DLPI_SUCCESS) {
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
|
||||
retv, p->errbuf);
|
||||
err = dlpromiscon(p, DL_PROMISC_MULTI);
|
||||
if (err < 0)
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to enable SAP promiscuity. */
|
||||
retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP);
|
||||
if (retv != DLPI_SUCCESS) {
|
||||
if (p->opt.promisc) {
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
|
||||
retv, p->errbuf);
|
||||
err = dlpromiscon(p, DL_PROMISC_SAP);
|
||||
if (err < 0) {
|
||||
/*
|
||||
* Not fatal, since the DL_PROMISC_PHYS mode worked.
|
||||
* Report it as a warning, however.
|
||||
*/
|
||||
if (p->opt.promisc)
|
||||
err = PCAP_WARNING;
|
||||
else
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Not fatal, since the DL_PROMISC_PHYS mode worked. */
|
||||
fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
|
||||
" %s:(%s)\n", p->opt.source, dlpi_strerror(retv));
|
||||
}
|
||||
|
||||
/* Determine link type. */
|
||||
if ((retv = dlpi_info(p->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) {
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf);
|
||||
|
@ -219,6 +229,26 @@ bad:
|
|||
return (err);
|
||||
}
|
||||
|
||||
#define STRINGIFY(n) #n
|
||||
|
||||
static int
|
||||
dlpromiscon(pcap_t *p, bpf_u_int32 level)
|
||||
{
|
||||
int err;
|
||||
|
||||
retv = dlpi_promiscon(p->hd, level);
|
||||
if (retv != DLPI_SUCCESS) {
|
||||
if (retv == DL_SYSERR && errno == EACCES)
|
||||
err = PCAP_ERROR_PERM_DENIED;
|
||||
else
|
||||
err = PCAP_ERROR;
|
||||
pcap_libdlpi_err(p->opt.source, "dlpi_promiscon" STRINGIFY(level),
|
||||
retv, p->errbuf);
|
||||
return (err);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
|
||||
* network links that are plumbed and are up. dlpi_walk(3DLPI) will find
|
||||
|
|
6
pcap.c
6
pcap.c
|
@ -470,7 +470,8 @@ fail:
|
|||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
|
||||
p->errbuf);
|
||||
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
|
||||
status == PCAP_ERROR_PERM_DENIED)
|
||||
status == PCAP_ERROR_PERM_DENIED ||
|
||||
status == PCAP_ERROR_PROMISC_PERM_DENIED)
|
||||
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source,
|
||||
pcap_statustostr(status), p->errbuf);
|
||||
else
|
||||
|
@ -1149,6 +1150,9 @@ pcap_statustostr(int errnum)
|
|||
|
||||
case PCAP_ERROR_CANTSET_TSTAMP_TYPE:
|
||||
return ("That device doesn't support setting the time stamp type");
|
||||
|
||||
case PCAP_ERROR_PROMISC_PERM_DENIED:
|
||||
return ("You don't have permission to capture in promiscuous mode on that device");
|
||||
}
|
||||
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
|
||||
return(ebuf);
|
||||
|
|
|
@ -252,6 +252,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
|||
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
|
||||
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
|
||||
#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
|
||||
#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
|
||||
|
||||
/*
|
||||
* Warning codes for the pcap API.
|
||||
|
|
|
@ -57,6 +57,9 @@ 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_PROMISC_PERM_DENIED
|
||||
if the process has permission to open the capture source but doesn't
|
||||
have permission to put it into promiscuous mode,
|
||||
.B PCAP_ERROR_RFMON_NOTSUP
|
||||
if monitor mode was specified but the capture source doesn't support
|
||||
monitor mode,
|
||||
|
|
Reference in New Issue