]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/pcap-win32.c
Fix build.
[FreeBSD/FreeBSD.git] / contrib / libpcap / pcap-win32.c
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__
51 int* _errno();
52 #define errno (*_errno())
53 #endif /* __MINGW32__ */
54
55 static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
56 static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
57 static int pcap_getnonblock_win32(pcap_t *, char *);
58 static 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  */
72 struct 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  */
86 struct 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
94 CRITICAL_SECTION g_PcapCompileCriticalSection;
95
96 BOOL 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 */
111 int 
112 wsockinit()
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
133 int pcap_wsockinit()
134 {
135        return wsockinit();
136 }
137
138 static int
139 pcap_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 */
151 static int
152 pcap_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 */
163 static int
164 pcap_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*/
176 static int
177 pcap_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*/
188 static Adapter *
189 pcap_getadapter_win32(pcap_t *p)
190 {
191         return p->adapter;
192 }
193
194 static int
195 pcap_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
301 static int
302 pcap_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 */
463 static int 
464 pcap_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
492 static void
493 pcap_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
506 static int
507 pcap_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);
775 bad:
776         pcap_cleanup_win32(p);
777         return (PCAP_ERROR);
778 }
779
780 pcap_t *
781 pcap_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
824 static int
825 pcap_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  */
885 static int 
886 pcap_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
905 static int
906 pcap_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
918 static int
919 pcap_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*/
947 int
948 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
949 {
950         return (0);
951 }