]> The Tcpdump Group git mirrors - libpcap/commitdiff
In pcap_open(), use pcap_create() and pcap_activate() for local interfaces.
authorGuy Harris <[email protected]>
Mon, 13 Mar 2017 22:20:10 +0000 (15:20 -0700)
committerGuy Harris <[email protected]>
Mon, 13 Mar 2017 22:20:10 +0000 (15:20 -0700)
This allows PCAP_OPENFLAG_MAX_RESPONSIVENESS to work on UN*X (it means
"immediate mode").

pcap-new.c
pcap/pcap.h

index 8c526225271db9efb5a1963d1b7137e84843abff..08ba85c9d625b00d31cd507a182e4bea6d983da7 100644 (file)
@@ -554,6 +554,7 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
        char name[PCAP_BUF_SIZE];
        int type;
        pcap_t *fp;
        char name[PCAP_BUF_SIZE];
        int type;
        pcap_t *fp;
+       int status;
 
        if (strlen(source) > PCAP_BUF_SIZE)
        {
 
        if (strlen(source) > PCAP_BUF_SIZE)
        {
@@ -574,24 +575,42 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
                fp = pcap_open_offline(name, errbuf);
                break;
 
                fp = pcap_open_offline(name, errbuf);
                break;
 
-       case PCAP_SRC_IFREMOTE:
-               /*
-                * Although we already have host, port and iface, we prefer
-                * to pass only 'source' to pcap_open_rpcap(), so that it
-                * has to call pcap_parsesrcstr() again.
-                * This is less optimized, but much clearer.
-                */
-               fp = pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
-               break;
-
        case PCAP_SRC_IFLOCAL:
        case PCAP_SRC_IFLOCAL:
-               fp = pcap_open_live(name, snaplen, (flags & PCAP_OPENFLAG_PROMISCUOUS), read_timeout, errbuf);
-
+               fp = pcap_create(source, errbuf);
+               if (fp == NULL)
+                       return (NULL);
+               status = pcap_set_snaplen(fp, snaplen);
+               if (status < 0)
+                       goto fail;
+               if (flags & PCAP_OPENFLAG_PROMISCUOUS)
+               {
+                       status = pcap_set_promisc(fp, 1);
+                       if (status < 0)
+                               goto fail;
+               }
+               if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS)
+               {
+                       status = pcap_set_immediate_mode(fp, 1);
+                       if (status < 0)
+                               goto fail;
+               }
+               status = pcap_set_timeout(fp, read_timeout);
+               if (status < 0)
+                       goto fail;
+               status = pcap_activate(fp);
+               if (status < 0)
+                       goto fail;
 #ifdef _WIN32
                /*
 #ifdef _WIN32
                /*
-                * these flags are supported on Windows only
+                * This flag is supported on Windows only.
+                * XXX - is there a way to support it with
+                * the capture mechanisms on UN*X?  It's not
+                * exactly a "set direction" operation; I
+                * think it means "do not capture packets
+                * injected with pcap_sendpacket() or
+                * pcap_inject()".
                 */
                 */
-               if (fp != NULL && fp->adapter != NULL)
+               if (fp->adapter != NULL)
                {
                        /* disable loopback capture if requested */
                        if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
                {
                        /* disable loopback capture if requested */
                        if (flags & PCAP_OPENFLAG_NOCAPTURE_LOCAL)
@@ -603,20 +622,33 @@ pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout,
                                        return NULL;
                                }
                        }
                                        return NULL;
                                }
                        }
-
-                       /* set mintocopy to zero if requested */
-                       if (flags & PCAP_OPENFLAG_MAX_RESPONSIVENESS)
-                       {
-                               if (!PacketSetMinToCopy(fp->adapter, 0))
-                               {
-                                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Unable to set max responsiveness.");
-                                       pcap_close(fp);
-                                       return NULL;
-                               }
-                       }
                }
 #endif /* _WIN32 */
                }
 #endif /* _WIN32 */
+               break;
+
+       fail:
+               if (status == PCAP_ERROR)
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+                           source, fp->errbuf);
+               else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
+                   status == PCAP_ERROR_PERM_DENIED ||
+                   status == PCAP_ERROR_PROMISC_PERM_DENIED)
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)",
+                           source, pcap_statustostr(status), fp->errbuf);
+               else
+                       pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+                           source, pcap_statustostr(status));
+               pcap_close(fp);
+               return NULL;
 
 
+       case PCAP_SRC_IFREMOTE:
+               /*
+                * Although we already have host, port and iface, we prefer
+                * to pass only 'source' to pcap_open_rpcap(), so that it
+                * has to call pcap_parsesrcstr() again.
+                * This is less optimized, but much clearer.
+                */
+               fp = pcap_open_rpcap(source, snaplen, flags, read_timeout, auth, errbuf);
                break;
 
        default:
                break;
 
        default:
index 5bb02057190e5d03a9d0ff81e6fe177feb7c17a2..82d48dde68a4349da4dd37cffba6cc17f9e1f510 100644 (file)
@@ -695,8 +695,6 @@ PCAP_API void       bpf_dump(const struct bpf_program *, int);
  * a bridge) that need the best responsiveness.
  *
  * The equivalent with pcap_create()/pcap_activate() is "immediate mode".
  * a bridge) that need the best responsiveness.
  *
  * The equivalent with pcap_create()/pcap_activate() is "immediate mode".
- * XXX - this currently uses pcap_open_live() for local capture sources,
- * so this flag currently only works on Windows.
  */
 #define PCAP_OPENFLAG_MAX_RESPONSIVENESS       0x00000010
 
  */
 #define PCAP_OPENFLAG_MAX_RESPONSIVENESS       0x00000010