1 /* capture_wpcap_packet.c
2 * WinPcap-specific interfaces for low-level information (packet.dll).
3 * We load WinPcap at run
4 * time, so that we only need one Ethereal binary and one Tethereal binary
5 * for Windows, regardless of whether WinPcap is installed or not.
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@ethereal.com>
11 * Copyright 2001 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #if defined HAVE_LIBPCAP && defined _WIN32
37 /* XXX - yes, I know, I should move cppmagic.h to a generic location. */
38 #include "tools/lemon/cppmagic.h"
40 #include <epan/value_string.h>
47 #include "capture_wpcap_packet.h"
49 gboolean has_wpacket = FALSE;
52 /* This module will use the PacketRequest function in packet.dll (coming with WinPcap) to "directly" access
53 * the Win32 NDIS network driver(s) and ask for various values (status, statistics, ...).
55 * Unfortunately, the definitions required for this are not available through the usual windows header files,
56 * but require the Windows "Device Driver Kit" which is not available for free :-(
58 * Fortunately, the definitions needed to access the various NDIS values are available from various OSS projects:
59 * - WinPcap in Ntddndis.h
60 * - Ndiswrapper in driver/ndis.h and driver/iw_ndis.h
61 * - cygwin (MingW?) in usr/include/w32api/ddk/ndis.h and ntddndis.h
65 /* The MSDN description of the NDIS driver API is available at:
66 /* MSDN Home > MSDN Library > Win32 and COM Development > Driver Development Kit > Network Devices and Protocols > Reference */
68 /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/network/hh/network/21oidovw_d55042e5-0b8a-4439-8ef2-be7331e98464.xml.asp */
70 /* Some more interesting links:
71 * http://sourceforge.net/projects/ndiswrapper/
72 * http://www.osronline.com/lists_archive/windbg/thread521.html
73 * http://cvs.sourceforge.net/viewcvs.py/mingw/w32api/include/ddk/ndis.h?view=markup
74 * http://cvs.sourceforge.net/viewcvs.py/mingw/w32api/include/ddk/ntddndis.h?view=markup
79 /******************************************************************************************************************************/
80 /* stuff to load WinPcap's packet.dll and the functions required from it */
82 static PCHAR (*p_PacketGetVersion) (void);
83 static LPADAPTER (*p_PacketOpenAdapter) (char *adaptername);
84 static void (*p_PacketCloseAdapter) (LPADAPTER);
85 static int (*p_PacketRequest) (LPADAPTER, int, void *);
93 #define SYM(x, y) { STRINGIFY(x) , (gpointer) &CONCAT(p_,x), y }
96 wpcap_packet_load(void)
99 /* These are the symbols I need or want from packet.dll */
100 static const symbol_table_t symbols[] = {
101 SYM(PacketGetVersion, FALSE),
102 SYM(PacketOpenAdapter, FALSE),
103 SYM(PacketCloseAdapter, FALSE),
104 SYM(PacketRequest, FALSE),
105 { NULL, NULL, FALSE }
108 GModule *wh; /* wpcap handle */
109 const symbol_table_t *sym;
111 wh = g_module_open("packet", 0);
119 if (!g_module_symbol(wh, sym->name, sym->ptr)) {
122 * We don't care if it's missing; we just
128 * We require this symbol.
141 /******************************************************************************************************************************/
142 /* functions to access the NDIS driver values */
145 /* get dll version */
147 wpcap_packet_get_version(void)
152 return p_PacketGetVersion();
156 /* open the interface */
158 wpcap_packet_open(char *if_name)
162 g_assert(has_wpacket);
163 adapter = p_PacketOpenAdapter(if_name);
169 /* close the interface */
171 wpcap_packet_close(void *adapter)
174 g_assert(has_wpacket);
175 p_PacketCloseAdapter(adapter);
179 /* do a packet request call */
181 wpcap_packet_request(void *adapter, ULONG Oid, int set, char *value, unsigned int *length)
184 ULONG IoCtlBufferLength=(sizeof(PACKET_OID_DATA) + (*length) - 1);
185 PPACKET_OID_DATA OidData;
188 g_assert(has_wpacket);
190 if(p_PacketRequest == NULL) {
191 g_warning("packet_request not available\n");
195 OidData=GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,IoCtlBufferLength);
196 if (OidData == NULL) {
197 g_warning("packet_link_status failed\n");
202 OidData->Length = *length;
204 Status = p_PacketRequest(adapter, set, OidData);
207 g_assert(OidData->Length <= *length);
208 memcpy(value, OidData->Data, OidData->Length);
209 *length = OidData->Length;
212 GlobalFreePtr (OidData);
222 /* get an UINT value using the packet request call */
224 wpcap_packet_request_uint(void *adapter, ULONG Oid, UINT *value)
227 int length = sizeof(UINT);
230 Status = wpcap_packet_request(adapter, Oid, FALSE /* !set */, (char *) value, &length);
232 g_assert(length == sizeof(UINT));
240 /* get an ULONG value using the NDIS packet request call */
242 wpcap_packet_request_ulong(void *adapter, ULONG Oid, ULONG *value)
245 int length = sizeof(ULONG);
248 Status = wpcap_packet_request(adapter, Oid, FALSE /* !set */, (char *) value, &length);
250 g_assert(length == sizeof(ULONG));
258 #else /* HAVE_LIBPCAP && _WIN32 */
261 wpcap_packet_load(void)
266 #endif /* HAVE_LIBPCAP */