Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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().
  • Loading branch information...
commit 74b7b4259fde15dbb07cde3a5920e9f7e0ed4484 1 parent b26d8d2
Guy Harris guyharris authored
84 pcap-dlpi.c
@@ -143,10 +143,9 @@ static int dl_doattach(int, int, char *);
143 143 #ifdef DL_HP_RAWDLS
144 144 static int dl_dohpuxbind(int, char *);
145 145 #endif
146   -static int dlattachreq(int, bpf_u_int32, char *);
  146 +static int dlpromiscon(pcap_t *, bpf_u_int32);
147 147 static int dlbindreq(int, bpf_u_int32, char *);
148 148 static int dlbindack(int, char *, char *, int *);
149   -static int dlpromisconreq(int, bpf_u_int32, char *);
150 149 static int dlokack(int, const char *, char *, char *);
151 150 static int dlinforeq(int, char *);
152 151 static int dlinfoack(int, char *, char *);
@@ -610,9 +609,12 @@ pcap_activate_dlpi(pcap_t *p)
610 609 /*
611 610 ** Enable promiscuous (not necessary on send FD)
612 611 */
613   - if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
614   - dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
  612 + status = dlpromiscon(p, DL_PROMISC_PHYS);
  613 + if (status < 0) {
  614 + if (status == PCAP_ERROR_PERM_DENIED)
  615 + status = PCAP_ERROR_PROMISC_PERM_DENIED;
615 616 goto bad;
  617 + }
616 618
617 619 /*
618 620 ** Try to enable multicast (you would have thought
@@ -620,8 +622,8 @@ pcap_activate_dlpi(pcap_t *p)
620 622 ** HP-UX or SINIX) (Not necessary on send FD)
621 623 */
622 624 #if !defined(__hpux) && !defined(sinix)
623   - if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
624   - dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
  625 + status = dlpromiscon(p, DL_PROMISC_MULTI);
  626 + if (status < 0)
625 627 status = PCAP_WARNING;
626 628 #endif
627 629 }
@@ -636,15 +638,20 @@ pcap_activate_dlpi(pcap_t *p)
636 638 !p->opt.promisc &&
637 639 #endif
638 640 #ifdef HAVE_SOLARIS
639   - !isatm &&
  641 + !isatm
640 642 #endif
641   - (dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
642   - dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
643   - /* Not fatal if promisc since the DL_PROMISC_PHYS worked */
644   - if (p->opt.promisc)
645   - status = PCAP_WARNING;
646   - else
647   - goto bad;
  643 + ) {
  644 + status = dlpromiscon(p, DL_PROMISC_SAP);
  645 + if (status < 0) {
  646 + /*
  647 + * Not fatal, since the DL_PROMISC_PHYS mode worked.
  648 + * Report it as a warning, however.
  649 + */
  650 + if (p->opt.promisc)
  651 + status = PCAP_WARNING;
  652 + else
  653 + goto bad;
  654 + }
648 655 }
649 656 #endif /* sinix */
650 657
@@ -815,11 +822,15 @@ split_dname(char *device, int *unitp, char *ebuf)
815 822 static int
816 823 dl_doattach(int fd, int ppa, char *ebuf)
817 824 {
  825 + dl_attach_req_t req;
818 826 bpf_u_int32 buf[MAXDLBUF];
819 827 int err;
820 828
821   - if (dlattachreq(fd, ppa, ebuf) < 0)
  829 + req.dl_primitive = DL_ATTACH_REQ;
  830 + req.dl_ppa = ppa;
  831 + if (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf) < 0)
822 832 return (PCAP_ERROR);
  833 +
823 834 err = dlokack(fd, "attach", (char *)buf, ebuf);
824 835 if (err < 0)
825 836 return (err);
@@ -877,6 +888,27 @@ dl_dohpuxbind(int fd, char *ebuf)
877 888 }
878 889 #endif
879 890
  891 +#define STRINGIFY(n) #n
  892 +
  893 +static int
  894 +dlpromiscon(pcap_t *p, bpf_u_int32 level)
  895 +{
  896 + dl_promiscon_req_t req;
  897 + bpf_u_int32 buf[MAXDLBUF];
  898 + int err;
  899 +
  900 + req.dl_primitive = DL_PROMISCON_REQ;
  901 + req.dl_level = level;
  902 + if (send_request(p->fd, (char *)&req, sizeof(req), "promiscon",
  903 + p->errbuf) < 0)
  904 + return (PCAP_ERROR);
  905 + err = dlokack(p->fd, "promiscon" STRINGIFY(level), (char *)buf,
  906 + p->errbuf);
  907 + if (err < 0)
  908 + return (err);
  909 + return (0);
  910 +}
  911 +
880 912 int
881 913 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
882 914 {
@@ -1222,17 +1254,6 @@ dlprim(bpf_u_int32 prim)
1222 1254 }
1223 1255
1224 1256 static int
1225   -dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf)
1226   -{
1227   - dl_attach_req_t req;
1228   -
1229   - req.dl_primitive = DL_ATTACH_REQ;
1230   - req.dl_ppa = ppa;
1231   -
1232   - return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));
1233   -}
1234   -
1235   -static int
1236 1257 dlbindreq(int fd, bpf_u_int32 sap, char *ebuf)
1237 1258 {
1238 1259
@@ -1260,17 +1281,6 @@ dlbindack(int fd, char *bufp, char *ebuf, int *uerror)
1260 1281 }
1261 1282
1262 1283 static int
1263   -dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf)
1264   -{
1265   - dl_promiscon_req_t req;
1266   -
1267   - req.dl_primitive = DL_PROMISCON_REQ;
1268   - req.dl_level = level;
1269   -
1270   - return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));
1271   -}
1272   -
1273   -static int
1274 1284 dlokack(int fd, const char *what, char *bufp, char *ebuf)
1275 1285 {
1276 1286
68 pcap-libdlpi.c
@@ -49,6 +49,7 @@ static const char rcsid[] _U_ =
49 49 #include "dlpisubs.h"
50 50
51 51 /* Forwards. */
  52 +static int dlpromiscon(pcap_t *, bpf_u_int32);
52 53 static int pcap_read_libdlpi(pcap_t *, int, pcap_handler, u_char *);
53 54 static int pcap_inject_libdlpi(pcap_t *, const void *, size_t);
54 55 static void pcap_close_libdlpi(pcap_t *);
@@ -139,34 +140,43 @@ pcap_activate_libdlpi(pcap_t *p)
139 140
140 141 /* Enable promiscuous mode. */
141 142 if (p->opt.promisc) {
142   - retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_PHYS);
143   - if (retv != DLPI_SUCCESS) {
144   - pcap_libdlpi_err(p->opt.source,
145   - "dlpi_promisc(PHYSICAL)", retv, p->errbuf);
  143 + err = dlpromiscon(p, DL_PROMISC_PHYS);
  144 + if (err < 0) {
  145 + /*
  146 + * "You don't have permission to capture on
  147 + * this device" and "you don't have permission
  148 + * to capture in promiscuous mode on this
  149 + * device" are different; let the user know,
  150 + * so if they can't get permission to
  151 + * capture in promiscuous mode, they can at
  152 + * least try to capture in non-promiscuous
  153 + * mode.
  154 + *
  155 + * XXX - you might have to capture in
  156 + * promiscuous mode to see outgoing packets.
  157 + */
  158 + if (err == PCAP_ERROR_PERM_DENIED)
  159 + err = PCAP_ERROR_PROMISC_PERM_DENIED;
146 160 goto bad;
147 161 }
148 162 } else {
149 163 /* Try to enable multicast. */
150   - retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_MULTI);
151   - if (retv != DLPI_SUCCESS) {
152   - pcap_libdlpi_err(p->opt.source, "dlpi_promisc(MULTI)",
153   - retv, p->errbuf);
  164 + err = dlpromiscon(p, DL_PROMISC_MULTI);
  165 + if (err < 0)
154 166 goto bad;
155   - }
156 167 }
157 168
158 169 /* Try to enable SAP promiscuity. */
159   - retv = dlpi_promiscon(p->dlpi_hd, DL_PROMISC_SAP);
160   - if (retv != DLPI_SUCCESS) {
161   - if (p->opt.promisc) {
162   - pcap_libdlpi_err(p->opt.source, "dlpi_promisc(SAP)",
163   - retv, p->errbuf);
  170 + err = dlpromiscon(p, DL_PROMISC_SAP);
  171 + if (err < 0) {
  172 + /*
  173 + * Not fatal, since the DL_PROMISC_PHYS mode worked.
  174 + * Report it as a warning, however.
  175 + */
  176 + if (p->opt.promisc)
  177 + err = PCAP_WARNING;
  178 + else
164 179 goto bad;
165   - }
166   -
167   - /* Not fatal, since the DL_PROMISC_PHYS mode worked. */
168   - fprintf(stderr, "WARNING: dlpi_promisc(SAP) failed on"
169   - " %s:(%s)\n", p->opt.source, dlpi_strerror(retv));
170 180 }
171 181
172 182 /* Determine link type. */
@@ -219,6 +229,26 @@ pcap_activate_libdlpi(pcap_t *p)
219 229 return (err);
220 230 }
221 231
  232 +#define STRINGIFY(n) #n
  233 +
  234 +static int
  235 +dlpromiscon(pcap_t *p, bpf_u_int32 level)
  236 +{
  237 + int err;
  238 +
  239 + retv = dlpi_promiscon(p->hd, level);
  240 + if (retv != DLPI_SUCCESS) {
  241 + if (retv == DL_SYSERR && errno == EACCES)
  242 + err = PCAP_ERROR_PERM_DENIED;
  243 + else
  244 + err = PCAP_ERROR;
  245 + pcap_libdlpi_err(p->opt.source, "dlpi_promiscon" STRINGIFY(level),
  246 + retv, p->errbuf);
  247 + return (err);
  248 + }
  249 + return (0);
  250 +}
  251 +
222 252 /*
223 253 * In Solaris, the "standard" mechanism" i.e SIOCGLIFCONF will only find
224 254 * network links that are plumbed and are up. dlpi_walk(3DLPI) will find
6 pcap.c
@@ -470,7 +470,8 @@ pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *er
470 470 snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
471 471 p->errbuf);
472 472 else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
473   - status == PCAP_ERROR_PERM_DENIED)
  473 + status == PCAP_ERROR_PERM_DENIED ||
  474 + status == PCAP_ERROR_PROMISC_PERM_DENIED)
474 475 snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source,
475 476 pcap_statustostr(status), p->errbuf);
476 477 else
@@ -1149,6 +1150,9 @@ pcap_statustostr(int errnum)
1149 1150
1150 1151 case PCAP_ERROR_CANTSET_TSTAMP_TYPE:
1151 1152 return ("That device doesn't support setting the time stamp type");
  1153 +
  1154 + case PCAP_ERROR_PROMISC_PERM_DENIED:
  1155 + return ("You don't have permission to capture in promiscuous mode on that device");
1152 1156 }
1153 1157 (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
1154 1158 return(ebuf);
1  pcap/pcap.h
@@ -252,6 +252,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
252 252 #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
253 253 #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
254 254 #define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
  255 +#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
255 256
256 257 /*
257 258 * Warning codes for the pcap API.
3  pcap_activate.3pcap
@@ -57,6 +57,9 @@ if the capture source specified when the handle was created doesn't
57 57 exist,
58 58 .B PCAP_ERROR_PERM_DENIED
59 59 if the process doesn't have permission to open the capture source,
  60 +.B PCAP_ERROR_PROMISC_PERM_DENIED
  61 +if the process has permission to open the capture source but doesn't
  62 +have permission to put it into promiscuous mode,
60 63 .B PCAP_ERROR_RFMON_NOTSUP
61 64 if monitor mode was specified but the capture source doesn't support
62 65 monitor mode,

0 comments on commit 74b7b42

Please sign in to comment.
Something went wrong with that request. Please try again.