/* * We are only intested in DL_NOTE_LINK_UP events which we've registered for * in nwamd_dlpi_add_link(). But we have to keep calling dlpi_recv() to * force the notification callback to be executed. */ static void * nwamd_dlpi_thread(void *arg) { int rc; dlpi_handle_t *dh = arg; do { rc = dlpi_recv(*dh, NULL, NULL, NULL, NULL, -1, NULL); } while (rc == DLPI_SUCCESS); nlog(LOG_ERR, "dlpi_recv failed: %s", dlpi_strerror(rc)); return (NULL); }
/* * Read data received on DLPI handle. Returns -2 if told to terminate, else * returns the number of packets read. */ static int pcap_read_libdlpi(pcap_t *p, int count, pcap_handler callback, u_char *user) { struct pcap_dlpi *pd = p->priv; int len; u_char *bufp; size_t msglen; int retv; len = p->cc; if (len != 0) { bufp = p->bp; goto process_pkts; } do { /* Has "pcap_breakloop()" been called? */ if (p->break_loop) { /* * Yes - clear the flag that indicates that it has, * and return -2 to indicate that we were told to * break out of the loop. */ p->break_loop = 0; return (-2); } msglen = p->bufsize; bufp = p->buffer + p->offset; retv = dlpi_recv(pd->dlpi_hd, NULL, NULL, bufp, &msglen, -1, NULL); if (retv != DLPI_SUCCESS) { /* * This is most likely a call to terminate out of the * loop. So, do not return an error message, instead * check if "pcap_breakloop()" has been called above. */ if (retv == DL_SYSERR && errno == EINTR) { len = 0; continue; } pcap_libdlpi_err(dlpi_linkname(pd->dlpi_hd), "dlpi_recv", retv, p->errbuf); return (-1); } len = msglen; } while (len == 0); process_pkts: return (pcap_process_pkts(p, callback, user, count, bufp, len)); }
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); }