diff options
author | Guy Harris <gharris@sonic.net> | 2023-01-16 00:42:46 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-16 00:42:46 -0800 |
commit | 7b955929deb75804ec74dffc2934cbef7c1196c6 (patch) | |
tree | d2041a9baf6050d454b13871c9be66e9a5c2cad1 | |
parent | 56b17aaab04148851bd3ea0f7580c0834dc49906 (diff) | |
parent | a9487778d264f8e272ddb6c8b9dc4897a05d4fdb (diff) | |
download | libpcap-7b955929deb75804ec74dffc2934cbef7c1196c6.tar.gz |
Merge pull request #1142 from hansleidekker/mmap
Add an option to force memory-mapped buffers to be mapped as accessible to 32-bit code
-rw-r--r-- | pcap-bpf.c | 8 | ||||
-rw-r--r-- | pcap-int.h | 5 | ||||
-rw-r--r-- | pcap-linux.c | 22 | ||||
-rw-r--r-- | pcap.c | 5 | ||||
-rw-r--r-- | pcap/pcap.h | 1 | ||||
-rw-r--r-- | pcap_init.3pcap | 3 |
6 files changed, 34 insertions, 10 deletions
@@ -1790,6 +1790,7 @@ pcap_activate_bpf(pcap_t *p) #ifdef HAVE_ZEROCOPY_BPF struct bpf_zbuf bz; u_int bufmode, zbufmax; + int flags = MAP_ANON; #endif fd = bpf_open(p->errbuf); @@ -2092,10 +2093,13 @@ pcap_activate_bpf(pcap_t *p) pb->zbufsize = roundup(v, getpagesize()); if (pb->zbufsize > zbufmax) pb->zbufsize = zbufmax; +#ifdef MAP_32BIT + if (pcap_mmap_32bit) flags |= MAP_32BIT; +#endif pb->zbuf1 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE, - MAP_ANON, -1, 0); + flags, -1, 0); pb->zbuf2 = mmap(NULL, pb->zbufsize, PROT_READ | PROT_WRITE, - MAP_ANON, -1, 0); + flags, -1, 0); if (pb->zbuf1 == MAP_FAILED || pb->zbuf2 == MAP_FAILED) { pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, errno, "mmap"); @@ -108,6 +108,11 @@ extern int pcap_new_api; extern int pcap_utf_8_mode; /* + * Map packet buffers with 32-bit addresses. + */ +extern int pcap_mmap_32bit; + +/* * Swap byte ordering of unsigned long long timestamp on a big endian * machine. */ diff --git a/pcap-linux.c b/pcap-linux.c index 43d2a9f0..871cb662 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -829,7 +829,7 @@ static void pcap_cleanup_linux( pcap_t *handle ) } if (handlep->oneshot_buffer != NULL) { - free(handlep->oneshot_buffer); + munmap(handlep->oneshot_buffer, handle->snapshot); handlep->oneshot_buffer = NULL; } @@ -2661,14 +2661,17 @@ static int setup_mmapped(pcap_t *handle, int *status) { struct pcap_linux *handlep = handle->priv; - int ret; + int ret, flags = MAP_ANONYMOUS | MAP_PRIVATE; /* * Attempt to allocate a buffer to hold the contents of one * packet, for use by the oneshot callback. */ - handlep->oneshot_buffer = malloc(handle->snapshot); - if (handlep->oneshot_buffer == NULL) { +#ifdef MAP_32BIT + if (pcap_mmap_32bit) flags |= MAP_32BIT; +#endif + handlep->oneshot_buffer = mmap(0, handle->snapshot, PROT_READ | PROT_WRITE, flags, -1, 0); + if (handlep->oneshot_buffer == MAP_FAILED) { pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "can't allocate oneshot buffer"); *status = PCAP_ERROR; @@ -2681,7 +2684,7 @@ setup_mmapped(pcap_t *handle, int *status) } ret = prepare_tpacket_socket(handle); if (ret == -1) { - free(handlep->oneshot_buffer); + munmap(handlep->oneshot_buffer, handle->snapshot); handlep->oneshot_buffer = NULL; *status = PCAP_ERROR; return ret; @@ -2692,7 +2695,7 @@ setup_mmapped(pcap_t *handle, int *status) * Error attempting to enable memory-mapped capture; * fail. create_ring() has set *status. */ - free(handlep->oneshot_buffer); + munmap(handlep->oneshot_buffer, handle->snapshot); handlep->oneshot_buffer = NULL; return -1; } @@ -2870,6 +2873,7 @@ create_ring(pcap_t *handle, int *status) { struct pcap_linux *handlep = handle->priv; unsigned i, j, frames_per_block; + int flags = MAP_SHARED; #ifdef HAVE_TPACKET3 /* * For sockets using TPACKET_V2, the extra stuff at the end of a @@ -3252,8 +3256,10 @@ retry: /* memory map the rx ring */ handlep->mmapbuflen = req.tp_block_nr * req.tp_block_size; - handlep->mmapbuf = mmap(0, handlep->mmapbuflen, - PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); +#ifdef MAP_32BIT + if (pcap_mmap_32bit) flags |= MAP_32BIT; +#endif + handlep->mmapbuf = mmap(0, handlep->mmapbuflen, PROT_READ | PROT_WRITE, flags, handle->fd, 0); if (handlep->mmapbuf == MAP_FAILED) { pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "can't mmap rx ring"); @@ -230,6 +230,7 @@ pcap_wsockinit(void) */ int pcap_new_api; /* pcap_lookupdev() always fails */ int pcap_utf_8_mode; /* Strings should be in UTF-8. */ +int pcap_mmap_32bit; /* Map packet buffers with 32-bit addresses. */ int pcap_init(unsigned int opts, char *errbuf) @@ -267,6 +268,10 @@ pcap_init(unsigned int opts, char *errbuf) pcap_utf_8_mode = 1; break; + case PCAP_MMAP_32BIT: + pcap_mmap_32bit = 1; + break; + default: snprintf(errbuf, PCAP_ERRBUF_SIZE, "Unknown options specified"); return (PCAP_ERROR); diff --git a/pcap/pcap.h b/pcap/pcap.h index 78570744..88b96847 100644 --- a/pcap/pcap.h +++ b/pcap/pcap.h @@ -429,6 +429,7 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, */ #define PCAP_CHAR_ENC_LOCAL 0x00000000U /* strings are in the local character encoding */ #define PCAP_CHAR_ENC_UTF_8 0x00000001U /* strings are in UTF-8 */ +#define PCAP_MMAP_32BIT 0x00000002U /* map packet buffers with 32-bit addresses */ PCAP_AVAILABLE_1_10 PCAP_API int pcap_init(unsigned int, char *); diff --git a/pcap_init.3pcap b/pcap_init.3pcap index a807d0ec..f9876d63 100644 --- a/pcap_init.3pcap +++ b/pcap_init.3pcap @@ -49,6 +49,9 @@ caller, as being in the local character encoding. .B PCAP_CHAR_ENC_UTF_8 Treat all strings supplied as arguments, and return all strings to the caller, as being in UTF-8. +.B PCAP_MMAP_32BIT +Map packet buffers with 32-bit addresses. +.TP .PP On UNIX-like systems, the local character encoding is assumed to be UTF-8, so no character encoding transformations are done. |