char name[PCAP_BUF_SIZE];
int type;
pcap_t *fp;
+ int status;
if (strlen(source) > PCAP_BUF_SIZE)
{
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:
- 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
/*
- * 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)
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 */
+ 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: