summaryrefslogtreecommitdiffstats
path: root/contrib/libpcap/pcap-libdlpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libpcap/pcap-libdlpi.c')
-rw-r--r--contrib/libpcap/pcap-libdlpi.c72
1 files changed, 52 insertions, 20 deletions
diff --git a/contrib/libpcap/pcap-libdlpi.c b/contrib/libpcap/pcap-libdlpi.c
index 87cd08b..8d6a038 100644
--- a/contrib/libpcap/pcap-libdlpi.c
+++ b/contrib/libpcap/pcap-libdlpi.c
@@ -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 *);
@@ -114,7 +115,8 @@ pcap_activate_libdlpi(pcap_t *p)
if (retv != DLPI_SUCCESS) {
if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK)
err = PCAP_ERROR_NO_SUCH_DEVICE;
- else if (retv == DL_SYSERR && errno == EACCES)
+ else if (retv == DL_SYSERR &&
+ (errno == EPERM || errno == EACCES))
err = PCAP_ERROR_PERM_DENIED;
pcap_libdlpi_err(p->opt.source, "dlpi_open", retv,
p->errbuf);
@@ -139,34 +141,43 @@ 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. */
@@ -219,6 +230,27 @@ 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 == EPERM || 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
OpenPOWER on IntegriCloud