summaryrefslogtreecommitdiff
path: root/pcap-linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcap-linux.c')
-rw-r--r--pcap-linux.c654
1 files changed, 401 insertions, 253 deletions
diff --git a/pcap-linux.c b/pcap-linux.c
index 13bd8529f65c..e0fe1d3e0237 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -70,9 +70,7 @@
#define _GNU_SOURCE
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#include <errno.h>
#include <stdio.h>
@@ -81,6 +79,7 @@
#include <fcntl.h>
#include <string.h>
#include <limits.h>
+#include <endian.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -98,6 +97,7 @@
#include <sys/eventfd.h>
#include "pcap-int.h"
+#include "pcap-util.h"
#include "pcap/sll.h"
#include "pcap/vlan.h"
#include "pcap/can_socketcan.h"
@@ -111,7 +111,7 @@
#error "Libpcap will only work if TPACKET_V2 is supported; you must build for a 2.6.27 or later kernel"
#endif
-/* check for memory mapped access avaibility. We assume every needed
+/* check for memory mapped access availability. We assume every needed
* struct is defined if the macro TPACKET_HDRLEN is defined, because it
* uses many ring related structs and macros */
#ifdef TPACKET3_HDRLEN
@@ -221,10 +221,10 @@ struct pcap_linux {
*/
static int get_if_flags(const char *, bpf_u_int32 *, char *);
static int is_wifi(const char *);
-static void map_arphrd_to_dlt(pcap_t *, int, const char *, int);
+static int map_arphrd_to_dlt(pcap_t *, int, const char *, int);
static int pcap_activate_linux(pcap_t *);
static int setup_socket(pcap_t *, int);
-static int setup_mmapped(pcap_t *, int *);
+static int setup_mmapped(pcap_t *);
static int pcap_can_set_rfmon_linux(pcap_t *);
static int pcap_inject_linux(pcap_t *, const void *, int);
static int pcap_stats_linux(pcap_t *, struct pcap_stat *);
@@ -245,7 +245,7 @@ union thdr {
#define RING_GET_CURRENT_FRAME(h) RING_GET_FRAME_AT(h, h->offset)
static void destroy_ring(pcap_t *handle);
-static int create_ring(pcap_t *handle, int *status);
+static int create_ring(pcap_t *handle);
static int prepare_tpacket_socket(pcap_t *handle);
static int pcap_read_linux_mmap_v2(pcap_t *, int, pcap_handler , u_char *);
#ifdef HAVE_TPACKET3
@@ -253,7 +253,7 @@ static int pcap_read_linux_mmap_v3(pcap_t *, int, pcap_handler , u_char *);
#endif
static int pcap_setnonblock_linux(pcap_t *p, int nonblock);
static int pcap_getnonblock_linux(pcap_t *p);
-static void pcap_oneshot_linux(u_char *user, const struct pcap_pkthdr *h,
+static void pcapint_oneshot_linux(u_char *user, const struct pcap_pkthdr *h,
const u_char *bytes);
/*
@@ -287,7 +287,7 @@ static void pcap_oneshot_linux(u_char *user, const struct pcap_pkthdr *h,
#else
/*
* This is being compiled on a system that lacks TP_STATUS_VLAN_VALID,
- * so we testwith the value it has in the 3.0 and later kernels, so
+ * so we test with the value it has in the 3.0 and later kernels, so
* we can test it if we're running on a system that has it. (If we're
* running on a system that doesn't have it, it won't be set in the
* tp_status field, so the tests of it will always fail; that means
@@ -336,7 +336,7 @@ static struct sock_fprog total_fcode
static int iface_dsa_get_proto_info(const char *device, pcap_t *handle);
pcap_t *
-pcap_create_interface(const char *device, char *ebuf)
+pcapint_create_interface(const char *device, char *ebuf)
{
pcap_t *handle;
@@ -365,7 +365,7 @@ pcap_create_interface(const char *device, char *ebuf)
*/
handle->tstamp_precision_list = malloc(2 * sizeof(u_int));
if (handle->tstamp_precision_list == NULL) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
pcap_close(handle);
return NULL;
@@ -374,8 +374,12 @@ pcap_create_interface(const char *device, char *ebuf)
handle->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
handle->tstamp_precision_count = 2;
+ /*
+ * Start out with the breakloop handle not open; we don't
+ * need it until we're activated and ready to capture.
+ */
struct pcap_linux *handlep = handle->priv;
- handlep->poll_breakloop_fd = eventfd(0, EFD_NONBLOCK);
+ handlep->poll_breakloop_fd = -1;
return handle;
}
@@ -461,7 +465,7 @@ get_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path,
free(pathstr);
return 0;
}
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s: Can't readlink %s", device, pathstr);
free(pathstr);
return PCAP_ERROR;
@@ -618,7 +622,7 @@ DIAG_ON_NARROWING
*/
handlep->mondevice = strdup(mondevice);
if (handlep->mondevice == NULL) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "strdup");
/*
* Get rid of the monitor device.
@@ -742,7 +746,7 @@ pcap_can_set_rfmon_linux(pcap_t *handle)
*
* Compared to /proc/net/dev this avoids counting software drops,
* but may be unimplemented and just return 0.
- * The author has found no straigthforward way to check for support.
+ * The author has found no straightforward way to check for support.
*/
static long long int
linux_get_stat(const char * if_name, const char * stat) {
@@ -817,7 +821,7 @@ static void pcap_cleanup_linux( pcap_t *handle )
* Take this pcap out of the list of pcaps for which we
* have to take the interface out of some mode.
*/
- pcap_remove_from_pcaps_to_close(handle);
+ pcapint_remove_from_pcaps_to_close(handle);
}
if (handle->fd != -1) {
@@ -846,7 +850,7 @@ static void pcap_cleanup_linux( pcap_t *handle )
close(handlep->poll_breakloop_fd);
handlep->poll_breakloop_fd = -1;
}
- pcap_cleanup_live_common(handle);
+ pcapint_cleanup_live_common(handle);
}
#ifdef HAVE_TPACKET3
@@ -939,13 +943,20 @@ set_poll_timeout(struct pcap_linux *handlep)
static void pcap_breakloop_linux(pcap_t *handle)
{
- pcap_breakloop_common(handle);
+ pcapint_breakloop_common(handle);
struct pcap_linux *handlep = handle->priv;
uint64_t value = 1;
- /* XXX - what if this fails? */
- if (handlep->poll_breakloop_fd != -1)
+
+ if (handlep->poll_breakloop_fd != -1) {
+ /*
+ * XXX - pcap_breakloop() doesn't have a return value,
+ * so we can't indicate an error.
+ */
+DIAG_OFF_WARN_UNUSED_RESULT
(void)write(handlep->poll_breakloop_fd, &value, sizeof(value));
+DIAG_ON_WARN_UNUSED_RESULT
+ }
}
/*
@@ -996,13 +1007,17 @@ pcap_activate_linux(pcap_t *handle)
const char *device;
int is_any_device;
struct ifreq ifr;
- int status = 0;
- int status2 = 0;
+ int status;
int ret;
device = handle->opt.device;
/*
+ * Start out assuming no warnings.
+ */
+ status = 0;
+
+ /*
* Make sure the name we were handed will fit into the ioctls we
* might perform on the device; if not, return a "No such device"
* indication, as the Linux kernel shouldn't support creating
@@ -1036,7 +1051,7 @@ pcap_activate_linux(pcap_t *handle)
handlep->device = strdup(device);
if (handlep->device == NULL) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "strdup");
status = PCAP_ERROR;
goto fail;
@@ -1084,22 +1099,57 @@ pcap_activate_linux(pcap_t *handle)
status = ret;
goto fail;
}
+ if (ret > 0) {
+ /*
+ * We got a warning; return that, as handle->errbuf
+ * might have been overwritten by this warning.
+ */
+ status = ret;
+ }
+
/*
- * Success.
+ * Success (possibly with a warning).
+ *
+ * First, try to allocate an event FD for breakloop, if
+ * we're not going to start in non-blocking mode.
+ */
+ if (!handle->opt.nonblock) {
+ handlep->poll_breakloop_fd = eventfd(0, EFD_NONBLOCK);
+ if (handlep->poll_breakloop_fd == -1) {
+ /*
+ * Failed.
+ */
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "could not open eventfd");
+ status = PCAP_ERROR;
+ goto fail;
+ }
+ }
+
+ /*
+ * Succeeded.
* Try to set up memory-mapped access.
*/
- ret = setup_mmapped(handle, &status);
- if (ret == -1) {
+ ret = setup_mmapped(handle);
+ if (ret < 0) {
/*
* We failed to set up to use it, or the
* kernel supports it, but we failed to
- * enable it. status has been set to the
+ * enable it. The return value is the
* error status to return and, if it's
* PCAP_ERROR, handle->errbuf contains
* the error message.
*/
+ status = ret;
goto fail;
}
+ if (ret > 0) {
+ /*
+ * We got a warning; return that, as handle->errbuf
+ * might have been overwritten by this warning.
+ */
+ status = ret;
+ }
/*
* We succeeded. status has been set to the status to return,
@@ -1109,9 +1159,9 @@ pcap_activate_linux(pcap_t *handle)
* Now that we have activated the mmap ring, we can
* set the correct protocol.
*/
- if ((status2 = iface_bind(handle->fd, handlep->ifindex,
+ if ((ret = iface_bind(handle->fd, handlep->ifindex,
handle->errbuf, pcap_protocol(handle))) != 0) {
- status = status2;
+ status = ret;
goto fail;
}
@@ -1136,7 +1186,7 @@ pcap_activate_linux(pcap_t *handle)
break;
#endif
}
- handle->oneshot_callback = pcap_oneshot_linux;
+ handle->oneshot_callback = pcapint_oneshot_linux;
handle->selectable_fd = handle->fd;
return status;
@@ -1245,7 +1295,7 @@ device_still_exists(pcap_t *handle)
/*
* Error - report an error and return -1.
*/
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "getsockname failed");
return (-1);
}
@@ -1272,7 +1322,7 @@ pcap_inject_linux(pcap_t *handle, const void *buf, int size)
/*
* We don't support sending on the "any" device.
*/
- pcap_strlcpy(handle->errbuf,
+ pcapint_strlcpy(handle->errbuf,
"Sending packets isn't supported on the \"any\" device",
PCAP_ERRBUF_SIZE);
return (-1);
@@ -1286,7 +1336,7 @@ pcap_inject_linux(pcap_t *handle, const void *buf, int size)
* socket?
* Is a "sendto()" required there?
*/
- pcap_strlcpy(handle->errbuf,
+ pcapint_strlcpy(handle->errbuf,
"Sending packets isn't supported in cooked mode",
PCAP_ERRBUF_SIZE);
return (-1);
@@ -1294,7 +1344,7 @@ pcap_inject_linux(pcap_t *handle, const void *buf, int size)
ret = (int)send(handle->fd, buf, size, 0);
if (ret == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "send");
return (-1);
}
@@ -1425,17 +1475,12 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats)
return 0;
}
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno,
"failed to get statistics from socket");
return -1;
}
/*
- * Description string for the "any" device.
- */
-static const char any_descr[] = "Pseudo-device that captures on all interfaces";
-
-/*
* A PF_PACKET socket can be bound to any network interface.
*/
static int
@@ -1587,7 +1632,7 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
sock = get_if_ioctl_socket();
if (sock == -1) {
- pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno,
+ pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno,
"Can't create socket to get ethtool information for %s",
name);
return -1;
@@ -1667,7 +1712,7 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
#ifdef ETHTOOL_GLINK
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
info.cmd = ETHTOOL_GLINK;
/*
* XXX - while Valgrind handles SIOCETHTOOL and knows that
@@ -1715,7 +1760,7 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
/*
* Other error.
*/
- pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
save_errno,
"%s: SIOCETHTOOL(ETHTOOL_GLINK) ioctl failed",
name);
@@ -1745,24 +1790,19 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf)
}
int
-pcap_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
+pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf)
{
/*
* Get the list of regular interfaces first.
*/
- if (pcap_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
+ if (pcapint_findalldevs_interfaces(devlistp, errbuf, can_be_bound,
get_if_flags) == -1)
return (-1); /* failure */
/*
* Add the "any" device.
- * As it refers to all network devices, not to any particular
- * network device, the notion of "connected" vs. "disconnected"
- * doesn't apply.
*/
- if (add_dev(devlistp, "any",
- PCAP_IF_UP|PCAP_IF_RUNNING|PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE,
- any_descr, errbuf) == NULL)
+ if (pcap_add_any_dev(devlistp, errbuf) == NULL)
return (-1);
return (0);
@@ -1825,9 +1865,11 @@ is_wifi(const char *device)
* to pick some type that works in raw mode, or fail.
*
* Sets the link type to -1 if unable to map the type.
+ *
+ * Returns 0 on success or a PCAP_ERROR_ value on error.
*/
-static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
- const char *device, int cooked_ok)
+static int map_arphrd_to_dlt(pcap_t *handle, int arptype,
+ const char *device, int cooked_ok)
{
static const char cdma_rmnet[] = "cdma_rmnet";
@@ -1848,7 +1890,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
*/
if (strncmp(device, cdma_rmnet, sizeof cdma_rmnet - 1) == 0) {
handle->linktype = DLT_RAW;
- return;
+ return 0;
}
/*
@@ -1878,7 +1920,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
*/
ret = iface_dsa_get_proto_info(device, handle);
if (ret < 0)
- return;
+ return ret;
if (ret == 1) {
/*
@@ -1895,14 +1937,14 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
* It's not a Wi-Fi device; offer DOCSIS.
*/
handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
- /*
- * If that fails, just leave the list empty.
- */
- if (handle->dlt_list != NULL) {
- handle->dlt_list[0] = DLT_EN10MB;
- handle->dlt_list[1] = DLT_DOCSIS;
- handle->dlt_count = 2;
+ if (handle->dlt_list == NULL) {
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc");
+ return (PCAP_ERROR);
}
+ handle->dlt_list[0] = DLT_EN10MB;
+ handle->dlt_list[1] = DLT_DOCSIS;
+ handle->dlt_count = 2;
}
/* FALLTHROUGH */
@@ -2191,17 +2233,17 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
* IP-over-FC on which somebody wants to capture
* packets.
*/
+ handle->linktype = DLT_FC_2;
handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 3);
- /*
- * If that fails, just leave the list empty.
- */
- if (handle->dlt_list != NULL) {
- handle->dlt_list[0] = DLT_FC_2;
- handle->dlt_list[1] = DLT_FC_2_WITH_FRAME_DELIMS;
- handle->dlt_list[2] = DLT_IP_OVER_FC;
- handle->dlt_count = 3;
+ if (handle->dlt_list == NULL) {
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc");
+ return (PCAP_ERROR);
}
- handle->linktype = DLT_FC_2;
+ handle->dlt_list[0] = DLT_FC_2;
+ handle->dlt_list[1] = DLT_FC_2_WITH_FRAME_DELIMS;
+ handle->dlt_list[2] = DLT_IP_OVER_FC;
+ handle->dlt_count = 3;
break;
#ifndef ARPHRD_IRDA
@@ -2271,29 +2313,13 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype,
handle->linktype = -1;
break;
}
-}
-
-static void
-set_dlt_list_cooked(pcap_t *handle)
-{
- /*
- * Support both DLT_LINUX_SLL and DLT_LINUX_SLL2.
- */
- handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
-
- /*
- * If that failed, just leave the list empty.
- */
- if (handle->dlt_list != NULL) {
- handle->dlt_list[0] = DLT_LINUX_SLL;
- handle->dlt_list[1] = DLT_LINUX_SLL2;
- handle->dlt_count = 2;
- }
+ return (0);
}
/*
* Try to set up a PF_PACKET socket.
- * Returns 0 on success and a PCAP_ERROR_ value on failure.
+ * Returns 0 or a PCAP_WARNING_ value on success and a PCAP_ERROR_ value
+ * on failure.
*/
static int
setup_socket(pcap_t *handle, int is_any_device)
@@ -2333,13 +2359,23 @@ setup_socket(pcap_t *handle, int is_any_device)
status = PCAP_ERROR_PERM_DENIED;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Attempt to create packet socket failed - CAP_NET_RAW may be required");
+ } else if (errno == EAFNOSUPPORT) {
+ /*
+ * PF_PACKET sockets not supported.
+ * Perhaps we're running on the WSL1 module
+ * in the Windows NT kernel rather than on
+ * a real Linux kernel.
+ */
+ status = PCAP_ERROR_CAPTURE_NOTSUP;
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "PF_PACKET sockets not supported - is this WSL1?");
} else {
/*
* Other error.
*/
status = PCAP_ERROR;
}
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "socket");
return status;
}
@@ -2391,6 +2427,7 @@ setup_socket(pcap_t *handle, int is_any_device)
* on.
*/
close(sock_fd);
+
return PCAP_ERROR_RFMON_NOTSUP;
}
@@ -2408,7 +2445,11 @@ setup_socket(pcap_t *handle, int is_any_device)
close(sock_fd);
return arptype;
}
- map_arphrd_to_dlt(handle, arptype, device, 1);
+ status = map_arphrd_to_dlt(handle, arptype, device, 1);
+ if (status < 0) {
+ close(sock_fd);
+ return status;
+ }
if (handle->linktype == -1 ||
handle->linktype == DLT_LINUX_SLL ||
handle->linktype == DLT_LINUX_IRDA ||
@@ -2431,7 +2472,7 @@ setup_socket(pcap_t *handle, int is_any_device)
* warning message.
*/
if (close(sock_fd) == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "close");
return PCAP_ERROR;
}
@@ -2445,7 +2486,7 @@ setup_socket(pcap_t *handle, int is_any_device)
* any failure is a "this shouldn't
* happen" case.
*/
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "socket");
return PCAP_ERROR;
}
@@ -2460,7 +2501,6 @@ setup_socket(pcap_t *handle, int is_any_device)
free(handle->dlt_list);
handle->dlt_list = NULL;
handle->dlt_count = 0;
- set_dlt_list_cooked(handle);
}
if (handle->linktype == -1) {
@@ -2476,6 +2516,7 @@ setup_socket(pcap_t *handle, int is_any_device)
"falling back to cooked "
"socket",
arptype);
+ status = PCAP_WARNING;
}
/*
@@ -2487,12 +2528,6 @@ setup_socket(pcap_t *handle, int is_any_device)
handle->linktype != DLT_LINUX_LAPD &&
handle->linktype != DLT_NETLINK)
handle->linktype = DLT_LINUX_SLL;
- if (handle->linktype == -1) {
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "unknown arptype %d, defaulting to cooked mode",
- arptype);
- status = PCAP_WARNING;
- }
}
handlep->ifindex = iface_get_id(sock_fd, device,
@@ -2521,12 +2556,19 @@ setup_socket(pcap_t *handle, int is_any_device)
/*
* It uses cooked mode.
+ * Support both DLT_LINUX_SLL and DLT_LINUX_SLL2.
*/
handlep->cooked = 1;
handle->linktype = DLT_LINUX_SLL;
- handle->dlt_list = NULL;
- handle->dlt_count = 0;
- set_dlt_list_cooked(handle);
+ handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ if (handle->dlt_list == NULL) {
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno, "malloc");
+ return (PCAP_ERROR);
+ }
+ handle->dlt_list[0] = DLT_LINUX_SLL;
+ handle->dlt_list[1] = DLT_LINUX_SLL2;
+ handle->dlt_count = 2;
/*
* We're not bound to a device.
@@ -2566,7 +2608,7 @@ setup_socket(pcap_t *handle, int is_any_device)
mr.mr_type = PACKET_MR_PROMISC;
if (setsockopt(sock_fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&mr, sizeof(mr)) == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "setsockopt (PACKET_ADD_MEMBERSHIP)");
close(sock_fd);
return PCAP_ERROR;
@@ -2585,7 +2627,7 @@ setup_socket(pcap_t *handle, int is_any_device)
val = 1;
if (setsockopt(sock_fd, SOL_PACKET, PACKET_AUXDATA, &val,
sizeof(val)) == -1 && errno != ENOPROTOOPT) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "setsockopt (PACKET_AUXDATA)");
close(sock_fd);
return PCAP_ERROR;
@@ -2651,17 +2693,17 @@ setup_socket(pcap_t *handle, int is_any_device)
/*
* Attempt to setup memory-mapped access.
*
- * On success, returns 1, and sets *status to 0 if there are no warnings
- * or to a PCAP_WARNING_ code if there is a warning.
+ * On success, returns 0 if there are no warnings or a PCAP_WARNING_ code
+ * if there is a warning.
*
- * On error, returns -1, and sets *status to the appropriate error code;
- * if that is PCAP_ERROR, sets handle->errbuf to the appropriate message.
+ * On error, returns the appropriate error code; if that is PCAP_ERROR,
+ * sets handle->errbuf to the appropriate message.
*/
static int
-setup_mmapped(pcap_t *handle, int *status)
+setup_mmapped(pcap_t *handle)
{
struct pcap_linux *handlep = handle->priv;
- int ret;
+ int status;
/*
* Attempt to allocate a buffer to hold the contents of one
@@ -2669,36 +2711,34 @@ setup_mmapped(pcap_t *handle, int *status)
*/
handlep->oneshot_buffer = malloc(handle->snapshot);
if (handlep->oneshot_buffer == NULL) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "can't allocate oneshot buffer");
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
if (handle->opt.buffer_size == 0) {
/* by default request 2M for the ring buffer */
handle->opt.buffer_size = 2*1024*1024;
}
- ret = prepare_tpacket_socket(handle);
- if (ret == -1) {
+ status = prepare_tpacket_socket(handle);
+ if (status == -1) {
free(handlep->oneshot_buffer);
handlep->oneshot_buffer = NULL;
- *status = PCAP_ERROR;
- return ret;
+ return PCAP_ERROR;
}
- ret = create_ring(handle, status);
- if (ret == -1) {
+ status = create_ring(handle);
+ if (status < 0) {
/*
* Error attempting to enable memory-mapped capture;
- * fail. create_ring() has set *status.
+ * fail. The return value is the status to return.
*/
free(handlep->oneshot_buffer);
handlep->oneshot_buffer = NULL;
- return -1;
+ return status;
}
/*
- * Success. *status has been set either to 0 if there are no
+ * Success. status has been set either to 0 if there are no
* warnings or to a PCAP_WARNING_ value if there is a warning.
*
* handle->offset is used to get the current position into the rx ring.
@@ -2710,7 +2750,7 @@ setup_mmapped(pcap_t *handle, int *status)
*/
set_poll_timeout(handlep);
- return 1;
+ return status;
}
/*
@@ -2761,7 +2801,7 @@ init_tpacket(pcap_t *handle, int version, const char *version_str)
/*
* Some unexpected error.
*/
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "can't get %s header len on packet socket",
version_str);
}
@@ -2772,7 +2812,7 @@ init_tpacket(pcap_t *handle, int version, const char *version_str)
val = version;
if (setsockopt(handle->fd, SOL_PACKET, PACKET_VERSION, &val,
sizeof(val)) < 0) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "can't activate %s on packet socket", version_str);
return -1;
}
@@ -2859,14 +2899,14 @@ prepare_tpacket_socket(pcap_t *handle)
/*
* Attempt to set up memory-mapped access.
*
- * On success, returns 1, and sets *status to 0 if there are no warnings
- * or to a PCAP_WARNING_ code if there is a warning.
+ * On success, returns 0 if there are no warnings or to a PCAP_WARNING_ code
+ * if there is a warning.
*
- * On error, returns -1, and sets *status to the appropriate error code;
- * if that is PCAP_ERROR, sets handle->errbuf to the appropriate message.
+ * On error, returns the appropriate error code; if that is PCAP_ERROR,
+ * sets handle->errbuf to the appropriate message.
*/
static int
-create_ring(pcap_t *handle, int *status)
+create_ring(pcap_t *handle)
{
struct pcap_linux *handlep = handle->priv;
unsigned i, j, frames_per_block;
@@ -2883,11 +2923,12 @@ create_ring(pcap_t *handle, int *status)
socklen_t len;
unsigned int sk_type, tp_reserve, maclen, tp_hdrlen, netoff, macoff;
unsigned int frame_size;
+ int status;
/*
- * Start out assuming no warnings or errors.
+ * Start out assuming no warnings.
*/
- *status = 0;
+ status = 0;
/*
* Reserve space for VLAN tag reconstruction.
@@ -2919,11 +2960,10 @@ create_ring(pcap_t *handle, int *status)
len = sizeof(tp_reserve);
if (setsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE,
&tp_reserve, len) < 0) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"setsockopt (PACKET_RESERVE)");
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
switch (handlep->tp_version) {
@@ -2968,15 +3008,11 @@ create_ring(pcap_t *handle, int *status)
mtu = iface_get_mtu(handle->fd, handle->opt.device,
handle->errbuf);
- if (mtu == -1) {
- *status = PCAP_ERROR;
- return -1;
- }
+ if (mtu == -1)
+ return PCAP_ERROR;
offload = iface_get_offload(handle);
- if (offload == -1) {
- *status = PCAP_ERROR;
- return -1;
- }
+ if (offload == -1)
+ return PCAP_ERROR;
if (offload)
max_frame_len = MAX(mtu, 65535);
else
@@ -2993,10 +3029,9 @@ create_ring(pcap_t *handle, int *status)
len = sizeof(sk_type);
if (getsockopt(handle->fd, SOL_SOCKET, SO_TYPE, &sk_type,
&len) < 0) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "getsockopt (SO_TYPE)");
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
maclen = (sk_type == SOCK_DGRAM) ? 0 : MAX_LINKHEADER_SIZE;
/* XXX: in the kernel maclen is calculated from
@@ -3061,8 +3096,7 @@ create_ring(pcap_t *handle, int *status)
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Internal error: unknown TPACKET_ value %u",
handlep->tp_version);
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
/* compute the minimum block size that will handle this frame.
@@ -3111,7 +3145,7 @@ create_ring(pcap_t *handle, int *status)
hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
ifr.ifr_data = (void *)&hwconfig;
/*
@@ -3128,10 +3162,9 @@ create_ring(pcap_t *handle, int *status)
* and, if they can't, shouldn't
* try requesting hardware time stamps.
*/
- *status = PCAP_ERROR_PERM_DENIED;
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Attempt to set hardware timestamp failed - CAP_NET_ADMIN may be required");
- return -1;
+ return PCAP_ERROR_PERM_DENIED;
case EOPNOTSUPP:
case ERANGE:
@@ -3149,15 +3182,14 @@ create_ring(pcap_t *handle, int *status)
* We'll just fall back on the standard
* host time stamps.
*/
- *status = PCAP_WARNING_TSTAMP_TYPE_NOTSUP;
+ status = PCAP_WARNING_TSTAMP_TYPE_NOTSUP;
break;
default:
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"SIOCSHWTSTAMP failed");
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
} else {
/*
@@ -3181,11 +3213,10 @@ create_ring(pcap_t *handle, int *status)
}
if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP,
(void *)&timesource, sizeof(timesource))) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"can't set PACKET_TIMESTAMP");
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
}
}
@@ -3244,10 +3275,9 @@ retry:
req.tp_frame_nr -= req.tp_frame_nr/20;
goto retry;
}
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "can't create rx ring on packet socket");
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
/* memory map the rx ring */
@@ -3255,25 +3285,23 @@ retry:
handlep->mmapbuf = mmap(0, handlep->mmapbuflen,
PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
if (handlep->mmapbuf == MAP_FAILED) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "can't mmap rx ring");
/* clear the allocated ring on error*/
destroy_ring(handle);
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
/* allocate a ring for each frame header pointer*/
handle->cc = req.tp_frame_nr;
handle->buffer = malloc(handle->cc * sizeof(union thdr *));
if (!handle->buffer) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "can't allocate ring of frame headers");
destroy_ring(handle);
- *status = PCAP_ERROR;
- return -1;
+ return PCAP_ERROR;
}
/* fill the header ring with proper frame ptr*/
@@ -3288,7 +3316,7 @@ retry:
handle->bufsize = req.tp_frame_size;
handle->offset = 0;
- return 1;
+ return status;
}
/* free all ring related resources*/
@@ -3334,7 +3362,7 @@ destroy_ring(pcap_t *handle)
* pcap_next() or pcap_next_ex().
*/
static void
-pcap_oneshot_linux(u_char *user, const struct pcap_pkthdr *h,
+pcapint_oneshot_linux(u_char *user, const struct pcap_pkthdr *h,
const u_char *bytes)
{
struct oneshot_userdata *sp = (struct oneshot_userdata *)user;
@@ -3361,10 +3389,10 @@ pcap_setnonblock_linux(pcap_t *handle, int nonblock)
struct pcap_linux *handlep = handle->priv;
/*
- * Set the file descriptor to non-blocking mode, as we use
+ * Set the file descriptor to the requested mode, as we use
* it for sending packets.
*/
- if (pcap_setnonblock_fd(handle, nonblock) == -1)
+ if (pcapint_setnonblock_fd(handle, nonblock) == -1)
return -1;
/*
@@ -3372,6 +3400,9 @@ pcap_setnonblock_linux(pcap_t *handle, int nonblock)
* preserve the timeout value provided with pcap_set_timeout.
*/
if (nonblock) {
+ /*
+ * We're setting the mode to non-blocking mode.
+ */
if (handlep->timeout >= 0) {
/*
* Indicate that we're switching to
@@ -3385,14 +3416,15 @@ pcap_setnonblock_linux(pcap_t *handle, int nonblock)
handlep->poll_breakloop_fd = -1;
}
} else {
+ /*
+ * We're setting the mode to blocking mode.
+ */
if (handlep->poll_breakloop_fd == -1) {
/* If we did not have an eventfd, open one now that we are blocking. */
if ( ( handlep->poll_breakloop_fd = eventfd(0, EFD_NONBLOCK) ) == -1 ) {
- int save_errno = errno;
- snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Could not open eventfd: %s",
- strerror(errno));
- errno = save_errno;
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
+ PCAP_ERRBUF_SIZE, errno,
+ "could not open eventfd");
return -1;
}
}
@@ -3527,7 +3559,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
* Error. If it's not EINTR, report it.
*/
if (errno != EINTR) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"can't poll on packet socket");
return PCAP_ERROR;
@@ -3629,7 +3661,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
"Error condition on packet socket: Reported error was 0");
return PCAP_ERROR;
} else {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE,
err,
"Error condition on packet socket");
@@ -3651,7 +3683,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
nread = read(handlep->poll_breakloop_fd, &value,
sizeof(value));
if (nread == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE,
errno,
"Error reading from event FD");
@@ -3738,7 +3770,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
* The device still exists; try to see if it's up.
*/
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, handlep->device,
+ pcapint_strlcpy(ifr.ifr_name, handlep->device,
sizeof(ifr.ifr_name));
if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
if (errno == ENXIO || errno == ENODEV) {
@@ -3752,7 +3784,7 @@ static int pcap_wait_for_frames_mmap(pcap_t *handle)
"The interface disappeared");
return PCAP_ERROR;
} else {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"%s: Can't get flags",
handlep->device);
@@ -3803,7 +3835,6 @@ static int pcap_handle_packet_mmap(
unsigned char *bp;
struct sockaddr_ll *sll;
struct pcap_pkthdr pcaphdr;
- pcap_can_socketcan_hdr *canhdr;
unsigned int snaplen = tp_snaplen;
struct utsname utsname;
@@ -3932,56 +3963,173 @@ static int pcap_handle_packet_mmap(
* DLT_CAN_SOCKETCAN is expected to provide.
*/
if (sll->sll_hatype == ARPHRD_CAN) {
- /*
- * DLT_CAN_SOCKETCAN is specified as having the
- * CAN ID and flags in network byte order, but
- * capturing on a CAN device provides it in host
- * byte order. Convert it to network byte order.
- */
- canhdr = (pcap_can_socketcan_hdr *)bp;
- canhdr->can_id = htonl(canhdr->can_id);
+ pcap_can_socketcan_hdr *canhdr = (pcap_can_socketcan_hdr *)bp;
+ uint16_t protocol = ntohs(sll->sll_protocol);
/*
- * In addition, set the CANFD_FDF flag if
- * the protocol is LINUX_SLL_P_CANFD, as
- * the protocol field itself isn't in
- * the packet to indicate that it's a
- * CAN FD packet.
+ * Check the protocol field from the sll header.
+ * If it's one of the known CAN protocol types,
+ * make sure the appropriate flags are set, so
+ * that a program can tell what type of frame
+ * it is.
+ *
+ * The two flags are:
+ *
+ * CANFD_FDF, which is in the fd_flags field
+ * of the CAN classic/CAN FD header;
+ *
+ * CANXL_XLF, which is in the flags field
+ * of the CAN XL header, which overlaps
+ * the payload_length field of the CAN
+ * classic/CAN FD header.
*/
- uint16_t protocol = ntohs(sll->sll_protocol);
- if (protocol == LINUX_SLL_P_CANFD) {
+ switch (protocol) {
+
+ case LINUX_SLL_P_CAN:
+ /*
+ * CAN classic.
+ *
+ * Zero out the fd_flags and reserved
+ * fields, in case they're uninitialized
+ * crap, and clear the CANXL_XLF bit in
+ * the payload_length field.
+ *
+ * This means that the CANFD_FDF flag isn't
+ * set in the fd_flags field, and that
+ * the CANXL_XLF bit isn't set in the
+ * payload_length field, so this frame
+ * will appear to be a CAN classic frame.
+ */
+ canhdr->payload_length &= ~CANXL_XLF;
+ canhdr->fd_flags = 0;
+ canhdr->reserved1 = 0;
+ canhdr->reserved2 = 0;
+ break;
+
+ case LINUX_SLL_P_CANFD:
+ /*
+ * Set CANFD_FDF in the fd_flags field,
+ * and clear the CANXL_XLF bit in the
+ * payload_length field, so this frame
+ * will appear to be a CAN FD frame.
+ */
+ canhdr->payload_length &= ~CANXL_XLF;
canhdr->fd_flags |= CANFD_FDF;
/*
- * Zero out all the unknown bits in
- * fd_flags and clear the reserved
- * fields, so that a program reading
- * this can assume that CANFD_FDF
- * is set because we set it, not
- * because some uninitialized crap
- * was provided in the fd_flags
- * field.
+ * Zero out all the unknown bits in fd_flags
+ * and clear the reserved fields, so that
+ * a program reading this can assume that
+ * CANFD_FDF is set because we set it, not
+ * because some uninitialized crap was
+ * provided in the fd_flags field.
*
* (At least some LINKTYPE_CAN_SOCKETCAN
- * files attached to Wireshark bugs
- * had uninitialized junk there, so it
- * does happen.)
+ * files attached to Wireshark bugs had
+ * uninitialized junk there, so it does
+ * happen.)
*
- * Update this if Linux adds more flag
- * bits to the fd_flags field or uses
- * either of the reserved fields for
- * FD frames.
+ * Update this if Linux adds more flag bits
+ * to the fd_flags field or uses either of
+ * the reserved fields for FD frames.
*/
- canhdr->fd_flags &= ~(CANFD_FDF|CANFD_ESI|CANFD_BRS);
+ canhdr->fd_flags &= (CANFD_FDF|CANFD_ESI|CANFD_BRS);
canhdr->reserved1 = 0;
canhdr->reserved2 = 0;
+ break;
+
+ case LINUX_SLL_P_CANXL:
+ /*
+ * CAN XL frame.
+ *
+ * Make sure the CANXL_XLF bit is set in
+ * the payload_length field, so that
+ * this frame will appear to be a
+ * CAN XL frame.
+ */
+ canhdr->payload_length |= CANXL_XLF;
+ break;
+ }
+
+ /*
+ * Put multi-byte header fields in a byte-order
+ *-independent format.
+ */
+ if (canhdr->payload_length & CANXL_XLF) {
+ /*
+ * This is a CAN XL frame.
+ *
+ * DLT_CAN_SOCKETCAN is specified as having
+ * the Priority ID/VCID field in big--
+ * endian byte order, and the payload length
+ * and Acceptance Field in little-endian byte
+ * order. but capturing on a CAN device
+ * provides them in host byte order.
+ * Convert them to the appropriate byte
+ * orders.
+ *
+ * The reason we put the first field
+ * into big-endian byte order is that
+ * older libpcap code, ignorant of
+ * CAN XL, treated it as the CAN ID
+ * field and put it into big-endian
+ * byte order, and we don't want to
+ * break code that understands CAN XL
+ * headers, and treats that field as
+ * being big-endian.
+ *
+ * The other fields are put in little-
+ * endian byte order is that older
+ * libpcap code, ignorant of CAN XL,
+ * left those fields alone, and the
+ * processors on which the CAN XL
+ * frames were captured are likely
+ * to be little-endian processors.
+ */
+ pcap_can_socketcan_xl_hdr *canxl_hdr = (pcap_can_socketcan_xl_hdr *)bp;
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /*
+ * We're capturing on a little-endian
+ * machine, so we put the priority/VCID
+ * field into big-endian byte order, and
+ * leave the payload length and acceptance
+ * field in little-endian byte order.
+ */
+ /* Byte-swap priority/VCID. */
+ canxl_hdr->priority_vcid = SWAPLONG(canxl_hdr->priority_vcid);
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ /*
+ * We're capturing on a big-endian
+ * machine, so we want to leave the
+ * priority/VCID field alone, and byte-swap
+ * the payload length and acceptance
+ * fields to little-endian.
+ */
+ /* Byte-swap the payload length */
+ canxl_hdr->payload_length = SWAPSHORT(canxl_hdr->payload_length);
+
+ /*
+ * Byte-swap the acceptance field.
+ *
+ * XXX - is it just a 4-octet string,
+ * not in any byte order?
+ */
+ canxl_hdr->acceptance_field = SWAPLONG(canxl_hdr->acceptance_field);
+#else
+#error "Unknown byte order"
+#endif
} else {
/*
- * Clear CANFD_FDF if it's set (probably
- * again meaning that this field is
- * uninitialized junk).
+ * CAN or CAN FD frame.
+ *
+ * DLT_CAN_SOCKETCAN is specified as having
+ * the CAN ID and flags in network byte
+ * order, but capturing on a CAN device
+ * provides it in host byte order. Convert
+ * it to network byte order.
*/
- canhdr->fd_flags &= ~CANFD_FDF;
+ canhdr->can_id = htonl(canhdr->can_id);
}
}
}
@@ -3992,7 +4140,7 @@ static int pcap_handle_packet_mmap(
aux_data.vlan_tag_present = tp_vlan_tci_valid;
aux_data.vlan_tag = tp_vlan_tci & 0x0fff;
- if (pcap_filter_with_aux_data(handle->fcode.bf_insns,
+ if (pcapint_filter_with_aux_data(handle->fcode.bf_insns,
bp,
tp_len,
snaplen,
@@ -4324,7 +4472,7 @@ pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter)
if (!handle)
return -1;
if (!filter) {
- pcap_strlcpy(handle->errbuf, "setfilter: No filter specified",
+ pcapint_strlcpy(handle->errbuf, "setfilter: No filter specified",
PCAP_ERRBUF_SIZE);
return -1;
}
@@ -4333,8 +4481,8 @@ pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter)
/* Make our private copy of the filter */
- if (install_bpf_program(handle, filter) < 0)
- /* install_bpf_program() filled in errbuf */
+ if (pcapint_install_bpf_program(handle, filter) < 0)
+ /* pcapint_install_bpf_program() filled in errbuf */
return -1;
/*
@@ -4471,7 +4619,7 @@ pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter)
*/
if (handlep->filter_in_userland) {
if (reset_kernel_filter(handle) == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"can't remove kernel filter");
err = -2; /* fatal error */
@@ -4558,10 +4706,10 @@ iface_get_id(int fd, const char *device, char *ebuf)
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFINDEX");
return -1;
}
@@ -4605,7 +4753,7 @@ iface_bind(int fd, int ifindex, char *ebuf, int protocol)
ret = PCAP_ERROR_NO_SUCH_DEVICE;
} else {
ret = PCAP_ERROR;
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "bind");
}
return ret;
@@ -4614,7 +4762,7 @@ iface_bind(int fd, int ifindex, char *ebuf, int protocol)
/* Any pending errors, e.g., network is down? */
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "getsockopt (SO_ERROR)");
return PCAP_ERROR;
}
@@ -4629,7 +4777,7 @@ iface_bind(int fd, int ifindex, char *ebuf, int protocol)
*/
return PCAP_ERROR_IFACE_NOT_UP;
} else if (err > 0) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
err, "bind");
return PCAP_ERROR;
}
@@ -4719,7 +4867,7 @@ added:
* If we haven't already done so, arrange to have
* "pcap_close_all()" called when we exit.
*/
- if (!pcap_do_addexit(handle)) {
+ if (!pcapint_do_addexit(handle)) {
/*
* "atexit()" failed; don't put the interface
* in rfmon mode, just give up.
@@ -4734,9 +4882,9 @@ added:
* Now configure the monitor interface up.
*/
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, handlep->mondevice, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, handlep->mondevice, sizeof(ifr.ifr_name));
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s: Can't get flags for %s", device,
handlep->mondevice);
del_mon_if(handle, sock_fd, &nlstate, device,
@@ -4746,7 +4894,7 @@ added:
}
ifr.ifr_flags |= IFF_UP|IFF_RUNNING;
if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s: Can't set flags for %s", device,
handlep->mondevice);
del_mon_if(handle, sock_fd, &nlstate, device,
@@ -4769,7 +4917,7 @@ added:
/*
* Add this to the list of pcaps to close when we exit.
*/
- pcap_add_to_pcaps_to_close(handle);
+ pcapint_add_to_pcaps_to_close(handle);
return 1;
}
@@ -4808,7 +4956,7 @@ iface_set_all_ts_types(pcap_t *handle, char *ebuf)
handle->tstamp_type_list = malloc(NUM_SOF_TIMESTAMPING_TYPES * sizeof(u_int));
if (handle->tstamp_type_list == NULL) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
return -1;
}
@@ -4848,13 +4996,13 @@ iface_get_ts_types(const char *device, pcap_t *handle, char *ebuf)
*/
fd = get_if_ioctl_socket();
if (fd < 0) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "socket for SIOCETHTOOL(ETHTOOL_GET_TS_INFO)");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
memset(&info, 0, sizeof(info));
info.cmd = ETHTOOL_GET_TS_INFO;
ifr.ifr_data = (caddr_t)&info;
@@ -4889,7 +5037,7 @@ iface_get_ts_types(const char *device, pcap_t *handle, char *ebuf)
/*
* Other error.
*/
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
save_errno,
"%s: SIOCETHTOOL(ETHTOOL_GET_TS_INFO) ioctl failed",
device);
@@ -4925,7 +5073,7 @@ iface_get_ts_types(const char *device, pcap_t *handle, char *ebuf)
if (num_ts_types != 0) {
handle->tstamp_type_list = malloc(num_ts_types * sizeof(u_int));
if (handle->tstamp_type_list == NULL) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
return -1;
}
@@ -5006,7 +5154,7 @@ iface_ethtool_flag_ioctl(pcap_t *handle, int cmd, const char *cmdname,
struct ethtool_value eval;
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
eval.cmd = cmd;
eval.data = 0;
ifr.ifr_data = (caddr_t)&eval;
@@ -5021,7 +5169,7 @@ iface_ethtool_flag_ioctl(pcap_t *handle, int cmd, const char *cmdname,
*/
return 0;
}
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s: SIOCETHTOOL(%s) ioctl failed",
handle->opt.device, cmdname);
return -1;
@@ -5153,7 +5301,7 @@ iface_dsa_get_proto_info(const char *device, pcap_t *handle)
fd = asprintf(&pathstr, "/sys/class/net/%s/dsa/tagging", device);
if (fd < 0) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
fd, "asprintf");
return PCAP_ERROR;
}
@@ -5168,7 +5316,7 @@ iface_dsa_get_proto_info(const char *device, pcap_t *handle)
r = read(fd, buf, sizeof(buf) - 1);
if (r <= 0) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "read");
close(fd);
return PCAP_ERROR;
@@ -5213,10 +5361,10 @@ iface_get_mtu(int fd, const char *device, char *ebuf)
return BIGGER_THAN_ALL_MTUS;
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFMTU, &ifr) == -1) {
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFMTU");
return -1;
}
@@ -5234,7 +5382,7 @@ iface_get_arptype(int fd, const char *device, char *ebuf)
int ret;
memset(&ifr, 0, sizeof(ifr));
- pcap_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ pcapint_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
if (errno == ENODEV) {
@@ -5248,7 +5396,7 @@ iface_get_arptype(int fd, const char *device, char *ebuf)
ebuf[0] = '\0';
} else {
ret = PCAP_ERROR;
- pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "SIOCGIFHWADDR");
}
return ret;
@@ -5275,7 +5423,7 @@ fix_program(pcap_t *handle, struct sock_fprog *fcode)
len = handle->fcode.bf_len;
f = (struct bpf_insn *)malloc(prog_size);
if (f == NULL) {
- pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
return -1;
}
@@ -5467,13 +5615,13 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
*/
save_mode = fcntl(handle->fd, F_GETFL, 0);
if (save_mode == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"can't get FD flags when changing filter");
return -2;
}
if (fcntl(handle->fd, F_SETFL, save_mode | O_NONBLOCK) < 0) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"can't set nonblocking mode when changing filter");
return -2;
@@ -5490,13 +5638,13 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
*/
(void)fcntl(handle->fd, F_SETFL, save_mode);
(void)reset_kernel_filter(handle);
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, save_errno,
"recv failed when changing filter");
return -2;
}
if (fcntl(handle->fd, F_SETFL, save_mode) == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"can't restore FD flags when changing filter");
return -2;
@@ -5527,7 +5675,7 @@ set_kernel_filter(pcap_t *handle, struct sock_fprog *fcode)
* Report it as a fatal error.
*/
if (reset_kernel_filter(handle) == -1) {
- pcap_fmt_errmsg_for_errno(handle->errbuf,
+ pcapint_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno,
"can't remove kernel total filter");
return -2; /* fatal error */
@@ -5567,7 +5715,7 @@ reset_kernel_filter(pcap_t *handle)
int
pcap_set_protocol_linux(pcap_t *p, int protocol)
{
- if (pcap_check_activated(p))
+ if (pcapint_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
p->opt.protocol = protocol;
return (0);