Mike Kershaw <dragorn at kismetwireless dot net>
Mike Wiacek <mike at iroot dot net>
Monroe Williams <monroe at pobox dot com>
+ N. Leiten <nleiten at sourceforge dot net>
Nicolas Dade <ndade at nsd dot dyndns dot org>
Octavian Cerna <tavy at ylabs dot com>
Olaf Kirch <okir at caldera dot de>
char *errstr;
if (odm_unlock(odmlockid) == -1) {
- if (odm_err_msg(odmerrno, &errstr) == -1)
- errstr = "Unknown error";
- snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: odm_unlock failed: %s",
- errstr);
+ if (errbuf != NULL) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_unlock failed: %s",
+ errstr);
+ }
return (PCAP_ERROR);
}
if (odm_terminate() == -1) {
- if (odm_err_msg(odmerrno, &errstr) == -1)
- errstr = "Unknown error";
- snprintf(errbuf, PCAP_ERRBUF_SIZE,
- "bpf_load: odm_terminate failed: %s",
- errstr);
+ if (errbuf != NULL) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_terminate failed: %s",
+ errstr);
+ }
return (PCAP_ERROR);
}
if (major == -1) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: genmajor failed: %s", pcap_strerror(errno));
- (void)bpf_odmcleanup(errbuf);
+ (void)bpf_odmcleanup(NULL);
return (PCAP_ERROR);
}
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"bpf_load: genminor failed: %s",
pcap_strerror(errno));
- (void)bpf_odmcleanup(errbuf);
+ (void)bpf_odmcleanup(NULL);
return (PCAP_ERROR);
}
}
return h.raw;
}
+#ifndef POLLRDHUP
+#define POLLRDHUP 0
+#endif
+
static int
pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
u_char *user)
{
+ int timeout;
int pkts = 0;
char c;
/* wait for frames availability.*/
- if ((handle->md.timeout >= 0) &&
- !pcap_get_ring_frame(handle, TP_STATUS_USER)) {
+ if (!pcap_get_ring_frame(handle, TP_STATUS_USER)) {
struct pollfd pollinfo;
int ret;
pollinfo.fd = handle->fd;
pollinfo.events = POLLIN;
+ if (handle->md.timeout == 0)
+ timeout = -1; /* block forever */
+ else if (handle->md.timeout > 0)
+ timeout = handle->md.timeout; /* block for that amount of time */
+ else
+ timeout = 0; /* non-blocking mode - poll to pick up errors */
do {
- /* poll() requires a negative timeout to wait forever */
- ret = poll(&pollinfo, 1, (handle->md.timeout > 0)?
- handle->md.timeout: -1);
- if ((ret < 0) && (errno != EINTR)) {
+ ret = poll(&pollinfo, 1, timeout);
+ if (ret < 0 && errno != EINTR) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't poll on packet socket: %s",
pcap_strerror(errno));
return PCAP_ERROR;
- } else if (ret > 0) {
+ } else if (ret > 0 &&
+ (pollinfo.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
/*
- * There's some indication on the descriptor.
- * Check for indications other than
- * "you can read on this descriptor".
+ * There's some indication other than
+ * "you can read on this descriptor" on
+ * the descriptor.
*/
-#ifdef POLLRDHUP
if (pollinfo.revents & (POLLHUP | POLLRDHUP)) {
-#else
- if (pollinfo.revents & POLLHUP) {
-#endif
snprintf(handle->errbuf,
PCAP_ERRBUF_SIZE,
"Hangup on packet socket");
*
* XXX - make the socket non-blocking?
*/
- if (recv(handle->fd, c, sizeof c,
+ if (recv(handle->fd, &c, sizeof c,
MSG_PEEK) != -1)
continue; /* what, no error? */
if (errno == ENETDOWN) {
.B poll()
cannot be used on it those versions of Mac OS X. Kqueues also don't
work on that descriptor.
+.BR poll() ,
+but not kqueues, work on that descriptor in Mac OS X releases prior to
+10.4;
+.B poll()
+and kqueues work on that descriptor in Mac OS X 10.6 and later.
.PP
.B pcap_get_selectable_fd()
is not available on Windows.