From e6b89d9420708a324c1e4bc3e6a2021709b3e875 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sun, 11 Oct 2009 22:15:24 -0700 Subject: If we get POLLERR when polling a socket in memory-mapped mode, do a recv() on the socket to get the error code. --- pcap-linux.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'pcap-linux.c') diff --git a/pcap-linux.c b/pcap-linux.c index 29d79c4..8356ba5 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -1365,7 +1365,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) * * XXX - we should really return * PCAP_ERROR_IFACE_NOT_UP, but pcap_dispatch() - * etc. aren't defined to retur that. + * etc. aren't defined to return that. */ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "The interface went down"); @@ -2934,6 +2934,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) { int pkts = 0; + char c; /* wait for frames availability.*/ if ((handle->md.timeout >= 0) && @@ -2970,9 +2971,35 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, return PCAP_ERROR; } if (pollinfo.revents & POLLERR) { - snprintf(handle->errbuf, - PCAP_ERRBUF_SIZE, - "Error condition on packet socket"); + /* + * A recv() will give us the + * actual error code. + * + * XXX - make the socket non-blocking? + */ + if (recv(handle->fd, c, sizeof c, + MSG_PEEK) != -1) + continue; /* what, no error? */ + if (errno == ENETDOWN) { + /* + * The device on which we're + * capturing went away. + * + * XXX - we should really return + * PCAP_ERROR_IFACE_NOT_UP, + * but pcap_dispatch() etc. + * aren't defined to return + * that. + */ + snprintf(handle->errbuf, + PCAP_ERRBUF_SIZE, + "The interface went down"); + } else { + snprintf(handle->errbuf, + PCAP_ERRBUF_SIZE, + "Error condition on packet socket: %s", + strerror(errno)); + } return PCAP_ERROR; } if (pollinfo.revents & POLLNVAL) { -- cgit v1.2.3