2 * Unit test for wpcap functions
4 * Copyright 2022 Hans Leidekker for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define WIN32_NO_STATUS
26 #include "wine/test.h"
28 #define PCAP_MMAP_32BIT 2
29 #define PCAP_ERRBUF_SIZE 256
30 #define PCAP_ERROR_PERM_DENIED -8
32 typedef struct pcap pcap_t
;
33 typedef struct pcap_if pcap_if_t
;
34 typedef struct pcap_dumper pcap_dumper_t
;
46 unsigned int ps_ifdrop
;
49 unsigned int ps_netdrop
;
63 struct bpf_insn
*bf_insns
;
77 static int (CDECL
*ppcap_activate
)( pcap_t
* );
78 static void (CDECL
*ppcap_breakloop
)( pcap_t
* );
79 static int (CDECL
*ppcap_bufsize
)( pcap_t
* );
80 static int (CDECL
*ppcap_can_set_rfmon
)( pcap_t
* );
81 static void (CDECL
*ppcap_close
)( pcap_t
* );
82 static int (CDECL
*ppcap_compile
)( pcap_t
*, struct bpf_program
*, const char *, int, unsigned int );
83 static pcap_t
* (CDECL
*ppcap_create
)( const char *, char * );
84 static int (CDECL
*ppcap_datalink
)( pcap_t
* );
85 static int (CDECL
*ppcap_datalink_name_to_val
)( const char * );
86 static const char * (CDECL
*ppcap_datalink_val_to_description
)( int );
87 static const char * (CDECL
*ppcap_datalink_val_to_name
)( int );
88 static int (CDECL
*ppcap_dispatch
)( pcap_t
*, int,
89 void (CALLBACK
*)(unsigned char *, const struct pcap_pkthdr
*, const unsigned char *),
91 static pcap_dumper_t
* (CDECL
*ppcap_dump_open
)( pcap_t
*, const char * );
92 static void (CDECL
*ppcap_dump
)( unsigned char *, const struct pcap_pkthdr
*, const unsigned char * );
93 static void (CDECL
*ppcap_dump_close
)( pcap_dumper_t
* );
94 static int (CDECL
*ppcap_findalldevs
)( pcap_if_t
**, char * );
95 static void (CDECL
*ppcap_freealldevs
)( pcap_if_t
* );
96 static void (CDECL
*ppcap_free_datalinks
)( int * );
97 static void (CDECL
*ppcap_free_tstamp_types
)( int * );
98 static void (CDECL
*ppcap_freecode
)( struct bpf_program
* );
99 static void * (CDECL
*ppcap_get_airpcap_handle
)( pcap_t
* );
100 static int (CDECL
*ppcap_get_tstamp_precision
)( pcap_t
* );
101 static char * (CDECL
*ppcap_geterr
)( pcap_t
* );
102 static int (CDECL
*ppcap_getnonblock
)( pcap_t
*, char * );
103 static int (CDECL
*ppcap_init
)( unsigned int, char * );
104 static const char * (CDECL
*ppcap_lib_version
)( void );
105 static int (CDECL
*ppcap_list_datalinks
)( pcap_t
*, int ** );
106 static int (CDECL
*ppcap_list_tstamp_types
)( pcap_t
*, int ** );
107 static char * (CDECL
*ppcap_lookupdev
)( char * );
108 static int (CDECL
*ppcap_lookupnet
)( const char *, unsigned int *, unsigned int *, char * );
109 static int (CDECL
*ppcap_loop
)( pcap_t
*, int,
110 void (CALLBACK
*)(unsigned char *, const struct pcap_pkthdr
*, const unsigned char *),
112 static int (CDECL
*ppcap_set_buffer_size
)( pcap_t
*, int );
113 static int (CDECL
*ppcap_set_datalink
)( pcap_t
*, int );
114 static int (CDECL
*ppcap_set_promisc
)( pcap_t
*, int );
115 static int (CDECL
*ppcap_set_timeout
)( pcap_t
*, int );
116 static int (CDECL
*ppcap_set_tstamp_precision
)( pcap_t
*, int );
117 static int (CDECL
*ppcap_setfilter
)( pcap_t
*, struct bpf_program
* );
118 static int (CDECL
*ppcap_snapshot
)( pcap_t
* );
119 static int (CDECL
*ppcap_stats
)( pcap_t
*, struct pcap_stat
* );
120 static int CDECL (*ppcap_tstamp_type_name_to_val
)( const char * );
121 static const char * (CDECL
*ppcap_tstamp_type_val_to_description
)( int );
122 static const char * (CDECL
*ppcap_tstamp_type_val_to_name
)( int );
124 static void CALLBACK
capture_callback( unsigned char *user
, const struct pcap_pkthdr
*hdr
, const unsigned char *bytes
)
126 trace( "user %p hdr %p byte %p\n", user
, hdr
, bytes
);
129 static void test_capture( void )
131 char errbuf
[PCAP_ERRBUF_SIZE
], *dev
, *err
;
134 struct pcap_stat stats
;
135 unsigned int net
, mask
;
136 struct bpf_program program
;
137 int ret
, *links
, *types
;
139 dev
= ppcap_lookupdev( errbuf
);
140 ok( dev
!= NULL
, "got NULL (%s)\n", errbuf
);
142 pcap
= ppcap_create( dev
, errbuf
);
143 ok( pcap
!= NULL
, "got NULL (%s)\n", errbuf
);
145 ret
= ppcap_set_promisc( pcap
, 1 );
146 ok( !ret
, "got %d\n", ret
);
148 ret
= ppcap_set_timeout( pcap
, 100 );
149 ok( !ret
, "got %d\n", ret
);
151 ret
= ppcap_set_tstamp_precision( pcap
, 0 );
152 ok( !ret
, "got %d\n", ret
);
154 ret
= ppcap_can_set_rfmon( pcap
);
155 ok( !ret
, "got %d\n", ret
);
157 ret
= ppcap_getnonblock( pcap
, errbuf
);
158 ok( ret
== -3, "got %d\n", ret
);
160 ret
= ppcap_datalink( pcap
);
161 ok( ret
== -3, "got %d\n", ret
);
163 err
= ppcap_geterr( pcap
);
164 ok( err
!= NULL
, "got NULL\n" );
166 ret
= ppcap_set_buffer_size( pcap
, 2097152 );
167 ok( !ret
, "got %d\n", ret
);
169 ret
= ppcap_activate( pcap
);
170 if (ret
== PCAP_ERROR_PERM_DENIED
)
172 skip( "no permission\n" );
176 ok( !ret
, "got %d\n", ret
);
178 ret
= ppcap_set_buffer_size( pcap
, 256000 );
179 ok( ret
== -4, "got %d\n", ret
);
181 ret
= ppcap_bufsize( pcap
);
182 ok( ret
> 0, "got %d\n", ret
);
184 ret
= ppcap_getnonblock( pcap
, errbuf
);
185 ok( !ret
, "got %d\n", ret
);
187 ret
= ppcap_get_tstamp_precision( pcap
);
188 trace( "pcap_get_tstamp_precision %d\n", ret
);
190 ret
= ppcap_datalink( pcap
);
191 trace( "pcap_datalink %d\n", ret
);
194 ret
= ppcap_list_datalinks( pcap
, &links
);
195 ok( ret
> 0, "got %d\n", ret
);
196 ok( links
!= NULL
, "got NULL\n" );
198 ret
= ppcap_set_datalink( pcap
, links
[0] );
199 ok( !ret
, "got %d\n", ret
);
200 ppcap_free_datalinks( links
);
203 ret
= ppcap_list_tstamp_types( pcap
, &types
);
204 ok( ret
> 0, "got %d\n", ret
);
205 ok( types
!= NULL
, "got NULL\n" );
206 ppcap_free_tstamp_types( types
);
209 ret
= ppcap_lookupnet( dev
, &net
, &mask
, errbuf
);
210 ok( !ret
, "got %d\n", ret
);
212 memset( &program
, 0, sizeof(program
) );
213 ret
= ppcap_compile( pcap
, &program
, "", 1, 0xffffff );
214 ok( !ret
, "got %d\n", ret
);
216 ret
= ppcap_setfilter( pcap
, &program
);
217 ok( !ret
, "got %d\n", ret
);
218 ppcap_freecode( &program
);
220 ret
= ppcap_snapshot( pcap
);
221 ok( ret
> 0, "got %d\n", ret
);
223 ret
= ppcap_dispatch( pcap
, 1, capture_callback
, NULL
);
224 ok( ret
>= 0, "got %d\n", ret
);
226 aircap
= ppcap_get_airpcap_handle( pcap
);
227 ok( aircap
== NULL
, "got %p\n", aircap
);
229 memset( &stats
, 0, sizeof(stats
) );
230 ret
= ppcap_stats( pcap
, &stats
);
231 ok( !ret
, "got %d\n", ret
);
235 static void test_datalink( void )
240 str
= ppcap_datalink_val_to_name( 0 );
241 ok( str
!= NULL
, "got NULL\n" );
242 ok( !strcmp(str
, "NULL"), "got %s\n", wine_dbgstr_a(str
) );
244 ret
= ppcap_datalink_name_to_val( str
);
245 ok( !ret
, "got %d\n", ret
);
247 str
= ppcap_datalink_val_to_description( 0 );
248 ok( str
!= NULL
, "got NULL\n" );
249 ok( !strcmp(str
, "BSD loopback"), "got %s\n", wine_dbgstr_a(str
) );
251 str
= ppcap_datalink_val_to_name( 1 );
252 ok( str
!= NULL
, "got NULL\n" );
253 ok( !strcmp(str
, "EN10MB"), "got %s\n", wine_dbgstr_a(str
) );
255 ret
= ppcap_datalink_name_to_val( str
);
256 ok( ret
== 1, "got %d\n", ret
);
258 str
= ppcap_datalink_val_to_description( 1 );
259 ok( str
!= NULL
, "got NULL\n" );
260 ok( !strcmp(str
, "Ethernet"), "got %s\n", wine_dbgstr_a(str
) );
263 static void CALLBACK
dump_callback( unsigned char *user
, const struct pcap_pkthdr
*hdr
, const unsigned char *bytes
)
265 trace( "user %p hdr %p bytes %p\n", user
, hdr
, bytes
);
266 ppcap_dump( user
, hdr
, bytes
);
269 static void test_dump( void )
271 char errbuf
[PCAP_ERRBUF_SIZE
], path
[MAX_PATH
], filename
[MAX_PATH
];
274 pcap_dumper_t
*dumper
;
278 ret
= ppcap_findalldevs( &devs
, errbuf
);
279 ok( !ret
, "got %d (%s)\n", ret
, errbuf
);
280 ok( devs
!= NULL
, "got NULL\n" );
282 pcap
= ppcap_create( devs
->name
, errbuf
);
283 ok( pcap
!= NULL
, "got NULL (%s)\n", errbuf
);
285 ret
= ppcap_set_timeout( pcap
, 100 );
286 ok( !ret
, "got %d\n", ret
);
288 ret
= ppcap_activate( pcap
);
289 if (ret
== PCAP_ERROR_PERM_DENIED
)
291 skip( "no permission\n" );
292 ppcap_freealldevs( devs
);
296 ok( !ret
, "got %d\n", ret
);
298 ret
= ppcap_bufsize( pcap
);
299 ok( ret
> 0, "got %d\n", ret
);
301 GetTempPathA( sizeof(path
), path
);
302 GetTempFileNameA( path
, "cap", 0, filename
);
304 dumper
= ppcap_dump_open( pcap
, filename
);
305 ok( dumper
!= NULL
, "got NULL\n" );
307 ret
= ppcap_dispatch( pcap
, 1, dump_callback
, NULL
);
308 ok( ret
>= 0, "got %d\n", ret
);
310 ppcap_dump_close( dumper
);
311 ppcap_freealldevs( devs
);
313 DeleteFileA( filename
);
318 char errbuf
[PCAP_ERRBUF_SIZE
];
319 HMODULE module
= LoadLibraryW( L
"wpcap.dll" );
322 win_skip( "wpcap.dll not found\n" );
325 ppcap_activate
= (void *)GetProcAddress( module
, "pcap_activate" );
326 ppcap_breakloop
= (void *)GetProcAddress( module
, "pcap_breakloop" );
327 ppcap_bufsize
= (void *)GetProcAddress( module
, "pcap_bufsize" );
328 ppcap_can_set_rfmon
= (void *)GetProcAddress( module
, "pcap_can_set_rfmon" );
329 ppcap_close
= (void *)GetProcAddress( module
, "pcap_close" );
330 ppcap_compile
= (void *)GetProcAddress( module
, "pcap_compile" );
331 ppcap_create
= (void *)GetProcAddress( module
, "pcap_create" );
332 ppcap_datalink
= (void *)GetProcAddress( module
, "pcap_datalink" );
333 ppcap_datalink_name_to_val
= (void *)GetProcAddress( module
, "pcap_datalink_name_to_val" );
334 ppcap_datalink_val_to_description
= (void *)GetProcAddress( module
, "pcap_datalink_val_to_description" );
335 ppcap_datalink_val_to_name
= (void *)GetProcAddress( module
, "pcap_datalink_val_to_name" );
336 ppcap_dispatch
= (void *)GetProcAddress( module
, "pcap_dispatch" );
337 ppcap_dump_open
= (void *)GetProcAddress( module
, "pcap_dump_open" );
338 ppcap_dump
= (void *)GetProcAddress( module
, "pcap_dump" );
339 ppcap_dump_close
= (void *)GetProcAddress( module
, "pcap_dump_close" );
340 ppcap_get_airpcap_handle
= (void *)GetProcAddress( module
, "pcap_get_airpcap_handle" );
341 ppcap_get_tstamp_precision
= (void *)GetProcAddress( module
, "pcap_get_tstamp_precision" );
342 ppcap_geterr
= (void *)GetProcAddress( module
, "pcap_geterr" );
343 ppcap_getnonblock
= (void *)GetProcAddress( module
, "pcap_getnonblock" );
344 ppcap_findalldevs
= (void *)GetProcAddress( module
, "pcap_findalldevs" );
345 ppcap_freealldevs
= (void *)GetProcAddress( module
, "pcap_freealldevs" );
346 ppcap_free_datalinks
= (void *)GetProcAddress( module
, "pcap_free_datalinks" );
347 ppcap_free_tstamp_types
= (void *)GetProcAddress( module
, "pcap_free_tstamp_types" );
348 ppcap_freecode
= (void *)GetProcAddress( module
, "pcap_freecode" );
349 ppcap_init
= (void *)GetProcAddress( module
, "pcap_init" );
350 ppcap_lib_version
= (void *)GetProcAddress( module
, "pcap_lib_version" );
351 ppcap_list_datalinks
= (void *)GetProcAddress( module
, "pcap_list_datalinks" );
352 ppcap_list_tstamp_types
= (void *)GetProcAddress( module
, "pcap_list_tstamp_types" );
353 ppcap_lookupdev
= (void *)GetProcAddress( module
, "pcap_lookupdev" );
354 ppcap_lookupnet
= (void *)GetProcAddress( module
, "pcap_lookupnet" );
355 ppcap_loop
= (void *)GetProcAddress( module
, "pcap_loop" );
356 ppcap_set_buffer_size
= (void *)GetProcAddress( module
, "pcap_set_buffer_size" );
357 ppcap_set_datalink
= (void *)GetProcAddress( module
, "pcap_set_datalink" );
358 ppcap_set_promisc
= (void *)GetProcAddress( module
, "pcap_set_promisc" );
359 ppcap_set_timeout
= (void *)GetProcAddress( module
, "pcap_set_timeout" );
360 ppcap_set_tstamp_precision
= (void *)GetProcAddress( module
, "pcap_set_tstamp_precision" );
361 ppcap_setfilter
= (void *)GetProcAddress( module
, "pcap_setfilter" );
362 ppcap_snapshot
= (void *)GetProcAddress( module
, "pcap_snapshot" );
363 ppcap_stats
= (void *)GetProcAddress( module
, "pcap_stats" );
364 ppcap_tstamp_type_name_to_val
= (void *)GetProcAddress( module
, "pcap_tstamp_type_name_to_val" );
365 ppcap_tstamp_type_val_to_description
= (void *)GetProcAddress( module
, "pcap_tstamp_type_val_to_description" );
366 ppcap_tstamp_type_val_to_name
= (void *)GetProcAddress( module
, "pcap_tstamp_type_val_to_name" );
368 trace( "lib version %s\n", ppcap_lib_version() );
369 trace( "supports PCAP_MMAP_32BIT: %s\n", (ppcap_init(PCAP_MMAP_32BIT
, errbuf
) < 0) ? "no" : "yes" );