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