Hello,
On Wed, Mar 01, 2017 at 05:50:57AM +0100, Joerg Mayer wrote:
> I'm trying to get libpcap working on macOS.
...
> Trying to understand the problem it looks like accessing struct pcap_md (the
> rpcap specific stuff) is broken on non-win32 platforms (or at least on bpf
> platforms).
>
> The intended memory layout seems to be:
>
> struct pcap_t (containing a pointer to priv if it exits)
> priv:
> struct pcap_
> struct pcap_md (if compiling with HAVE_REMOTE)
>
> The current implementation seems to
>
> a) only allocate the memory for pcap_md on win (pcap_create_interface() in
>pcap-win32.c), thus causing an out of bounds access on other platforms.
> b) the access to pcap_md is calculated as priv + sizeof(struct pcap_win)
>on all platforms which gets redeclared in pcap-new.c and pcap-rpcap.c
>for just this purpose. This looks wrong to me but I'm not sure.
OK, I think I managed to fix this one. Please see attached patch.
Now it fails (i.e. it no longer crashes!) with:
jmayer@newegg:~/worktmp/libpcap/build(master)$ dumpcap -i
rpcap://10.122.4.11/wifi0
Capturing on 'rpcap://10.122.4.11/wifi0'
dumpcap: Invalid capture filter "(null)" for interface
'rpcap://10.122.4.11/wifi0'.
That string isn't a valid capture filter (not-yet-activated pcap_t passed to
pcap_compile).
See the User's Guide for a description of the capture filter syntax.
jmayer@newegg:~/worktmp/libpcap/build(master)$ dumpcap -i
rpcap://10.122.4.11/wifi0 -L
Data link types of interface rpcap://10.122.4.11/wifi0 (use option -y to set):
DLT -3 (not supported)
Both of which seem to be libpcap problems (or symptoms of the same problem).
Kind regards
JÖrg
--
Joerg Mayer
We are stuck with technology when what we really want is just stuff that
works. Some say that should read Microsoft instead of technology.
Fix access to struct pcap_md on non-Windows
Previously it was assumed that pcap_md was at offset pcap_t + pcap_win.
That assumption was only correct on Windows systems.
Signed-off-by: Joerg Mayer
---
pcap-int.h | 3 +++
pcap-new.c | 4 ++--
pcap-rpcap.c | 20 +---
pcap.c | 18 +++---
4 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/pcap-int.h b/pcap-int.h
index 5c8c129..e74eec8 100644
--- a/pcap-int.h
+++ b/pcap-int.h
@@ -178,6 +178,9 @@ struct pcap {
int break_loop; /* flag set to force break from packet-reading
loop */
void *priv; /* private data for methods */
+#ifdef HAVE_REMOTE
+ void *priv_md; /* private data for rpcap */
+#endif
int swapped;
FILE *rfile;/* null if live capture, non-null if savefile */
diff --git a/pcap-new.c b/pcap-new.c
index 494e425..816f51d 100644
--- a/pcap-new.c
+++ b/pcap-new.c
@@ -940,7 +940,7 @@ pcap_t *pcap_open(const char *source, int snaplen, int
flags, int read_timeout,
}
struct pcap_md *md; /* structure
used when doing a remote live capture */
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct
pcap_win));
+ md = (struct pcap_md *)fp->priv_md;
fp->snapshot = snaplen;
fp->opt.timeout = read_timeout;
@@ -994,7 +994,7 @@ struct pcap_samp *pcap_setsampling(pcap_t *p)
{
struct pcap_md *md; /* structure used when
doing a remote live capture */
- md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
+ md = (struct pcap_md *)p->priv_md;
return &(md->rmt_samp);
}
diff --git a/pcap-rpcap.c b/pcap-rpcap.c
index f5f3fa5..51c07ae 100644
--- a/pcap-rpcap.c
+++ b/pcap-rpcap.c
@@ -216,7 +216,7 @@ static int pcap_read_nocb_remote(pcap_t *p, struct
pcap_pkthdr **pkt_header, u_c
struct timeval tv; /* maximum time the select()
can block waiting for data */
struct pcap_md *md; /* structure used when doing a
remote live capture */
- md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
+ md = (struct pcap_md *)p->priv_md;
/*
* Define the packet buffer timeout, to be used in the select()
@@ -423,7 +423,7 @@ static void pcap_cleanup_remote(pcap_t *fp)
int active = 0; /* active mode or not?
*/
struct pcap_md *md; /* structure used when
doing a remote live capture */
- md = (struct pcap_md *) ((u_char*)fp->priv + sizeof(struct pcap_win));
+ md = (struct pcap_md *)fp->priv_md;
/* detect if we're in active mode */
temp = activeHosts;
@@ -559,7 +559,7 @@ static struct pcap_stat *rpcap_stats_remote(pcap_t *p,
struct pcap_stat *ps, int
int retval; /* temp variable which stores
functions return value */
struct pcap_md *md; /* structure used