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
,
505 static NTSTATUS
wow64_compile( void *args
)
515 } const *params32
= args
;
517 struct compile_params params
=
520 ULongToPtr(params32
->program_len
),
521 ULongToPtr(params32
->program_insns
),
522 ULongToPtr(params32
->str
),
526 return wrap_compile( ¶ms
);
529 static NTSTATUS
wow64_create( void *args
)
536 } const *params32
= args
;
538 struct create_params params
=
540 ULongToPtr(params32
->source
),
541 ULongToPtr(params32
->errbuf
),
542 ULongToPtr(params32
->handle
),
544 return wrap_create( ¶ms
);
547 static NTSTATUS
wow64_datalink_name_to_val( void *args
)
552 } const *params32
= args
;
554 struct datalink_name_to_val_params params
=
556 ULongToPtr(params32
->name
),
558 return wrap_datalink_name_to_val( ¶ms
);
561 static NTSTATUS
wow64_datalink_val_to_description( void *args
)
568 } const *params32
= args
;
570 struct datalink_val_to_description_params params
=
573 ULongToPtr(params32
->buf
),
574 ULongToPtr(params32
->buflen
)
576 return wrap_datalink_val_to_description( ¶ms
);
579 static NTSTATUS
wow64_datalink_val_to_name( void *args
)
586 } const *params32
= args
;
588 struct datalink_val_to_name_params params
=
591 ULongToPtr(params32
->buf
),
592 ULongToPtr(params32
->buflen
)
594 return wrap_datalink_val_to_name( ¶ms
);
597 static NTSTATUS
wow64_dump( void *args
)
604 } const *params32
= args
;
606 struct dump_params params
=
608 ULongToPtr(params32
->user
),
609 ULongToPtr(params32
->hdr
),
610 ULongToPtr(params32
->packet
)
612 return wrap_dump( ¶ms
);
615 static NTSTATUS
wow64_dump_open( void *args
)
622 } const *params32
= args
;
624 struct datalink_val_to_name_params params
=
627 ULongToPtr(params32
->name
),
628 ULongToPtr(params32
->ret_handle
)
630 return wrap_dump_open( ¶ms
);
633 static NTSTATUS
wow64_findalldevs( void *args
)
640 } const *params32
= args
;
642 struct findalldevs_params params
=
644 ULongToPtr(params32
->buf
),
645 ULongToPtr(params32
->buflen
),
646 ULongToPtr(params32
->errbuf
)
648 return wrap_findalldevs( ¶ms
);
651 static NTSTATUS
wow64_geterr( void *args
)
657 } const *params32
= args
;
659 struct geterr_params params
=
662 ULongToPtr(params32
->errbuf
)
664 return wrap_geterr( ¶ms
);
667 static NTSTATUS
wow64_getnonblock( void *args
)
673 } const *params32
= args
;
675 struct getnonblock_params params
=
678 ULongToPtr(params32
->errbuf
)
680 return wrap_getnonblock( ¶ms
);
683 static NTSTATUS
wow64_init( void *args
)
689 } const *params32
= args
;
691 struct init_params params
=
694 ULongToPtr(params32
->errbuf
)
696 return wrap_init( ¶ms
);
699 static NTSTATUS
wow64_lib_version( void *args
)
705 } const *params32
= args
;
707 struct lib_version_params params
=
709 ULongToPtr(params32
->version
),
712 return wrap_lib_version( ¶ms
);
715 static NTSTATUS
wow64_list_datalinks( void *args
)
722 } const *params32
= args
;
724 struct list_datalinks_params params
=
727 ULongToPtr(params32
->links
),
728 ULongToPtr(params32
->count
)
730 return wrap_list_datalinks( ¶ms
);
733 static NTSTATUS
wow64_list_tstamp_types( void *args
)
740 } const *params32
= args
;
742 struct list_tstamp_types_params params
=
745 ULongToPtr(params32
->types
),
746 ULongToPtr(params32
->count
)
748 return wrap_list_tstamp_types( ¶ms
);
751 static NTSTATUS
wow64_lookupnet( void *args
)
759 } const *params32
= args
;
761 struct lookupnet_params params
=
763 ULongToPtr(params32
->device
),
764 ULongToPtr(params32
->net
),
765 ULongToPtr(params32
->mask
),
766 ULongToPtr(params32
->errbuf
)
768 return wrap_lookupnet( ¶ms
);
771 static NTSTATUS
wow64_next_ex( void *args
)
778 } const *params32
= args
;
780 struct next_ex_params params
=
783 ULongToPtr(params32
->hdr
),
784 ULongToPtr(params32
->data
)
786 return wrap_next_ex( ¶ms
);
789 static NTSTATUS
wow64_open_live( void *args
)
799 } const *params32
= args
;
801 struct open_live_params params
=
803 ULongToPtr(params32
->source
),
807 ULongToPtr(params32
->errbuf
),
808 ULongToPtr(params32
->handle
)
810 return wrap_open_live( ¶ms
);
813 static NTSTATUS
wow64_sendpacket( void *args
)
820 } const *params32
= args
;
822 struct sendpacket_params params
=
825 ULongToPtr(params32
->buf
),
828 return wrap_sendpacket( ¶ms
);
831 static NTSTATUS
wow64_setfilter( void *args
)
836 unsigned int program_len
;
838 } const *params32
= args
;
840 struct setfilter_params params
=
843 params32
->program_len
,
844 ULongToPtr(params32
->program_insns
)
846 return wrap_setfilter( ¶ms
);
849 static NTSTATUS
wow64_setnonblock( void *args
)
856 } const *params32
= args
;
858 struct setnonblock_params params
=
862 ULongToPtr(params32
->errbuf
)
864 return wrap_setnonblock( ¶ms
);
867 static NTSTATUS
wow64_tstamp_type_name_to_val( void *args
)
872 } const *params32
= args
;
874 struct tstamp_type_name_to_val_params params
=
876 ULongToPtr(params32
->name
)
878 return wrap_tstamp_type_name_to_val( ¶ms
);
881 static NTSTATUS
wow64_tstamp_type_val_to_description( void *args
)
888 } const *params32
= args
;
890 struct tstamp_type_val_to_description_params params
=
893 ULongToPtr(params32
->buf
),
894 ULongToPtr(params32
->buflen
)
896 return wrap_tstamp_type_val_to_description( ¶ms
);
899 static NTSTATUS
wow64_tstamp_type_val_to_name( void *args
)
906 } const *params32
= args
;
908 struct tstamp_type_val_to_name_params params
=
911 ULongToPtr(params32
->buf
),
912 ULongToPtr(params32
->buflen
)
914 return wrap_tstamp_type_val_to_name( ¶ms
);
917 const unixlib_entry_t __wine_unix_call_wow64_funcs
[] =
927 wow64_datalink_name_to_val
,
928 wow64_datalink_val_to_description
,
929 wow64_datalink_val_to_name
,
934 wrap_get_tstamp_precision
,
939 wow64_list_datalinks
,
940 wow64_list_tstamp_types
,
947 wrap_set_buffer_size
,
953 wrap_set_tstamp_precision
,
954 wrap_set_tstamp_type
,
959 wow64_tstamp_type_name_to_val
,
960 wow64_tstamp_type_val_to_description
,
961 wow64_tstamp_type_val_to_name
,
966 #endif /* HAVE_PCAP_PCAP_H */