wpcap: Convert pcap_pkthdr structures.

Structure layout is different on 64-bit.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51818
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2021-10-04 14:36:40 +02:00 committed by Alexandre Julliard
parent be9362190c
commit a999d57d6a
3 changed files with 75 additions and 24 deletions

View File

@ -28,6 +28,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h>
#include "ntstatus.h" #include "ntstatus.h"
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include "windef.h" #include "windef.h"
@ -37,6 +38,7 @@
#include "wine/debug.h" #include "wine/debug.h"
#include "unixlib.h" #include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(wpcap);
WINE_DECLARE_DEBUG_CHANNEL(winediag); WINE_DECLARE_DEBUG_CHANNEL(winediag);
static const struct pcap_callbacks *callbacks; static const struct pcap_callbacks *callbacks;
@ -101,12 +103,19 @@ static const char * CDECL wrap_datalink_val_to_name( int link )
static void wrap_pcap_handler( unsigned char *user, const struct pcap_pkthdr *hdr, const unsigned char *packet ) static void wrap_pcap_handler( unsigned char *user, const struct pcap_pkthdr *hdr, const unsigned char *packet )
{ {
struct handler_callback *cb = (struct handler_callback *)user; struct handler_callback *cb = (struct handler_callback *)user;
callbacks->handler( cb, hdr, packet ); struct pcap_pkthdr_win32 hdr_win32;
if (hdr->ts.tv_sec > INT_MAX || hdr->ts.tv_usec > INT_MAX) WARN( "truncating timeval values(s)\n" );
hdr_win32.ts.tv_sec = hdr->ts.tv_sec;
hdr_win32.ts.tv_usec = hdr->ts.tv_usec;
hdr_win32.caplen = hdr->caplen;
hdr_win32.len = hdr->len;
callbacks->handler( cb, &hdr_win32, packet );
} }
static int CDECL wrap_dispatch( struct pcap *pcap, int count, static int CDECL wrap_dispatch( struct pcap *pcap, int count,
void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), void (CALLBACK *callback)(unsigned char *, const struct pcap_pkthdr_win32 *,
unsigned char *user ) const unsigned char *), unsigned char *user )
{ {
if (callback) if (callback)
{ {
@ -118,9 +127,15 @@ static int CDECL wrap_dispatch( struct pcap *pcap, int count,
return pcap_dispatch( pcap->handle, count, NULL, user ); return pcap_dispatch( pcap->handle, count, NULL, user );
} }
static void CDECL wrap_dump( unsigned char *user, const void *hdr, const unsigned char *packet ) static void CDECL wrap_dump( unsigned char *user, const struct pcap_pkthdr_win32 *hdr, const unsigned char *packet )
{ {
return pcap_dump( user, hdr, packet ); struct pcap_pkthdr hdr_unix;
hdr_unix.ts.tv_sec = hdr->ts.tv_sec;
hdr_unix.ts.tv_usec = hdr->ts.tv_usec;
hdr_unix.caplen = hdr->caplen;
hdr_unix.len = hdr->len;
return pcap_dump( user, &hdr_unix, packet );
} }
static void * CDECL wrap_dump_open( struct pcap *pcap, const char *name ) static void * CDECL wrap_dump_open( struct pcap *pcap, const char *name )
@ -193,8 +208,8 @@ static int CDECL wrap_lookupnet( const char *device, unsigned int *net, unsigned
} }
static int CDECL wrap_loop( struct pcap *pcap, int count, static int CDECL wrap_loop( struct pcap *pcap, int count,
void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), void (CALLBACK *callback)(unsigned char *, const struct pcap_pkthdr_win32 *,
unsigned char *user ) const unsigned char *), unsigned char *user )
{ {
if (callback) if (callback)
{ {
@ -216,14 +231,37 @@ static int CDECL wrap_minor_version( struct pcap *pcap )
return pcap_minor_version( pcap->handle ); return pcap_minor_version( pcap->handle );
} }
static const unsigned char * CDECL wrap_next( struct pcap *pcap, void *hdr ) static const unsigned char * CDECL wrap_next( struct pcap *pcap, struct pcap_pkthdr_win32 *hdr )
{ {
return pcap_next( pcap->handle, hdr ); struct pcap_pkthdr hdr_unix;
const unsigned char *ret;
if ((ret = pcap_next( pcap->handle, &hdr_unix )))
{
if (hdr_unix.ts.tv_sec > INT_MAX || hdr_unix.ts.tv_usec > INT_MAX) WARN( "truncating timeval values(s)\n" );
hdr->ts.tv_sec = hdr_unix.ts.tv_sec;
hdr->ts.tv_usec = hdr_unix.ts.tv_usec;
hdr->caplen = hdr_unix.caplen;
hdr->len = hdr_unix.len;
}
return ret;
} }
static int CDECL wrap_next_ex( struct pcap *pcap, void **hdr, const unsigned char **data ) static int CDECL wrap_next_ex( struct pcap *pcap, struct pcap_pkthdr_win32 **hdr, const unsigned char **data )
{ {
return pcap_next_ex( pcap->handle, (struct pcap_pkthdr **)hdr, data ); struct pcap_pkthdr *hdr_unix;
int ret;
if ((ret = pcap_next_ex( pcap->handle, &hdr_unix, data )) == 1)
{
if (hdr_unix->ts.tv_sec > INT_MAX || hdr_unix->ts.tv_usec > INT_MAX) WARN( "truncating timeval values(s)\n" );
pcap->hdr.ts.tv_sec = hdr_unix->ts.tv_sec;
pcap->hdr.ts.tv_usec = hdr_unix->ts.tv_usec;
pcap->hdr.caplen = hdr_unix->caplen;
pcap->hdr.len = hdr_unix->len;
*hdr = &pcap->hdr;
}
return ret;
} }
static struct pcap * CDECL wrap_open_live( const char *source, int snaplen, int promisc, int to_ms, char *errbuf ) static struct pcap * CDECL wrap_open_live( const char *source, int snaplen, int promisc, int to_ms, char *errbuf )

View File

@ -23,14 +23,26 @@ struct pcap_if_hdr
char *name; char *name;
}; };
struct pcap_pkthdr_win32
{
struct
{
int tv_sec;
int tv_usec;
} ts;
unsigned int caplen;
unsigned int len;
};
struct pcap struct pcap
{ {
void *handle; void *handle;
struct pcap_pkthdr_win32 hdr;
}; };
struct handler_callback struct handler_callback
{ {
void (CALLBACK *callback)( unsigned char *, const void *, const unsigned char * ); void (CALLBACK *callback)( unsigned char *, const struct pcap_pkthdr_win32 *, const unsigned char * );
void *user; void *user;
}; };
@ -47,9 +59,9 @@ struct pcap_funcs
const char * (CDECL *datalink_val_to_description)( int ); const char * (CDECL *datalink_val_to_description)( int );
const char * (CDECL *datalink_val_to_name)( int ); const char * (CDECL *datalink_val_to_name)( int );
int (CDECL *dispatch)( struct pcap *, int, int (CDECL *dispatch)( struct pcap *, int,
void (CALLBACK *)(unsigned char *, const void *, const unsigned char *), void (CALLBACK *)(unsigned char *, const struct pcap_pkthdr_win32 *, const unsigned char *),
unsigned char * ); unsigned char * );
void (CDECL *dump)( unsigned char *, const void *, const unsigned char * ); void (CDECL *dump)( unsigned char *, const struct pcap_pkthdr_win32 *, const unsigned char * );
void * (CDECL *dump_open)( struct pcap *, const char * ); void * (CDECL *dump_open)( struct pcap *, const char * );
int (CDECL *findalldevs)( struct pcap_if_hdr **, char * ); int (CDECL *findalldevs)( struct pcap_if_hdr **, char * );
void (CDECL *free_datalinks)( int * ); void (CDECL *free_datalinks)( int * );
@ -64,12 +76,12 @@ struct pcap_funcs
int (CDECL *list_tstamp_types)( struct pcap *, int ** ); int (CDECL *list_tstamp_types)( struct pcap *, int ** );
int (CDECL *lookupnet)( const char *, unsigned int *, unsigned int *, char * ); int (CDECL *lookupnet)( const char *, unsigned int *, unsigned int *, char * );
int (CDECL *loop)( struct pcap *, int, int (CDECL *loop)( struct pcap *, int,
void (CALLBACK *)(unsigned char *, const void *, const unsigned char *), void (CALLBACK *)(unsigned char *, const struct pcap_pkthdr_win32 *, const unsigned char *),
unsigned char * ); unsigned char * );
int (CDECL *major_version)( struct pcap * ); int (CDECL *major_version)( struct pcap * );
int (CDECL *minor_version)( struct pcap * ); int (CDECL *minor_version)( struct pcap * );
const unsigned char * (CDECL *next)( struct pcap *, void * ); const unsigned char * (CDECL *next)( struct pcap *, struct pcap_pkthdr_win32 * );
int (CDECL *next_ex)( struct pcap *, void **, const unsigned char ** ); int (CDECL *next_ex)( struct pcap *, struct pcap_pkthdr_win32 **, const unsigned char ** );
struct pcap * (CDECL *open_live)( const char *, int, int, int, char * ); struct pcap * (CDECL *open_live)( const char *, int, int, int, char * );
int (CDECL *sendpacket)( struct pcap *, const unsigned char *, int ); int (CDECL *sendpacket)( struct pcap *, const unsigned char *, int );
int (CDECL *set_buffer_size)( struct pcap *, int ); int (CDECL *set_buffer_size)( struct pcap *, int );
@ -92,5 +104,5 @@ struct pcap_funcs
struct pcap_callbacks struct pcap_callbacks
{ {
void (CDECL *handler)( struct handler_callback *, const void *, const unsigned char * ); void (CDECL *handler)( struct handler_callback *, const struct pcap_pkthdr_win32 *, const unsigned char * );
}; };

View File

@ -94,14 +94,14 @@ const char * CDECL pcap_datalink_val_to_name( int link )
} }
int CDECL pcap_dispatch( struct pcap *pcap, int count, int CDECL pcap_dispatch( struct pcap *pcap, int count,
void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), void (CALLBACK *callback)(unsigned char *, const struct pcap_pkthdr_win32 *, const unsigned char *),
unsigned char *user ) unsigned char *user )
{ {
TRACE( "%p, %d, %p, %p\n", pcap, count, callback, user ); TRACE( "%p, %d, %p, %p\n", pcap, count, callback, user );
return pcap_funcs->dispatch( pcap, count, callback, user ); return pcap_funcs->dispatch( pcap, count, callback, user );
} }
void CDECL pcap_dump( unsigned char *user, const void *hdr, const unsigned char *packet ) void CDECL pcap_dump( unsigned char *user, const struct pcap_pkthdr_win32 *hdr, const unsigned char *packet )
{ {
TRACE( "%p, %p, %p\n", user, hdr, packet ); TRACE( "%p, %p, %p\n", user, hdr, packet );
pcap_funcs->dump( user, hdr, packet ); pcap_funcs->dump( user, hdr, packet );
@ -249,7 +249,7 @@ int CDECL pcap_lookupnet( const char *device, unsigned int *net, unsigned int *m
} }
int CDECL pcap_loop( struct pcap *pcap, int count, int CDECL pcap_loop( struct pcap *pcap, int count,
void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), void (CALLBACK *callback)(unsigned char *, const struct pcap_pkthdr_win32 *, const unsigned char *),
unsigned char *user) unsigned char *user)
{ {
TRACE( "%p, %d, %p, %p\n", pcap, count, callback, user ); TRACE( "%p, %d, %p, %p\n", pcap, count, callback, user );
@ -268,13 +268,13 @@ int CDECL pcap_minor_version( struct pcap *pcap )
return pcap_funcs->minor_version( pcap ); return pcap_funcs->minor_version( pcap );
} }
const unsigned char * CDECL pcap_next( struct pcap *pcap, void *hdr ) const unsigned char * CDECL pcap_next( struct pcap *pcap, struct pcap_pkthdr_win32 *hdr )
{ {
TRACE( "%p, %p\n", pcap, hdr ); TRACE( "%p, %p\n", pcap, hdr );
return pcap_funcs->next( pcap, hdr ); return pcap_funcs->next( pcap, hdr );
} }
int CDECL pcap_next_ex( struct pcap *pcap, void **hdr, const unsigned char **data ) int CDECL pcap_next_ex( struct pcap *pcap, struct pcap_pkthdr_win32 **hdr, const unsigned char **data )
{ {
TRACE( "%p, %p, %p\n", pcap, hdr, data ); TRACE( "%p, %p, %p\n", pcap, hdr, data );
return pcap_funcs->next_ex( pcap, hdr, data ); return pcap_funcs->next_ex( pcap, hdr, data );
@ -450,7 +450,8 @@ int CDECL wsockinit( void )
return 0; return 0;
} }
static void CDECL pcap_handler_cb( struct handler_callback *cb, const void *hdr, const unsigned char *packet ) static void CDECL pcap_handler_cb( struct handler_callback *cb, const struct pcap_pkthdr_win32 *hdr,
const unsigned char *packet )
{ {
TRACE( "%p, %p, %p\n", cb, hdr, packet ); TRACE( "%p, %p, %p\n", cb, hdr, packet );
cb->callback( cb->user, hdr, packet ); cb->callback( cb->user, hdr, packet );