]> The Tcpdump Group git mirrors - libpcap/commitdiff
(pcap_open_live): repair BIOCSBLEN loop. from Guy Harris <[email protected]>
authorassar <assar>
Tue, 11 Jul 2000 23:00:05 +0000 (23:00 +0000)
committerassar <assar>
Tue, 11 Jul 2000 23:00:05 +0000 (23:00 +0000)
pcap-bpf.c

index 566e5869a960251e0c2913892604c46d71626ac2..137e407698e0385e18fb15dc35ef35b740a792e1 100644 (file)
@@ -20,7 +20,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.35 2000-07-11 00:37:05 assar Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.36 2000-07-11 23:00:05 assar Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -195,29 +195,43 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
                    "kernel bpf filter out of date");
                goto bad;
        }
+
+       /*
+        * Try finding a good size for the buffer; 32768 may be too
+        * big, so keep cutting it in half until we find a size
+        * that works, or run out of sizes to try.
+        */
        v = 32768;      /* XXX this should be a user-accessible hook */
-       /* try finding a good size for the buffer */
-       do {
-               (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
-               (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
-               if ((ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) &&
-                   (errno != ENOBUFS)) {
-                       snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
-                           errno, device, pcap_strerror(errno));
-                       goto bad;
-               }
-               v >>= 2;
-       } while (fd < 0 && errno == ENOBUFS);
-
-       (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
-
-       (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
-       if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
-               snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s",
-                   device, pcap_strerror(errno));
+       do {
+               /* Ignore the return value - this is because the call fails
+                * on BPF systems that don't have kernel malloc.  And if
+                * the call fails, it's no big deal, we just continue to
+                * use the standard buffer size.
+                */
+               (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
+
+               (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+               if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
+                       break;  /* that size worked; we're done */
+
+               if (errno != ENOBUFS) {
+                       snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
+                           device, pcap_strerror(errno));
+                       goto bad;
+               }
+
+               /*
+                * Try a smaller size.
+                */
+               v >>= 2;
+       } while (v != 0);
+
+       if (v == 0) {
+               snprintf(ebuf, PCAP_ERRBUF_SIZE,
+                        "BIOCSBLEN: %s: No buffer size worked", device);
                goto bad;
        }
+
        /* Get the data link layer type. */
        if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
                snprintf(ebuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",