summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2020-07-01 02:15:40 -0700
committerGuy Harris <gharris@sonic.net>2020-07-01 02:15:40 -0700
commit5a68762e8b0cae345e4f42ff2dc4eee9ce32329d (patch)
tree86aa6ef65f73ee37f2ac80031ae2f81bb2d3c457
parent89b721fb41bf47b21662752221a4dd13a464da99 (diff)
downloadlibpcap-5a68762e8b0cae345e4f42ff2dc4eee9ce32329d.tar.gz
Handle the pcap_t+private data in a fashion that makes fewer assumptions.
The sizeof operator and alignof macro can be given a type "name" that's anonymous, e.g. sizeof(struct { int a; char *b; }). Have pcap_create_common() and pcap_open_offline_common() take, as arguments, the total size of a structure containing both the pcap_t and the private data as members, and the offset of the private data in that structure, and define macros that calculate those given, as an argument, the data type of the private data. This avoids making assumptions about the alignment of those two items within the structure; that *might* fix GitHub issue #940 if the issue is that the ARM compiler being used does 16-byte alignment of the private structure, rather than the 8-byte alignment we were wiring in.
-rw-r--r--pcap-airpcap.c2
-rw-r--r--pcap-bpf.c2
-rw-r--r--pcap-bt-linux.c2
-rw-r--r--pcap-bt-monitor-linux.c10
-rw-r--r--pcap-dag.c2
-rw-r--r--pcap-dbus.c2
-rw-r--r--pcap-dlpi.c2
-rw-r--r--pcap-dos.c2
-rw-r--r--pcap-dpdk.c2
-rw-r--r--pcap-haiku.cpp3
-rw-r--r--pcap-int.h31
-rw-r--r--pcap-libdlpi.c2
-rw-r--r--pcap-linux.c2
-rw-r--r--pcap-netfilter-linux.c2
-rw-r--r--pcap-netmap.c2
-rw-r--r--pcap-nit.c2
-rw-r--r--pcap-npf.c2
-rw-r--r--pcap-pf.c2
-rw-r--r--pcap-rdmasniff.c2
-rw-r--r--pcap-rpcap.c2
-rw-r--r--pcap-septel.c2
-rw-r--r--pcap-sita.c10
-rw-r--r--pcap-snf.c2
-rw-r--r--pcap-snit.c2
-rw-r--r--pcap-snoop.c2
-rw-r--r--pcap-tc.c2
-rw-r--r--pcap-usb-linux.c2
-rw-r--r--pcap.c45
-rw-r--r--sf-pcap.c2
-rw-r--r--sf-pcapng.c2
30 files changed, 89 insertions, 60 deletions
diff --git a/pcap-airpcap.c b/pcap-airpcap.c
index 7d7700ce..4876ec96 100644
--- a/pcap-airpcap.c
+++ b/pcap-airpcap.c
@@ -991,7 +991,7 @@ airpcap_create(const char *device, char *ebuf, int *is_ours)
* Yes.
*/
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_airpcap));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_airpcap);
if (p == NULL)
return (NULL);
diff --git a/pcap-bpf.c b/pcap-bpf.c
index e2e4e91f..10e3fab4 100644
--- a/pcap-bpf.c
+++ b/pcap-bpf.c
@@ -444,7 +444,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof (struct pcap_bpf));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_bpf);
if (p == NULL)
return (NULL);
diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c
index dbaa92ea..2969ff8d 100644
--- a/pcap-bt-linux.c
+++ b/pcap-bt-linux.c
@@ -173,7 +173,7 @@ bt_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_bt));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_bt);
if (p == NULL)
return (NULL);
diff --git a/pcap-bt-monitor-linux.c b/pcap-bt-monitor-linux.c
index 7b75b5cc..ad4fc375 100644
--- a/pcap-bt-monitor-linux.c
+++ b/pcap-bt-monitor-linux.c
@@ -50,6 +50,14 @@
#define INTERFACE_NAME "bluetooth-monitor"
/*
+ * Private data.
+ * Currently contains nothing.
+ */
+struct pcap_bt_monitor {
+ int dummy;
+};
+
+/*
* Fields and alignment must match the declaration in the Linux kernel 3.4+.
* See struct hci_mon_hdr in include/net/bluetooth/hci_mon.h.
*/
@@ -256,7 +264,7 @@ bt_monitor_create(const char *device, char *ebuf, int *is_ours)
}
*is_ours = 1;
- p = pcap_create_common(ebuf, 0);
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_bt_monitor);
if (p == NULL)
return NULL;
diff --git a/pcap-dag.c b/pcap-dag.c
index 62f6e649..4df15274 100644
--- a/pcap-dag.c
+++ b/pcap-dag.c
@@ -1071,7 +1071,7 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_dag));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_dag);
if (p == NULL)
return NULL;
diff --git a/pcap-dbus.c b/pcap-dbus.c
index 24c987a6..506f150f 100644
--- a/pcap-dbus.c
+++ b/pcap-dbus.c
@@ -314,7 +314,7 @@ dbus_create(const char *device, char *ebuf, int *is_ours)
}
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_dbus));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_dbus);
if (p == NULL)
return (NULL);
diff --git a/pcap-dlpi.c b/pcap-dlpi.c
index c43c1b15..abba8aef 100644
--- a/pcap-dlpi.c
+++ b/pcap-dlpi.c
@@ -1880,7 +1880,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
struct pcap_dlpi *pd;
#endif
- p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_dlpi);
if (p == NULL)
return (NULL);
diff --git a/pcap-dos.c b/pcap-dos.c
index 2d897093..16f15564 100644
--- a/pcap-dos.c
+++ b/pcap-dos.c
@@ -153,7 +153,7 @@ pcap_t *pcap_create_interface (const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof (struct pcap_dos));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_dos);
if (p == NULL)
return (NULL);
diff --git a/pcap-dpdk.c b/pcap-dpdk.c
index b00373f1..837ad1c2 100644
--- a/pcap-dpdk.c
+++ b/pcap-dpdk.c
@@ -972,7 +972,7 @@ pcap_t * pcap_dpdk_create(const char *device, char *ebuf, int *is_ours)
if (! *is_ours)
return NULL;
//memset will happen
- p = pcap_create_common(ebuf, sizeof(struct pcap_dpdk));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_dpdk);
if (p == NULL)
return NULL;
diff --git a/pcap-haiku.cpp b/pcap-haiku.cpp
index 38aefb76..701cac38 100644
--- a/pcap-haiku.cpp
+++ b/pcap-haiku.cpp
@@ -238,8 +238,7 @@ pcap_create_interface(const char *device, char *errorBuffer)
return NULL;
}
- pcap_t* handle = pcap_create_common(errorBuffer,
- sizeof (struct pcap_haiku));
+ pcap_t* handle = PCAP_CREATE_COMMON(errorBuffer, struct pcap_haiku);
if (handle == NULL) {
snprintf(errorBuffer, PCAP_ERRBUF_SIZE, "malloc: %s", strerror(errno));
close(socket);
diff --git a/pcap-int.h b/pcap-int.h
index 789ad572..f612913e 100644
--- a/pcap-int.h
+++ b/pcap-int.h
@@ -34,6 +34,8 @@
#ifndef pcap_int_h
#define pcap_int_h
+#include <stddef.h>
+
#include <signal.h>
#include <pcap/pcap.h>
@@ -461,7 +463,19 @@ int pcap_setnonblock_fd(pcap_t *p, int);
* by pcap_create routines.
*/
pcap_t *pcap_create_interface(const char *, char *);
-pcap_t *pcap_create_common(char *, size_t);
+
+/*
+ * This wrapper takes an error buffer pointer and a type to use for the
+ * private data, and calls pcap_create_common(), passing it the error
+ * buffer pointer, the size fo the private data type, in bytes, and the
+ * offset of the private data from the beginning of the structure, in
+ * bytes.
+ */
+#define PCAP_CREATE_COMMON(ebuf, type) \
+ pcap_create_common(ebuf, \
+ sizeof (struct { pcap_t __common; type __private; }), \
+ offsetof (struct { pcap_t __common; type __private; }, __private))
+pcap_t *pcap_create_common(char *, size_t, size_t);
int pcap_do_addexit(pcap_t *);
void pcap_add_to_pcaps_to_close(pcap_t *);
void pcap_remove_from_pcaps_to_close(pcap_t *);
@@ -533,7 +547,20 @@ int add_addr_to_if(pcap_if_list_t *, const char *, bpf_u_int32,
* treats the pathname as being in UTF-8, rather than the local
* code page, on Windows.
*/
-pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
+
+/*
+ * This wrapper takes an error buffer pointer and a type to use for the
+ * private data, and calls pcap_create_common(), passing it the error
+ * buffer pointer, the size fo the private data type, in bytes, and the
+ * offset of the private data from the beginning of the structure, in
+ * bytes.
+ */
+#define PCAP_OPEN_OFFLINE_COMMON(ebuf, type) \
+ pcap_open_offline_common(ebuf, \
+ sizeof (struct { pcap_t __common; type __private; }), \
+ offsetof (struct { pcap_t __common; type __private; }, __private))
+pcap_t *pcap_open_offline_common(char *ebuf, size_t total_size,
+ size_t private_data);
bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen);
void sf_cleanup(pcap_t *p);
#ifdef _WIN32
diff --git a/pcap-libdlpi.c b/pcap-libdlpi.c
index 68328b4b..ef3fdac3 100644
--- a/pcap-libdlpi.c
+++ b/pcap-libdlpi.c
@@ -477,7 +477,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_dlpi);
if (p == NULL)
return (NULL);
diff --git a/pcap-linux.c b/pcap-linux.c
index 546d0369..de21cd43 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -329,7 +329,7 @@ pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *handle;
- handle = pcap_create_common(ebuf, sizeof (struct pcap_linux));
+ handle = PCAP_CREATE_COMMON(ebuf, struct pcap_linux);
if (handle == NULL)
return NULL;
diff --git a/pcap-netfilter-linux.c b/pcap-netfilter-linux.c
index ced93027..cdd6d7fc 100644
--- a/pcap-netfilter-linux.c
+++ b/pcap-netfilter-linux.c
@@ -743,7 +743,7 @@ netfilter_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_netfilter));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_netfilter);
if (p == NULL)
return (NULL);
diff --git a/pcap-netmap.c b/pcap-netmap.c
index 3613a756..27d36e5b 100644
--- a/pcap-netmap.c
+++ b/pcap-netmap.c
@@ -286,7 +286,7 @@ pcap_netmap_create(const char *device, char *ebuf, int *is_ours)
*is_ours = (!strncmp(device, "netmap:", 7) || !strncmp(device, "vale", 4));
if (! *is_ours)
return NULL;
- p = pcap_create_common(ebuf, sizeof (struct pcap_netmap));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_netmap);
if (p == NULL)
return (NULL);
p->activate_op = pcap_netmap_activate;
diff --git a/pcap-nit.c b/pcap-nit.c
index b73eaad7..cfd95191 100644
--- a/pcap-nit.c
+++ b/pcap-nit.c
@@ -370,7 +370,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof (struct pcap_nit));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_nit);
if (p == NULL)
return (NULL);
diff --git a/pcap-npf.c b/pcap-npf.c
index 688b21f7..cdc0a715 100644
--- a/pcap-npf.c
+++ b/pcap-npf.c
@@ -1315,7 +1315,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof(struct pcap_win));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_win);
if (p == NULL)
return (NULL);
diff --git a/pcap-pf.c b/pcap-pf.c
index c50507b9..f483a0e6 100644
--- a/pcap-pf.c
+++ b/pcap-pf.c
@@ -535,7 +535,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof (struct pcap_pf));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_pf);
if (p == NULL)
return (NULL);
diff --git a/pcap-rdmasniff.c b/pcap-rdmasniff.c
index 032b80f8..224821de 100644
--- a/pcap-rdmasniff.c
+++ b/pcap-rdmasniff.c
@@ -395,7 +395,7 @@ rdmasniff_create(const char *device, char *ebuf, int *is_ours)
!strncmp(device, dev_list[i]->name, namelen)) {
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_rdmasniff));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_rdmasniff);
if (p) {
p->activate_op = rdmasniff_activate;
priv = p->priv;
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
index 836681a1..787b67a8 100644
--- a/pcap-rpcap.c
+++ b/pcap-rpcap.c
@@ -2319,7 +2319,7 @@ pcap_t *pcap_open_rpcap(const char *source, int snaplen, int flags, int read_tim
struct rpcap_header header; /* header of the RPCAP packet */
struct rpcap_openreply openreply; /* open reply message */
- fp = pcap_create_common(errbuf, sizeof (struct pcap_rpcap));
+ fp = PCAP_CREATE_COMMON(errbuf, struct pcap_rpcap);
if (fp == NULL)
{
return NULL;
diff --git a/pcap-septel.c b/pcap-septel.c
index c59dbc19..759e622c 100644
--- a/pcap-septel.c
+++ b/pcap-septel.c
@@ -233,7 +233,7 @@ pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
/* OK, it's probably ours. */
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_septel));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_septel);
if (p == NULL)
return NULL;
diff --git a/pcap-sita.c b/pcap-sita.c
index 03006332..90e7f6f1 100644
--- a/pcap-sita.c
+++ b/pcap-sita.c
@@ -72,6 +72,14 @@ typedef struct unit {
int len; /* the current size of the inbound message */
} unit_t;
+/*
+ * Private data.
+ * Currently contains nothing.
+ */
+struct pcap_sita {
+ int dummy;
+};
+
static unit_t units[MAX_CHASSIS+1][MAX_GEOSLOT+1]; /* we use indexes of 1 through 8, but we reserve/waste index 0 */
static fd_set readfds; /* a place to store the file descriptors for the connections to the IOPs */
static int max_fs;
@@ -1033,7 +1041,7 @@ static int pcap_activate_sita(pcap_t *handle) {
pcap_t *pcap_create_interface(const char *device _U_, char *ebuf) {
pcap_t *p;
- p = pcap_create_common(ebuf, 0);
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_sita);
if (p == NULL)
return (NULL);
diff --git a/pcap-snf.c b/pcap-snf.c
index 6bf504ea..3c37abf3 100644
--- a/pcap-snf.c
+++ b/pcap-snf.c
@@ -540,7 +540,7 @@ snf_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_snf));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_snf);
if (p == NULL)
return NULL;
ps = p->priv;
diff --git a/pcap-snit.c b/pcap-snit.c
index 6f063c9b..ca6222cf 100644
--- a/pcap-snit.c
+++ b/pcap-snit.c
@@ -459,7 +459,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof (struct pcap_snit));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_snit);
if (p == NULL)
return (NULL);
diff --git a/pcap-snoop.c b/pcap-snoop.c
index fe46314d..2f44b1dd 100644
--- a/pcap-snoop.c
+++ b/pcap-snoop.c
@@ -421,7 +421,7 @@ pcap_create_interface(const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(ebuf, sizeof (struct pcap_snoop));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_snoop);
if (p == NULL)
return (NULL);
diff --git a/pcap-tc.c b/pcap-tc.c
index ef409d32..9902633a 100644
--- a/pcap-tc.c
+++ b/pcap-tc.c
@@ -703,7 +703,7 @@ TcCreate(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_tc));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_tc);
if (p == NULL)
return NULL;
diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c
index ddab03a9..98d22de4 100644
--- a/pcap-usb-linux.c
+++ b/pcap-usb-linux.c
@@ -617,7 +617,7 @@ usb_create(const char *device, char *ebuf, int *is_ours)
/* OK, it's probably ours. */
*is_ours = 1;
- p = pcap_create_common(ebuf, sizeof (struct pcap_usb_linux));
+ p = PCAP_CREATE_COMMON(ebuf, struct pcap_usb_linux);
if (p == NULL)
return (NULL);
diff --git a/pcap.c b/pcap.c
index 0625e669..58ef71d2 100644
--- a/pcap.c
+++ b/pcap.c
@@ -2437,27 +2437,16 @@ initialize_ops(pcap_t *p)
}
static pcap_t *
-pcap_alloc_pcap_t(char *ebuf, size_t size)
+pcap_alloc_pcap_t(char *ebuf, size_t total_size, size_t private_offset)
{
char *chunk;
pcap_t *p;
/*
- * 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.
- *
- * The structure following it must be aligned on
- * the appropriate alignment boundary for this platform.
- * We align on an 8-byte boundary as that's probably what
- * at least some platforms do, even with 32-bit integers,
- * and because we can't be sure that some values won't
- * require 8-byte alignment even on platforms with 32-bit
- * integers.
+ * total_size is the size of a structure containing a pcap_t
+ * followed by a private structure.
*/
-#define PCAP_T_ALIGNED_SIZE ((sizeof(pcap_t) + 7U) & ~0x7U)
- chunk = calloc(PCAP_T_ALIGNED_SIZE + size, 1);
+ chunk = calloc(total_size, 1);
if (chunk == NULL) {
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
errno, "malloc");
@@ -2479,26 +2468,24 @@ pcap_alloc_pcap_t(char *ebuf, size_t size)
#endif /* MSDOS */
#endif /* _WIN32 */
- 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 + PCAP_T_ALIGNED_SIZE);
- }
+ /*
+ * private_offset is the offset, in bytes, of the private
+ * data from the beginning of the structure.
+ *
+ * Set the pointer to the private data; that's private_offset
+ * bytes past the pcap_t.
+ */
+ p->priv = (void *)(chunk + private_offset);
return (p);
}
pcap_t *
-pcap_create_common(char *ebuf, size_t size)
+pcap_create_common(char *ebuf, size_t total_size, size_t private_offset)
{
pcap_t *p;
- p = pcap_alloc_pcap_t(ebuf, size);
+ p = pcap_alloc_pcap_t(ebuf, total_size, private_offset);
if (p == NULL)
return (NULL);
@@ -2878,11 +2865,11 @@ fail:
}
pcap_t *
-pcap_open_offline_common(char *ebuf, size_t size)
+pcap_open_offline_common(char *ebuf, size_t total_size, size_t private_offset)
{
pcap_t *p;
- p = pcap_alloc_pcap_t(ebuf, size);
+ p = pcap_alloc_pcap_t(ebuf, total_size, private_offset);
if (p == NULL)
return (NULL);
diff --git a/sf-pcap.c b/sf-pcap.c
index 5c416b0c..d8443e98 100644
--- a/sf-pcap.c
+++ b/sf-pcap.c
@@ -240,7 +240,7 @@ pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
* OK, this is a good pcap file.
* Allocate a pcap_t for it.
*/
- p = pcap_open_offline_common(errbuf, sizeof (struct pcap_sf));
+ p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_sf);
if (p == NULL) {
/* Allocation failed. */
*err = 1;
diff --git a/sf-pcapng.c b/sf-pcapng.c
index 24eb5f73..f7f413d3 100644
--- a/sf-pcapng.c
+++ b/sf-pcapng.c
@@ -876,7 +876,7 @@ pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision,
* OK, this is a good pcapng file.
* Allocate a pcap_t for it.
*/
- p = pcap_open_offline_common(errbuf, sizeof (struct pcap_ng_sf));
+ p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_ng_sf);
if (p == NULL) {
/* Allocation failed. */
*err = 1;