pcap_cleanup_live_common(handle);
}
+/*
+ * We don't support non-blocking mode. I'm not sure what we'd
+ * do to support it and, given that we don't support select()/
+ * poll()/epoll()/kqueue watch etc., it probably doesn't
+ * matter.
+ */
+static int
+dbus_getnonblock(pcap_t *p)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing on D-Bus");
+ return (-1);
+}
+
+static int
+dbus_setnonblock(pcap_t *p, int nonblock _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing on D-Bus");
+ return (-1);
+}
+
static int
dbus_activate(pcap_t *handle)
{
handle->setfilter_op = install_bpf_program; /* XXX, later add support for dbus_bus_add_match() */
handle->setdirection_op = NULL;
handle->set_datalink_op = NULL; /* can't change data link type */
-#ifndef _WIN32
- handle->getnonblock_op = pcap_getnonblock_fd;
- handle->setnonblock_op = pcap_setnonblock_fd;
-#endif
+ handle->getnonblock_op = dbus_getnonblock;
+ handle->setnonblock_op = dbus_setnonblock;
handle->stats_op = dbus_stats;
handle->cleanup_op = dbus_cleanup;
#ifndef _WIN32
+ /*
+ * Unfortunately, trying to do a select()/poll()/epoll()/
+ * kqueue watch/etc. on a D-Bus connection isn't a simple
+ * case of "give me an FD on which to wait".
+ *
+ * Apparently, you have to register "add watch", "remove watch",
+ * and "toggle watch" functions with
+ * dbus_connection_set_watch_functions(),
+ * keep a *set* of FDs, add to that set in the "add watch"
+ * function, subtract from it in the "remove watch" function,
+ * and either add to or subtract from that set in the "toggle
+ * watch" function, and do the wait on *all* of the FDs in the
+ * set. (Yes, you need the "toggle watch" function, so that
+ * the main loop doesn't itself need to check for whether
+ * a given watch is enabled or disabled - most libpcap programs
+ * know nothing about D-Bus and shouldn't *have* to know anything
+ * about D-Bus other than how to decode D-Bus messages.)
+ *
+ * Implementing that would require considerable changes in
+ * the way libpcap exports "selectable FDs" to its client.
+ * Until that's done, we just say "you can't do that".
+ */
handle->selectable_fd = handle->fd = -1;
#endif
return (NULL);
p->activate_op = dbus_activate;
+#ifndef _WIN32
+ /*
+ * Set these up front, so that, even if our client tries
+ * to set non-blocking mode before we're activated, or
+ * query the state of non-blocking mode, they get an error,
+ * rather than having the non-blocking mode option set
+ * for use later.
+ */
+ p->getnonblock_op = dbus_getnonblock;
+ p->setnonblock_op = dbus_setnonblock;
+#endif
return (p);
}
return 0;
}
+/* We don't currently support non-blocking mode. */
+static int
+pcap_getnonblock_rpcap(pcap_t *p)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing remotely with rpcap");
+ return (-1);
+}
+
+static int
+pcap_setnonblock_rpcap(pcap_t *p, int nonblock _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Non-blocking mode isn't supported for capturing remotely with rpcap");
+ return (-1);
+}
+
/*
* This function opens a remote adapter by opening an RPCAP connection and
* so on.
fp->read_op = pcap_read_rpcap;
fp->save_current_filter_op = pcap_save_current_filter_rpcap;
fp->setfilter_op = pcap_setfilter_rpcap;
- fp->getnonblock_op = NULL; /* This is not implemented in remote capture */
- fp->setnonblock_op = NULL; /* This is not implemented in remote capture */
+ fp->getnonblock_op = pcap_getnonblock_rpcap;
+ fp->setnonblock_op = pcap_setnonblock_rpcap;
fp->stats_op = pcap_stats_rpcap;
#ifdef _WIN32
fp->stats_ex_op = pcap_stats_ex_rpcap;
return NULL;
p->activate_op = TcActivate;
- p->setnonblock_op = TcSetNonBlock; /* not supported */
+ /*
+ * Set these up front, so that, even if our client tries
+ * to set non-blocking mode before we're activated, or
+ * query the state of non-blocking mode, they get an error,
+ * rather than having the non-blocking mode option set
+ * for use later.
+ */
+ p->getnonblock_op = TcGetNonBlock;
+ p->setnonblock_op = TcSetNonBlock;
return p;
}
static int TcGetNonBlock(pcap_t *p)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Getting the non blocking status is not available for TurboCap ports");
- return -1;
-
+ "Non-blocking mode isn't supported for TurboCap ports");
+ return -1;
}
+
static int TcSetNonBlock(pcap_t *p, int nonblock)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "Setting the non blocking status is not available for TurboCap ports");
- return -1;
+ "Non-blocking mode isn't supported for TurboCap ports");
+ return -1;
}
-
static void TcCleanup(pcap_t *p)
{
struct pcap_tc *pt = p->priv;