pcap-win32.c revision 214518
1/*
2 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3 * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Politecnico di Torino, CACE Technologies
16 * nor the names of its contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#ifndef lint
35static const char rcsid[] _U_ =
36    "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.42 2008-05-21 22:15:25 gianluca Exp $ (LBL)";
37#endif
38
39#include <pcap-int.h>
40#include <Packet32.h>
41#ifdef __MINGW32__
42#include <ddk/ndis.h>
43#else /*__MINGW32__*/
44#include <ntddndis.h>
45#endif /*__MINGW32__*/
46#ifdef HAVE_DAG_API
47#include <dagnew.h>
48#include <dagapi.h>
49#endif /* HAVE_DAG_API */
50#ifdef __MINGW32__
51int* _errno();
52#define errno (*_errno())
53#endif /* __MINGW32__ */
54
55static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
56static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
57static int pcap_getnonblock_win32(pcap_t *, char *);
58static int pcap_setnonblock_win32(pcap_t *, int, char *);
59
60/*dimension of the buffer in the pcap_t structure*/
61#define	WIN32_DEFAULT_USER_BUFFER_SIZE 256000
62
63/*dimension of the buffer in the kernel driver NPF */
64#define	WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
65
66/* Equivalent to ntohs(), but a lot faster under Windows */
67#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
68
69/*
70 * Header that the WinPcap driver associates to the packets.
71 * Once was in bpf.h
72 */
73struct bpf_hdr {
74	struct timeval	bh_tstamp;	/* time stamp */
75	bpf_u_int32	bh_caplen;	/* length of captured portion */
76	bpf_u_int32	bh_datalen;	/* original length of packet */
77	u_short		bh_hdrlen;	/* length of bpf header (this struct
78					   plus alignment padding) */
79};
80
81CRITICAL_SECTION g_PcapCompileCriticalSection;
82
83BOOL WINAPI DllMain(
84  HANDLE hinstDLL,
85  DWORD dwReason,
86  LPVOID lpvReserved
87)
88{
89	if (dwReason == DLL_PROCESS_ATTACH)
90	{
91		InitializeCriticalSection(&g_PcapCompileCriticalSection);
92	}
93
94	return TRUE;
95}
96
97/* Start winsock */
98int
99wsockinit()
100{
101	WORD wVersionRequested;
102	WSADATA wsaData;
103	int err;
104	wVersionRequested = MAKEWORD( 1, 1);
105	err = WSAStartup( wVersionRequested, &wsaData );
106	if ( err != 0 )
107	{
108		return -1;
109	}
110	return 0;
111}
112
113
114static int
115pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
116{
117
118	if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){
119		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());
120		return -1;
121	}
122
123	return 0;
124}
125
126/* Set the dimension of the kernel-level capture buffer */
127static int
128pcap_setbuff_win32(pcap_t *p, int dim)
129{
130	if(PacketSetBuff(p->adapter,dim)==FALSE)
131	{
132		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
133		return -1;
134	}
135	return 0;
136}
137
138/* Set the driver working mode */
139static int
140pcap_setmode_win32(pcap_t *p, int mode)
141{
142	if(PacketSetMode(p->adapter,mode)==FALSE)
143	{
144		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
145		return -1;
146	}
147
148	return 0;
149}
150
151/*set the minimum amount of data that will release a read call*/
152static int
153pcap_setmintocopy_win32(pcap_t *p, int size)
154{
155	if(PacketSetMinToCopy(p->adapter, size)==FALSE)
156	{
157		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
158		return -1;
159	}
160	return 0;
161}
162
163static int
164pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
165{
166	int cc;
167	int n = 0;
168	register u_char *bp, *ep;
169
170	cc = p->cc;
171	if (p->cc == 0) {
172		/*
173		 * Has "pcap_breakloop()" been called?
174		 */
175		if (p->break_loop) {
176			/*
177			 * Yes - clear the flag that indicates that it
178			 * has, and return -2 to indicate that we were
179			 * told to break out of the loop.
180			 */
181			p->break_loop = 0;
182			return (-2);
183		}
184
185	    /* capture the packets */
186		if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
187			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
188			return (-1);
189		}
190
191		cc = p->Packet->ulBytesReceived;
192
193		bp = p->Packet->Buffer;
194	}
195	else
196		bp = p->bp;
197
198	/*
199	 * Loop through each packet.
200	 */
201#define bhp ((struct bpf_hdr *)bp)
202	ep = bp + cc;
203	while (1) {
204		register int caplen, hdrlen;
205
206		/*
207		 * Has "pcap_breakloop()" been called?
208		 * If so, return immediately - if we haven't read any
209		 * packets, clear the flag and return -2 to indicate
210		 * that we were told to break out of the loop, otherwise
211		 * leave the flag set, so that the *next* call will break
212		 * out of the loop without having read any packets, and
213		 * return the number of packets we've processed so far.
214		 */
215		if (p->break_loop) {
216			if (n == 0) {
217				p->break_loop = 0;
218				return (-2);
219			} else {
220				p->bp = bp;
221				p->cc = ep - bp;
222				return (n);
223			}
224		}
225		if (bp >= ep)
226			break;
227
228		caplen = bhp->bh_caplen;
229		hdrlen = bhp->bh_hdrlen;
230
231		/*
232		 * XXX A bpf_hdr matches a pcap_pkthdr.
233		 */
234		(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
235		bp += BPF_WORDALIGN(caplen + hdrlen);
236		if (++n >= cnt && cnt > 0) {
237			p->bp = bp;
238			p->cc = ep - bp;
239			return (n);
240		}
241	}
242#undef bhp
243	p->cc = 0;
244	return (n);
245}
246
247#ifdef HAVE_DAG_API
248static int
249pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
250{
251	u_char *dp = NULL;
252	int	packet_len = 0, caplen = 0;
253	struct pcap_pkthdr	pcap_header;
254	u_char *endofbuf;
255	int n = 0;
256	dag_record_t *header;
257	unsigned erf_record_len;
258	ULONGLONG ts;
259	int cc;
260	unsigned swt;
261	unsigned dfp = p->adapter->DagFastProcess;
262
263	cc = p->cc;
264	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
265	{
266	    /* Get new packets from the network */
267		if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){
268			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
269			return (-1);
270		}
271
272		cc = p->Packet->ulBytesReceived;
273		if(cc == 0)
274			/* The timeout has expired but we no packets arrived */
275			return 0;
276		header = (dag_record_t*)p->adapter->DagBuffer;
277	}
278	else
279		header = (dag_record_t*)p->bp;
280
281	endofbuf = (char*)header + cc;
282
283	/*
284	 * Cycle through the packets
285	 */
286	do
287	{
288		erf_record_len = SWAPS(header->rlen);
289		if((char*)header + erf_record_len > endofbuf)
290			break;
291
292		/* Increase the number of captured packets */
293		p->md.stat.ps_recv++;
294
295		/* Find the beginning of the packet */
296		dp = ((u_char *)header) + dag_record_size;
297
298		/* Determine actual packet len */
299		switch(header->type)
300		{
301		case TYPE_ATM:
302			packet_len = ATM_SNAPLEN;
303			caplen = ATM_SNAPLEN;
304			dp += 4;
305
306			break;
307
308		case TYPE_ETH:
309			swt = SWAPS(header->wlen);
310			packet_len = swt - (p->md.dag_fcs_bits);
311			caplen = erf_record_len - dag_record_size - 2;
312			if (caplen > packet_len)
313			{
314				caplen = packet_len;
315			}
316			dp += 2;
317
318			break;
319
320		case TYPE_HDLC_POS:
321			swt = SWAPS(header->wlen);
322			packet_len = swt - (p->md.dag_fcs_bits);
323			caplen = erf_record_len - dag_record_size;
324			if (caplen > packet_len)
325			{
326				caplen = packet_len;
327			}
328
329			break;
330		}
331
332		if(caplen > p->snapshot)
333			caplen = p->snapshot;
334
335		/*
336		 * Has "pcap_breakloop()" been called?
337		 * If so, return immediately - if we haven't read any
338		 * packets, clear the flag and return -2 to indicate
339		 * that we were told to break out of the loop, otherwise
340		 * leave the flag set, so that the *next* call will break
341		 * out of the loop without having read any packets, and
342		 * return the number of packets we've processed so far.
343		 */
344		if (p->break_loop)
345		{
346			if (n == 0)
347			{
348				p->break_loop = 0;
349				return (-2);
350			}
351			else
352			{
353				p->bp = (char*)header;
354				p->cc = endofbuf - (char*)header;
355				return (n);
356			}
357		}
358
359		if(!dfp)
360		{
361			/* convert between timestamp formats */
362			ts = header->ts;
363			pcap_header.ts.tv_sec = (int)(ts >> 32);
364			ts = (ts & 0xffffffffi64) * 1000000;
365			ts += 0x80000000; /* rounding */
366			pcap_header.ts.tv_usec = (int)(ts >> 32);
367			if (pcap_header.ts.tv_usec >= 1000000) {
368				pcap_header.ts.tv_usec -= 1000000;
369				pcap_header.ts.tv_sec++;
370			}
371		}
372
373		/* No underlaying filtering system. We need to filter on our own */
374		if (p->fcode.bf_insns)
375		{
376			if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
377			{
378				/* Move to next packet */
379				header = (dag_record_t*)((char*)header + erf_record_len);
380				continue;
381			}
382		}
383
384		/* Fill the header for the user suppplied callback function */
385		pcap_header.caplen = caplen;
386		pcap_header.len = packet_len;
387
388		/* Call the callback function */
389		(*callback)(user, &pcap_header, dp);
390
391		/* Move to next packet */
392		header = (dag_record_t*)((char*)header + erf_record_len);
393
394		/* Stop if the number of packets requested by user has been reached*/
395		if (++n >= cnt && cnt > 0)
396		{
397			p->bp = (char*)header;
398			p->cc = endofbuf - (char*)header;
399			return (n);
400		}
401	}
402	while((u_char*)header < endofbuf);
403
404  return 1;
405}
406#endif /* HAVE_DAG_API */
407
408/* Send a packet to the network */
409static int
410pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
411	LPPACKET PacketToSend;
412
413	PacketToSend=PacketAllocatePacket();
414
415	if (PacketToSend == NULL)
416	{
417		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");
418		return -1;
419	}
420
421	PacketInitPacket(PacketToSend,(PVOID)buf,size);
422	if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
423		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
424		PacketFreePacket(PacketToSend);
425		return -1;
426	}
427
428	PacketFreePacket(PacketToSend);
429
430	/*
431	 * We assume it all got sent if "PacketSendPacket()" succeeded.
432	 * "pcap_inject()" is expected to return the number of bytes
433	 * sent.
434	 */
435	return size;
436}
437
438static void
439pcap_cleanup_win32(pcap_t *p)
440{
441	if (p->adapter != NULL) {
442		PacketCloseAdapter(p->adapter);
443		p->adapter = NULL;
444	}
445	if (p->Packet) {
446		PacketFreePacket(p->Packet);
447		p->Packet = NULL;
448	}
449	pcap_cleanup_live_common(p);
450}
451
452static int
453pcap_activate_win32(pcap_t *p)
454{
455	NetType type;
456
457	if (p->opt.rfmon) {
458		/*
459		 * No monitor mode on Windows.  It could be done on
460		 * Vista with drivers that support the native 802.11
461		 * mechanism and monitor mode.
462		 */
463		return (PCAP_ERROR_RFMON_NOTSUP);
464	}
465
466	/* Init WinSock */
467	wsockinit();
468
469	p->adapter = PacketOpenAdapter(p->opt.source);
470
471	if (p->adapter == NULL)
472	{
473		/* Adapter detected but we are not able to open it. Return failure. */
474		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
475		return PCAP_ERROR;
476	}
477
478	/*get network type*/
479	if(PacketGetNetType (p->adapter,&type) == FALSE)
480	{
481		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
482		goto bad;
483	}
484
485	/*Set the linktype*/
486	switch (type.LinkType)
487	{
488	case NdisMediumWan:
489		p->linktype = DLT_EN10MB;
490		break;
491
492	case NdisMedium802_3:
493		p->linktype = DLT_EN10MB;
494		/*
495		 * This is (presumably) a real Ethernet capture; give it a
496		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
497		 * that an application can let you choose it, in case you're
498		 * capturing DOCSIS traffic that a Cisco Cable Modem
499		 * Termination System is putting out onto an Ethernet (it
500		 * doesn't put an Ethernet header onto the wire, it puts raw
501		 * DOCSIS frames out on the wire inside the low-level
502		 * Ethernet framing).
503		 */
504		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
505		/*
506		 * If that fails, just leave the list empty.
507		 */
508		if (p->dlt_list != NULL) {
509			p->dlt_list[0] = DLT_EN10MB;
510			p->dlt_list[1] = DLT_DOCSIS;
511			p->dlt_count = 2;
512		}
513		break;
514
515	case NdisMediumFddi:
516		p->linktype = DLT_FDDI;
517		break;
518
519	case NdisMedium802_5:
520		p->linktype = DLT_IEEE802;
521		break;
522
523	case NdisMediumArcnetRaw:
524		p->linktype = DLT_ARCNET;
525		break;
526
527	case NdisMediumArcnet878_2:
528		p->linktype = DLT_ARCNET;
529		break;
530
531	case NdisMediumAtm:
532		p->linktype = DLT_ATM_RFC1483;
533		break;
534
535	case NdisMediumCHDLC:
536		p->linktype = DLT_CHDLC;
537		break;
538
539	case NdisMediumPPPSerial:
540		p->linktype = DLT_PPP_SERIAL;
541		break;
542
543	case NdisMediumNull:
544		p->linktype = DLT_NULL;
545		break;
546
547	case NdisMediumBare80211:
548		p->linktype = DLT_IEEE802_11;
549		break;
550
551	case NdisMediumRadio80211:
552		p->linktype = DLT_IEEE802_11_RADIO;
553		break;
554
555	case NdisMediumPpi:
556		p->linktype = DLT_PPI;
557		break;
558
559	default:
560		p->linktype = DLT_EN10MB;			/*an unknown adapter is assumed to be ethernet*/
561		break;
562	}
563
564	/* Set promiscuous mode */
565	if (p->opt.promisc)
566	{
567
568		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
569		{
570			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
571			goto bad;
572		}
573	}
574	else
575	{
576		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
577		{
578			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
579			goto bad;
580		}
581	}
582
583	/* Set the buffer size */
584	p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
585
586	/* allocate Packet structure used during the capture */
587	if((p->Packet = PacketAllocatePacket())==NULL)
588	{
589		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
590		goto bad;
591	}
592
593	if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
594	{
595	/*
596	 * Traditional Adapter
597	 */
598		/*
599		 * If the buffer size wasn't explicitly set, default to
600		 * WIN32_DEFAULT_USER_BUFFER_SIZE.
601		 */
602	 	if (p->opt.buffer_size == 0)
603	 		p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
604
605		if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
606		{
607			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
608			goto bad;
609		}
610
611		p->buffer = (u_char *)malloc(p->bufsize);
612		if (p->buffer == NULL)
613		{
614			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
615			goto bad;
616		}
617
618		PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
619
620		/* tell the driver to copy the buffer only if it contains at least 16K */
621		if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
622		{
623			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s", pcap_win32strerror());
624			goto bad;
625		}
626	}
627	else
628#ifdef HAVE_DAG_API
629	{
630	/*
631	 * Dag Card
632	 */
633		LONG	status;
634		HKEY	dagkey;
635		DWORD	lptype;
636		DWORD	lpcbdata;
637		int		postype = 0;
638		char	keyname[512];
639
640		snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
641			"SYSTEM\\CurrentControlSet\\Services\\DAG",
642			strstr(_strlwr(p->opt.source), "dag"));
643		do
644		{
645			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
646			if(status != ERROR_SUCCESS)
647				break;
648
649			status = RegQueryValueEx(dagkey,
650				"PosType",
651				NULL,
652				&lptype,
653				(char*)&postype,
654				&lpcbdata);
655
656			if(status != ERROR_SUCCESS)
657			{
658				postype = 0;
659			}
660
661			RegCloseKey(dagkey);
662		}
663		while(FALSE);
664
665
666		p->snapshot = PacketSetSnapLen(p->adapter, snaplen);
667
668		/* Set the length of the FCS associated to any packet. This value
669		 * will be subtracted to the packet length */
670		p->md.dag_fcs_bits = p->adapter->DagFcsLen;
671	}
672#else
673	goto bad;
674#endif /* HAVE_DAG_API */
675
676	PacketSetReadTimeout(p->adapter, p->md.timeout);
677
678#ifdef HAVE_DAG_API
679	if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
680	{
681		/* install dag specific handlers for read and setfilter */
682		p->read_op = pcap_read_win32_dag;
683		p->setfilter_op = pcap_setfilter_win32_dag;
684	}
685	else
686	{
687#endif /* HAVE_DAG_API */
688		/* install traditional npf handlers for read and setfilter */
689		p->read_op = pcap_read_win32_npf;
690		p->setfilter_op = pcap_setfilter_win32_npf;
691#ifdef HAVE_DAG_API
692	}
693#endif /* HAVE_DAG_API */
694	p->setdirection_op = NULL;	/* Not implemented. */
695	    /* XXX - can this be implemented on some versions of Windows? */
696	p->inject_op = pcap_inject_win32;
697	p->set_datalink_op = NULL;	/* can't change data link type */
698	p->getnonblock_op = pcap_getnonblock_win32;
699	p->setnonblock_op = pcap_setnonblock_win32;
700	p->stats_op = pcap_stats_win32;
701	p->setbuff_op = pcap_setbuff_win32;
702	p->setmode_op = pcap_setmode_win32;
703	p->setmintocopy_op = pcap_setmintocopy_win32;
704	p->cleanup_op = pcap_cleanup_win32;
705
706	return (0);
707bad:
708	pcap_cleanup_win32(p);
709	return (PCAP_ERROR);
710}
711
712pcap_t *
713pcap_create(const char *device, char *ebuf)
714{
715	pcap_t *p;
716
717	if (strlen(device) == 1)
718	{
719		/*
720		 * It's probably a unicode string
721		 * Convert to ascii and pass it to pcap_create_common
722		 *
723		 * This wonderful hack is needed because pcap_lookupdev still returns
724		 * unicode strings, and it's used by windump when no device is specified
725		 * in the command line
726		 */
727		size_t length;
728		char* deviceAscii;
729
730		length = wcslen((wchar_t*)device);
731
732		deviceAscii = (char*)malloc(length + 1);
733
734		if (deviceAscii == NULL)
735		{
736			snprintf(ebuf, PCAP_ERRBUF_SIZE, "Malloc failed");
737			return NULL;
738		}
739
740		snprintf(deviceAscii, length + 1, "%ws", (wchar_t*)device);
741		p = pcap_create_common(deviceAscii, ebuf);
742		free(deviceAscii);
743	}
744	else
745	{
746		p = pcap_create_common(device, ebuf);
747	}
748
749	if (p == NULL)
750		return (NULL);
751
752	p->activate_op = pcap_activate_win32;
753	return (p);
754}
755
756static int
757pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
758{
759	if(PacketSetBpf(p->adapter,fp)==FALSE){
760		/*
761		 * Kernel filter not installed.
762		 * XXX - fall back on userland filtering, as is done
763		 * on other platforms?
764		 */
765		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
766		return (-1);
767	}
768
769	/*
770	 * Discard any previously-received packets, as they might have
771	 * passed whatever filter was formerly in effect, but might
772	 * not pass this filter (BIOCSETF discards packets buffered
773	 * in the kernel, so you can lose packets in any case).
774	 */
775	p->cc = 0;
776	return (0);
777}
778
779/*
780 * We filter at user level, since the kernel driver does't process the packets
781 */
782static int
783pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
784
785	if(!fp)
786	{
787		strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
788		return -1;
789	}
790
791	/* Install a user level filter */
792	if (install_bpf_program(p, fp) < 0)
793	{
794		snprintf(p->errbuf, sizeof(p->errbuf),
795			"setfilter, unable to install the filter: %s", pcap_strerror(errno));
796		return -1;
797	}
798
799	p->md.use_bpf = 0;
800
801	return (0);
802}
803
804static int
805pcap_getnonblock_win32(pcap_t *p, char *errbuf)
806{
807	/*
808	 * XXX - if there were a PacketGetReadTimeout() call, we
809	 * would use it, and return 1 if the timeout is -1
810	 * and 0 otherwise.
811	 */
812	return (p->nonblock);
813}
814
815static int
816pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
817{
818	int newtimeout;
819
820	if (nonblock) {
821		/*
822		 * Set the read timeout to -1 for non-blocking mode.
823		 */
824		newtimeout = -1;
825	} else {
826		/*
827		 * Restore the timeout set when the device was opened.
828		 * (Note that this may be -1, in which case we're not
829		 * really leaving non-blocking mode.)
830		 */
831		newtimeout = p->md.timeout;
832	}
833	if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
834		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
835		    "PacketSetReadTimeout: %s", pcap_win32strerror());
836		return (-1);
837	}
838	p->nonblock = (newtimeout == -1);
839	return (0);
840}
841
842/*platform-dependent routine to add devices other than NDIS interfaces*/
843int
844pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
845{
846	return (0);
847}
848