diff options
author | Guy Harris <gharris@sonic.net> | 2020-07-01 02:15:40 -0700 |
---|---|---|
committer | Guy Harris <gharris@sonic.net> | 2020-07-01 02:15:40 -0700 |
commit | 5a68762e8b0cae345e4f42ff2dc4eee9ce32329d (patch) | |
tree | 86aa6ef65f73ee37f2ac80031ae2f81bb2d3c457 | |
parent | 89b721fb41bf47b21662752221a4dd13a464da99 (diff) | |
download | libpcap-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.c | 2 | ||||
-rw-r--r-- | pcap-bpf.c | 2 | ||||
-rw-r--r-- | pcap-bt-linux.c | 2 | ||||
-rw-r--r-- | pcap-bt-monitor-linux.c | 10 | ||||
-rw-r--r-- | pcap-dag.c | 2 | ||||
-rw-r--r-- | pcap-dbus.c | 2 | ||||
-rw-r--r-- | pcap-dlpi.c | 2 | ||||
-rw-r--r-- | pcap-dos.c | 2 | ||||
-rw-r--r-- | pcap-dpdk.c | 2 | ||||
-rw-r--r-- | pcap-haiku.cpp | 3 | ||||
-rw-r--r-- | pcap-int.h | 31 | ||||
-rw-r--r-- | pcap-libdlpi.c | 2 | ||||
-rw-r--r-- | pcap-linux.c | 2 | ||||
-rw-r--r-- | pcap-netfilter-linux.c | 2 | ||||
-rw-r--r-- | pcap-netmap.c | 2 | ||||
-rw-r--r-- | pcap-nit.c | 2 | ||||
-rw-r--r-- | pcap-npf.c | 2 | ||||
-rw-r--r-- | pcap-pf.c | 2 | ||||
-rw-r--r-- | pcap-rdmasniff.c | 2 | ||||
-rw-r--r-- | pcap-rpcap.c | 2 | ||||
-rw-r--r-- | pcap-septel.c | 2 | ||||
-rw-r--r-- | pcap-sita.c | 10 | ||||
-rw-r--r-- | pcap-snf.c | 2 | ||||
-rw-r--r-- | pcap-snit.c | 2 | ||||
-rw-r--r-- | pcap-snoop.c | 2 | ||||
-rw-r--r-- | pcap-tc.c | 2 | ||||
-rw-r--r-- | pcap-usb-linux.c | 2 | ||||
-rw-r--r-- | pcap.c | 45 | ||||
-rw-r--r-- | sf-pcap.c | 2 | ||||
-rw-r--r-- | sf-pcapng.c | 2 |
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); @@ -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; @@ -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); @@ -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); @@ -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; @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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; |