]> The Tcpdump Group git mirrors - libpcap/commitdiff
Merge branch 'master' of git://github.com/mcr/libpcap
authorStephen Donnelly <[email protected]>
Wed, 14 Oct 2009 00:51:40 +0000 (13:51 +1300)
committerStephen Donnelly <[email protected]>
Wed, 14 Oct 2009 00:51:40 +0000 (13:51 +1300)
CREDITS
pcap-bpf.c
pcap-linux.c
pcap_get_selectable_fd.3pcap

diff --git a/CREDITS b/CREDITS
index 1ed5b664a90a1853459ab4091036f7e82e9af757..326afa585a193379b76a2b82e72031e430a2fa14 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -84,6 +84,7 @@ Additional people who have contributed patches:
        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>
index b0408da254cd6af89f2e08657afc81151dad76e4..86d1bee048386257805a78b86baa9fd77aaf6942 100644 (file)
@@ -1050,20 +1050,24 @@ bpf_odmcleanup(char *errbuf)
        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);
        }
 
@@ -1096,7 +1100,7 @@ bpf_load(char *errbuf)
        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);
        }
 
@@ -1107,7 +1111,7 @@ bpf_load(char *errbuf)
                        snprintf(errbuf, PCAP_ERRBUF_SIZE,
                            "bpf_load: genminor failed: %s",
                            pcap_strerror(errno));
-                       (void)bpf_odmcleanup(errbuf);
+                       (void)bpf_odmcleanup(NULL);
                        return (PCAP_ERROR);
                }
        }
index 8356ba54ef0d8fea6de6a8f8734bce00980fb211..9703040f183298c3a0d04c5363d27c2528802f68 100644 (file)
@@ -2929,42 +2929,47 @@ pcap_get_ring_frame(pcap_t *handle, int status)
        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");
@@ -2977,7 +2982,7 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
                                         *
                                         * 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) {
index 6cc4aa195e0e463ecba25f993337f63f8bcfb640..61be3d32e8ab975052ae019aa59a559a710e5395 100644 (file)
@@ -104,6 +104,11 @@ can be used on the descriptor returned by
 .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.