wpcap: Initial Proxy Implementation

André Hentschel nerv at dawncrow.de
Sat Mar 12 06:54:41 CST 2011


Some facts on that patch:

I made it an importlib, because that makes it possible and very easy to compile winpcap's tests with winelib.

I am targeting libpcap 1.0+, to ensure this i'm checking for "pcap/pcap.h" instead of "pcap.h" (see pcap documentation)
and for function pcap_create which started being available with 1.0, too.

The main reason for this proxy is to be able to run some win32-only pcap applications like the
IEC 61850 Demo Software at http://www.systemcorp.com.au/component/content/article/23-software/45-iec-61850-dll-example.html
or many others like Asn1Browser, Cain & Abel, Gamer's Internet Tunnel,
PacketVB (and PacketVB based Apps), SharpPcap based Apps and maybe coLinux in the future.
Of course non-win32-only Apps will work fully too, like Wireshark, but that's just a cool side effect.

I hope i made everything right with configure checking...

---
 configure.ac           |   13 +++
 dlls/wpcap/Makefile.in |    9 ++
 dlls/wpcap/main.c      |  227 ++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/wpcap/wpcap.spec  |   78 +++++++++++++++++
 4 files changed, 327 insertions(+), 0 deletions(-)
 create mode 100644 dlls/wpcap/Makefile.in
 create mode 100644 dlls/wpcap/main.c
 create mode 100644 dlls/wpcap/wpcap.spec

diff --git a/configure.ac b/configure.ac
index 624b0ce..029ad90 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,8 @@ AC_ARG_WITH(openssl,   AS_HELP_STRING([--without-openssl],[do not use OpenSSL]),
             [if test "x$withval" = "xno"; then ac_cv_header_openssl_err_h=no; ac_cv_header_openssl_ssl_h=no; fi])
 AC_ARG_WITH(oss,       AS_HELP_STRING([--without-oss],[do not use the OSS sound support]),
             [if test "x$withval" = "xno"; then ac_cv_header_soundcard_h=no; ac_cv_header_sys_soundcard_h=no; ac_cv_header_machine_soundcard_h=no; fi])
+AC_ARG_WITH(pcap,    AS_HELP_STRING([--without-pcap],[do not use libpcap]),
+            [if test "x$withval" = "xno"; then ac_cv_header_pcap_pcap_h=no; fi])
 AC_ARG_WITH(png,       AS_HELP_STRING([--without-png],[do not use PNG]),
             [if test "x$withval" = "xno"; then ac_cv_header_png_h=no; fi])
 AC_ARG_WITH(pthread,   AS_HELP_STRING([--without-pthread],[do not use the pthread library]),
@@ -442,6 +444,7 @@ AC_CHECK_HEADERS(\
 	netinet/tcp_fsm.h \
 	openssl/err.h \
 	openssl/ssl.h \
+	pcap/pcap.h \
 	png.h \
 	poll.h \
 	port.h \
@@ -1137,6 +1140,15 @@ WINE_NOTICE_WITH(opencl,[test "x$ac_cv_lib_OpenCL_clGetPlatformInfo" != xyes],
                  [OpenCL ${notice_platform}development files not found, OpenCL won't be supported.])
 test "x$ac_cv_lib_OpenCL_clGetPlatformInfo" != xyes && enable_opencl=${enable_opencl:-no}
 
+dnl **** Check for libpcap ****
+if test "$ac_cv_header_pcap_pcap_h" = "yes"
+then
+    AC_CHECK_LIB(pcap,pcap_create,[AC_SUBST(LIBPCAP,["-lpcap"])])
+fi
+WINE_NOTICE_WITH(pcap,[test "x$ac_cv_lib_pcap_pcap_create" != xyes],
+                 [pcap ${notice_platform}development files not found, wpcap won't be supported.])
+test "x$ac_cv_lib_pcap_pcap_create" != xyes && enable_pcap=${enable_pcap:-no}
+
 dnl **** Check for libxml2 ****
 
 AC_SUBST(XML2LIBS,"")
@@ -2863,6 +2875,7 @@ WINE_CONFIG_DLL(wmi)
 WINE_CONFIG_DLL(wmiutils)
 WINE_CONFIG_DLL(wnaspi32,,[implib])
 WINE_CONFIG_DLL(wow32,enable_win16,[implib])
+WINE_CONFIG_DLL(wpcap,,[implib])
 WINE_CONFIG_DLL(ws2_32,,[implib])
 WINE_CONFIG_TEST(dlls/ws2_32/tests)
 WINE_CONFIG_DLL(wsock32,,[implib])
diff --git a/dlls/wpcap/Makefile.in b/dlls/wpcap/Makefile.in
new file mode 100644
index 0000000..9bbce4c
--- /dev/null
+++ b/dlls/wpcap/Makefile.in
@@ -0,0 +1,9 @@
+MODULE    = wpcap.dll
+IMPORTLIB = wpcap
+DELAYIMPORTS = ws2_32
+EXTRALIBS = @LIBPCAP@
+
+C_SRCS = \
+	main.c
+
+ at MAKE_DLL_RULES@
diff --git a/dlls/wpcap/main.c b/dlls/wpcap/main.c
new file mode 100644
index 0000000..ed9fb14
--- /dev/null
+++ b/dlls/wpcap/main.c
@@ -0,0 +1,227 @@
+/*
+ * WPcap.dll Proxy.
+ *
+ * Copyright 2011 André Hentschel
+ *
+ * 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
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <pcap/pcap.h>
+#include "winsock2.h"
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wpcap);
+WINE_DECLARE_DEBUG_CHANNEL(winediag);
+
+VOID CDECL wine_pcap_breakloop(pcap_t *p)
+{
+    TRACE("(%p)\n", p);
+    return pcap_breakloop(p);
+}
+
+VOID CDECL wine_pcap_close(pcap_t *p)
+{
+    TRACE("(%p)\n", p);
+    pcap_close(p);
+}
+
+INT CDECL wine_pcap_compile(pcap_t *p, struct bpf_program *program,
+                            CONST CHAR *buf, INT optimize, UINT mask)
+{
+    TRACE("(%p)\n", p);
+    return pcap_compile(p, program, buf, optimize, mask);
+}
+
+INT CDECL wine_pcap_datalink(pcap_t *p)
+{
+    TRACE("(%p)\n", p);
+    return pcap_datalink(p);
+}
+
+INT CDECL wine_pcap_datalink_name_to_val(CONST CHAR *name)
+{
+    TRACE("(%s)\n", debugstr_a(name));
+    return pcap_datalink_name_to_val(name);
+}
+
+CONST CHAR *CDECL wine_pcap_datalink_val_to_description(INT dlt)
+{
+    TRACE("(%i)\n", dlt);
+    return pcap_datalink_val_to_description(dlt);
+}
+
+CONST CHAR *CDECL wine_pcap_datalink_val_to_name(INT dlt)
+{
+    TRACE("(%i)\n", dlt);
+    return pcap_datalink_val_to_name(dlt);
+}
+
+INT CDECL wine_pcap_dispatch(pcap_t *p, INT cnt, pcap_handler callback, UCHAR *user)
+{
+    TRACE("(%p %i %p %p)\n", p, cnt, callback, user);
+    return pcap_dispatch(p, cnt, callback, user);
+}
+
+INT CDECL wine_pcap_findalldevs(pcap_if_t **alldevsp, CHAR *errbuf)
+{
+    INT ret;
+    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");
+    return ret;
+}
+
+VOID CDECL wine_pcap_freealldevs(pcap_if_t *alldevs)
+{
+    TRACE("(%p)\n", alldevs);
+    pcap_freealldevs(alldevs);
+}
+
+VOID CDECL wine_pcap_freecode(struct bpf_program *fp)
+{
+    TRACE("(%p)\n", fp);
+    return pcap_freecode(fp);
+}
+
+CHAR* CDECL wine_pcap_geterr(pcap_t *p)
+{
+    TRACE("(%p)\n", p);
+    return pcap_geterr(p);
+}
+
+INT CDECL wine_pcap_getnonblock(pcap_t *p, CHAR *errbuf)
+{
+    TRACE("(%p %p)\n", p, errbuf);
+    return pcap_getnonblock(p, errbuf);
+}
+
+CONST CHAR *CDECL wine_pcap_lib_version(VOID)
+{
+    CONST CHAR *ret;
+    ret = pcap_lib_version();
+    TRACE("%s\n", debugstr_a(ret));
+    return ret;
+}
+
+INT CDECL wine_pcap_list_datalinks(pcap_t *p, INT **dlt_buffer)
+{
+    TRACE("(%p %p)\n", p, dlt_buffer);
+    return pcap_list_datalinks(p, dlt_buffer);
+}
+
+CHAR* CDECL wine_pcap_lookupdev(CHAR *errbuf)
+{
+    TRACE("(%p)\n", errbuf);
+    return pcap_lookupdev(errbuf);
+}
+
+INT CDECL wine_pcap_lookupnet(CONST CHAR *device, UINT *netp, UINT *maskp, CHAR *errbuf)
+{
+    TRACE("(%p %p %p %p)\n", device, netp, maskp, errbuf);
+    return pcap_lookupnet(device, netp, maskp, errbuf);
+}
+
+INT CDECL wine_pcap_loop(pcap_t *p, INT cnt, pcap_handler callback, UCHAR *user)
+{
+    TRACE("(%p %i %p %p)\n", p, cnt, callback, user);
+    return pcap_loop(p, cnt, callback, user);
+}
+
+INT CDECL wine_pcap_major_version(pcap_t *p)
+{
+    TRACE("(%p)\n", p);
+    return pcap_major_version(p);
+}
+
+INT CDECL wine_pcap_minor_version(pcap_t *p)
+{
+    TRACE("(%p)\n", p);
+    return pcap_minor_version(p);
+}
+
+CONST UCHAR* CDECL wine_pcap_next(pcap_t *p, struct pcap_pkthdr *h)
+{
+    TRACE("(%p %p)\n", p, h);
+    return pcap_next(p, h);
+}
+
+INT CDECL wine_pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, CONST UCHAR **pkt_data)
+{
+    TRACE("(%p %p %p)\n", p, pkt_header, pkt_data);
+    return pcap_next_ex(p,pkt_header,pkt_data);
+}
+
+pcap_t * CDECL wine_pcap_open_live(CONST CHAR *source, INT snaplen,
+                                   INT promisc , INT to_ms , CHAR *errbuf)
+{
+    TRACE("(%p %i %i %i %p)\n", source, snaplen, promisc, to_ms, errbuf);
+    return pcap_open_live(source, snaplen, promisc, to_ms, errbuf);
+}
+
+INT CDECL wine_pcap_sendpacket(pcap_t *p, CONST UCHAR *buf, INT size)
+{
+    TRACE("(%p %p %i)\n", p, buf, size);
+    return pcap_sendpacket(p, buf, size);
+}
+
+INT CDECL wine_pcap_set_datalink(pcap_t *p, INT dlt)
+{
+    TRACE("(%p %i)\n", p, dlt);
+    return pcap_set_datalink(p, dlt);
+}
+
+INT CDECL wine_pcap_setbuff(pcap_t * p, INT dim)
+{
+    FIXME("(%p %i) stub\n", p, dim);
+    return 0;
+}
+
+INT CDECL wine_pcap_setfilter(pcap_t *p, struct bpf_program *fp)
+{
+    TRACE("(%p %p)\n", p, fp);
+    return pcap_setfilter(p, fp);
+}
+
+INT CDECL wine_pcap_setnonblock(pcap_t *p, INT nonblock, CHAR *errbuf)
+{
+    TRACE("(%p %i %p)\n", p, nonblock, errbuf);
+    return pcap_setnonblock(p, nonblock, errbuf);
+}
+
+INT CDECL wine_pcap_snapshot(pcap_t *p)
+{
+    TRACE("(%p)\n", p);
+    return pcap_snapshot(p);
+}
+
+INT CDECL wine_pcap_stats(pcap_t *p, struct pcap_stat *ps)
+{
+    TRACE("(%p %p)\n", p, ps);
+    return pcap_stats(p, ps);
+}
+
+INT CDECL wine_wsockinit(VOID)
+{
+    WSADATA wsadata;
+    TRACE("()\n");
+    if (WSAStartup(MAKEWORD(1,1), &wsadata)) return -1;
+    return 0;
+}
diff --git a/dlls/wpcap/wpcap.spec b/dlls/wpcap/wpcap.spec
new file mode 100644
index 0000000..1841ab4
--- /dev/null
+++ b/dlls/wpcap/wpcap.spec
@@ -0,0 +1,78 @@
+@ stub bpf_dump
+@ stub bpf_filter
+@ stub bpf_image
+@ stub bpf_validate
+@ stub endservent
+@ stub eproto_db
+@ stub getservent
+@ stub install_bpf_program
+@ cdecl pcap_breakloop(ptr) wine_pcap_breakloop
+@ cdecl pcap_close(ptr) wine_pcap_close
+@ cdecl pcap_compile(ptr ptr str long long)  wine_pcap_compile
+@ stub pcap_compile_nopcap
+@ stub pcap_createsrcstr
+@ cdecl pcap_datalink(ptr) wine_pcap_datalink
+@ cdecl pcap_datalink_name_to_val(str) wine_pcap_datalink_name_to_val
+@ cdecl pcap_datalink_val_to_description(long) wine_pcap_datalink_val_to_description
+@ cdecl pcap_datalink_val_to_name(long) wine_pcap_datalink_val_to_name
+@ cdecl pcap_dispatch(ptr long long str) wine_pcap_dispatch
+@ stub pcap_dump
+@ stub pcap_dump_close
+@ stub pcap_dump_file
+@ stub pcap_dump_flush
+@ stub pcap_dump_ftell
+@ stub pcap_dump_open
+@ stub pcap_file
+@ stub pcap_fileno
+@ cdecl pcap_findalldevs(ptr str) wine_pcap_findalldevs
+@ stub pcap_findalldevs_ex #(str ptr ptr str)
+@ cdecl pcap_freealldevs(ptr) wine_pcap_freealldevs
+@ cdecl pcap_freecode(ptr) wine_pcap_freecode
+@ stub pcap_get_airpcap_handle
+@ cdecl pcap_geterr(ptr) wine_pcap_geterr
+@ stub pcap_getevent
+@ cdecl pcap_getnonblock(ptr ptr) wine_pcap_getnonblock
+@ stub pcap_is_swapped
+@ cdecl pcap_lib_version() wine_pcap_lib_version
+@ cdecl pcap_list_datalinks(ptr ptr) wine_pcap_list_datalinks
+@ stub pcap_live_dump
+@ stub pcap_live_dump_ended
+@ cdecl pcap_lookupdev(str) wine_pcap_lookupdev
+@ cdecl pcap_lookupnet(str ptr ptr str) wine_pcap_lookupnet
+@ cdecl pcap_loop(ptr long long str) wine_pcap_loop
+@ cdecl pcap_major_version(ptr) wine_pcap_major_version
+@ cdecl pcap_minor_version(ptr) wine_pcap_minor_version
+@ cdecl pcap_next(ptr ptr) wine_pcap_next
+@ stub pcap_next_etherent
+@ cdecl pcap_next_ex(ptr ptr ptr) wine_pcap_next_ex
+@ stub pcap_offline_filter
+@ stub pcap_offline_read
+@ stub pcap_open
+@ stub pcap_open_dead
+@ cdecl pcap_open_live(str long long long str) wine_pcap_open_live
+@ stub pcap_open_offline
+@ stub pcap_parsesrcstr
+@ stub pcap_perror
+@ stub pcap_read
+@ stub pcap_remoteact_accept
+@ stub pcap_remoteact_cleanup
+@ stub pcap_remoteact_close
+@ stub pcap_remoteact_list
+@ cdecl pcap_sendpacket(ptr str long) wine_pcap_sendpacket
+@ stub pcap_sendqueue_alloc
+@ stub pcap_sendqueue_destroy
+@ stub pcap_sendqueue_queue
+@ stub pcap_sendqueue_transmit
+@ cdecl pcap_set_datalink(ptr long) wine_pcap_set_datalink
+@ cdecl pcap_setbuff(ptr long) wine_pcap_setbuff
+@ cdecl pcap_setfilter(ptr ptr) wine_pcap_setfilter
+@ stub pcap_setmintocopy
+@ stub pcap_setmode #(ptr long)
+@ cdecl pcap_setnonblock(ptr long ptr) wine_pcap_setnonblock
+@ stub pcap_setsampling
+@ stub pcap_setuserbuffer
+@ cdecl pcap_snapshot(ptr) wine_pcap_snapshot
+@ cdecl pcap_stats(ptr ptr) wine_pcap_stats
+@ stub pcap_stats_ex
+@ stub pcap_strerror
+@ cdecl wsockinit() wine_wsockinit
-- 

Best Regards, André Hentschel



More information about the wine-patches mailing list