int main(int argc, char *argv[]) { int c, ret; char *eptr; unsigned long sap; uint_t bind_sap; dlpi_handle_t dh; dlrecv_prog = basename(argv[0]); while ((c = getopt(argc, argv, ":s:")) != -1) { switch (c) { case 's': errno = 0; sap = strtoul(optarg, &eptr, 10); if (errno != 0 || sap == 0 || sap >= UINT16_MAX || *eptr != '\0') { dlrecv_usage("Invalid value for sap (-s): %s\n", optarg); return (2); } dlrecv_sap = sap; break; case ':': dlrecv_usage("Option -%c requires an operand\n", optopt); return (2); case '?': dlrecv_usage("Unknown option: -%c\n", optopt); return (2); } } argc -= optind; argv += optind; if (argc != 1) { dlrecv_usage("missing required operands\n"); return (2); } if ((ret = dlpi_open(argv[0], &dh, 0)) != DLPI_SUCCESS) { warnx("failed to open %s: %s\n", argv[0], dlpi_strerror(ret)); exit(1); } if ((ret = dlpi_bind(dh, dlrecv_sap, &bind_sap)) != DLPI_SUCCESS) { warnx("failed to bind to sap 0x%x: %s\n", dlrecv_sap, dlpi_strerror(ret)); exit(1); } if (bind_sap != dlrecv_sap) { warnx("failed to bind to requested sap 0x%x, bound to " "0x%x\n", dlrecv_sap, bind_sap); exit(1); } for (;;) { dlpi_recvinfo_t rinfo; dlsend_msg_t msg; size_t msglen; boolean_t invalid = B_FALSE; msglen = sizeof (msg); ret = dlpi_recv(dh, NULL, NULL, &msg, &msglen, -1, &rinfo); if (ret != DLPI_SUCCESS) { warnx("failed to receive data: %s\n", dlpi_strerror(ret)); continue; } if (msglen != rinfo.dri_totmsglen) { warnx("message truncated: expected %ld bytes, " "got %ld\n", sizeof (dlsend_msg_t), rinfo.dri_totmsglen); invalid = B_TRUE; } if (msglen != sizeof (msg)) { warnx("message too short: expected %ld bytes, " "got %ld\n", sizeof (dlsend_msg_t), msglen); invalid = B_TRUE; } if (!invalid) { invalid = !dlrecv_isvalid(&msg); } dlrecv_print(&msg, &rinfo, invalid); } /* LINTED: E_STMT_NOT_REACHED */ return (0); }
static int pcap_activate_libdlpi(pcap_t *p) { struct pcap_dlpi *pd = p->priv; int retv; dlpi_handle_t dh; dlpi_info_t dlinfo; int err = PCAP_ERROR; /* * Enable Solaris raw and passive DLPI extensions; * dlpi_open() will not fail if the underlying link does not support * passive mode. See dlpi(7P) for details. */ retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE); if (retv != DLPI_SUCCESS) { if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK) err = PCAP_ERROR_NO_SUCH_DEVICE; 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); return (err); } pd->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. */ if ((retv = dlpi_bind(pd->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) { pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf); goto bad; } /* Enable promiscuous mode. */ if (p->opt.promisc) { 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. */ err = dlpromiscon(p, DL_PROMISC_MULTI); if (err < 0) goto bad; } /* Try to enable SAP promiscuity. */ 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; } /* Determine link type. */ if ((retv = dlpi_info(pd->dlpi_hd, &dlinfo, 0)) != DLPI_SUCCESS) { pcap_libdlpi_err(p->opt.source, "dlpi_info", retv, p->errbuf); goto bad; } if (pcap_process_mactype(p, dlinfo.di_mactype) != 0) goto bad; p->fd = dlpi_fd(pd->dlpi_hd); /* Push and configure bufmod. */ if (pcap_conf_bufmod(p, p->snapshot) != 0) goto bad; /* * Flush the read side. */ if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", pcap_strerror(errno)); goto bad; } /* Allocate data buffer. */ if (pcap_alloc_databuf(p) != 0) goto bad; /* * "p->fd" is a FD for a STREAMS device, so "select()" and * "poll()" should work on it. */ p->selectable_fd = p->fd; p->read_op = pcap_read_libdlpi; p->inject_op = pcap_inject_libdlpi; p->setfilter_op = install_bpf_program; /* No kernel filtering */ p->setdirection_op = NULL; /* Not implemented */ p->set_datalink_op = NULL; /* Can't change data link type */ p->getnonblock_op = pcap_getnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd; p->stats_op = pcap_stats_dlpi; p->cleanup_op = pcap_cleanup_libdlpi; return (0); bad: pcap_cleanup_libdlpi(p); return (err); }
static int pcap_activate_libdlpi(pcap_t *p) { int retv; dlpi_handle_t dh; dlpi_info_t dlinfo; int err = PCAP_ERROR; /* * Enable Solaris raw and passive DLPI extensions; * dlpi_open() will not fail if the underlying link does not support * passive mode. See dlpi(7P) for details. */ retv = dlpi_open(p->opt.source, &dh, DLPI_RAW|DLPI_PASSIVE); if (retv != DLPI_SUCCESS) { if (retv == DLPI_ELINKNAMEINVAL || retv == DLPI_ENOLINK) err = PCAP_ERROR_NO_SUCH_DEVICE; else if (retv == DL_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; 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. */ if ((retv = dlpi_bind(p->dlpi_hd, DLPI_ANY_SAP, 0)) != DLPI_SUCCESS) { pcap_libdlpi_err(p->opt.source, "dlpi_bind", retv, p->errbuf); goto bad; } /* 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); 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); 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); 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); goto bad; } if (pcap_process_mactype(p, dlinfo.di_mactype) != 0) goto bad; p->fd = dlpi_fd(p->dlpi_hd); /* Push and configure bufmod. */ if (pcap_conf_bufmod(p, p->snapshot, p->md.timeout) != 0) goto bad; /* * Flush the read side. */ if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) { snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s", pcap_strerror(errno)); goto bad; } /* Allocate data buffer. */ if (pcap_alloc_databuf(p) != 0) goto bad; /* * "p->fd" is a FD for a STREAMS device, so "select()" and * "poll()" should work on it. */ p->selectable_fd = p->fd; p->read_op = pcap_read_libdlpi; p->inject_op = pcap_inject_libdlpi; p->setfilter_op = install_bpf_program; /* No kernel filtering */ p->setdirection_op = NULL; /* Not implemented */ p->set_datalink_op = NULL; /* Can't change data link type */ p->getnonblock_op = pcap_getnonblock_fd; p->setnonblock_op = pcap_setnonblock_fd; p->stats_op = pcap_stats_dlpi; p->cleanup_op = pcap_cleanup_libdlpi; return (0); bad: pcap_cleanup_libdlpi(p); return (err); }