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