summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/libpcap/pcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/contrib/libpcap/pcap.c')
-rw-r--r--freebsd/contrib/libpcap/pcap.c1185
1 files changed, 855 insertions, 330 deletions
diff --git a/freebsd/contrib/libpcap/pcap.c b/freebsd/contrib/libpcap/pcap.c
index e2991fb3..c7e7d02e 100644
--- a/freebsd/contrib/libpcap/pcap.c
+++ b/freebsd/contrib/libpcap/pcap.c
@@ -33,20 +33,13 @@
* SUCH DAMAGE.
*/
-#if 0
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.128 2008-12-23 20:13:29 guy Exp $ (LBL)";
-#endif
-#endif
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#ifdef WIN32
+#ifdef _WIN32
#include <pcap-stdinc.h>
-#else /* WIN32 */
+#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
@@ -57,7 +50,7 @@ static const char rcsid[] _U_ =
#endif
#include <sys/types.h>
#include <sys/mman.h>
-#endif /* WIN32 */
+#endif /* _WIN32 */
#include <stdio.h>
#include <stdlib.h>
@@ -90,6 +83,10 @@ static const char rcsid[] _U_ =
#include "pcap-snf.h"
#endif /* HAVE_SNF_API */
+#ifdef HAVE_TC_API
+#include "pcap-tc.h"
+#endif /* HAVE_TC_API */
+
#ifdef PCAP_SUPPORT_USB
#include "pcap-usb-linux.h"
#endif
@@ -98,25 +95,66 @@ static const char rcsid[] _U_ =
#include "pcap-bt-linux.h"
#endif
-#ifdef PCAP_SUPPORT_CAN
-#include "pcap-can-linux.h"
-#endif
-
-#ifdef PCAP_SUPPORT_CANUSB
-#include "pcap-canusb-linux.h"
+#ifdef PCAP_SUPPORT_BT_MONITOR
+#include "pcap-bt-monitor-linux.h"
#endif
#ifdef PCAP_SUPPORT_NETFILTER
#include "pcap-netfilter-linux.h"
#endif
-int
+#ifdef PCAP_SUPPORT_NETMAP
+pcap_t* pcap_netmap_create(const char *device, char *ebuf, int *is_ours);
+#endif
+
+#ifdef PCAP_SUPPORT_DBUS
+#include "pcap-dbus.h"
+#endif
+
+static int
pcap_not_initialized(pcap_t *pcap)
{
+ /* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */
+ (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
+ "This handle hasn't been activated yet");
/* this means 'not initialized' */
return (PCAP_ERROR_NOT_ACTIVATED);
}
+#ifdef _WIN32
+static void *
+pcap_not_initialized_ptr(pcap_t *pcap)
+{
+ (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
+ "This handle hasn't been activated yet");
+ return (NULL);
+}
+
+static HANDLE
+pcap_getevent_not_initialized(pcap_t *pcap)
+{
+ (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
+ "This handle hasn't been activated yet");
+ return (INVALID_HANDLE_VALUE);
+}
+
+static u_int
+pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync)
+{
+ (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
+ "This handle hasn't been activated yet");
+ return (0);
+}
+
+static PAirpcapHandle
+pcap_get_airpcap_handle_not_initialized(pcap_t *pcap)
+{
+ (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf),
+ "This handle hasn't been activated yet");
+ return (NULL);
+}
+#endif
+
/*
* Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't,
* a PCAP_ERROR value on an error.
@@ -159,7 +197,7 @@ pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
p->tstamp_type_count);
if (*tstamp_typesp == NULL) {
- (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
return (PCAP_ERROR);
}
@@ -191,7 +229,7 @@ pcap_free_tstamp_types(int *tstamp_type_list)
* packet data cannot be guaranteed to be available after the callback
* returns, so that a copy must be made.
*/
-static void
+void
pcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt)
{
struct oneshot_userdata *sp = (struct oneshot_userdata *)user;
@@ -227,7 +265,7 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
/* Saves a pointer to the packet headers */
*pkt_header= &p->pcap_header;
- if (p->sf.rfile != NULL) {
+ if (p->rfile != NULL) {
int status;
/* We are on an offline capture */
@@ -264,47 +302,13 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
}
-#if defined(DAG_ONLY)
-int
-pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
-{
- return (dag_findalldevs(alldevsp, errbuf));
-}
-
-pcap_t *
-pcap_create(const char *source, char *errbuf)
-{
- return (dag_create(source, errbuf));
-}
-#elif defined(SEPTEL_ONLY)
-int
-pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
-{
- return (septel_findalldevs(alldevsp, errbuf));
-}
-
-pcap_t *
-pcap_create(const char *source, char *errbuf)
-{
- return (septel_create(source, errbuf));
-}
-#elif defined(SNF_ONLY)
-int
-pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
-{
- return (snf_findalldevs(alldevsp, errbuf));
-}
-
-pcap_t *
-pcap_create(const char *source, char *errbuf)
-{
- return (snf_create(source, errbuf));
-}
-#else /* regular pcap */
-struct capture_source_type {
+static struct capture_source_type {
int (*findalldevs_op)(pcap_if_t **, char *);
pcap_t *(*create_op)(const char *, char *, int *);
} capture_source_types[] = {
+#ifdef PCAP_SUPPORT_NETMAP
+ { NULL, pcap_netmap_create },
+#endif
#ifdef HAVE_DAG_API
{ dag_findalldevs, dag_create },
#endif
@@ -314,14 +318,14 @@ struct capture_source_type {
#ifdef HAVE_SNF_API
{ snf_findalldevs, snf_create },
#endif
+#ifdef HAVE_TC_API
+ { TcFindAllDevs, TcCreate },
+#endif
#ifdef PCAP_SUPPORT_BT
{ bt_findalldevs, bt_create },
#endif
-#if PCAP_SUPPORT_CANUSB
- { canusb_findalldevs, canusb_create },
-#endif
-#ifdef PCAP_SUPPORT_CAN
- { can_findalldevs, can_create },
+#ifdef PCAP_SUPPORT_BT_MONITOR
+ { bt_monitor_findalldevs, bt_monitor_create },
#endif
#ifdef PCAP_SUPPORT_USB
{ usb_findalldevs, usb_create },
@@ -329,6 +333,9 @@ struct capture_source_type {
#ifdef PCAP_SUPPORT_NETFILTER
{ netfilter_findalldevs, netfilter_create },
#endif
+#ifdef PCAP_SUPPORT_DBUS
+ { dbus_findalldevs, dbus_create },
+#endif
{ NULL, NULL }
};
@@ -344,26 +351,11 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
size_t i;
/*
- * Get the list of regular interfaces first.
+ * Find all the local network interfaces on which we
+ * can capture.
*/
- if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1)
- return (-1); /* failure */
-
- /*
- * Add any interfaces that need a platform-specific mechanism
- * to find.
- */
- if (pcap_platform_finddevs(alldevsp, errbuf) == -1) {
- /*
- * We had an error; free the list we've been
- * constructing.
- */
- if (*alldevsp != NULL) {
- pcap_freealldevs(*alldevsp);
- *alldevsp = NULL;
- }
+ if (pcap_platform_finddevs(alldevsp, errbuf) == -1)
return (-1);
- }
/*
* Ask each of the non-local-network-interface capture
@@ -382,25 +374,58 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
return (-1);
}
}
+
return (0);
}
pcap_t *
-pcap_create(const char *source, char *errbuf)
+pcap_create(const char *device, char *errbuf)
{
size_t i;
int is_theirs;
pcap_t *p;
+ char *device_str;
/*
- * A null source name is equivalent to the "any" device -
+ * A null device name is equivalent to the "any" device -
* which might not be supported on this platform, but
* this means that you'll get a "not supported" error
* rather than, say, a crash when we try to dereference
* the null pointer.
*/
- if (source == NULL)
- source = "any";
+ if (device == NULL)
+ device_str = strdup("any");
+ else {
+#ifdef _WIN32
+ /*
+ * If the string appears to be little-endian UCS-2/UTF-16,
+ * convert it to ASCII.
+ *
+ * XXX - to UTF-8 instead? Or report an error if any
+ * character isn't ASCII?
+ */
+ if (device[0] != '\0' && device[1] == '\0') {
+ size_t length;
+
+ length = wcslen((wchar_t *)device);
+ device_str = (char *)malloc(length + 1);
+ if (device_str == NULL) {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (NULL);
+ }
+
+ pcap_snprintf(device_str, length + 1, "%ws",
+ (const wchar_t *)device);
+ } else
+#endif
+ device_str = strdup(device);
+ }
+ if (device_str == NULL) {
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (NULL);
+ }
/*
* Try each of the non-local-network-interface capture
@@ -409,7 +434,8 @@ pcap_create(const char *source, char *errbuf)
*/
for (i = 0; capture_source_types[i].create_op != NULL; i++) {
is_theirs = 0;
- p = capture_source_types[i].create_op(source, errbuf, &is_theirs);
+ p = capture_source_types[i].create_op(device_str, errbuf,
+ &is_theirs);
if (is_theirs) {
/*
* The device name refers to a device of the
@@ -420,6 +446,14 @@ pcap_create(const char *source, char *errbuf)
* should return that to report the failure
* to create.
*/
+ if (p == NULL) {
+ /*
+ * We assume the caller filled in errbuf.
+ */
+ free(device_str);
+ return (NULL);
+ }
+ p->opt.device = device_str;
return (p);
}
}
@@ -427,9 +461,17 @@ pcap_create(const char *source, char *errbuf)
/*
* OK, try it as a regular network interface.
*/
- return (pcap_create_interface(source, errbuf));
+ p = pcap_create_interface(device_str, errbuf);
+ if (p == NULL) {
+ /*
+ * We assume the caller filled in errbuf.
+ */
+ free(device_str);
+ return (NULL);
+ }
+ p->opt.device = device_str;
+ return (p);
}
-#endif
static void
initialize_ops(pcap_t *p)
@@ -447,10 +489,19 @@ initialize_ops(pcap_t *p)
p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
p->stats_op = (stats_op_t)pcap_not_initialized;
-#ifdef WIN32
+#ifdef _WIN32
+ p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
p->setmode_op = (setmode_op_t)pcap_not_initialized;
p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
+ p->getevent_op = pcap_getevent_not_initialized;
+ p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized;
+ p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized;
+ p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized;
+ p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized;
+ p->live_dump_op = (live_dump_op_t)pcap_not_initialized;
+ p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized;
+ p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized;
#endif
/*
@@ -461,38 +512,65 @@ initialize_ops(pcap_t *p)
p->cleanup_op = pcap_cleanup_live_common;
/*
- * In most cases, the standard one-short callback can
+ * In most cases, the standard one-shot callback can
* be used for pcap_next()/pcap_next_ex().
*/
p->oneshot_callback = pcap_oneshot;
}
-pcap_t *
-pcap_create_common(const char *source, char *ebuf)
+static pcap_t *
+pcap_alloc_pcap_t(char *ebuf, size_t size)
{
+ char *chunk;
pcap_t *p;
- p = malloc(sizeof(*p));
- if (p == NULL) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ /*
+ * Allocate a chunk of memory big enough for a pcap_t
+ * plus a structure following it of size "size". The
+ * structure following it is a private data structure
+ * for the routines that handle this pcap_t.
+ */
+ chunk = malloc(sizeof (pcap_t) + size);
+ if (chunk == NULL) {
+ pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return (NULL);
}
- memset(p, 0, sizeof(*p));
-#ifndef WIN32
+ memset(chunk, 0, sizeof (pcap_t) + size);
+
+ /*
+ * Get a pointer to the pcap_t at the beginning.
+ */
+ p = (pcap_t *)chunk;
+
+#ifndef _WIN32
p->fd = -1; /* not opened yet */
p->selectable_fd = -1;
- p->send_fd = -1;
#endif
- p->opt.source = strdup(source);
- if (p->opt.source == NULL) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
- pcap_strerror(errno));
- free(p);
- return (NULL);
+ if (size == 0) {
+ /* No private data was requested. */
+ p->priv = NULL;
+ } else {
+ /*
+ * Set the pointer to the private data; that's the structure
+ * of size "size" following the pcap_t.
+ */
+ p->priv = (void *)(chunk + sizeof (pcap_t));
}
+ return (p);
+}
+
+pcap_t *
+pcap_create_common(char *ebuf, size_t size)
+{
+ pcap_t *p;
+
+ p = pcap_alloc_pcap_t(ebuf, size);
+ if (p == NULL)
+ return (NULL);
+
/*
* Default to "can't set rfmon mode"; if it's supported by
* a platform, the create routine that called us can set
@@ -504,11 +582,20 @@ pcap_create_common(const char *source, char *ebuf)
initialize_ops(p);
/* put in some defaults*/
- pcap_set_timeout(p, 0);
- pcap_set_snaplen(p, 65535); /* max packet size */
+ p->snapshot = MAXIMUM_SNAPLEN; /* max packet size */
+ p->opt.timeout = 0; /* no timeout specified */
+ p->opt.buffer_size = 0; /* use the platform's default */
p->opt.promisc = 0;
- p->opt.buffer_size = 0;
+ p->opt.rfmon = 0;
+ p->opt.immediate = 0;
p->opt.tstamp_type = -1; /* default to not setting time stamp type */
+ p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
+
+ /*
+ * Start out with no BPF code generation flags set.
+ */
+ p->bpf_codegen_flags = 0;
+
return (p);
}
@@ -516,7 +603,7 @@ int
pcap_check_activated(pcap_t *p)
{
if (p->activated) {
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
" operation on activated capture");
return (-1);
}
@@ -528,6 +615,16 @@ pcap_set_snaplen(pcap_t *p, int snaplen)
{
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
+
+ /*
+ * Turn invalid values, or excessively large values, into
+ * the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (snaplen <= 0 || snaplen > MAXIMUM_SNAPLEN)
+ snaplen = MAXIMUM_SNAPLEN;
p->snapshot = snaplen;
return (0);
}
@@ -555,7 +652,7 @@ pcap_set_timeout(pcap_t *p, int timeout_ms)
{
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
- p->md.timeout = timeout_ms;
+ p->opt.timeout = timeout_ms;
return (0);
}
@@ -568,42 +665,122 @@ pcap_set_tstamp_type(pcap_t *p, int tstamp_type)
return (PCAP_ERROR_ACTIVATED);
/*
- * If p->tstamp_type_count is 0, we don't support setting
- * the time stamp type at all.
+ * The argument should have been u_int, but that's too late
+ * to change now - it's an API.
*/
- if (p->tstamp_type_count == 0)
- return (PCAP_ERROR_CANTSET_TSTAMP_TYPE);
+ if (tstamp_type < 0)
+ return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP);
/*
- * Check whether we claim to support this type of time stamp.
+ * If p->tstamp_type_count is 0, we only support PCAP_TSTAMP_HOST;
+ * the default time stamp type is PCAP_TSTAMP_HOST.
*/
- for (i = 0; i < p->tstamp_type_count; i++) {
- if (p->tstamp_type_list[i] == tstamp_type) {
- /*
- * Yes.
- */
+ if (p->tstamp_type_count == 0) {
+ if (tstamp_type == PCAP_TSTAMP_HOST) {
p->opt.tstamp_type = tstamp_type;
return (0);
}
+ } else {
+ /*
+ * Check whether we claim to support this type of time stamp.
+ */
+ for (i = 0; i < p->tstamp_type_count; i++) {
+ if (p->tstamp_type_list[i] == (u_int)tstamp_type) {
+ /*
+ * Yes.
+ */
+ p->opt.tstamp_type = tstamp_type;
+ return (0);
+ }
+ }
}
/*
- * No. We support setting the time stamp type, but not to this
- * particular value.
+ * We don't support this type of time stamp.
*/
return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP);
}
int
+pcap_set_immediate_mode(pcap_t *p, int immediate)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.immediate = immediate;
+ return (0);
+}
+
+int
pcap_set_buffer_size(pcap_t *p, int buffer_size)
{
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
+ if (buffer_size <= 0) {
+ /*
+ * Silently ignore invalid values.
+ */
+ return (0);
+ }
p->opt.buffer_size = buffer_size;
return (0);
}
int
+pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision)
+{
+ int i;
+
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+
+ /*
+ * The argument should have been u_int, but that's too late
+ * to change now - it's an API.
+ */
+ if (tstamp_precision < 0)
+ return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP);
+
+ /*
+ * If p->tstamp_precision_count is 0, we only support setting
+ * the time stamp precision to microsecond precision; every
+ * pcap module *MUST* support microsecond precision, even if
+ * it does so by converting the native precision to
+ * microseconds.
+ */
+ if (p->tstamp_precision_count == 0) {
+ if (tstamp_precision == PCAP_TSTAMP_PRECISION_MICRO) {
+ p->opt.tstamp_precision = tstamp_precision;
+ return (0);
+ }
+ } else {
+ /*
+ * Check whether we claim to support this precision of
+ * time stamp.
+ */
+ for (i = 0; i < p->tstamp_precision_count; i++) {
+ if (p->tstamp_precision_list[i] == (u_int)tstamp_precision) {
+ /*
+ * Yes.
+ */
+ p->opt.tstamp_precision = tstamp_precision;
+ return (0);
+ }
+ }
+ }
+
+ /*
+ * We don't support this time stamp precision.
+ */
+ return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP);
+}
+
+int
+pcap_get_tstamp_precision(pcap_t *p)
+{
+ return (p->opt.tstamp_precision);
+}
+
+int
pcap_activate(pcap_t *p)
{
int status;
@@ -628,7 +805,7 @@ pcap_activate(pcap_t *p)
* handle errors other than PCAP_ERROR, return the
* error message corresponding to the status.
*/
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s",
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s",
pcap_statustostr(status));
}
@@ -642,12 +819,12 @@ pcap_activate(pcap_t *p)
}
pcap_t *
-pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
+pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf)
{
pcap_t *p;
int status;
- p = pcap_create(source, errbuf);
+ p = pcap_create(device, errbuf);
if (p == NULL)
return (NULL);
status = pcap_set_snaplen(p, snaplen);
@@ -676,33 +853,37 @@ pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *er
return (p);
fail:
if (status == PCAP_ERROR)
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
p->errbuf);
else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
status == PCAP_ERROR_PERM_DENIED ||
status == PCAP_ERROR_PROMISC_PERM_DENIED)
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source,
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device,
pcap_statustostr(status), p->errbuf);
else
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device,
pcap_statustostr(status));
pcap_close(p);
return (NULL);
}
-int
-pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+pcap_t *
+pcap_open_offline_common(char *ebuf, size_t size)
{
- return (p->read_op(p, cnt, callback, user));
+ pcap_t *p;
+
+ p = pcap_alloc_pcap_t(ebuf, size);
+ if (p == NULL)
+ return (NULL);
+
+ p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
+
+ return (p);
}
-/*
- * XXX - is this necessary?
- */
int
-pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
{
-
return (p->read_op(p, cnt, callback, user));
}
@@ -712,7 +893,7 @@ pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
register int n;
for (;;) {
- if (p->sf.rfile != NULL) {
+ if (p->rfile != NULL) {
/*
* 0 means EOF, so don't loop if we get 0.
*/
@@ -728,7 +909,7 @@ pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
}
if (n <= 0)
return (n);
- if (cnt > 0) {
+ if (!PACKET_COUNT_IS_UNLIMITED(cnt)) {
cnt -= n;
if (cnt <= 0)
return (0);
@@ -748,18 +929,24 @@ pcap_breakloop(pcap_t *p)
int
pcap_datalink(pcap_t *p)
{
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
return (p->linktype);
}
int
pcap_datalink_ext(pcap_t *p)
{
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
return (p->linktype_ext);
}
int
pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
{
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
if (p->dlt_count == 0) {
/*
* We couldn't fetch the list of DLTs, which means
@@ -769,18 +956,18 @@ pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
*/
*dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
if (*dlt_buffer == NULL) {
- (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
- return (-1);
+ return (PCAP_ERROR);
}
**dlt_buffer = p->linktype;
return (1);
} else {
*dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count);
if (*dlt_buffer == NULL) {
- (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
- return (-1);
+ return (PCAP_ERROR);
}
(void)memcpy(*dlt_buffer, p->dlt_list,
sizeof(**dlt_buffer) * p->dlt_count);
@@ -811,6 +998,9 @@ pcap_set_datalink(pcap_t *p, int dlt)
int i;
const char *dlt_name;
+ if (dlt < 0)
+ goto unsupported;
+
if (p->dlt_count == 0 || p->set_datalink_op == NULL) {
/*
* We couldn't fetch the list of DLTs, or we don't
@@ -828,7 +1018,7 @@ pcap_set_datalink(pcap_t *p, int dlt)
return (0);
}
for (i = 0; i < p->dlt_count; i++)
- if (p->dlt_list[i] == dlt)
+ if (p->dlt_list[i] == (u_int)dlt)
break;
if (i >= p->dlt_count)
goto unsupported;
@@ -856,11 +1046,11 @@ pcap_set_datalink(pcap_t *p, int dlt)
unsupported:
dlt_name = pcap_datalink_val_to_name(dlt);
if (dlt_name != NULL) {
- (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"%s is not one of the DLTs supported by this device",
dlt_name);
} else {
- (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf),
"DLT %d is not one of the DLTs supported by this device",
dlt);
}
@@ -958,113 +1148,139 @@ struct dlt_choice {
int dlt;
};
-#define DLT_CHOICE(code, description) { #code, description, code }
+#define DLT_CHOICE(code, description) { #code, description, DLT_ ## code }
#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
static struct dlt_choice dlt_choices[] = {
- DLT_CHOICE(DLT_NULL, "BSD loopback"),
- DLT_CHOICE(DLT_EN10MB, "Ethernet"),
- DLT_CHOICE(DLT_IEEE802, "Token ring"),
- DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"),
- DLT_CHOICE(DLT_SLIP, "SLIP"),
- DLT_CHOICE(DLT_PPP, "PPP"),
- DLT_CHOICE(DLT_FDDI, "FDDI"),
- DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"),
- DLT_CHOICE(DLT_RAW, "Raw IP"),
- DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
- DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
- DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
- DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
- DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
- DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"),
- DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
- DLT_CHOICE(DLT_IEEE802_11, "802.11"),
- DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
- DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
- DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
- DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
- DLT_CHOICE(DLT_LTALK, "Localtalk"),
- DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
- DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"),
- DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
- DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
- DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
- DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"),
- DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
- DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
- DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
- DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"),
- DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"),
- DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"),
- DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"),
- DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
- DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"),
- DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
- DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"),
- DLT_CHOICE(DLT_MTP2, "SS7 MTP2"),
- DLT_CHOICE(DLT_MTP3, "SS7 MTP3"),
- DLT_CHOICE(DLT_SCCP, "SS7 SCCP"),
- DLT_CHOICE(DLT_DOCSIS, "DOCSIS"),
- DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
- DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
- DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
- DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"),
- DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"),
- DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
- DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"),
- DLT_CHOICE(DLT_GPF_T, "GPF-T"),
- DLT_CHOICE(DLT_GPF_F, "GPF-F"),
- DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"),
- DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"),
- DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"),
- DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
- DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"),
- DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"),
- DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"),
- DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"),
- DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"),
- DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"),
- DLT_CHOICE(DLT_A429, "Arinc 429"),
- DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"),
- DLT_CHOICE(DLT_USB, "USB"),
- DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"),
- DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"),
- DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"),
- DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"),
- DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"),
- DLT_CHOICE(DLT_PPI, "Per-Packet Information"),
- DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"),
- DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"),
- DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"),
- DLT_CHOICE(DLT_SITA, "SITA pseudo-header"),
- DLT_CHOICE(DLT_ERF, "Endace ERF header"),
- DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"),
- DLT_CHOICE(DLT_IPMB, "IPMB"),
- DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"),
- DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
- DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"),
- DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
- DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"),
- DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"),
- DLT_CHOICE(DLT_DECT, "DECT"),
- DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"),
- DLT_CHOICE(DLT_WIHART, "Wireless HART"),
- DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"),
- DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"),
- DLT_CHOICE(DLT_IPNET, "Solaris ipnet"),
- DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"),
- DLT_CHOICE(DLT_IPV4, "Raw IPv4"),
- DLT_CHOICE(DLT_IPV6, "Raw IPv6"),
- DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
- DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"),
- DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"),
- DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"),
- DLT_CHOICE(DLT_DVB_CI, "DVB-CI"),
- DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"),
- DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"),
- DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
- DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
- DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"),
+ DLT_CHOICE(NULL, "BSD loopback"),
+ DLT_CHOICE(EN10MB, "Ethernet"),
+ DLT_CHOICE(IEEE802, "Token ring"),
+ DLT_CHOICE(ARCNET, "BSD ARCNET"),
+ DLT_CHOICE(SLIP, "SLIP"),
+ DLT_CHOICE(PPP, "PPP"),
+ DLT_CHOICE(FDDI, "FDDI"),
+ DLT_CHOICE(ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"),
+ DLT_CHOICE(RAW, "Raw IP"),
+ DLT_CHOICE(SLIP_BSDOS, "BSD/OS SLIP"),
+ DLT_CHOICE(PPP_BSDOS, "BSD/OS PPP"),
+ DLT_CHOICE(ATM_CLIP, "Linux Classical IP-over-ATM"),
+ DLT_CHOICE(PPP_SERIAL, "PPP over serial"),
+ DLT_CHOICE(PPP_ETHER, "PPPoE"),
+ DLT_CHOICE(SYMANTEC_FIREWALL, "Symantec Firewall"),
+ DLT_CHOICE(C_HDLC, "Cisco HDLC"),
+ DLT_CHOICE(IEEE802_11, "802.11"),
+ DLT_CHOICE(FRELAY, "Frame Relay"),
+ DLT_CHOICE(LOOP, "OpenBSD loopback"),
+ DLT_CHOICE(ENC, "OpenBSD encapsulated IP"),
+ DLT_CHOICE(LINUX_SLL, "Linux cooked"),
+ DLT_CHOICE(LTALK, "Localtalk"),
+ DLT_CHOICE(PFLOG, "OpenBSD pflog file"),
+ DLT_CHOICE(PFSYNC, "Packet filter state syncing"),
+ DLT_CHOICE(PRISM_HEADER, "802.11 plus Prism header"),
+ DLT_CHOICE(IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
+ DLT_CHOICE(SUNATM, "Sun raw ATM"),
+ DLT_CHOICE(IEEE802_11_RADIO, "802.11 plus radiotap header"),
+ DLT_CHOICE(ARCNET_LINUX, "Linux ARCNET"),
+ DLT_CHOICE(JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
+ DLT_CHOICE(JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
+ DLT_CHOICE(JUNIPER_ES, "Juniper Encryption Services PIC"),
+ DLT_CHOICE(JUNIPER_GGSN, "Juniper GGSN PIC"),
+ DLT_CHOICE(JUNIPER_MFR, "Juniper FRF.16 Frame Relay"),
+ DLT_CHOICE(JUNIPER_ATM2, "Juniper ATM2 PIC"),
+ DLT_CHOICE(JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
+ DLT_CHOICE(JUNIPER_ATM1, "Juniper ATM1 PIC"),
+ DLT_CHOICE(APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
+ DLT_CHOICE(MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"),
+ DLT_CHOICE(MTP2, "SS7 MTP2"),
+ DLT_CHOICE(MTP3, "SS7 MTP3"),
+ DLT_CHOICE(SCCP, "SS7 SCCP"),
+ DLT_CHOICE(DOCSIS, "DOCSIS"),
+ DLT_CHOICE(LINUX_IRDA, "Linux IrDA"),
+ DLT_CHOICE(IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
+ DLT_CHOICE(JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
+ DLT_CHOICE(BACNET_MS_TP, "BACnet MS/TP"),
+ DLT_CHOICE(PPP_PPPD, "PPP for pppd, with direction flag"),
+ DLT_CHOICE(JUNIPER_PPPOE, "Juniper PPPoE"),
+ DLT_CHOICE(JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
+ DLT_CHOICE(GPRS_LLC, "GPRS LLC"),
+ DLT_CHOICE(GPF_T, "GPF-T"),
+ DLT_CHOICE(GPF_F, "GPF-F"),
+ DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"),
+ DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"),
+ DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"),
+ DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"),
+ DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"),
+ DLT_CHOICE(JUNIPER_PPP, "Juniper PPP"),
+ DLT_CHOICE(JUNIPER_FRELAY, "Juniper Frame Relay"),
+ DLT_CHOICE(JUNIPER_CHDLC, "Juniper C-HDLC"),
+ DLT_CHOICE(MFR, "FRF.16 Frame Relay"),
+ DLT_CHOICE(JUNIPER_VP, "Juniper Voice PIC"),
+ DLT_CHOICE(A429, "Arinc 429"),
+ DLT_CHOICE(A653_ICM, "Arinc 653 Interpartition Communication"),
+ DLT_CHOICE(USB_FREEBSD, "USB with FreeBSD header"),
+ DLT_CHOICE(BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"),
+ DLT_CHOICE(IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"),
+ DLT_CHOICE(USB_LINUX, "USB with Linux header"),
+ DLT_CHOICE(CAN20B, "Controller Area Network (CAN) v. 2.0B"),
+ DLT_CHOICE(IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"),
+ DLT_CHOICE(PPI, "Per-Packet Information"),
+ DLT_CHOICE(IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"),
+ DLT_CHOICE(JUNIPER_ISM, "Juniper Integrated Service Module"),
+ DLT_CHOICE(IEEE802_15_4, "IEEE 802.15.4 with FCS"),
+ DLT_CHOICE(SITA, "SITA pseudo-header"),
+ DLT_CHOICE(ERF, "Endace ERF header"),
+ DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"),
+ DLT_CHOICE(IPMB, "IPMB"),
+ DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"),
+ DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
+ DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"),
+ DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
+ DLT_CHOICE(MPLS, "MPLS with label as link-layer header"),
+ DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"),
+ DLT_CHOICE(USB_LINUX_MMAPPED, "USB with padded Linux header"),
+ DLT_CHOICE(DECT, "DECT"),
+ DLT_CHOICE(AOS, "AOS Space Data Link protocol"),
+ DLT_CHOICE(WIHART, "Wireless HART"),
+ DLT_CHOICE(FC_2, "Fibre Channel FC-2"),
+ DLT_CHOICE(FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"),
+ DLT_CHOICE(IPNET, "Solaris ipnet"),
+ DLT_CHOICE(CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"),
+ DLT_CHOICE(IPV4, "Raw IPv4"),
+ DLT_CHOICE(IPV6, "Raw IPv6"),
+ DLT_CHOICE(IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
+ DLT_CHOICE(DBUS, "D-Bus"),
+ DLT_CHOICE(JUNIPER_VS, "Juniper Virtual Server"),
+ DLT_CHOICE(JUNIPER_SRX_E2E, "Juniper SRX E2E"),
+ DLT_CHOICE(JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"),
+ DLT_CHOICE(DVB_CI, "DVB-CI"),
+ DLT_CHOICE(MUX27010, "MUX27010"),
+ DLT_CHOICE(STANAG_5066_D_PDU, "STANAG 5066 D_PDUs"),
+ DLT_CHOICE(JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"),
+ DLT_CHOICE(NFLOG, "Linux netfilter log messages"),
+ DLT_CHOICE(NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
+ DLT_CHOICE(NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
+ DLT_CHOICE(IPOIB, "RFC 4391 IP-over-Infiniband"),
+ DLT_CHOICE(MPEG_2_TS, "MPEG-2 transport stream"),
+ DLT_CHOICE(NG40, "ng40 protocol tester Iub/Iur"),
+ DLT_CHOICE(NFC_LLCP, "NFC LLCP PDUs with pseudo-header"),
+ DLT_CHOICE(INFINIBAND, "InfiniBand"),
+ DLT_CHOICE(SCTP, "SCTP"),
+ DLT_CHOICE(USBPCAP, "USB with USBPcap header"),
+ DLT_CHOICE(RTAC_SERIAL, "Schweitzer Engineering Laboratories RTAC packets"),
+ DLT_CHOICE(BLUETOOTH_LE_LL, "Bluetooth Low Energy air interface"),
+ DLT_CHOICE(NETLINK, "Linux netlink"),
+ DLT_CHOICE(BLUETOOTH_LINUX_MONITOR, "Bluetooth Linux Monitor"),
+ DLT_CHOICE(BLUETOOTH_BREDR_BB, "Bluetooth Basic Rate/Enhanced Data Rate baseband packets"),
+ DLT_CHOICE(BLUETOOTH_LE_LL_WITH_PHDR, "Bluetooth Low Energy air interface with pseudo-header"),
+ DLT_CHOICE(PROFIBUS_DL, "PROFIBUS data link layer"),
+ DLT_CHOICE(PKTAP, "Apple DLT_PKTAP"),
+ DLT_CHOICE(EPON, "Ethernet with 802.3 Clause 65 EPON preamble"),
+ DLT_CHOICE(IPMI_HPM_2, "IPMI trace packets"),
+ DLT_CHOICE(ZWAVE_R1_R2, "Z-Wave RF profile R1 and R2 packets"),
+ DLT_CHOICE(ZWAVE_R3, "Z-Wave RF profile R3 packets"),
+ DLT_CHOICE(WATTSTOPPER_DLM, "WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol"),
+ DLT_CHOICE(ISO_14443, "ISO 14443 messages"),
+ DLT_CHOICE(RDS, "IEC 62106 Radio Data System groups"),
DLT_CHOICE_SENTINEL
};
@@ -1074,8 +1290,7 @@ pcap_datalink_name_to_val(const char *name)
int i;
for (i = 0; dlt_choices[i].name != NULL; i++) {
- if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
- name) == 0)
+ if (pcap_strcasecmp(dlt_choices[i].name, name) == 0)
return (dlt_choices[i].dlt);
}
return (-1);
@@ -1088,7 +1303,7 @@ pcap_datalink_val_to_name(int dlt)
for (i = 0; dlt_choices[i].name != NULL; i++) {
if (dlt_choices[i].dlt == dlt)
- return (dlt_choices[i].name + sizeof("DLT_") - 1);
+ return (dlt_choices[i].name);
}
return (NULL);
}
@@ -1159,47 +1374,55 @@ pcap_tstamp_type_val_to_description(int tstamp_type)
int
pcap_snapshot(pcap_t *p)
{
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
return (p->snapshot);
}
int
pcap_is_swapped(pcap_t *p)
{
- return (p->sf.swapped);
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
+ return (p->swapped);
}
int
pcap_major_version(pcap_t *p)
{
- return (p->sf.version_major);
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
+ return (p->version_major);
}
int
pcap_minor_version(pcap_t *p)
{
- return (p->sf.version_minor);
+ if (!p->activated)
+ return (PCAP_ERROR_NOT_ACTIVATED);
+ return (p->version_minor);
}
FILE *
pcap_file(pcap_t *p)
{
- return (p->sf.rfile);
+ return (p->rfile);
}
int
pcap_fileno(pcap_t *p)
{
-#ifndef WIN32
+#ifndef _WIN32
return (p->fd);
#else
if (p->adapter != NULL)
return ((int)(DWORD)p->adapter->hFile);
else
- return (-1);
+ return (PCAP_ERROR);
#endif
}
-#if !defined(WIN32) && !defined(MSDOS)
+#if !defined(_WIN32) && !defined(MSDOS)
int
pcap_get_selectable_fd(pcap_t *p)
{
@@ -1208,7 +1431,7 @@ pcap_get_selectable_fd(pcap_t *p)
#endif
void
-pcap_perror(pcap_t *p, char *prefix)
+pcap_perror(pcap_t *p, const char *prefix)
{
fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
}
@@ -1239,11 +1462,8 @@ pcap_getnonblock(pcap_t *p, char *errbuf)
/*
* Get the current non-blocking mode setting, under the assumption that
* it's just the standard POSIX non-blocking flag.
- *
- * We don't look at "p->nonblock", in case somebody tweaked the FD
- * directly.
*/
-#if !defined(WIN32) && !defined(MSDOS)
+#if !defined(_WIN32) && !defined(MSDOS)
int
pcap_getnonblock_fd(pcap_t *p, char *errbuf)
{
@@ -1251,7 +1471,7 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
@@ -1279,7 +1499,7 @@ pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
return (ret);
}
-#if !defined(WIN32) && !defined(MSDOS)
+#if !defined(_WIN32) && !defined(MSDOS)
/*
* Set non-blocking mode, under the assumption that it's just the
* standard POSIX non-blocking flag. (This can be called by the
@@ -1293,7 +1513,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
@@ -1302,7 +1522,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
else
fdflags &= ~O_NONBLOCK;
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
- snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
+ pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
pcap_strerror(errno));
return (-1);
}
@@ -1310,21 +1530,18 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
}
#endif
-#ifdef WIN32
+#ifdef _WIN32
/*
- * Generate a string for the last Win32-specific error (i.e. an error generated when
+ * Generate a string for a Win32-specific error (i.e. an error generated when
* calling a Win32 API).
* For errors occurred during standard C calls, we still use pcap_strerror()
*/
-char *
-pcap_win32strerror(void)
+void
+pcap_win32_err_to_str(DWORD error, char *errbuf)
{
- DWORD error;
- static char errbuf[PCAP_ERRBUF_SIZE+1];
- int errlen;
+ size_t errlen;
char *p;
- error = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
PCAP_ERRBUF_SIZE, NULL);
@@ -1338,8 +1555,7 @@ pcap_win32strerror(void)
errbuf[errlen - 2] = '\0';
}
p = strchr(errbuf, '\0');
- snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error);
- return (errbuf);
+ pcap_snprintf (p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error);
}
#endif
@@ -1394,8 +1610,11 @@ pcap_statustostr(int errnum)
case PCAP_ERROR_PROMISC_PERM_DENIED:
return ("You don't have permission to capture in promiscuous mode on that device");
+
+ case PCAP_ERROR_TSTAMP_PRECISION_NOTSUP:
+ return ("That device doesn't support that time stamp precision");
}
- (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
+ (void)pcap_snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf);
}
@@ -1406,16 +1625,25 @@ const char *
pcap_strerror(int errnum)
{
#ifdef HAVE_STRERROR
+#ifdef _WIN32
+ static char errbuf[PCAP_ERRBUF_SIZE];
+ errno_t errno;
+ errno = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum);
+ if (errno != 0) /* errno = 0 if successful */
+ strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE);
+ return (errbuf);
+#else
return (strerror(errnum));
+#endif /* _WIN32 */
#else
extern int sys_nerr;
extern const char *const sys_errlist[];
- static char ebuf[15+10+1];
+ static char errbuf[PCAP_ERRBUF_SIZE];
if ((unsigned int)errnum < sys_nerr)
return ((char *)sys_errlist[errnum]);
- (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
- return(ebuf);
+ (void)pcap_snprintf(errbuf, sizeof errbuf, "Unknown error: %d", errnum);
+ return (errbuf);
#endif
}
@@ -1435,7 +1663,7 @@ int
pcap_setdirection(pcap_t *p, pcap_direction_t d)
{
if (p->setdirection_op == NULL) {
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Setting direction is not implemented on this platform");
return (-1);
} else
@@ -1451,12 +1679,18 @@ pcap_stats(pcap_t *p, struct pcap_stat *ps)
static int
pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
{
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Statistics aren't available from a pcap_open_dead pcap_t");
return (-1);
}
-#ifdef WIN32
+#ifdef _WIN32
+struct pcap_stat *
+pcap_stats_ex(pcap_t *p, int *pcap_stat_size)
+{
+ return (p->stats_ex_op(p, pcap_stat_size));
+}
+
int
pcap_setbuff(pcap_t *p, int dim)
{
@@ -1466,7 +1700,7 @@ pcap_setbuff(pcap_t *p, int dim)
static int
pcap_setbuff_dead(pcap_t *p, int dim)
{
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The kernel buffer size cannot be set on a pcap_open_dead pcap_t");
return (-1);
}
@@ -1480,7 +1714,7 @@ pcap_setmode(pcap_t *p, int mode)
static int
pcap_setmode_dead(pcap_t *p, int mode)
{
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"impossible to set mode on a pcap_open_dead pcap_t");
return (-1);
}
@@ -1494,10 +1728,178 @@ pcap_setmintocopy(pcap_t *p, int size)
static int
pcap_setmintocopy_dead(pcap_t *p, int size)
{
- snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"The mintocopy parameter cannot be set on a pcap_open_dead pcap_t");
return (-1);
}
+
+HANDLE
+pcap_getevent(pcap_t *p)
+{
+ return (p->getevent_op(p));
+}
+
+static HANDLE
+pcap_getevent_dead(pcap_t *p)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "A pcap_open_dead pcap_t has no event handle");
+ return (INVALID_HANDLE_VALUE);
+}
+
+int
+pcap_oid_get_request(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
+{
+ return (p->oid_get_request_op(p, oid, data, lenp));
+}
+
+static int
+pcap_oid_get_request_dead(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_,
+ size_t *lenp _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "An OID get request cannot be performed on a pcap_open_dead pcap_t");
+ return (PCAP_ERROR);
+}
+
+int
+pcap_oid_set_request(pcap_t *p, bpf_u_int32 oid, const void *data, size_t *lenp)
+{
+ return (p->oid_set_request_op(p, oid, data, lenp));
+}
+
+static int
+pcap_oid_set_request_dead(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
+ size_t *lenp _U_)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "An OID set request cannot be performed on a pcap_open_dead pcap_t");
+ return (PCAP_ERROR);
+}
+
+pcap_send_queue *
+pcap_sendqueue_alloc(u_int memsize)
+{
+ pcap_send_queue *tqueue;
+
+ /* Allocate the queue */
+ tqueue = (pcap_send_queue *)malloc(sizeof(pcap_send_queue));
+ if (tqueue == NULL){
+ return (NULL);
+ }
+
+ /* Allocate the buffer */
+ tqueue->buffer = (char *)malloc(memsize);
+ if (tqueue->buffer == NULL) {
+ free(tqueue);
+ return (NULL);
+ }
+
+ tqueue->maxlen = memsize;
+ tqueue->len = 0;
+
+ return (tqueue);
+}
+
+void
+pcap_sendqueue_destroy(pcap_send_queue *queue)
+{
+ free(queue->buffer);
+ free(queue);
+}
+
+int
+pcap_sendqueue_queue(pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
+{
+ if (queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > queue->maxlen){
+ return (-1);
+ }
+
+ /* Copy the pcap_pkthdr header*/
+ memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr));
+ queue->len += sizeof(struct pcap_pkthdr);
+
+ /* copy the packet */
+ memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen);
+ queue->len += pkt_header->caplen;
+
+ return (0);
+}
+
+u_int
+pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue, int sync)
+{
+ return (p->sendqueue_transmit_op(p, queue, sync));
+}
+
+static u_int
+pcap_sendqueue_transmit_dead(pcap_t *p, pcap_send_queue *queue, int sync)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Packets cannot be transmitted on a pcap_open_dead pcap_t");
+ return (0);
+}
+
+int
+pcap_setuserbuffer(pcap_t *p, int size)
+{
+ return (p->setuserbuffer_op(p, size));
+}
+
+static int
+pcap_setuserbuffer_dead(pcap_t *p, int size)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The user buffer cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+int
+pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks)
+{
+ return (p->live_dump_op(p, filename, maxsize, maxpacks));
+}
+
+static int
+pcap_live_dump_dead(pcap_t *p, char *filename, int maxsize, int maxpacks)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+int
+pcap_live_dump_ended(pcap_t *p, int sync)
+{
+ return (p->live_dump_ended_op(p, sync));
+}
+
+static int
+pcap_live_dump_ended_dead(pcap_t *p, int sync)
+{
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+PAirpcapHandle
+pcap_get_airpcap_handle(pcap_t *p)
+{
+ PAirpcapHandle handle;
+
+ handle = p->get_airpcap_handle_op(p);
+ if (handle == NULL) {
+ (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf),
+ "This isn't an AirPcap device");
+ }
+ return (handle);
+}
+
+static PAirpcapHandle
+pcap_get_airpcap_handle_dead(pcap_t *p)
+{
+ return (NULL);
+}
#endif
/*
@@ -1542,12 +1944,11 @@ pcap_do_addexit(pcap_t *p)
* "pcap_close_all()" called when we exit.
*/
if (!did_atexit) {
- if (atexit(pcap_close_all) == -1) {
+ if (atexit(pcap_close_all) != 0) {
/*
* "atexit()" failed; let our caller know.
*/
- strncpy(p->errbuf, "atexit failed",
- PCAP_ERRBUF_SIZE);
+ strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE);
return (0);
}
did_atexit = 1;
@@ -1558,7 +1959,7 @@ pcap_do_addexit(pcap_t *p)
void
pcap_add_to_pcaps_to_close(pcap_t *p)
{
- p->md.next = pcaps_to_close;
+ p->next = pcaps_to_close;
pcaps_to_close = p;
}
@@ -1568,7 +1969,7 @@ pcap_remove_from_pcaps_to_close(pcap_t *p)
pcap_t *pc, *prevpc;
for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
- prevpc = pc, pc = pc->md.next) {
+ prevpc = pc, pc = pc->next) {
if (pc == p) {
/*
* Found it. Remove it from the list.
@@ -1577,12 +1978,12 @@ pcap_remove_from_pcaps_to_close(pcap_t *p)
/*
* It was at the head of the list.
*/
- pcaps_to_close = pc->md.next;
+ pcaps_to_close = pc->next;
} else {
/*
* It was in the middle of the list.
*/
- prevpc->md.next = pc->md.next;
+ prevpc->next = pc->next;
}
break;
}
@@ -1606,14 +2007,18 @@ pcap_cleanup_live_common(pcap_t *p)
p->tstamp_type_list = NULL;
p->tstamp_type_count = 0;
}
+ if (p->tstamp_precision_list != NULL) {
+ free(p->tstamp_precision_list);
+ p->tstamp_precision_list = NULL;
+ p->tstamp_precision_count = 0;
+ }
pcap_freecode(&p->fcode);
-#if !defined(WIN32) && !defined(MSDOS)
+#if !defined(_WIN32) && !defined(MSDOS)
if (p->fd >= 0) {
close(p->fd);
p->fd = -1;
}
p->selectable_fd = -1;
- p->send_fd = -1;
#endif
}
@@ -1624,27 +2029,59 @@ pcap_cleanup_dead(pcap_t *p _U_)
}
pcap_t *
-pcap_open_dead(int linktype, int snaplen)
+pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision)
{
pcap_t *p;
+ switch (precision) {
+
+ case PCAP_TSTAMP_PRECISION_MICRO:
+ case PCAP_TSTAMP_PRECISION_NANO:
+ break;
+
+ default:
+ return NULL;
+ }
p = malloc(sizeof(*p));
if (p == NULL)
return NULL;
memset (p, 0, sizeof(*p));
p->snapshot = snaplen;
p->linktype = linktype;
+ p->opt.tstamp_precision = precision;
p->stats_op = pcap_stats_dead;
-#ifdef WIN32
+#ifdef _WIN32
+ p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr;
p->setbuff_op = pcap_setbuff_dead;
p->setmode_op = pcap_setmode_dead;
p->setmintocopy_op = pcap_setmintocopy_dead;
+ p->getevent_op = pcap_getevent_dead;
+ p->oid_get_request_op = pcap_oid_get_request_dead;
+ p->oid_set_request_op = pcap_oid_set_request_dead;
+ p->sendqueue_transmit_op = pcap_sendqueue_transmit_dead;
+ p->setuserbuffer_op = pcap_setuserbuffer_dead;
+ p->live_dump_op = pcap_live_dump_dead;
+ p->live_dump_ended_op = pcap_live_dump_ended_dead;
+ p->get_airpcap_handle_op = pcap_get_airpcap_handle_dead;
#endif
p->cleanup_op = pcap_cleanup_dead;
+
+ /*
+ * A "dead" pcap_t never requires special BPF code generation.
+ */
+ p->bpf_codegen_flags = 0;
+
p->activated = 1;
return (p);
}
+pcap_t *
+pcap_open_dead(int linktype, int snaplen)
+{
+ return (pcap_open_dead_with_tstamp_precision(linktype, snaplen,
+ PCAP_TSTAMP_PRECISION_MICRO));
+}
+
/*
* API compatible with WinPcap's "send a packet" routine - returns -1
* on error, 0 otherwise.
@@ -1672,8 +2109,8 @@ pcap_inject(pcap_t *p, const void *buf, size_t size)
void
pcap_close(pcap_t *p)
{
- if (p->opt.source != NULL)
- free(p->opt.source);
+ if (p->opt.device != NULL)
+ free(p->opt.device);
p->cleanup_op(p);
free(p);
}
@@ -1696,36 +2133,29 @@ pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h,
return (0);
}
-/*
- * We make the version string static, and return a pointer to it, rather
- * than exporting the version string directly. On at least some UNIXes,
- * if you import data from a shared library into an program, the data is
- * bound into the program binary, so if the string in the version of the
- * library with which the program was linked isn't the same as the
- * string in the version of the library with which the program is being
- * run, various undesirable things may happen (warnings, the string
- * being the one from the version of the library with which the program
- * was linked, or even weirder things, such as the string being the one
- * from the library but being truncated).
- */
-#ifdef HAVE_VERSION_H
-#include "version.h"
-#else
-static const char pcap_version_string[] = "libpcap version 1.x.y";
-#endif
+#include "pcap_version.h"
+
+#ifdef _WIN32
-#ifdef WIN32
+static char *full_pcap_version_string;
+
+#ifdef HAVE_VERSION_H
/*
- * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap
- * version numbers when building WinPcap. (It'd be nice to do so for
- * the packet.dll version number as well.)
+ * libpcap being built for Windows, as part of a WinPcap/Npcap source
+ * tree. Include version.h from that source tree to get the WinPcap/Npcap
+ * version.
+ *
+ * XXX - it'd be nice if we could somehow generate the WinPcap version number
+ * when building WinPcap. (It'd be nice to do so for the packet.dll version
+ * number as well.)
*/
-static const char wpcap_version_string[] = "4.0";
+#include "../../version.h"
+
+static const char wpcap_version_string[] = WINPCAP_VER_STRING;
static const char pcap_version_string_fmt[] =
- "WinPcap version %s, based on %s";
+ WINPCAP_PRODUCT_NAME " version %s, based on %s";
static const char pcap_version_string_packet_dll_fmt[] =
- "WinPcap version %s (packet.dll version %s), based on %s";
-static char *full_pcap_version_string;
+ WINPCAP_PRODUCT_NAME " version %s (packet.dll version %s), based on %s";
const char *
pcap_lib_version(void)
@@ -1750,8 +2180,12 @@ pcap_lib_version(void)
strlen(pcap_version_string);
full_pcap_version_string =
malloc(full_pcap_version_string_len);
- sprintf(full_pcap_version_string,
- pcap_version_string_fmt, wpcap_version_string,
+ if (full_pcap_version_string == NULL)
+ return (NULL);
+ pcap_snprintf(full_pcap_version_string,
+ full_pcap_version_string_len,
+ pcap_version_string_fmt,
+ wpcap_version_string,
pcap_version_string);
} else {
/*
@@ -1767,16 +2201,57 @@ pcap_lib_version(void)
strlen(packet_version_string) +
strlen(pcap_version_string);
full_pcap_version_string = malloc(full_pcap_version_string_len);
-
- sprintf(full_pcap_version_string,
+ if (full_pcap_version_string == NULL)
+ return (NULL);
+ pcap_snprintf(full_pcap_version_string,
+ full_pcap_version_string_len,
pcap_version_string_packet_dll_fmt,
- wpcap_version_string, packet_version_string,
+ wpcap_version_string,
+ packet_version_string,
pcap_version_string);
}
}
return (full_pcap_version_string);
}
+#else /* HAVE_VERSION_H */
+
+/*
+ * libpcap being built for Windows, not as part of a WinPcap/Npcap source
+ * tree.
+ */
+static const char pcap_version_string_packet_dll_fmt[] =
+ "%s (packet.dll version %s)";
+const char *
+pcap_lib_version(void)
+{
+ char *packet_version_string;
+ size_t full_pcap_version_string_len;
+
+ if (full_pcap_version_string == NULL) {
+ /*
+ * Generate the version string. Report the packet.dll
+ * version.
+ */
+ packet_version_string = PacketGetVersion();
+ full_pcap_version_string_len =
+ (sizeof pcap_version_string_packet_dll_fmt - 4) +
+ strlen(pcap_version_string) +
+ strlen(packet_version_string);
+ full_pcap_version_string = malloc(full_pcap_version_string_len);
+ if (full_pcap_version_string == NULL)
+ return (NULL);
+ pcap_snprintf(full_pcap_version_string,
+ full_pcap_version_string_len,
+ pcap_version_string_packet_dll_fmt,
+ pcap_version_string,
+ packet_version_string);
+ }
+ return (full_pcap_version_string);
+}
+
+#endif /* HAVE_VERSION_H */
+
#elif defined(MSDOS)
static char *full_pcap_version_string;
@@ -1796,6 +2271,8 @@ pcap_lib_version (void)
sizeof dospfx + strlen(pcap_version_string);
full_pcap_version_string =
malloc(full_pcap_version_string_len);
+ if (full_pcap_version_string == NULL)
+ return (NULL);
strcpy(full_pcap_version_string, dospfx);
strcat(full_pcap_version_string, pcap_version_string);
}
@@ -1810,3 +2287,51 @@ pcap_lib_version(void)
return (pcap_version_string);
}
#endif
+
+#ifdef YYDEBUG
+/*
+ * Set the internal "debug printout" flag for the filter expression parser.
+ * The code to print that stuff is present only if YYDEBUG is defined, so
+ * the flag, and the routine to set it, are defined only if YYDEBUG is
+ * defined.
+ *
+ * This is intended for libpcap developers, not for general use.
+ * If you want to set these in a program, you'll have to declare this
+ * routine yourself, with the appropriate DLL import attribute on Windows;
+ * it's not declared in any header file, and won't be declared in any
+ * header file provided by libpcap.
+ */
+PCAP_API void pcap_set_parser_debug(int value);
+
+PCAP_API_DEF void
+pcap_set_parser_debug(int value)
+{
+ extern int pcap_debug;
+
+ pcap_debug = value;
+}
+#endif
+
+#ifdef BDEBUG
+/*
+ * Set the internal "debug printout" flag for the filter expression optimizer.
+ * The code to print that stuff is present only if BDEBUG is defined, so
+ * the flag, and the routine to set it, are defined only if BDEBUG is
+ * defined.
+ *
+ * This is intended for libpcap developers, not for general use.
+ * If you want to set these in a program, you'll have to declare this
+ * routine yourself, with the appropriate DLL import attribute on Windows;
+ * it's not declared in any header file, and won't be declared in any
+ * header file provided by libpcap.
+ */
+PCAP_API void pcap_set_optimizer_debug(int value);
+
+PCAP_API_DEF void
+pcap_set_optimizer_debug(int value)
+{
+ extern int pcap_optimizer_debug;
+
+ pcap_optimizer_debug = value;
+}
+#endif