1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California)
4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * All rights reserved.
5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Redistribution and use in source and binary forms, with or without
7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * modification, are permitted provided that the following conditions
8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * are met:
9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * notice, this list of conditions and the following disclaimer.
12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * notice, this list of conditions and the following disclaimer in the
14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * documentation and/or other materials provided with the distribution.
15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3. Neither the name of the Politecnico di Torino, CACE Technologies
16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * nor the names of its contributors may be used to endorse or promote
17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * products derived from this software without specific prior written
18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * permission.
19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef lint
35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ =
36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25.2.7 2007/06/14 22:07:14 gianluca Exp $ (LBL)";
37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <pcap-int.h>
40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <Packet32.h>
41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <Ntddndis.h>
42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <dagnew.h>
44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <dagapi.h>
45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __MINGW32__
47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint* _errno();
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define errno (*_errno())
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* __MINGW32__ */
50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_getnonblock_win32(pcap_t *, char *);
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setnonblock_win32(pcap_t *, int, char *);
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define	PcapBufSize 256000	/*dimension of the buffer in the pcap_t structure*/
57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define	SIZE_BUF 1000000
58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Equivalent to ntohs(), but a lot faster under Windows */
60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Header that the WinPcap driver associates to the packets.
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Once was in bpf.h
65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct bpf_hdr {
67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct timeval	bh_tstamp;	/* time stamp */
68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32	bh_caplen;	/* length of captured portion */
69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	bpf_u_int32	bh_datalen;	/* original length of packet */
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_short		bh_hdrlen;	/* length of bpf header (this struct
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					   plus alignment padding) */
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project};
73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Start winsock */
75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectwsockinit()
77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	WORD wVersionRequested;
79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	WSADATA wsaData;
80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int err;
81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	wVersionRequested = MAKEWORD( 1, 1);
82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	err = WSAStartup( wVersionRequested, &wsaData );
83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ( err != 0 )
84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){
96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());
97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int cc;
107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n = 0;
108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register u_char *bp, *ep;
109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	cc = p->cc;
111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->cc == 0) {
112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->break_loop) {
116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Yes - clear the flag that indicates that it
118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * has, and return -2 to indicate that we were
119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * told to break out of the loop.
120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->break_loop = 0;
122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (-2);
123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    /* capture the packets */
126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (-1);
129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		cc = p->Packet->ulBytesReceived;
132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bp = p->Packet->Buffer;
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bp = p->bp;
137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Loop through each packet.
140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define bhp ((struct bpf_hdr *)bp)
142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ep = bp + cc;
143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (1) {
144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		register int caplen, hdrlen;
145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If so, return immediately - if we haven't read any
149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * packets, clear the flag and return -2 to indicate
150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * that we were told to break out of the loop, otherwise
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * leave the flag set, so that the *next* call will break
152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * out of the loop without having read any packets, and
153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * return the number of packets we've processed so far.
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->break_loop) {
156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (n == 0) {
157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->break_loop = 0;
158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return (-2);
159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else {
160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->bp = bp;
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->cc = ep - bp;
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return (n);
163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (bp >= ep)
166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		caplen = bhp->bh_caplen;
169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		hdrlen = bhp->bh_hdrlen;
170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX A bpf_hdr matches a pcap_pkthdr.
173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bp += BPF_WORDALIGN(caplen + hdrlen);
176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (++n >= cnt && cnt > 0) {
177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->bp = bp;
178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->cc = ep - bp;
179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (n);
180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#undef bhp
183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->cc = 0;
184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (n);
185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_char *dp = NULL;
192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int	packet_len = 0, caplen = 0;
193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct pcap_pkthdr	pcap_header;
194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_char *endofbuf;
195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n = 0;
196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	dag_record_t *header;
197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned erf_record_len;
198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ULONGLONG ts;
199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int cc;
200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned swt;
201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned dfp = p->adapter->DagFastProcess;
202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	cc = p->cc;
204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    /* Get new packets from the network */
207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){
208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (-1);
210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		cc = p->Packet->ulBytesReceived;
213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(cc == 0)
214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* The timeout has expired but we no packets arrived */
215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return 0;
216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		header = (dag_record_t*)p->adapter->DagBuffer;
217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		header = (dag_record_t*)p->bp;
220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	endofbuf = (char*)header + cc;
222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Cycle through the packets
225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	do
227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		erf_record_len = SWAPS(header->rlen);
229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if((char*)header + erf_record_len > endofbuf)
230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Increase the number of captured packets */
233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->md.stat.ps_recv++;
234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Find the beginning of the packet */
236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		dp = ((u_char *)header) + dag_record_size;
237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Determine actual packet len */
239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch(header->type)
240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ATM:
242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len = ATM_SNAPLEN;
243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = ATM_SNAPLEN;
244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dp += 4;
245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ETH:
249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			swt = SWAPS(header->wlen);
250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len = swt - (p->md.dag_fcs_bits);
251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = erf_record_len - dag_record_size - 2;
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (caplen > packet_len)
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len;
255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dp += 2;
257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_HDLC_POS:
261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			swt = SWAPS(header->wlen);
262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len = swt - (p->md.dag_fcs_bits);
263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = erf_record_len - dag_record_size;
264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (caplen > packet_len)
265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len;
267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(caplen > p->snapshot)
273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = p->snapshot;
274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If so, return immediately - if we haven't read any
278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * packets, clear the flag and return -2 to indicate
279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * that we were told to break out of the loop, otherwise
280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * leave the flag set, so that the *next* call will break
281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * out of the loop without having read any packets, and
282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * return the number of packets we've processed so far.
283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->break_loop)
285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (n == 0)
287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->break_loop = 0;
289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return (-2);
290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			else
292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->bp = (char*)header;
294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->cc = endofbuf - (char*)header;
295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return (n);
296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(!dfp)
300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* convert between timestamp formats */
302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts = header->ts;
303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.ts.tv_sec = (int)(ts >> 32);
304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts = (ts & 0xffffffffi64) * 1000000;
305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts += 0x80000000; /* rounding */
306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.ts.tv_usec = (int)(ts >> 32);
307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (pcap_header.ts.tv_usec >= 1000000) {
308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				pcap_header.ts.tv_usec -= 1000000;
309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				pcap_header.ts.tv_sec++;
310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* No underlaying filtering system. We need to filter on our own */
314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->fcode.bf_insns)
315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* Move to next packet */
319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				header = (dag_record_t*)((char*)header + erf_record_len);
320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				continue;
321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Fill the header for the user suppplied callback function */
325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		pcap_header.caplen = caplen;
326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		pcap_header.len = packet_len;
327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Call the callback function */
329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(*callback)(user, &pcap_header, dp);
330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Move to next packet */
332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		header = (dag_record_t*)((char*)header + erf_record_len);
333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Stop if the number of packets requested by user has been reached*/
335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (++n >= cnt && cnt > 0)
336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->bp = (char*)header;
338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->cc = endofbuf - (char*)header;
339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (n);
340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while((u_char*)header < endofbuf);
343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return 1;
345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Send a packet to the network */
349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_win32(pcap_t *p, const void *buf, size_t size){
351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	LPPACKET PacketToSend;
352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PacketToSend=PacketAllocatePacket();
354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (PacketToSend == NULL)
356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");
358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PacketInitPacket(PacketToSend,(PVOID)buf,size);
362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		PacketFreePacket(PacketToSend);
365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PacketFreePacket(PacketToSend);
369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * We assume it all got sent if "PacketSendPacket()" succeeded.
372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * "pcap_inject()" is expected to return the number of bytes
373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * sent.
374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return size;
376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_close_win32(pcap_t *p)
380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_close_common(p);
382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter != NULL) {
383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		PacketCloseAdapter(p->adapter);
384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->adapter = NULL;
385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->Packet) {
387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		PacketFreePacket(p->Packet);
388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->Packet = NULL;
389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t *
393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    char *ebuf)
395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register pcap_t *p;
397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	NetType type;
398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Init WinSock */
400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	wsockinit();
401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p = (pcap_t *)malloc(sizeof(*p));
403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p == NULL)
404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (NULL);
407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(p, 0, sizeof(*p));
409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->adapter=NULL;
410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->adapter = PacketOpenAdapter((char*)device);
412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter == NULL)
414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free(p);
416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Adapter detected but we are not able to open it. Return failure. */
417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return NULL;
419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*get network type*/
422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketGetNetType (p->adapter,&type) == FALSE)
423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto bad;
426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*Set the linktype*/
429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	switch (type.LinkType)
430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumWan:
432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_EN10MB;
433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMedium802_3:
436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_EN10MB;
437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * This is (presumably) a real Ethernet capture; give it a
439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * that an application can let you choose it, in case you're
441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * capturing DOCSIS traffic that a Cisco Cable Modem
442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Termination System is putting out onto an Ethernet (it
443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * doesn't put an Ethernet header onto the wire, it puts raw
444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * DOCSIS frames out on the wire inside the low-level
445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Ethernet framing).
446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If that fails, just leave the list empty.
450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->dlt_list != NULL) {
452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->dlt_list[0] = DLT_EN10MB;
453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->dlt_list[1] = DLT_DOCSIS;
454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->dlt_count = 2;
455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumFddi:
459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_FDDI;
460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMedium802_5:
463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_IEEE802;
464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumArcnetRaw:
467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_ARCNET;
468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumArcnet878_2:
471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_ARCNET;
472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumAtm:
475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_ATM_RFC1483;
476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumCHDLC:
479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_CHDLC;
480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumPPPSerial:
483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_PPP_SERIAL;
484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumNull:
487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_NULL;
488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumBare80211:
491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_IEEE802_11;
492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumRadio80211:
495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_IEEE802_11_RADIO;
496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumPpi:
499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_PPI;
500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_EN10MB;			/*an unknown adapter is assumed to be ethernet*/
504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Set promiscuous mode */
508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (promisc)
509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Set the buffer size */
527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->bufsize = PcapBufSize;
528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Store the timeout. Used by pcap_setnonblock() */
530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->timeout= to_ms;
531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* allocate Packet structure used during the capture */
533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if((p->Packet = PacketAllocatePacket())==NULL)
534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto bad;
537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Traditional Adapter
543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->buffer = (u_char *)malloc(PcapBufSize);
546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->buffer == NULL)
547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->snapshot = snaplen;
555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* allocate the standard buffer in the driver */
557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* tell the driver to copy the buffer only if it contains at least 16K */
564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Dag Card
575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		LONG	status;
577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		HKEY	dagkey;
578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		DWORD	lptype;
579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		DWORD	lpcbdata;
580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		int		postype = 0;
581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		char	keyname[512];
582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			"SYSTEM\\CurrentControlSet\\Services\\DAG",
585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			strstr(_strlwr((char*)device), "dag"));
586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		do
587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(status != ERROR_SUCCESS)
590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				break;
591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			status = RegQueryValueEx(dagkey,
593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				"PosType",
594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				NULL,
595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				&lptype,
596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				(char*)&postype,
597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				&lpcbdata);
598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(status != ERROR_SUCCESS)
600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				postype = 0;
602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			RegCloseKey(dagkey);
605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		while(FALSE);
607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->snapshot = PacketSetSnapLen(p->adapter, snaplen);
610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Set the length of the FCS associated to any packet. This value
612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * will be subtracted to the packet length */
613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->md.dag_fcs_bits = p->adapter->DagFcsLen;
614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	goto bad;
617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PacketSetReadTimeout(p->adapter, to_ms);
620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* install dag specific handlers for read and setfilter */
625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->read_op = pcap_read_win32_dag;
626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->setfilter_op = pcap_setfilter_win32_dag;
627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* install traditional npf handlers for read and setfilter */
632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->read_op = pcap_read_win32_npf;
633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->setfilter_op = pcap_setfilter_win32_npf;
634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->setdirection_op = NULL;	/* Not implemented. */
638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    /* XXX - can this be implemented on some versions of Windows? */
639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->inject_op = pcap_inject_win32;
640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->set_datalink_op = NULL;	/* can't change data link type */
641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->getnonblock_op = pcap_getnonblock_win32;
642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->setnonblock_op = pcap_setnonblock_win32;
643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->stats_op = pcap_stats_win32;
644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->close_op = pcap_close_win32;
645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (p);
647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbad:
648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter)
649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    PacketCloseAdapter(p->adapter);
650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->buffer != NULL)
651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free(p->buffer);
652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(p->Packet)
653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		PacketFreePacket(p->Packet);
654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Get rid of any link-layer type list we allocated.
656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->dlt_list != NULL)
658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free(p->dlt_list);
659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free(p);
660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (NULL);
661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketSetBpf(p->adapter,fp)==FALSE){
668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Kernel filter not installed.
670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - fall back on userland filtering, as is done
671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * on other platforms?
672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Discard any previously-received packets, as they might have
679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * passed whatever filter was formerly in effect, but might
680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * not pass this filter (BIOCSETF discards packets buffered
681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * in the kernel, so you can lose packets in any case).
682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->cc = 0;
684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We filter at user level, since the kernel driver does't process the packets
689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(!fp)
694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Install a user level filter */
700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (install_bpf_program(p, fp) < 0)
701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, sizeof(p->errbuf),
703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			"setfilter, unable to install the filter: %s", pcap_strerror(errno));
704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->md.use_bpf = 0;
708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_getnonblock_win32(pcap_t *p, char *errbuf)
714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * XXX - if there were a PacketGetReadTimeout() call, we
717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * would use it, and return 1 if the timeout is -1
718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * and 0 otherwise.
719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (p->nonblock);
721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int newtimeout;
727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (nonblock) {
729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Set the read timeout to -1 for non-blocking mode.
731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		newtimeout = -1;
733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else {
734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Restore the timeout set when the device was opened.
736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (Note that this may be -1, in which case we're not
737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * really leaving non-blocking mode.)
738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		newtimeout = p->timeout;
740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "PacketSetReadTimeout: %s", pcap_win32strerror());
744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->nonblock = (newtimeout == -1);
747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Set the driver working mode */
751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setmode(pcap_t *p, int mode){
753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter==NULL)
755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file");
757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketSetMode(p->adapter,mode)==FALSE)
761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Set the dimension of the kernel-level capture buffer */
770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setbuff(pcap_t *p, int dim)
772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter==NULL)
774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file");
776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketSetBuff(p->adapter,dim)==FALSE)
780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*set the minimum amount of data that will release a read call*/
788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setmintocopy(pcap_t *p, int size)
790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter==NULL)
792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture");
794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketSetMinToCopy(p->adapter, size)==FALSE)
798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
804