Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/wpcap/Makefile.in | 1 + dlls/wpcap/unixlib.c | 262 +++++++++++++++++++++++++++++ dlls/wpcap/unixlib.h | 71 ++++++++ dlls/wpcap/wpcap.c | 374 +++++++++++++++++++---------------------- dlls/wpcap/wpcap.spec | 2 +- 5 files changed, 510 insertions(+), 200 deletions(-) create mode 100644 dlls/wpcap/unixlib.c create mode 100644 dlls/wpcap/unixlib.h
diff --git a/dlls/wpcap/Makefile.in b/dlls/wpcap/Makefile.in index 91b4a955911..4409a8c9e3a 100644 --- a/dlls/wpcap/Makefile.in +++ b/dlls/wpcap/Makefile.in @@ -3,6 +3,7 @@ DELAYIMPORTS = ws2_32 EXTRALIBS = $(PCAP_LIBS)
C_SRCS = \ + unixlib.c \ wpcap.c
RC_SRCS = version.rc diff --git a/dlls/wpcap/unixlib.c b/dlls/wpcap/unixlib.c new file mode 100644 index 00000000000..64205ea0e94 --- /dev/null +++ b/dlls/wpcap/unixlib.c @@ -0,0 +1,262 @@ +/* + * Copyright 2011, 2014 André Hentschel + * Copyright 2021 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#ifdef HAVE_PCAP_PCAP_H +#include <pcap/pcap.h> + +#include <stdarg.h> +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" + +#include "wine/debug.h" +#include "unixlib.h" + +WINE_DECLARE_DEBUG_CHANNEL(winediag); + +static const struct pcap_callbacks *callbacks; + +static void CDECL wrap_breakloop( void *handle ) +{ + return pcap_breakloop( handle ); +} + +static void CDECL wrap_close( void *handle ) +{ + pcap_close( handle ); +} + +static int CDECL wrap_compile( void *handle, void *program, const char *buf, int optimize, unsigned int mask ) +{ + return pcap_compile( handle, program, buf, optimize, mask ); +} + +static int CDECL wrap_datalink( void *handle ) +{ + return pcap_datalink( handle ); +} + +static int CDECL wrap_datalink_name_to_val( const char *name ) +{ + return pcap_datalink_name_to_val( name ); +} + +static const char * CDECL wrap_datalink_val_to_description( int link ) +{ + return pcap_datalink_val_to_description( link ); +} + +static const char * CDECL wrap_datalink_val_to_name( int link ) +{ + return pcap_datalink_val_to_name( link ); +} + +void wrap_pcap_handler( unsigned char *user, const struct pcap_pkthdr *hdr, const unsigned char *packet ) +{ + struct handler_callback *cb = (struct handler_callback *)user; + callbacks->handler( cb, hdr, packet ); +} + +static int CDECL wrap_dispatch( void *handle, int count, + void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), + unsigned char *user ) +{ + if (callback) + { + struct handler_callback cb; + cb.callback = callback; + cb.user = user; + return pcap_dispatch( handle, count, wrap_pcap_handler, (unsigned char *)&cb ); + } + return pcap_dispatch( handle, count, NULL, user ); +} + +static void CDECL wrap_dump( unsigned char *user, const void *hdr, const unsigned char *packet ) +{ + return pcap_dump( user, hdr, packet ); +} + +static void * CDECL wrap_dump_open( void *handle, const char *name ) +{ + return pcap_dump_open( handle, name ); +} + +static int CDECL wrap_findalldevs( struct pcap_if_hdr **devs, char *errbuf ) +{ + int ret; + ret = pcap_findalldevs( (pcap_if_t **)devs, errbuf ); + if (devs && !*devs) + ERR_(winediag)( "Failed to access raw network (pcap), this requires special permissions.\n" ); + return ret; +} + +static void CDECL wrap_freealldevs( struct pcap_if_hdr *devs ) +{ + pcap_freealldevs( (pcap_if_t *)devs ); +} + +static void CDECL wrap_freecode( void *program ) +{ + return pcap_freecode( program ); +} + +static char * CDECL wrap_geterr( void *handle ) +{ + return pcap_geterr( handle ); +} + +static int CDECL wrap_getnonblock( void *handle, char *errbuf ) +{ + return pcap_getnonblock( handle, errbuf ); +} + +static const char * CDECL wrap_lib_version( void ) +{ + return pcap_lib_version(); +} + +static int CDECL wrap_list_datalinks( void *handle, int **buf ) +{ + return pcap_list_datalinks( handle, buf ); +} + +static int CDECL wrap_lookupnet( const char *device, unsigned int *net, unsigned int *mask, char *errbuf ) +{ + return pcap_lookupnet( device, net, mask, errbuf ); +} + +static int CDECL wrap_loop( void *handle, int count, + void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), + unsigned char *user ) +{ + if (callback) + { + struct handler_callback cb; + cb.callback = callback; + cb.user = user; + return pcap_loop( handle, count, wrap_pcap_handler, (unsigned char *)&cb ); + } + return pcap_loop( handle, count, NULL, user ); +} + +static int CDECL wrap_major_version( void *handle ) +{ + return pcap_major_version( handle ); +} + +static int CDECL wrap_minor_version( void *handle ) +{ + return pcap_minor_version( handle ); +} + +static const unsigned char * CDECL wrap_next( void *handle, void *hdr ) +{ + return pcap_next( handle, hdr ); +} + +static int CDECL wrap_next_ex( void *handle, void **hdr, const unsigned char **data ) +{ + return pcap_next_ex( handle, (struct pcap_pkthdr **)hdr, data ); +} + +static void * CDECL wrap_open_live( const char *source, int snaplen, int promisc, int to_ms, char *errbuf ) +{ + return pcap_open_live( source, snaplen, promisc, to_ms, errbuf ); +} + +static int CDECL wrap_sendpacket( void *handle, const unsigned char *buf, int size ) +{ + return pcap_sendpacket( handle, buf, size ); +} + +static int CDECL wrap_set_datalink( void *handle, int link ) +{ + return pcap_set_datalink( handle, link ); +} + +static int CDECL wrap_setfilter( void *handle, void *program ) +{ + return pcap_setfilter( handle, program ); +} + +static int CDECL wrap_setnonblock( void *handle, int nonblock, char *errbuf ) +{ + return pcap_setnonblock( handle, nonblock, errbuf ); +} + +static int CDECL wrap_snapshot( void *handle ) +{ + return pcap_snapshot( handle ); +} + +static int CDECL wrap_stats( void *handle, void *stats ) +{ + return pcap_stats( handle, stats ); +} + +static const struct pcap_funcs funcs = +{ + wrap_breakloop, + wrap_close, + wrap_compile, + wrap_datalink, + wrap_datalink_name_to_val, + wrap_datalink_val_to_description, + wrap_datalink_val_to_name, + wrap_dispatch, + wrap_dump, + wrap_dump_open, + wrap_findalldevs, + wrap_freealldevs, + wrap_freecode, + wrap_geterr, + wrap_getnonblock, + wrap_lib_version, + wrap_list_datalinks, + wrap_lookupnet, + wrap_loop, + wrap_major_version, + wrap_minor_version, + wrap_next, + wrap_next_ex, + wrap_open_live, + wrap_sendpacket, + wrap_set_datalink, + wrap_setfilter, + wrap_setnonblock, + wrap_snapshot, + wrap_stats, +}; + +NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) +{ + if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS; + callbacks = ptr_in; + *(const struct pcap_funcs **)ptr_out = &funcs; + return STATUS_SUCCESS; +} +#endif /* HAVE_PCAP_PCAP_H */ diff --git a/dlls/wpcap/unixlib.h b/dlls/wpcap/unixlib.h new file mode 100644 index 00000000000..ac51eba3c15 --- /dev/null +++ b/dlls/wpcap/unixlib.h @@ -0,0 +1,71 @@ +/* + * Copyright 2011, 2014 André Hentschel + * Copyright 2021 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +struct pcap_if_hdr +{ + struct pcap_if_hdr *next; + char *name; +}; + +struct handler_callback +{ + void (CALLBACK *callback)( unsigned char *, const void *, const unsigned char * ); + void *user; +}; + +struct pcap_funcs +{ + void (CDECL *breakloop)( void * ); + void (CDECL *close)( void * ); + int (CDECL *compile)( void *, void *, const char *, int, unsigned int ); + int (CDECL *datalink)( void * ); + int (CDECL *datalink_name_to_val)( const char * ); + const char * (CDECL *datalink_val_to_description)( int ); + const char * (CDECL *datalink_val_to_name)( int ); + int (CDECL *dispatch)( void *, int, void (CALLBACK *)(unsigned char *, const void *, const unsigned char *), + unsigned char * ); + void (CDECL *dump)( unsigned char *, const void *, const unsigned char * ); + void * (CDECL *dump_open)( void *, const char * ); + int (CDECL *findalldevs)( struct pcap_if_hdr **, char * ); + void (CDECL *freealldevs)( struct pcap_if_hdr * ); + void (CDECL *freecode)( void * ); + char * (CDECL *geterr)( void * ); + int (CDECL *getnonblock)( void *, char * ); + const char * (CDECL *lib_version)( void ); + int (CDECL *list_datalinks)( void *, int ** ); + int (CDECL *lookupnet)( const char *, unsigned int *, unsigned int *, char * ); + int (CDECL *loop)( void *, int, void (CALLBACK *)(unsigned char *, const void *, const unsigned char *), + unsigned char * ); + int (CDECL *major_version)( void * ); + int (CDECL *minor_version)( void * ); + const unsigned char * (CDECL *next)( void *, void * ); + int (CDECL *next_ex)( void *, void **, const unsigned char ** ); + void * (CDECL *open_live)( const char *, int, int, int, char * ); + int (CDECL *sendpacket)( void *, const unsigned char *, int ); + int (CDECL *set_datalink)( void *, int ); + int (CDECL *setfilter)( void *, void * ); + int (CDECL *setnonblock)( void *, int, char * ); + int (CDECL *snapshot)( void * ); + int (CDECL *stats)( void *, void * ); +}; + +struct pcap_callbacks +{ + void (CDECL *handler)( struct handler_callback *, const void *, const unsigned char * ); +}; diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c index d2f1be7a312..ea9146d7d0d 100644 --- a/dlls/wpcap/wpcap.c +++ b/dlls/wpcap/wpcap.c @@ -18,34 +18,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <pcap/pcap.h> - -/* pcap.h might define those: */ -#undef SOCKET -#undef INVALID_SOCKET - -#define USE_WS_PREFIX -#include "winsock2.h" +#include <stdarg.h> #include "windef.h" #include "winbase.h" +#include "winternl.h" +#include "winnls.h" +#define USE_WS_PREFIX +#include "winsock2.h" + #include "wine/heap.h" #include "wine/debug.h" +#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(wpcap); -WINE_DECLARE_DEBUG_CHANNEL(winediag); - -#ifndef PCAP_SRC_FILE_STRING -#define PCAP_SRC_FILE_STRING "file://" -#endif -#ifndef PCAP_SRC_FILE -#define PCAP_SRC_FILE 2 -#endif -#ifndef PCAP_SRC_IF_STRING -#define PCAP_SRC_IF_STRING "rpcap://" -#endif -#ifndef PCAP_SRC_IFLOCAL -#define PCAP_SRC_IFLOCAL 3 -#endif + +const struct pcap_funcs *pcap_funcs = NULL;
static inline WCHAR *heap_strdupAtoW(const char *str) { @@ -63,233 +50,222 @@ static inline WCHAR *heap_strdupAtoW(const char *str) return ret; }
-void CDECL wine_pcap_breakloop(pcap_t *p) +void CDECL wine_pcap_breakloop( void *handle ) { - TRACE("(%p)\n", p); - return pcap_breakloop(p); + TRACE( "%p\n", handle ); + pcap_funcs->breakloop( handle ); }
-void CDECL wine_pcap_close(pcap_t *p) +void CDECL wine_pcap_close( void *handle ) { - TRACE("(%p)\n", p); - pcap_close(p); + TRACE( "%p\n", handle ); + pcap_funcs->close( handle ); }
-int CDECL wine_pcap_compile(pcap_t *p, struct bpf_program *program, const char *buf, int optimize, - unsigned int mask) +int CDECL wine_pcap_compile( void *handle, void *program, const char *buf, int optimize, unsigned int mask ) { - TRACE("(%p %p %s %i %u)\n", p, program, debugstr_a(buf), optimize, mask); - return pcap_compile(p, program, buf, optimize, mask); + TRACE( "%p, %p, %s, %d, %u\n", handle, program, debugstr_a(buf), optimize, mask ); + return pcap_funcs->compile( handle, program, buf, optimize, mask ); }
-int CDECL wine_pcap_datalink(pcap_t *p) +int CDECL wine_pcap_datalink( void *handle ) { - TRACE("(%p)\n", p); - return pcap_datalink(p); + TRACE( "%p\n", handle ); + return pcap_funcs->datalink( handle ); }
-int CDECL wine_pcap_datalink_name_to_val(const char *name) +int CDECL wine_pcap_datalink_name_to_val( const char *name ) { - TRACE("(%s)\n", debugstr_a(name)); - return pcap_datalink_name_to_val(name); + TRACE( "%s\n", debugstr_a(name) ); + return pcap_funcs->datalink_name_to_val( name ); }
-const char* CDECL wine_pcap_datalink_val_to_description(int dlt) +const char * CDECL wine_pcap_datalink_val_to_description( int link ) { - TRACE("(%i)\n", dlt); - return pcap_datalink_val_to_description(dlt); + TRACE( "%d\n", link ); + return pcap_funcs->datalink_val_to_description( link ); }
-const char* CDECL wine_pcap_datalink_val_to_name(int dlt) +const char * CDECL wine_pcap_datalink_val_to_name( int link ) { - TRACE("(%i)\n", dlt); - return pcap_datalink_val_to_name(dlt); + TRACE( "%d\n", link ); + return pcap_funcs->datalink_val_to_name( link ); }
-typedef struct +int CDECL wine_pcap_dispatch( void *handle, int count, + void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), + unsigned char *user ) { - void (CALLBACK *pfn_cb)(u_char *, const struct pcap_pkthdr *, const u_char *); - void *user_data; -} PCAP_HANDLER_CALLBACK; + TRACE( "%p, %d, %p, %p\n", handle, count, callback, user ); + return pcap_funcs->dispatch( handle, count, callback, user ); +}
-static void pcap_handler_callback(u_char *user_data, const struct pcap_pkthdr *h, const u_char *p) +void CDECL wine_pcap_dump( unsigned char *user, const void *hdr, const unsigned char *packet ) { - PCAP_HANDLER_CALLBACK *pcb; - TRACE("(%p %p %p)\n", user_data, h, p); - pcb = (PCAP_HANDLER_CALLBACK *)user_data; - pcb->pfn_cb(pcb->user_data, h, p); - TRACE("Callback COMPLETED\n"); + TRACE( "%p, %p, %p\n", user, hdr, packet ); + pcap_funcs->dump( user, hdr, packet ); }
-int CDECL wine_pcap_dispatch(pcap_t *p, int cnt, - void (CALLBACK *callback)(u_char *, const struct pcap_pkthdr *, const u_char *), - unsigned char *user) +void * CDECL wine_pcap_dump_open( void *handle, const char *filename ) { - TRACE("(%p %i %p %p)\n", p, cnt, callback, user); + void *dumper; + WCHAR *filenameW; + char *unix_path;
- if (callback) - { - PCAP_HANDLER_CALLBACK pcb; - pcb.pfn_cb = callback; - pcb.user_data = user; - return pcap_dispatch(p, cnt, pcap_handler_callback, (unsigned char *)&pcb); - } + TRACE( "%p, %s\n", handle, debugstr_a(filename) );
- return pcap_dispatch(p, cnt, NULL, user); -} + if (!(filenameW = heap_strdupAtoW( filename ))) return NULL; + unix_path = wine_get_unix_file_name( filenameW ); + heap_free( filenameW ); + if (!unix_path) return NULL;
-int CDECL wine_pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) -{ - int ret; + TRACE( "unix_path %s\n", debugstr_a(unix_path) );
- TRACE("(%p %p)\n", alldevsp, errbuf); - ret = pcap_findalldevs(alldevsp, errbuf); - if(alldevsp && !*alldevsp) - ERR_(winediag)("Failed to access raw network (pcap), this requires special permissions.\n"); + dumper = pcap_funcs->dump_open( handle, unix_path ); + heap_free( unix_path ); + return dumper; +}
- return ret; +int CDECL wine_pcap_findalldevs( struct pcap_if_hdr **devs, char *errbuf ) +{ + TRACE( "%p, %p\n", devs, errbuf ); + return pcap_funcs->findalldevs( devs, errbuf ); }
-int CDECL wine_pcap_findalldevs_ex(char *source, void *auth, pcap_if_t **alldevs, char *errbuf) +int CDECL wine_pcap_findalldevs_ex( char *source, void *auth, struct pcap_if_hdr **devs, char *errbuf ) { - FIXME("(%s %p %p %p): partial stub\n", debugstr_a(source), auth, alldevs, errbuf); - return wine_pcap_findalldevs(alldevs, errbuf); + FIXME( "%s, %p, %p, %p: partial stub\n", debugstr_a(source), auth, devs, errbuf ); + return pcap_funcs->findalldevs( devs, errbuf ); }
-void CDECL wine_pcap_freealldevs(pcap_if_t *alldevs) +void CDECL wine_pcap_freealldevs( struct pcap_if_hdr *devs ) { - TRACE("(%p)\n", alldevs); - pcap_freealldevs(alldevs); + TRACE( "%p\n", devs ); + pcap_funcs->freealldevs( devs ); }
-void CDECL wine_pcap_freecode(struct bpf_program *fp) +void CDECL wine_pcap_freecode( void *program ) { - TRACE("(%p)\n", fp); - return pcap_freecode(fp); + TRACE( "%p\n", program ); + pcap_funcs->freecode( program ); }
-typedef struct _AirpcapHandle *PAirpcapHandle; -PAirpcapHandle CDECL wine_pcap_get_airpcap_handle(pcap_t *p) +void * CDECL wine_pcap_get_airpcap_handle( void *handle ) { - TRACE("(%p)\n", p); + TRACE( "%p\n", handle ); return NULL; }
-char* CDECL wine_pcap_geterr(pcap_t *p) +char * CDECL wine_pcap_geterr( void *handle ) { - TRACE("(%p)\n", p); - return pcap_geterr(p); + TRACE( "%p\n", handle ); + return pcap_funcs->geterr( handle ); }
-int CDECL wine_pcap_getnonblock(pcap_t *p, char *errbuf) +int CDECL wine_pcap_getnonblock( void *handle, char *errbuf ) { - TRACE("(%p %p)\n", p, errbuf); - return pcap_getnonblock(p, errbuf); + TRACE( "%p, %p\n", handle, errbuf ); + return pcap_funcs->getnonblock( handle, errbuf ); }
-const char* CDECL wine_pcap_lib_version(void) +static char lib_version[256]; +static BOOL WINAPI init_lib_version( INIT_ONCE *once, void *param, void **ctx ) { - const char* ret = pcap_lib_version(); - TRACE("%s\n", debugstr_a(ret)); - return ret; + const char *str = pcap_funcs->lib_version(); + if (strlen( str ) < sizeof(lib_version)) strcpy( lib_version, str ); + return TRUE; }
-int CDECL wine_pcap_list_datalinks(pcap_t *p, int **dlt_buffer) +const char * CDECL wine_pcap_lib_version( void ) { - TRACE("(%p %p)\n", p, dlt_buffer); - return pcap_list_datalinks(p, dlt_buffer); + static INIT_ONCE once = INIT_ONCE_STATIC_INIT; + if (!lib_version[0]) InitOnceExecuteOnce( &once, init_lib_version, NULL, NULL ); + TRACE( "%s\n", debugstr_a(lib_version) ); + return lib_version; }
-char* CDECL wine_pcap_lookupdev(char *errbuf) +int CDECL wine_pcap_list_datalinks( void *handle, int **buf ) +{ + TRACE( "%p, %p\n", handle, buf ); + return pcap_funcs->list_datalinks( handle, buf ); +} + +char * CDECL wine_pcap_lookupdev( char *errbuf ) { static char *ret; - pcap_if_t *devs; + struct pcap_if_hdr *devs;
- TRACE("(%p)\n", errbuf); + TRACE( "%p\n", errbuf ); if (!ret) { - if (pcap_findalldevs( &devs, errbuf ) == -1) return NULL; + if (pcap_funcs->findalldevs( &devs, errbuf ) == -1) return NULL; if (!devs) return NULL; - if ((ret = heap_alloc( strlen(devs->name) + 1 ))) strcpy( ret, devs->name ); - pcap_freealldevs( devs ); + if ((ret = malloc( strlen(devs->name) + 1 ))) strcpy( ret, devs->name ); + pcap_funcs->freealldevs( devs ); } return ret; }
-int CDECL wine_pcap_lookupnet(const char *device, unsigned int *netp, unsigned int *maskp, - char *errbuf) +int CDECL wine_pcap_lookupnet( const char *device, unsigned int *net, unsigned int *mask, char *errbuf ) { - TRACE("(%s %p %p %p)\n", debugstr_a(device), netp, maskp, errbuf); - return pcap_lookupnet(device, netp, maskp, errbuf); + TRACE( "%s, %p, %p, %p\n", debugstr_a(device), net, mask, errbuf ); + return pcap_funcs->lookupnet( device, net, mask, errbuf ); }
-int CDECL wine_pcap_loop(pcap_t *p, int cnt, - void (CALLBACK *callback)(u_char *, const struct pcap_pkthdr *, const u_char *), - unsigned char *user) +int CDECL wine_pcap_loop( void *handle, int count, + void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *), + unsigned char *user) { - TRACE("(%p %i %p %p)\n", p, cnt, callback, user); - - if (callback) - { - PCAP_HANDLER_CALLBACK pcb; - pcb.pfn_cb = callback; - pcb.user_data = user; - return pcap_loop(p, cnt, pcap_handler_callback, (unsigned char *)&pcb); - } - - return pcap_loop(p, cnt, NULL, user); + TRACE( "%p, %d, %p, %p\n", handle, count, callback, user ); + return pcap_funcs->loop( handle, count, callback, user ); }
-int CDECL wine_pcap_major_version(pcap_t *p) +int CDECL wine_pcap_major_version( void *handle ) { - TRACE("(%p)\n", p); - return pcap_major_version(p); + TRACE( "%p\n", handle ); + return pcap_funcs->major_version( handle ); }
-int CDECL wine_pcap_minor_version(pcap_t *p) +int CDECL wine_pcap_minor_version( void *handle ) { - TRACE("(%p)\n", p); - return pcap_minor_version(p); + TRACE( "%p\n", handle ); + return pcap_funcs->minor_version( handle ); }
-const unsigned char* CDECL wine_pcap_next(pcap_t *p, struct pcap_pkthdr *h) +const unsigned char * CDECL wine_pcap_next( void *handle, void *hdr ) { - TRACE("(%p %p)\n", p, h); - return pcap_next(p, h); + TRACE( "%p, %p\n", handle, hdr ); + return pcap_funcs->next( handle, hdr ); }
-int CDECL wine_pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, const unsigned char **pkt_data) +int CDECL wine_pcap_next_ex( void *handle, void **hdr, const unsigned char **data ) { - TRACE("(%p %p %p)\n", p, pkt_header, pkt_data); - return pcap_next_ex(p, pkt_header, pkt_data); + TRACE( "%p, %p, %p\n", handle, hdr, data ); + return pcap_funcs->next_ex( handle, hdr, data ); }
-#ifndef PCAP_OPENFLAG_PROMISCUOUS #define PCAP_OPENFLAG_PROMISCUOUS 1 -#endif - -pcap_t* CDECL wine_pcap_open(const char *source, int snaplen, int flags, int read_timeout, - void *auth, char *errbuf) +void * CDECL wine_pcap_open( const char *source, int snaplen, int flags, int timeout, void *auth, char *errbuf ) { - int promisc = flags & PCAP_OPENFLAG_PROMISCUOUS; - FIXME("(%s %i %i %i %p %p): partial stub\n", debugstr_a(source), snaplen, flags, read_timeout, - auth, errbuf); - return pcap_open_live(source, snaplen, promisc, read_timeout, errbuf); + FIXME( "%s, %d, %d, %d, %p, %p: partial stub\n", debugstr_a(source), snaplen, flags, timeout, auth, errbuf ); + return pcap_funcs->open_live( source, snaplen, flags & PCAP_OPENFLAG_PROMISCUOUS, timeout, errbuf ); }
-pcap_t* CDECL wine_pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, - char *errbuf) +void * CDECL wine_pcap_open_live( const char *source, int snaplen, int promisc, int to_ms, char *errbuf ) { - TRACE("(%s %i %i %i %p)\n", debugstr_a(source), snaplen, promisc, to_ms, errbuf); - return pcap_open_live(source, snaplen, promisc, to_ms, errbuf); + TRACE( "%s, %d, %d, %d, %p\n", debugstr_a(source), snaplen, promisc, to_ms, errbuf ); + return pcap_funcs->open_live( source, snaplen, promisc, to_ms, errbuf ); }
-int CDECL wine_pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf) +#define PCAP_SRC_FILE 2 +#define PCAP_SRC_IFLOCAL 3 + +int CDECL wine_pcap_parsesrcstr( const char *source, int *type, char *host, char *port, char *name, char *errbuf ) { int t = PCAP_SRC_IFLOCAL; const char *p = source;
- FIXME("(%s %p %p %p %p %p): partial stub\n", debugstr_a(source), type, host, port, name, errbuf); + FIXME( "%s, %p, %p, %p, %p, %p: partial stub\n", debugstr_a(source), type, host, port, name, errbuf );
if (host) *host = '\0'; @@ -298,11 +274,11 @@ int CDECL wine_pcap_parsesrcstr(const char *source, int *type, char *host, char if (name) *name = '\0';
- if (!strncmp(p, PCAP_SRC_IF_STRING, strlen(PCAP_SRC_IF_STRING))) - p += strlen(PCAP_SRC_IF_STRING); - else if (!strncmp(p, PCAP_SRC_FILE_STRING, strlen(PCAP_SRC_FILE_STRING))) + if (!strncmp(p, "rpcap://", strlen("rpcap://"))) + p += strlen("rpcap://"); + else if (!strncmp(p, "file://", strlen("file://"))) { - p += strlen(PCAP_SRC_FILE_STRING); + p += strlen("file://"); t = PCAP_SRC_FILE; }
@@ -322,79 +298,79 @@ int CDECL wine_pcap_parsesrcstr(const char *source, int *type, char *host, char return 0; }
-int CDECL wine_pcap_sendpacket(pcap_t *p, const unsigned char *buf, int size) +int CDECL wine_pcap_sendpacket( void *handle, const unsigned char *buf, int size ) { - TRACE("(%p %p %i)\n", p, buf, size); - return pcap_sendpacket(p, buf, size); + TRACE( "%p, %p, %d\n", handle, buf, size ); + return pcap_funcs->sendpacket( handle, buf, size ); }
-int CDECL wine_pcap_set_datalink(pcap_t *p, int dlt) +int CDECL wine_pcap_set_datalink( void *handle, int link ) { - TRACE("(%p %i)\n", p, dlt); - return pcap_set_datalink(p, dlt); + TRACE( "%p, %d\n", handle, link ); + return pcap_funcs->set_datalink( handle, link ); }
-int CDECL wine_pcap_setbuff(pcap_t * p, int dim) +int CDECL wine_pcap_setbuff( void *handle, int size ) { - FIXME("(%p %i) stub\n", p, dim); + FIXME( "%p, %d\n", handle, size ); return 0; }
-int CDECL wine_pcap_setfilter(pcap_t *p, struct bpf_program *fp) +int CDECL wine_pcap_setfilter( void *handle, void *program ) { - TRACE("(%p %p)\n", p, fp); - return pcap_setfilter(p, fp); + TRACE( "%p, %p\n", handle, program ); + return pcap_funcs->setfilter( handle, program ); }
-int CDECL wine_pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) +int CDECL wine_pcap_setnonblock( void *handle, int nonblock, char *errbuf ) { - TRACE("(%p %i %p)\n", p, nonblock, errbuf); - return pcap_setnonblock(p, nonblock, errbuf); + TRACE( "%p, %d, %p\n", handle, nonblock, errbuf ); + return pcap_funcs->setnonblock( handle, nonblock, errbuf ); }
-int CDECL wine_pcap_snapshot(pcap_t *p) +int CDECL wine_pcap_snapshot( void *handle ) { - TRACE("(%p)\n", p); - return pcap_snapshot(p); + TRACE( "%p\n", handle ); + return pcap_funcs->snapshot( handle ); }
-int CDECL wine_pcap_stats(pcap_t *p, struct pcap_stat *ps) +int CDECL wine_pcap_stats( void *handle, void *stats ) { - TRACE("(%p %p)\n", p, ps); - return pcap_stats(p, ps); + TRACE( "%p, %p\n", handle, stats ); + return pcap_funcs->stats( handle, stats ); }
-int CDECL wine_wsockinit(void) +int CDECL wsockinit( void ) { WSADATA wsadata; - TRACE("()\n"); - if (WSAStartup(MAKEWORD(1,1), &wsadata)) return -1; + TRACE( "\n" ); + if (WSAStartup( MAKEWORD(1, 1), &wsadata )) return -1; return 0; }
-pcap_dumper_t* CDECL wine_pcap_dump_open(pcap_t *p, const char *fname) +static void CDECL pcap_handler_cb( struct handler_callback *cb, const void *hdr, const unsigned char *packet ) { - pcap_dumper_t *dumper; - WCHAR *fnameW = heap_strdupAtoW(fname); - char *unix_path; - - TRACE("(%p %s)\n", p, debugstr_a(fname)); - - unix_path = wine_get_unix_file_name(fnameW); - heap_free(fnameW); - if(!unix_path) - return NULL; - - TRACE("unix_path %s\n", debugstr_a(unix_path)); - - dumper = pcap_dump_open(p, unix_path); - heap_free(unix_path); - - return dumper; + TRACE( "%p, %p, %p\n", cb, hdr, packet ); + cb->callback( cb->user, hdr, packet ); + TRACE( "callback completed\n" ); }
-void CDECL wine_pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) +const struct pcap_callbacks pcap_callbacks = { - TRACE("(%p %p %p)\n", user, h, sp); - return pcap_dump(user, h, sp); + pcap_handler_cb +}; + +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved ) +{ + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls( hinst ); + if (__wine_init_unix_lib( hinst, reason, &pcap_callbacks, &pcap_funcs )) + ERR( "No pcap support, expect problems\n" ); + break; + case DLL_PROCESS_DETACH: + break; + } + return TRUE; } diff --git a/dlls/wpcap/wpcap.spec b/dlls/wpcap/wpcap.spec index ffb6ed1e551..fc11a798871 100644 --- a/dlls/wpcap/wpcap.spec +++ b/dlls/wpcap/wpcap.spec @@ -75,4 +75,4 @@ @ cdecl pcap_stats(ptr ptr) wine_pcap_stats @ stub pcap_stats_ex @ cdecl pcap_strerror(long) msvcrt.strerror -@ cdecl wsockinit() wine_wsockinit +@ cdecl wsockinit()