[PATCH 2/2] wpcap: Convert pcap_pkthdr structures.

Hans Leidekker hans at codeweavers.com
Mon Oct 4 07:36:40 CDT 2021


Structure layout is different on 64-bit.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51818
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/wpcap/unixlib.c | 60 ++++++++++++++++++++++++++++++++++++--------
 dlls/wpcap/unixlib.h | 26 +++++++++++++------
 dlls/wpcap/wpcap.c   | 13 +++++-----
 3 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/dlls/wpcap/unixlib.c b/dlls/wpcap/unixlib.c
index b48a5540edc..96e30fe2f11 100644
--- a/dlls/wpcap/unixlib.c
+++ b/dlls/wpcap/unixlib.c
@@ -28,6 +28,7 @@
 
 #include <stdarg.h>
 #include <stdlib.h>
+#include <limits.h>
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "windef.h"
@@ -37,6 +38,7 @@
 #include "wine/debug.h"
 #include "unixlib.h"
 
+WINE_DEFAULT_DEBUG_CHANNEL(wpcap);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
 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 )
 {
     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,
-                                void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *),
-                                unsigned char *user )
+                                void (CALLBACK *callback)(unsigned char *, const struct pcap_pkthdr_win32 *,
+                                                          const unsigned char *), unsigned char *user )
 {
     if (callback)
     {
@@ -118,9 +127,15 @@ static int CDECL wrap_dispatch( struct pcap *pcap, int count,
     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 )
@@ -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,
-                            void (CALLBACK *callback)(unsigned char *, const void *, const unsigned char *),
-                            unsigned char *user )
+                            void (CALLBACK *callback)(unsigned char *, const struct pcap_pkthdr_win32 *,
+                                                      const unsigned char *), unsigned char *user )
 {
     if (callback)
     {
@@ -216,14 +231,37 @@ static int CDECL wrap_minor_version( struct pcap *pcap )
     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 )
diff --git a/dlls/wpcap/unixlib.h b/dlls/wpcap/unixlib.h
index c5279f860fd..aa00bc33153 100644
--- a/dlls/wpcap/unixlib.h
+++ b/dlls/wpcap/unixlib.h
@@ -23,14 +23,26 @@ struct pcap_if_hdr
     char *name;
 };
 
+struct pcap_pkthdr_win32
+{
+    struct
+    {
+        int tv_sec;
+        int tv_usec;
+    } ts;
+    unsigned int caplen;
+    unsigned int len;
+};
+
 struct pcap
 {
     void *handle;
+    struct pcap_pkthdr_win32 hdr;
 };
 
 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;
 };
 
@@ -47,9 +59,9 @@ struct pcap_funcs
     const char * (CDECL *datalink_val_to_description)( int );
     const char * (CDECL *datalink_val_to_name)( 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 * );
-    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 * );
     int (CDECL *findalldevs)( struct pcap_if_hdr **, char * );
     void (CDECL *free_datalinks)( int * );
@@ -64,12 +76,12 @@ struct pcap_funcs
     int (CDECL *list_tstamp_types)( struct pcap *, int ** );
     int (CDECL *lookupnet)( const char *, unsigned int *, unsigned int *, char * );
     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 * );
     int (CDECL *major_version)( struct pcap * );
     int (CDECL *minor_version)( struct pcap * );
-    const unsigned char * (CDECL *next)( struct pcap *, void * );
-    int (CDECL *next_ex)( struct pcap *, void **, const unsigned char ** );
+    const unsigned char * (CDECL *next)( struct pcap *, struct pcap_pkthdr_win32 * );
+    int (CDECL *next_ex)( struct pcap *, struct pcap_pkthdr_win32 **, const unsigned char ** );
     struct pcap * (CDECL *open_live)( const char *, int, int, int, char * );
     int (CDECL *sendpacket)( struct pcap *, const unsigned char *, int );
     int (CDECL *set_buffer_size)( struct pcap *, int );
@@ -92,5 +104,5 @@ struct pcap_funcs
 
 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 * );
 };
diff --git a/dlls/wpcap/wpcap.c b/dlls/wpcap/wpcap.c
index a190634ac22..ffdb1a3e8d3 100644
--- a/dlls/wpcap/wpcap.c
+++ b/dlls/wpcap/wpcap.c
@@ -94,14 +94,14 @@ const char * CDECL pcap_datalink_val_to_name( int link )
 }
 
 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 )
 {
     TRACE( "%p, %d, %p, %p\n", 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 );
     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,
-                     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)
 {
     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 );
 }
 
-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 );
     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 );
     return pcap_funcs->next_ex( pcap, hdr, data );
@@ -450,7 +450,8 @@ int CDECL wsockinit( void )
     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 );
     cb->callback( cb->user, hdr, packet );
-- 
2.30.2




More information about the wine-devel mailing list