2 * Copyright 2011, 2014 André Hentschel
3 * Copyright 2021 Hans Leidekker for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #ifdef HAVE_PCAP_PCAP_H
27 #include <pcap/pcap.h>
34 #define WIN32_NO_STATUS
39 #include "wine/unixlib.h"
40 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(wpcap
);
45 static NTSTATUS
wrap_activate( void *args
)
47 const struct activate_params
*params
= args
;
48 return pcap_activate( (pcap_t
*)(ULONG_PTR
)params
->handle
);
51 static NTSTATUS
wrap_breakloop( void *args
)
53 const struct breakloop_params
*params
= args
;
54 pcap_breakloop( (pcap_t
*)(ULONG_PTR
)params
->handle
);
55 return STATUS_SUCCESS
;
58 static NTSTATUS
wrap_bufsize( void *args
)
60 const struct bufsize_params
*params
= args
;
61 return pcap_bufsize( (pcap_t
*)(ULONG_PTR
)params
->handle
);
64 static NTSTATUS
wrap_can_set_rfmon( void *args
)
66 const struct can_set_rfmon_params
*params
= args
;
67 return pcap_can_set_rfmon( (pcap_t
*)(ULONG_PTR
)params
->handle
);
70 static NTSTATUS
wrap_close( void *args
)
72 const struct close_params
*params
= args
;
73 pcap_close( (pcap_t
*)(ULONG_PTR
)params
->handle
);
74 return STATUS_SUCCESS
;
77 static NTSTATUS
wrap_compile( void *args
)
79 struct compile_params
*params
= args
;
80 struct bpf_program program
;
83 if (!(ret
= pcap_compile( (pcap_t
*)(ULONG_PTR
)params
->handle
, &program
, params
->str
, params
->optimize
,
86 if (*params
->program_len
< program
.bf_len
) ret
= STATUS_BUFFER_TOO_SMALL
;
87 else memcpy( params
->program_insns
, program
.bf_insns
, program
.bf_len
* sizeof(*program
.bf_insns
) );
88 *params
->program_len
= program
.bf_len
;
89 pcap_freecode( &program
);
94 static NTSTATUS
wrap_create( void *args
)
96 struct create_params
*params
= args
;
97 if (!(*params
->handle
= (ULONG_PTR
)pcap_create( params
->source
, params
->errbuf
))) return STATUS_NO_MEMORY
;
98 return STATUS_SUCCESS
;
101 static NTSTATUS
wrap_datalink( void *args
)
103 struct datalink_params
*params
= args
;
104 return pcap_datalink( (pcap_t
*)(ULONG_PTR
)params
->handle
);
107 static NTSTATUS
wrap_datalink_name_to_val( void *args
)
109 struct datalink_name_to_val_params
*params
= args
;
110 return pcap_datalink_name_to_val( params
->name
);
113 static NTSTATUS
wrap_datalink_val_to_description( void *args
)
115 const struct datalink_val_to_description_params
*params
= args
;
116 const char *str
= pcap_datalink_val_to_description( params
->link
);
119 if (!str
|| !params
->buf
) return STATUS_INVALID_PARAMETER
;
120 if ((len
= strlen( str
)) >= *params
->buflen
)
122 *params
->buflen
= len
+ 1;
123 return STATUS_BUFFER_TOO_SMALL
;
125 strcpy( params
->buf
, str
);
126 return STATUS_SUCCESS
;
129 static NTSTATUS
wrap_datalink_val_to_name( void *args
)
131 const struct datalink_val_to_name_params
*params
= args
;
132 const char *str
= pcap_datalink_val_to_name( params
->link
);
135 if (!str
|| !params
->buf
) return STATUS_INVALID_PARAMETER
;
136 if ((len
= strlen( str
)) >= *params
->buflen
)
138 *params
->buflen
= len
+ 1;
139 return STATUS_BUFFER_TOO_SMALL
;
141 strcpy( params
->buf
, str
);
142 return STATUS_SUCCESS
;
145 static NTSTATUS
wrap_dump( void *args
)
147 const struct dump_params
*params
= args
;
148 struct pcap_pkthdr hdr_unix
;
150 hdr_unix
.ts
.tv_sec
= params
->hdr
->ts
.tv_sec
;
151 hdr_unix
.ts
.tv_usec
= params
->hdr
->ts
.tv_usec
;
152 hdr_unix
.caplen
= params
->hdr
->caplen
;
153 hdr_unix
.len
= params
->hdr
->len
;
154 pcap_dump( params
->user
, &hdr_unix
, params
->packet
);
155 return STATUS_SUCCESS
;
158 static NTSTATUS
wrap_dump_close( void *args
)
160 const struct dump_close_params
*params
= args
;
161 pcap_dump_close( (pcap_dumper_t
*)(ULONG_PTR
)params
->handle
);
162 return STATUS_SUCCESS
;
165 static NTSTATUS
wrap_dump_open( void *args
)
167 const struct dump_open_params
*params
= args
;
168 *params
->ret_handle
= (ULONG_PTR
)pcap_dump_open( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->name
);
169 return STATUS_SUCCESS
;
172 static NTSTATUS
wrap_findalldevs( void *args
)
174 const struct findalldevs_params
*params
= args
;
175 pcap_if_t
*devs
= NULL
, *src
;
176 struct pcap_interface_offsets
*dst
= (struct pcap_interface_offsets
*)params
->buf
;
177 int ret
, len_total
= 0;
179 if ((ret
= pcap_findalldevs( &devs
, params
->errbuf
))) return ret
;
184 int len_name
= strlen( src
->name
) + 1, len_description
= src
->description
? strlen( src
->description
) + 1 : 0;
185 int len
= sizeof(*dst
) + len_name
+ len_description
;
187 if (*params
->buflen
>= len_total
+ len
)
189 dst
->name_offset
= sizeof(*dst
);
190 dst
->name_len
= len_name
;
191 strcpy( (char *)dst
+ dst
->name_offset
, src
->name
);
192 if (!len_description
) dst
->description_offset
= dst
->description_len
= 0;
195 dst
->description_offset
= dst
->name_offset
+ len_name
;
196 dst
->description_len
= len_description
;
197 strcpy( (char *)dst
+ dst
->description_offset
, src
->description
);
199 dst
->flags
= src
->flags
;
200 dst
= (struct pcap_interface_offsets
*)((char *)dst
+ len
);
206 if (*params
->buflen
< len_total
) ret
= STATUS_BUFFER_TOO_SMALL
;
207 *params
->buflen
= len_total
;
208 pcap_freealldevs( devs
);
212 static NTSTATUS
wrap_get_tstamp_precision( void *args
)
214 const struct get_tstamp_precision_params
*params
= args
;
215 return pcap_get_tstamp_precision( (pcap_t
*)(ULONG_PTR
)params
->handle
);
218 static NTSTATUS
wrap_geterr( void *args
)
220 const struct geterr_params
*params
= args
;
221 char *errbuf
= pcap_geterr( (pcap_t
*)(ULONG_PTR
)params
->handle
);
222 assert( strlen(errbuf
) < PCAP_ERRBUF_SIZE
);
223 strcpy( params
->errbuf
, errbuf
);
224 return STATUS_SUCCESS
;
227 static NTSTATUS
wrap_getnonblock( void *args
)
229 const struct getnonblock_params
*params
= args
;
230 return pcap_getnonblock( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->errbuf
);
233 static NTSTATUS
wrap_init( void *args
)
235 const struct init_params
*params
= args
;
236 return pcap_init( params
->opt
, params
->errbuf
);
239 static NTSTATUS
wrap_lib_version( void *args
)
241 const struct lib_version_params
*params
= args
;
242 const char *str
= pcap_lib_version();
243 unsigned int len
= min( strlen(str
) + 1, params
->size
);
245 memcpy( params
->version
, str
, len
);
246 params
->version
[len
- 1] = 0;
247 return STATUS_SUCCESS
;
250 static NTSTATUS
wrap_list_datalinks( void *args
)
252 const struct list_datalinks_params
*params
= args
;
253 NTSTATUS status
= STATUS_SUCCESS
;
254 int *links
= NULL
, count
;
256 if ((count
= pcap_list_datalinks( (pcap_t
*)(ULONG_PTR
)params
->handle
, &links
)) > 0)
258 if (*params
->count
< count
) status
= STATUS_BUFFER_TOO_SMALL
;
259 else memcpy( params
->links
, links
, count
* sizeof(*links
) );
261 pcap_free_datalinks( links
);
262 *params
->count
= count
;
266 static NTSTATUS
wrap_list_tstamp_types( void *args
)
268 const struct list_tstamp_types_params
*params
= args
;
269 NTSTATUS status
= STATUS_SUCCESS
;
270 int *types
= NULL
, count
;
272 if ((count
= pcap_list_tstamp_types( (pcap_t
*)(ULONG_PTR
)params
->handle
, &types
)) > 0)
274 if (*params
->count
< count
) status
= STATUS_BUFFER_TOO_SMALL
;
275 else memcpy( params
->types
, types
, count
* sizeof(*types
) );
277 pcap_free_tstamp_types( types
);
278 *params
->count
= count
;
282 static NTSTATUS
wrap_lookupnet( void *args
)
284 const struct lookupnet_params
*params
= args
;
285 return pcap_lookupnet( params
->device
, params
->net
, params
->mask
, params
->errbuf
);
288 static NTSTATUS
wrap_major_version( void *args
)
290 const struct major_version_params
*params
= args
;
291 return pcap_major_version( (pcap_t
*)(ULONG_PTR
)params
->handle
);
294 static NTSTATUS
wrap_minor_version( void *args
)
296 const struct minor_version_params
*params
= args
;
297 return pcap_minor_version( (pcap_t
*)(ULONG_PTR
)params
->handle
);
300 static NTSTATUS
wrap_next_ex( void *args
)
302 struct next_ex_params
*params
= args
;
303 struct pcap_pkthdr
*hdr_unix
;
306 if ((ret
= pcap_next_ex( (pcap_t
*)(ULONG_PTR
)params
->handle
, &hdr_unix
, params
->data
)) == 1)
308 if (hdr_unix
->ts
.tv_sec
> INT_MAX
|| hdr_unix
->ts
.tv_usec
> INT_MAX
) WARN( "truncating timeval values(s)\n" );
309 params
->hdr
->ts
.tv_sec
= hdr_unix
->ts
.tv_sec
;
310 params
->hdr
->ts
.tv_usec
= hdr_unix
->ts
.tv_usec
;
311 params
->hdr
->caplen
= hdr_unix
->caplen
;
312 params
->hdr
->len
= hdr_unix
->len
;
317 static NTSTATUS
wrap_open_live( void *args
)
319 const struct open_live_params
*params
= args
;
320 if (!(*params
->handle
= (ULONG_PTR
)pcap_open_live( params
->source
, params
->snaplen
, params
->promisc
,
321 params
->timeout
, params
->errbuf
))) return STATUS_NO_MEMORY
;
322 return STATUS_SUCCESS
;
325 static NTSTATUS
wrap_sendpacket( void *args
)
327 const struct sendpacket_params
*params
= args
;
328 return pcap_sendpacket( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->buf
, params
->size
);
331 static NTSTATUS
wrap_set_buffer_size( void *args
)
333 const struct set_buffer_size_params
*params
= args
;
334 return pcap_set_buffer_size( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->size
);
337 static NTSTATUS
wrap_set_datalink( void *args
)
339 const struct set_datalink_params
*params
= args
;
340 return pcap_set_datalink( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->link
);
343 static NTSTATUS
wrap_set_promisc( void *args
)
345 const struct set_promisc_params
*params
= args
;
346 return pcap_set_promisc( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->enable
);
349 static NTSTATUS
wrap_set_rfmon( void *args
)
351 const struct set_rfmon_params
*params
= args
;
352 return pcap_set_rfmon( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->enable
);
355 static NTSTATUS
wrap_set_snaplen( void *args
)
357 const struct set_snaplen_params
*params
= args
;
358 return pcap_set_snaplen( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->len
);
361 static NTSTATUS
wrap_set_timeout( void *args
)
363 const struct set_timeout_params
*params
= args
;
364 return pcap_set_timeout( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->timeout
);
367 static NTSTATUS
wrap_set_tstamp_precision( void *args
)
369 const struct set_tstamp_precision_params
*params
= args
;
370 return pcap_set_tstamp_precision( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->precision
);
373 static NTSTATUS
wrap_set_tstamp_type( void *args
)
375 const struct set_tstamp_type_params
*params
= args
;
376 return pcap_set_tstamp_type( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->type
);
379 static NTSTATUS
wrap_setfilter( void *args
)
381 const struct setfilter_params
*params
= args
;
382 struct bpf_program program
= { params
->program_len
, params
->program_insns
};
383 return pcap_setfilter( (pcap_t
*)(ULONG_PTR
)params
->handle
, &program
);
386 static NTSTATUS
wrap_setnonblock( void *args
)
388 const struct setnonblock_params
*params
= args
;
389 return pcap_setnonblock( (pcap_t
*)(ULONG_PTR
)params
->handle
, params
->nonblock
, params
->errbuf
);
392 static NTSTATUS
wrap_snapshot( void *args
)
394 const struct snapshot_params
*params
= args
;
395 return pcap_snapshot( (pcap_t
*)(ULONG_PTR
)params
->handle
);
398 static NTSTATUS
wrap_stats( void *args
)
400 struct stats_params
*params
= args
;
401 struct pcap_stat stat
;
404 if (!(ret
= pcap_stats( (pcap_t
*)(ULONG_PTR
)params
->handle
, &stat
)))
406 params
->stat
.ps_recv
= stat
.ps_recv
;
407 params
->stat
.ps_drop
= stat
.ps_drop
;
408 params
->stat
.ps_ifdrop
= stat
.ps_ifdrop
;
409 params
->stat
.ps_capt
= 0;
410 params
->stat
.ps_sent
= 0;
411 params
->stat
.ps_netdrop
= 0;
416 static NTSTATUS
wrap_tstamp_type_name_to_val( void *args
)
418 const struct tstamp_type_name_to_val_params
*params
= args
;
419 return pcap_tstamp_type_name_to_val( params
->name
);
422 static NTSTATUS
wrap_tstamp_type_val_to_description( void *args
)
424 const struct tstamp_type_val_to_description_params
*params
= args
;
425 const char *str
= pcap_tstamp_type_val_to_description( params
->type
);
428 if (!str
|| !params
->buf
) return STATUS_INVALID_PARAMETER
;
429 if ((len
= strlen( str
)) >= *params
->buflen
)
431 *params
->buflen
= len
+ 1;
432 return STATUS_BUFFER_TOO_SMALL
;
434 strcpy( params
->buf
, str
);
435 return STATUS_SUCCESS
;
438 static NTSTATUS
wrap_tstamp_type_val_to_name( void *args
)
440 const struct tstamp_type_val_to_name_params
*params
= args
;
441 const char *str
= pcap_tstamp_type_val_to_name( params
->type
);
444 if (!str
|| !params
->buf
) return STATUS_INVALID_PARAMETER
;
445 if ((len
= strlen( str
)) >= *params
->buflen
)
447 *params
->buflen
= len
+ 1;
448 return STATUS_BUFFER_TOO_SMALL
;
450 strcpy( params
->buf
, str
);
451 return STATUS_SUCCESS
;
454 const unixlib_entry_t __wine_unix_call_funcs
[] =
464 wrap_datalink_name_to_val
,
465 wrap_datalink_val_to_description
,
466 wrap_datalink_val_to_name
,
471 wrap_get_tstamp_precision
,
477 wrap_list_tstamp_types
,
484 wrap_set_buffer_size
,
490 wrap_set_tstamp_precision
,
491 wrap_set_tstamp_type
,
496 wrap_tstamp_type_name_to_val
,
497 wrap_tstamp_type_val_to_description
,
498 wrap_tstamp_type_val_to_name
,
501 C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs
) == unix_funcs_count
);
507 static NTSTATUS
wow64_compile( void *args
)
517 } const *params32
= args
;
519 struct compile_params params
=
522 ULongToPtr(params32
->program_len
),
523 ULongToPtr(params32
->program_insns
),
524 ULongToPtr(params32
->str
),
528 return wrap_compile( ¶ms
);
531 static NTSTATUS
wow64_create( void *args
)
538 } const *params32
= args
;
540 struct create_params params
=
542 ULongToPtr(params32
->source
),
543 ULongToPtr(params32
->errbuf
),
544 ULongToPtr(params32
->handle
),
546 return wrap_create( ¶ms
);
549 static NTSTATUS
wow64_datalink_name_to_val( void *args
)
554 } const *params32
= args
;
556 struct datalink_name_to_val_params params
=
558 ULongToPtr(params32
->name
),
560 return wrap_datalink_name_to_val( ¶ms
);
563 static NTSTATUS
wow64_datalink_val_to_description( void *args
)
570 } const *params32
= args
;
572 struct datalink_val_to_description_params params
=
575 ULongToPtr(params32
->buf
),
576 ULongToPtr(params32
->buflen
)
578 return wrap_datalink_val_to_description( ¶ms
);
581 static NTSTATUS
wow64_datalink_val_to_name( void *args
)
588 } const *params32
= args
;
590 struct datalink_val_to_name_params params
=
593 ULongToPtr(params32
->buf
),
594 ULongToPtr(params32
->buflen
)
596 return wrap_datalink_val_to_name( ¶ms
);
599 static NTSTATUS
wow64_dump( void *args
)
606 } const *params32
= args
;
608 struct dump_params params
=
610 ULongToPtr(params32
->user
),
611 ULongToPtr(params32
->hdr
),
612 ULongToPtr(params32
->packet
)
614 return wrap_dump( ¶ms
);
617 static NTSTATUS
wow64_dump_open( void *args
)
624 } const *params32
= args
;
626 struct datalink_val_to_name_params params
=
629 ULongToPtr(params32
->name
),
630 ULongToPtr(params32
->ret_handle
)
632 return wrap_dump_open( ¶ms
);
635 static NTSTATUS
wow64_findalldevs( void *args
)
642 } const *params32
= args
;
644 struct findalldevs_params params
=
646 ULongToPtr(params32
->buf
),
647 ULongToPtr(params32
->buflen
),
648 ULongToPtr(params32
->errbuf
)
650 return wrap_findalldevs( ¶ms
);
653 static NTSTATUS
wow64_geterr( void *args
)
659 } const *params32
= args
;
661 struct geterr_params params
=
664 ULongToPtr(params32
->errbuf
)
666 return wrap_geterr( ¶ms
);
669 static NTSTATUS
wow64_getnonblock( void *args
)
675 } const *params32
= args
;
677 struct getnonblock_params params
=
680 ULongToPtr(params32
->errbuf
)
682 return wrap_getnonblock( ¶ms
);
685 static NTSTATUS
wow64_init( void *args
)
691 } const *params32
= args
;
693 struct init_params params
=
696 ULongToPtr(params32
->errbuf
)
698 return wrap_init( ¶ms
);
701 static NTSTATUS
wow64_lib_version( void *args
)
707 } const *params32
= args
;
709 struct lib_version_params params
=
711 ULongToPtr(params32
->version
),
714 return wrap_lib_version( ¶ms
);
717 static NTSTATUS
wow64_list_datalinks( void *args
)
724 } const *params32
= args
;
726 struct list_datalinks_params params
=
729 ULongToPtr(params32
->links
),
730 ULongToPtr(params32
->count
)
732 return wrap_list_datalinks( ¶ms
);
735 static NTSTATUS
wow64_list_tstamp_types( void *args
)
742 } const *params32
= args
;
744 struct list_tstamp_types_params params
=
747 ULongToPtr(params32
->types
),
748 ULongToPtr(params32
->count
)
750 return wrap_list_tstamp_types( ¶ms
);
753 static NTSTATUS
wow64_lookupnet( void *args
)
761 } const *params32
= args
;
763 struct lookupnet_params params
=
765 ULongToPtr(params32
->device
),
766 ULongToPtr(params32
->net
),
767 ULongToPtr(params32
->mask
),
768 ULongToPtr(params32
->errbuf
)
770 return wrap_lookupnet( ¶ms
);
773 static NTSTATUS
wow64_next_ex( void *args
)
780 } const *params32
= args
;
782 struct next_ex_params params
=
785 ULongToPtr(params32
->hdr
),
786 ULongToPtr(params32
->data
)
788 return wrap_next_ex( ¶ms
);
791 static NTSTATUS
wow64_open_live( void *args
)
801 } const *params32
= args
;
803 struct open_live_params params
=
805 ULongToPtr(params32
->source
),
809 ULongToPtr(params32
->errbuf
),
810 ULongToPtr(params32
->handle
)
812 return wrap_open_live( ¶ms
);
815 static NTSTATUS
wow64_sendpacket( void *args
)
822 } const *params32
= args
;
824 struct sendpacket_params params
=
827 ULongToPtr(params32
->buf
),
830 return wrap_sendpacket( ¶ms
);
833 static NTSTATUS
wow64_setfilter( void *args
)
838 unsigned int program_len
;
840 } const *params32
= args
;
842 struct setfilter_params params
=
845 params32
->program_len
,
846 ULongToPtr(params32
->program_insns
)
848 return wrap_setfilter( ¶ms
);
851 static NTSTATUS
wow64_setnonblock( void *args
)
858 } const *params32
= args
;
860 struct setnonblock_params params
=
864 ULongToPtr(params32
->errbuf
)
866 return wrap_setnonblock( ¶ms
);
869 static NTSTATUS
wow64_tstamp_type_name_to_val( void *args
)
874 } const *params32
= args
;
876 struct tstamp_type_name_to_val_params params
=
878 ULongToPtr(params32
->name
)
880 return wrap_tstamp_type_name_to_val( ¶ms
);
883 static NTSTATUS
wow64_tstamp_type_val_to_description( void *args
)
890 } const *params32
= args
;
892 struct tstamp_type_val_to_description_params params
=
895 ULongToPtr(params32
->buf
),
896 ULongToPtr(params32
->buflen
)
898 return wrap_tstamp_type_val_to_description( ¶ms
);
901 static NTSTATUS
wow64_tstamp_type_val_to_name( void *args
)
908 } const *params32
= args
;
910 struct tstamp_type_val_to_name_params params
=
913 ULongToPtr(params32
->buf
),
914 ULongToPtr(params32
->buflen
)
916 return wrap_tstamp_type_val_to_name( ¶ms
);
919 const unixlib_entry_t __wine_unix_call_wow64_funcs
[] =
929 wow64_datalink_name_to_val
,
930 wow64_datalink_val_to_description
,
931 wow64_datalink_val_to_name
,
936 wrap_get_tstamp_precision
,
941 wow64_list_datalinks
,
942 wow64_list_tstamp_types
,
949 wrap_set_buffer_size
,
955 wrap_set_tstamp_precision
,
956 wrap_set_tstamp_type
,
961 wow64_tstamp_type_name_to_val
,
962 wow64_tstamp_type_val_to_description
,
963 wow64_tstamp_type_val_to_name
,
966 C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs
) == unix_funcs_count
);
970 #endif /* HAVE_PCAP_PCAP_H */