1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
3965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Copyright (c) 2005 - 2010 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.
15d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 3. Neither the name of the Politecnico di Torino, CACE Technologies
16d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * nor the names of its contributors may be used to endorse or promote
17d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes * 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
34965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#define PCAP_DONT_INCLUDE_PCAP_BPF_H
35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <Packet32.h>
36965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#include <pcap-int.h>
37965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#include <pcap/dlt.h>
38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef __MINGW32__
39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef __MINGW64__
40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <ntddndis.h>
41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else  /*__MINGW64__*/
42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <ddk/ntddndis.h>
43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <ddk/ndis.h>
44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /*__MINGW64__*/
45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else /*__MINGW32__*/
46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <ntddndis.h>
47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /*__MINGW32__*/
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <dagnew.h>
50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <dagapi.h>
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __MINGW32__
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint* _errno();
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define errno (*_errno())
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* __MINGW32__ */
56965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef HAVE_REMOTE
57965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#include "pcap-rpcap.h"
58965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* HAVE_REMOTE */
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_getnonblock_win32(pcap_t *, char *);
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setnonblock_win32(pcap_t *, int, char *);
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*dimension of the buffer in the pcap_t structure*/
66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define	WIN32_DEFAULT_USER_BUFFER_SIZE 256000
67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*dimension of the buffer in the kernel driver NPF */
69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define	WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Equivalent to ntohs(), but a lot faster under Windows */
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Private data for capturing on WinPcap devices.
76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct pcap_win {
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int nonblock;
79965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int rfmon_selfstart;		/* a flag tells whether the monitor mode is set by itself */
80965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int filtering_in_kernel;	/* using kernel filter */
81d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_DAG_API
83965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int	dag_fcs_bits;		/* Number of checksum bits from link layer */
84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
87511eca30a483e912c274e1d8ba3a0f8f081e2227JP AbgrallBOOL WINAPI DllMain(
88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall  HANDLE hinstDLL,
89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall  DWORD dwReason,
90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall  LPVOID lpvReserved
91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall)
92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
93965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (TRUE);
94965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
95965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
96965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/*
97965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Define stub versions of the monitor-mode support routines if this
98965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * isn't Npcap. HAVE_NPCAP_PACKET_API is defined by Npcap but not
99965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * WinPcap.
100965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */
101965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifndef HAVE_NPCAP_PACKET_API
102965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
103965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott HughesPacketIsMonitorModeSupported(PCHAR AdapterName _U_)
104965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
105965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
106965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * We don't support monitor mode.
107965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
108965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
109965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
111965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
112965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott HughesPacketSetMonitorMode(PCHAR AdapterName _U_, int mode _U_)
113965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
114965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
115965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * This should never be called, as PacketIsMonitorModeSupported()
116965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * will return 0, meaning "we don't support monitor mode, so
117965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * don't try to turn it on or off".
118965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
119965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
122965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
123965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott HughesPacketGetMonitorMode(PCHAR AdapterName _U_)
124965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
125965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
126965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * This should fail, so that pcap_activate_win32() returns
127965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * PCAP_ERROR_RFMON_NOTSUP if our caller requested monitor
128965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * mode.
129965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
130965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (-1);
131965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
132965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif
133965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Start winsock */
135d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesint
136965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hugheswsockinit(void)
137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	WORD wVersionRequested;
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	WSADATA wsaData;
140d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	static int err = -1;
141d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	static int done = 0;
142d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
143d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	if (done)
144965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (err);
145d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
146d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	wVersionRequested = MAKEWORD( 1, 1);
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	err = WSAStartup( wVersionRequested, &wsaData );
148d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	atexit ((void(*)(void))WSACleanup);
149d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	done = 1;
150d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ( err != 0 )
152d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		err = -1;
153965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (err);
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
156965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesint
157965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_wsockinit(void)
158d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes{
159965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes       return (wsockinit());
160d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes}
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
165965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	struct bpf_stat bstats;
166965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char errbuf[PCAP_ERRBUF_SIZE+1];
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
168965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
169965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Try to get statistics.
170965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 *
171965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * (Please note - "struct pcap_stat" is *not* the same as
172965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * WinPcap's "struct bpf_stat". It might currently have the
173965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * same layout, but let's not cheat.
174965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 *
175965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Note also that we don't fill in ps_capt, as we might have
176965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * been called by code compiled against an earlier version of
177965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * WinPcap that didn't have ps_capt, in which case filling it
178965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * in would stomp on whatever comes after the structure passed
179965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * to us.
180965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
181965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!PacketGetStats(p->adapter, &bstats)) {
182965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), errbuf);
183965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
184965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "PacketGetStats error: %s", errbuf);
185965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
187965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	ps->ps_recv = bstats.bs_recv;
188965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	ps->ps_drop = bstats.bs_drop;
189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
190965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
191965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * XXX - PacketGetStats() doesn't fill this in, so we just
192965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * return 0.
193965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
194965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#if 0
195965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	ps->ps_ifdrop = bstats.ps_ifdrop;
196965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#else
197965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	ps->ps_ifdrop = 0;
198965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif
199965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
200965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
201965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
202965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
203965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/*
204965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * Win32-only routine for getting statistics.
205965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes *
206965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * This way is definitely safer than passing the pcap_stat * from the userland.
207965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * In fact, there could happen than the user allocates a variable which is not
208965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * big enough for the new structure, and the library will write in a zone
209965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * which is not allocated to this variable.
210965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes *
211965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * In this way, we're pretty sure we are writing on memory allocated to this
212965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * variable.
213965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes *
214965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * XXX - but this is the wrong way to handle statistics.  Instead, we should
215965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * have an API that returns data in a form like the Options section of a
216965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * pcapng Interface Statistics Block:
217965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes *
218965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes *    http://xml2rfc.tools.ietf.org/cgi-bin/xml2rfc.cgi?url=https://raw.githubusercontent.com/pcapng/pcapng/master/draft-tuexen-opsawg-pcapng.xml&modeAsFormat=html/ascii&type=ascii#rfc.section.4.6
219965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes *
220965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * which would let us add new statistics straightforwardly and indicate which
221965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * statistics we are and are *not* providing, rather than having to provide
222965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes * possibly-bogus values for statistics we can't provide.
223965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes */
224965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstruct pcap_stat *
225965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size)
226965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
227965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	struct bpf_stat bstats;
228965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char errbuf[PCAP_ERRBUF_SIZE+1];
229965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
230965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	*pcap_stat_size = sizeof (p->stat);
231965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
232965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
233965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Try to get statistics.
234965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 *
235965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * (Please note - "struct pcap_stat" is *not* the same as
236965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * WinPcap's "struct bpf_stat". It might currently have the
237965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * same layout, but let's not cheat.)
238965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
239965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!PacketGetStatsEx(p->adapter, &bstats)) {
240965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), errbuf);
241965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
242965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "PacketGetStatsEx error: %s", errbuf);
243965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (NULL);
244965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
245965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->stat.ps_recv = bstats.bs_recv;
246965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->stat.ps_drop = bstats.bs_drop;
247965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->stat.ps_ifdrop = bstats.ps_ifdrop;
248965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef HAVE_REMOTE
249965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->stat.ps_capt = bstats.bs_capt;
250965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif
251965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (&p->stat);
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* Set the dimension of the kernel-level capture buffer */
255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_setbuff_win32(pcap_t *p, int dim)
257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if(PacketSetBuff(p->adapter,dim)==FALSE)
259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	{
260965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
261965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
263965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* Set the driver working mode */
267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_setmode_win32(pcap_t *p, int mode)
269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if(PacketSetMode(p->adapter,mode)==FALSE)
271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	{
272965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
273965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
276965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*set the minimum amount of data that will release a read call*/
280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_setmintocopy_win32(pcap_t *p, int size)
282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if(PacketSetMinToCopy(p->adapter, size)==FALSE)
284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	{
285965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
286965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
287965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
288965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
289965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
290965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
291965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic HANDLE
292965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_getevent_win32(pcap_t *p)
293965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
294965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (PacketGetReadEvent(p->adapter));
295965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
296965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
297965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
298965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_oid_get_request_win32(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
299965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
300965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	PACKET_OID_DATA *oid_data_arg;
301965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char errbuf[PCAP_ERRBUF_SIZE+1];
302965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
303965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
304965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
305965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * It should be big enough to hold "*lenp" bytes of data; it
306965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * will actually be slightly larger, as PACKET_OID_DATA has a
307965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * 1-byte data array at the end, standing in for the variable-length
308965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * data that's actually there.
309965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
310965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
311965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (oid_data_arg == NULL) {
312965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
313965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Couldn't allocate argument buffer for PacketRequest");
314965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (PCAP_ERROR);
315965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
316965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
317965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
318965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * No need to copy the data - we're doing a fetch.
319965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
320965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	oid_data_arg->Oid = oid;
321965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	oid_data_arg->Length = (ULONG)(*lenp);	/* XXX - check for ridiculously large value? */
322965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!PacketRequest(p->adapter, FALSE, oid_data_arg)) {
323965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), errbuf);
324965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
325965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error calling PacketRequest: %s", errbuf);
326965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		free(oid_data_arg);
327965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (PCAP_ERROR);
328965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
329965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
330965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
331965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Get the length actually supplied.
332965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
333965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	*lenp = oid_data_arg->Length;
334965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
335965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
336965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Copy back the data we fetched.
337965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
338965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	memcpy(data, oid_data_arg->Data, *lenp);
339965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	free(oid_data_arg);
340965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
341965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
342965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
343965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
344965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_oid_set_request_win32(pcap_t *p, bpf_u_int32 oid, const void *data,
345965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes    size_t *lenp)
346965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
347965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	PACKET_OID_DATA *oid_data_arg;
348965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char errbuf[PCAP_ERRBUF_SIZE+1];
349965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
350965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
351965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Allocate a PACKET_OID_DATA structure to hand to PacketRequest().
352965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * It should be big enough to hold "*lenp" bytes of data; it
353965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * will actually be slightly larger, as PACKET_OID_DATA has a
354965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * 1-byte data array at the end, standing in for the variable-length
355965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * data that's actually there.
356965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
357965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	oid_data_arg = malloc(sizeof (PACKET_OID_DATA) + *lenp);
358965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (oid_data_arg == NULL) {
359965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
360965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Couldn't allocate argument buffer for PacketRequest");
361965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (PCAP_ERROR);
362965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
363965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
364965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	oid_data_arg->Oid = oid;
365965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	oid_data_arg->Length = (ULONG)(*lenp);	/* XXX - check for ridiculously large value? */
366965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	memcpy(oid_data_arg->Data, data, *lenp);
367965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!PacketRequest(p->adapter, TRUE, oid_data_arg)) {
368965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), errbuf);
369965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
370965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error calling PacketRequest: %s", errbuf);
371965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		free(oid_data_arg);
372965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (PCAP_ERROR);
373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
374965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
375965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
376965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Get the length actually copied.
377965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
378965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	*lenp = oid_data_arg->Length;
379965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
380965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
381965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * No need to copy the data - we're doing a set.
382965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
383965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	free(oid_data_arg);
384965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
387965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic u_int
388965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_sendqueue_transmit_win32(pcap_t *p, pcap_send_queue *queue, int sync)
389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
390965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	u_int res;
391965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char errbuf[PCAP_ERRBUF_SIZE+1];
392965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
393965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (p->adapter==NULL) {
394965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
395965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Cannot transmit a queue to an offline capture or to a TurboCap port");
396965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (0);
397965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
398965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
399965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	res = PacketSendPackets(p->adapter,
400965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		queue->buffer,
401965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		queue->len,
402965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		(BOOLEAN)sync);
403965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
404965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if(res != queue->len){
405965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), errbuf);
406965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
407965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error opening adapter: %s", errbuf);
408965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
409965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
410965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (res);
411965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
412965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
413965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
414965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_setuserbuffer_win32(pcap_t *p, int size)
415965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
416965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	unsigned char *new_buff;
417965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
418965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (size<=0) {
419965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/* Bogus parameter */
420965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
421965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error: invalid size %d",size);
422965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
423965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
424965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
425965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/* Allocate the buffer */
426965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	new_buff=(unsigned char*)malloc(sizeof(char)*size);
427965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
428965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!new_buff) {
429965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
430965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error: not enough memory");
431965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
432965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
433965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
434965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	free(p->buffer);
435965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
436965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->buffer=new_buff;
437965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->bufsize=size;
438965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
439965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
440965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
442965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
443965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_live_dump_win32(pcap_t *p, char *filename, int maxsize, int maxpacks)
444965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
445965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	BOOLEAN res;
446965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
447965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/* Set the packet driver in dump mode */
448965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	res = PacketSetMode(p->adapter, PACKET_MODE_DUMP);
449965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if(res == FALSE){
450965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
451965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error setting dump mode");
452965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
453965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
454965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
455965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/* Set the name of the dump file */
456965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	res = PacketSetDumpName(p->adapter, filename, (int)strlen(filename));
457965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if(res == FALSE){
458965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
459965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error setting kernel dump file name");
460965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
461965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
462965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
463965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/* Set the limits of the dump file */
464965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	res = PacketSetDumpLimits(p->adapter, maxsize, maxpacks);
465965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
466965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (0);
467965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
468965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
469965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
470965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_live_dump_ended_win32(pcap_t *p, int sync)
471965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
472965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (PacketIsDumpEnded(p->adapter, (BOOLEAN)sync));
473965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
474965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
475965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic PAirpcapHandle
476965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_get_airpcap_handle_win32(pcap_t *p)
477965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
478965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef HAVE_AIRPCAP_API
479965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (PacketGetAirPcapHandle(p->adapter));
480965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#else
481965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (NULL);
482965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* HAVE_AIRPCAP_API */
483511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
484511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
488965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	PACKET Packet;
489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int cc;
490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n = 0;
491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register u_char *bp, *ep;
492d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	u_char *datap;
493d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	struct pcap_win *pw = p->priv;
494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	cc = p->cc;
496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->cc == 0) {
497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->break_loop) {
501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Yes - clear the flag that indicates that it
503d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			 * has, and return PCAP_ERROR_BREAK to indicate
504d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			 * that we were told to break out of the loop.
505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->break_loop = 0;
507d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			return (PCAP_ERROR_BREAK);
508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
510965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
511965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Capture the packets.
512965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 *
513965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * The PACKET structure had a bunch of extra stuff for
514965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Windows 9x/Me, but the only interesting data in it
515965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * in the versions of Windows that we support is just
516965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * a copy of p->buffer, a copy of p->buflen, and the
517965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * actual number of bytes read returned from
518965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * PacketReceivePacket(), none of which has to be
519965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * retained from call to call, so we just keep one on
520965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * the stack.
521965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
522965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (!PacketReceivePacket(p->adapter, &Packet, TRUE)) {
524965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
525d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			return (PCAP_ERROR);
526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
527d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
528965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		cc = Packet.ulBytesReceived;
529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
530965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		bp = p->buffer;
531d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	}
532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		bp = p->bp;
534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Loop through each packet.
537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define bhp ((struct bpf_hdr *)bp)
539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ep = bp + cc;
540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (1) {
541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		register int caplen, hdrlen;
542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If so, return immediately - if we haven't read any
546d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * packets, clear the flag and return PCAP_ERROR_BREAK
547d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * to indicate that we were told to break out of the loop,
548d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * otherwise leave the flag set, so that the *next* call
549d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * will break out of the loop without having read any
550d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * packets, and return the number of packets we've
551d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * processed so far.
552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->break_loop) {
554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (n == 0) {
555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->break_loop = 0;
556d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes				return (PCAP_ERROR_BREAK);
557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else {
558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->bp = bp;
559965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				p->cc = (int) (ep - bp);
560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return (n);
561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (bp >= ep)
564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		caplen = bhp->bh_caplen;
567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		hdrlen = bhp->bh_hdrlen;
568d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		datap = bp + hdrlen;
569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
571d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * Short-circuit evaluation: if using BPF filter
572d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * in kernel, no need to do it now - we already know
573d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * the packet passed the filter.
574d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
575d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * XXX - bpf_filter() should always return TRUE if
576d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * handed a null pointer for the program, but it might
577d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * just try to "run" the filter, so we check here.
578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
579d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		if (pw->filtering_in_kernel ||
580d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		    p->fcode.bf_insns == NULL ||
581d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		    bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
582d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			/*
583d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			 * XXX A bpf_hdr matches a pcap_pkthdr.
584d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			 */
585d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			(*callback)(user, (struct pcap_pkthdr*)bp, datap);
586d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			bp += Packet_WORDALIGN(caplen + hdrlen);
587d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) {
588d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes				p->bp = bp;
589965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				p->cc = (int) (ep - bp);
590d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes				return (n);
591d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			}
592d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		} else {
593d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			/*
594d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			 * Skip this packet.
595d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			 */
596d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			bp += Packet_WORDALIGN(caplen + hdrlen);
597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#undef bhp
600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->cc = 0;
601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (n);
602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
608511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_win *pw = p->priv;
609965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	PACKET Packet;
610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_char *dp = NULL;
611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int	packet_len = 0, caplen = 0;
612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct pcap_pkthdr	pcap_header;
613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	u_char *endofbuf;
614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n = 0;
615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	dag_record_t *header;
616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned erf_record_len;
617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ULONGLONG ts;
618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int cc;
619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned swt;
620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned dfp = p->adapter->DagFastProcess;
621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	cc = p->cc;
623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
625965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
626965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Get new packets from the network.
627965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 *
628965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * The PACKET structure had a bunch of extra stuff for
629965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Windows 9x/Me, but the only interesting data in it
630965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * in the versions of Windows that we support is just
631965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * a copy of p->buffer, a copy of p->buflen, and the
632965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * actual number of bytes read returned from
633965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * PacketReceivePacket(), none of which has to be
634965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * retained from call to call, so we just keep one on
635965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * the stack.
636965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
637965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
638965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (!PacketReceivePacket(p->adapter, &Packet, TRUE)) {
639965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (-1);
641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
643965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		cc = Packet.ulBytesReceived;
644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(cc == 0)
645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* The timeout has expired but we no packets arrived */
646965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			return (0);
647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		header = (dag_record_t*)p->adapter->DagBuffer;
648d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	}
649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		header = (dag_record_t*)p->bp;
651d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	endofbuf = (char*)header + cc;
653d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
654d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	/*
655d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	 * Cycle through the packets
656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	do
658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		erf_record_len = SWAPS(header->rlen);
660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if((char*)header + erf_record_len > endofbuf)
661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Increase the number of captured packets */
664965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		p->stat.ps_recv++;
665d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Find the beginning of the packet */
667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		dp = ((u_char *)header) + dag_record_size;
668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Determine actual packet len */
670d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		switch(header->type)
671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ATM:
673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len = ATM_SNAPLEN;
674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = ATM_SNAPLEN;
675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dp += 4;
676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ETH:
680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			swt = SWAPS(header->wlen);
681511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			packet_len = swt - (pw->dag_fcs_bits);
682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = erf_record_len - dag_record_size - 2;
683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (caplen > packet_len)
684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len;
686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dp += 2;
688d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
690d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_HDLC_POS:
692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			swt = SWAPS(header->wlen);
693511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			packet_len = swt - (pw->dag_fcs_bits);
694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = erf_record_len - dag_record_size;
695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (caplen > packet_len)
696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len;
698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
699d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
702d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(caplen > p->snapshot)
704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = p->snapshot;
705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If so, return immediately - if we haven't read any
709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * packets, clear the flag and return -2 to indicate
710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * that we were told to break out of the loop, otherwise
711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * leave the flag set, so that the *next* call will break
712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * out of the loop without having read any packets, and
713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * return the number of packets we've processed so far.
714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
715d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		if (p->break_loop)
716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
717d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			if (n == 0)
718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->break_loop = 0;
720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return (-2);
721d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			}
722d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			else
723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->bp = (char*)header;
725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->cc = endofbuf - (char*)header;
726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return (n);
727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(!dfp)
731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* convert between timestamp formats */
733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts = header->ts;
734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.ts.tv_sec = (int)(ts >> 32);
735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts = (ts & 0xffffffffi64) * 1000000;
736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts += 0x80000000; /* rounding */
737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.ts.tv_usec = (int)(ts >> 32);
738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (pcap_header.ts.tv_usec >= 1000000) {
739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				pcap_header.ts.tv_usec -= 1000000;
740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				pcap_header.ts.tv_sec++;
741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
743d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* No underlaying filtering system. We need to filter on our own */
745d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		if (p->fcode.bf_insns)
746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
747d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* Move to next packet */
750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				header = (dag_record_t*)((char*)header + erf_record_len);
751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				continue;
752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
754d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Fill the header for the user suppplied callback function */
756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		pcap_header.caplen = caplen;
757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		pcap_header.len = packet_len;
758d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Call the callback function */
760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(*callback)(user, &pcap_header, dp);
761d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Move to next packet */
763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		header = (dag_record_t*)((char*)header + erf_record_len);
764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Stop if the number of packets requested by user has been reached*/
766d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->bp = (char*)header;
769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->cc = endofbuf - (char*)header;
770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (n);
771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while((u_char*)header < endofbuf);
774d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
775965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (1);
776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Send a packet to the network */
780d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic int
781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_win32(pcap_t *p, const void *buf, size_t size){
782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	LPPACKET PacketToSend;
783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PacketToSend=PacketAllocatePacket();
785d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (PacketToSend == NULL)
787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
788965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");
789965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
791d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
792965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	PacketInitPacket(PacketToSend, (PVOID)buf, (UINT)size);
793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
794965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		PacketFreePacket(PacketToSend);
796965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	PacketFreePacket(PacketToSend);
800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * We assume it all got sent if "PacketSendPacket()" succeeded.
803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * "pcap_inject()" is expected to return the number of bytes
804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * sent.
805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
806965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return ((int)size);
807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
810511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_cleanup_win32(pcap_t *p)
811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
812965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	struct pcap_win *pw = p->priv;
813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter != NULL) {
814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		PacketCloseAdapter(p->adapter);
815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->adapter = NULL;
816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
817965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (pw->rfmon_selfstart)
818965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	{
819965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		PacketSetMonitorMode(p->opt.device, 0);
820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
821511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_cleanup_live_common(p);
822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
824511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
825511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_activate_win32(pcap_t *p)
826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
827511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_win *pw = p->priv;
828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	NetType type;
829965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int res;
830965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char errbuf[PCAP_ERRBUF_SIZE+1];
831965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
832965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef HAVE_REMOTE
833965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char host[PCAP_BUF_SIZE + 1];
834965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char port[PCAP_BUF_SIZE + 1];
835965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char name[PCAP_BUF_SIZE + 1];
836965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int srctype;
837965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int opensource_remote_result;
838965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
839965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	struct pcap_md *md;				/* structure used when doing a remote live capture */
840965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	md = (struct pcap_md *) ((u_char*)p->priv + sizeof(struct pcap_win));
841965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
842965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
843965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	Retrofit; we have to make older applications compatible with the remote capture
844965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	So, we're calling the pcap_open_remote() from here, that is a very dirty thing.
845965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	Obviously, we cannot exploit all the new features; for instance, we cannot
846965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	send authentication, we cannot use a UDP data connection, and so on.
847965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	*/
848965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (pcap_parsesrcstr(p->opt.device, &srctype, host, port, name, p->errbuf))
849965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return PCAP_ERROR;
850965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
851965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (srctype == PCAP_SRC_IFREMOTE)
852965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	{
853965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		opensource_remote_result = pcap_opensource_remote(p, NULL);
854965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
855965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (opensource_remote_result != 0)
856965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			return opensource_remote_result;
857965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
858965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		md->rmt_flags = (p->opt.promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0;
859965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
860965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return 0;
861965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
862965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
863965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (srctype == PCAP_SRC_IFLOCAL)
864965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	{
865965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
866965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		* If it starts with rpcap://, cut down the string
867965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		*/
868965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (strncmp(p->opt.device, PCAP_SRC_IF_STRING, strlen(PCAP_SRC_IF_STRING)) == 0)
869965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		{
870965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			size_t len = strlen(p->opt.device) - strlen(PCAP_SRC_IF_STRING) + 1;
871965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			char *new_string;
872965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			/*
873965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			* allocate a new string and free the old one
874965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			*/
875965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			if (len > 0)
876965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			{
877965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				new_string = (char*)malloc(len);
878965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				if (new_string != NULL)
879965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				{
880965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes					char *tmp;
881965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes					strcpy_s(new_string, len, p->opt.device + strlen(PCAP_SRC_IF_STRING));
882965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes					tmp = p->opt.device;
883965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes					p->opt.device = new_string;
884965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes					free(tmp);
885965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				}
886965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			}
887965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
888965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
889965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
890965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif	/* HAVE_REMOTE */
891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
892511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p->opt.rfmon) {
893511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
894965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Monitor mode is supported on Windows Vista and later.
895511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
896965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (PacketGetMonitorMode(p->opt.device) == 1)
897965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		{
898965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pw->rfmon_selfstart = 0;
899965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
900965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		else
901965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		{
902965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			if ((res = PacketSetMonitorMode(p->opt.device, 1)) != 1)
903965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			{
904965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				pw->rfmon_selfstart = 0;
905965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				// Monitor mode is not supported.
906965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				if (res == 0)
907965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				{
908965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes					return PCAP_ERROR_RFMON_NOTSUP;
909965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				}
910965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				else
911965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				{
912965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes					return PCAP_ERROR;
913965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				}
914965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			}
915965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			else
916965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			{
917965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				pw->rfmon_selfstart = 1;
918965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			}
919965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
920511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
921511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Init WinSock */
923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	wsockinit();
924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
925965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->adapter = PacketOpenAdapter(p->opt.device);
926d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->adapter == NULL)
928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Adapter detected but we are not able to open it. Return failure. */
930965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), errbuf);
931965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (pw->rfmon_selfstart)
932965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		{
933965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			PacketSetMonitorMode(p->opt.device, 0);
934965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
935965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
936965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Error opening adapter: %s", errbuf);
937965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (PCAP_ERROR);
938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
939d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*get network type*/
941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketGetNetType (p->adapter,&type) == FALSE)
942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
943965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), errbuf);
944965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
945965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "Cannot determine the network type: %s", errbuf);
946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto bad;
947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
948d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*Set the linktype*/
950d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	switch (type.LinkType)
951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumWan:
953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_EN10MB;
954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
955d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMedium802_3:
957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_EN10MB;
958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * This is (presumably) a real Ethernet capture; give it a
960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * that an application can let you choose it, in case you're
962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * capturing DOCSIS traffic that a Cisco Cable Modem
963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Termination System is putting out onto an Ethernet (it
964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * doesn't put an Ethernet header onto the wire, it puts raw
965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * DOCSIS frames out on the wire inside the low-level
966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Ethernet framing).
967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If that fails, just leave the list empty.
971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->dlt_list != NULL) {
973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->dlt_list[0] = DLT_EN10MB;
974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->dlt_list[1] = DLT_DOCSIS;
975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->dlt_count = 2;
976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
978d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumFddi:
980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_FDDI;
981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
982d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
983d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	case NdisMedium802_5:
984d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		p->linktype = DLT_IEEE802;
985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
986d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumArcnetRaw:
988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_ARCNET;
989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
990d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumArcnet878_2:
992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_ARCNET;
993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
994d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumAtm:
996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_ATM_RFC1483;
997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
998d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumCHDLC:
1000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_CHDLC;
1001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumPPPSerial:
1004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_PPP_SERIAL;
1005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumNull:
1008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_NULL;
1009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumBare80211:
1012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_IEEE802_11;
1013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumRadio80211:
1016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_IEEE802_11_RADIO;
1017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	case NdisMediumPpi:
1020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_PPI;
1021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	default:
1024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->linktype = DLT_EN10MB;			/*an unknown adapter is assumed to be ethernet*/
1025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		break;
1026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Set promiscuous mode */
1029d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	if (p->opt.promisc)
1030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
1033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
1034965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
1035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
1036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
1037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1038d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	else
1039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
1041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
1042965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
1043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
1044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
1045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Set the buffer size */
1048511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
1049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
1051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1052d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	/*
1053d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	 * Traditional Adapter
1054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
1055511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
1056511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * If the buffer size wasn't explicitly set, default to
1057965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * WIN32_DEFAULT_KERNEL_BUFFER_SIZE.
1058511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
1059511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 	if (p->opt.buffer_size == 0)
1060511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	 		p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
1061511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1062511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
1063511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		{
1064965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
1065511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			goto bad;
1066511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
1067d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1068965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		p->buffer = malloc(p->bufsize);
1069d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		if (p->buffer == NULL)
1070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
1071965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
1072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto bad;
1073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
1074d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1075d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		if (p->opt.immediate)
1076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
1077511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* tell the driver to copy the buffer as soon as data arrives */
1078511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if(PacketSetMinToCopy(p->adapter,0)==FALSE)
1079511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			{
1080965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				pcap_win32_err_to_str(GetLastError(), errbuf);
1081965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1082965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				    "Error calling PacketSetMinToCopy: %s",
1083965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				    errbuf);
1084511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				goto bad;
1085511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
1087511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		else
1088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
1089511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* tell the driver to copy the buffer only if it contains at least 16K */
1090511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
1091511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			{
1092965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				pcap_win32_err_to_str(GetLastError(), errbuf);
1093965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1094965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				    "Error calling PacketSetMinToCopy: %s",
1095965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes				    errbuf);
1096511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				goto bad;
1097511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
1098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
1099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
1101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
1102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1103d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	/*
1104d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	 * Dag Card
1105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
1106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		LONG	status;
1107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		HKEY	dagkey;
1108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		DWORD	lptype;
1109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		DWORD	lpcbdata;
1110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		int		postype = 0;
1111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		char	keyname[512];
1112d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1113965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
1114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			"SYSTEM\\CurrentControlSet\\Services\\DAG",
1115965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			strstr(_strlwr(p->opt.device), "dag"));
1116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		do
1117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
1118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
1119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(status != ERROR_SUCCESS)
1120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				break;
1121d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			status = RegQueryValueEx(dagkey,
1123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				"PosType",
1124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				NULL,
1125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				&lptype,
1126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				(char*)&postype,
1127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				&lpcbdata);
1128d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(status != ERROR_SUCCESS)
1130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
1131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				postype = 0;
1132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
1133d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			RegCloseKey(dagkey);
1135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
1136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		while(FALSE);
1137d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1138d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->snapshot = PacketSetSnapLen(p->adapter, snaplen);
1140d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1141d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		/* Set the length of the FCS associated to any packet. This value
1142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * will be subtracted to the packet length */
1143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		pw->dag_fcs_bits = p->adapter->DagFcsLen;
1144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
1146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	goto bad;
1147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
1148d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	PacketSetReadTimeout(p->adapter, p->opt.timeout);
1150d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
1152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
1153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* install dag specific handlers for read and setfilter */
1155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->read_op = pcap_read_win32_dag;
1156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->setfilter_op = pcap_setfilter_win32_dag;
1157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	else
1159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
1161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* install traditional npf handlers for read and setfilter */
1162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->read_op = pcap_read_win32_npf;
1163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->setfilter_op = pcap_setfilter_win32_npf;
1164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_API
1165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_API */
1167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->setdirection_op = NULL;	/* Not implemented. */
1168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    /* XXX - can this be implemented on some versions of Windows? */
1169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->inject_op = pcap_inject_win32;
1170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->set_datalink_op = NULL;	/* can't change data link type */
1171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->getnonblock_op = pcap_getnonblock_win32;
1172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->setnonblock_op = pcap_setnonblock_win32;
1173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->stats_op = pcap_stats_win32;
1174965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->stats_ex_op = pcap_stats_ex_win32;
1175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->setbuff_op = pcap_setbuff_win32;
1176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->setmode_op = pcap_setmode_win32;
1177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->setmintocopy_op = pcap_setmintocopy_win32;
1178965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->getevent_op = pcap_getevent_win32;
1179965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->oid_get_request_op = pcap_oid_get_request_win32;
1180965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->oid_set_request_op = pcap_oid_set_request_win32;
1181965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->sendqueue_transmit_op = pcap_sendqueue_transmit_win32;
1182965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->setuserbuffer_op = pcap_setuserbuffer_win32;
1183965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->live_dump_op = pcap_live_dump_win32;
1184965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->live_dump_ended_op = pcap_live_dump_ended_win32;
1185965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->get_airpcap_handle_op = pcap_get_airpcap_handle_win32;
1186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->cleanup_op = pcap_cleanup_win32;
1187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (0);
1189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectbad:
1190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_cleanup_win32(p);
1191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (PCAP_ERROR);
1192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1194965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes/*
1195965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes* Check if rfmon mode is supported on the pcap_t for Windows systems.
1196965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes*/
1197965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
1198965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_can_set_rfmon_win32(pcap_t *p)
1199965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
1200965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (PacketIsMonitorModeSupported(p->opt.device) == 1);
1201965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
1202965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_t *
1204965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_create_interface(const char *device _U_, char *ebuf)
1205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
1206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_t *p;
1207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1208965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef HAVE_REMOTE
1209965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p = pcap_create_common(ebuf, sizeof(struct pcap_win) + sizeof(struct pcap_md));
1210965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#else
1211965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p = pcap_create_common(ebuf, sizeof(struct pcap_win));
1212965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif /* HAVE_REMOTE */
1213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p == NULL)
1214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
1215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->activate_op = pcap_activate_win32;
1217965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	p->can_set_rfmon_op = pcap_can_set_rfmon_win32;
1218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (p);
1219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
1220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
1222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
1223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1224d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	struct pcap_win *pw = p->priv;
1225d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(PacketSetBpf(p->adapter,fp)==FALSE){
1227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Kernel filter not installed.
1229d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
1230d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * XXX - we don't know whether this failed because:
1231d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
1232d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  the kernel rejected the filter program as invalid,
1233d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  in which case we should fall back on userland
1234d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  filtering;
1235d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
1236d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  the kernel rejected the filter program as too big,
1237d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  in which case we should again fall back on
1238d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  userland filtering;
1239d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
1240d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  there was some other problem, in which case we
1241d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *  should probably report an error.
1242d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
1243d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * For NPF devices, the Win32 status will be
1244d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * STATUS_INVALID_DEVICE_REQUEST for invalid
1245d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * filters, but I don't know what it'd be for
1246d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * other problems, and for some other devices
1247d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * it might not be set at all.
1248d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
1249d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * So we just fall back on userland filtering in
1250d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * all cases.
1251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1252d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1253d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		/*
1254d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * install_bpf_program() validates the program.
1255d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 *
1256d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * XXX - what if we already have a filter in the kernel?
1257d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 */
1258d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		if (install_bpf_program(p, fp) < 0)
1259d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes			return (-1);
1260d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		pw->filtering_in_kernel = 0;	/* filtering in userland */
1261d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		return (0);
1262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
1265d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	 * It worked.
1266d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	 */
1267d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	pw->filtering_in_kernel = 1;	/* filtering in the kernel */
1268d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1269d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	/*
1270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Discard any previously-received packets, as they might have
1271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * passed whatever filter was formerly in effect, but might
1272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * not pass this filter (BIOCSETF discards packets buffered
1273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * in the kernel, so you can lose packets in any case).
1274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
1275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->cc = 0;
1276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
1277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We filter at user level, since the kernel driver does't process the packets
1281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1282d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughesstatic int
1283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
1284d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1285d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	if(!fp)
1286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1287965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		strlcpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
1288965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
1289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1290d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Install a user level filter */
1292d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes	if (install_bpf_program(p, fp) < 0)
1293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
1294965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(p->errbuf, sizeof(p->errbuf),
1295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			"setfilter, unable to install the filter: %s", pcap_strerror(errno));
1296965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
1297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1298d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes
1299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
1300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
1303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_getnonblock_win32(pcap_t *p, char *errbuf)
1304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_win *pw = p->priv;
1306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
1307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
1308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * XXX - if there were a PacketGetReadTimeout() call, we
1309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * would use it, and return 1 if the timeout is -1
1310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * and 0 otherwise.
1311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
1312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (pw->nonblock);
1313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
1316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
1317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_win *pw = p->priv;
1319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int newtimeout;
1320965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char win_errbuf[PCAP_ERRBUF_SIZE+1];
1321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (nonblock) {
1323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Set the read timeout to -1 for non-blocking mode.
1325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		newtimeout = -1;
1327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else {
1328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
1329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Restore the timeout set when the device was opened.
1330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * (Note that this may be -1, in which case we're not
1331965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * really leaving non-blocking mode.  However, although
1332965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * the timeout argument to pcap_set_timeout() and
1333965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * pcap_open_live() is an int, you're not supposed to
1334965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * supply a negative value, so that "shouldn't happen".)
1335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
1336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		newtimeout = p->opt.timeout;
1337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
1339965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), win_errbuf);
1340965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
1341965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    "PacketSetReadTimeout: %s", win_errbuf);
1342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
1343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pw->nonblock = (newtimeout == -1);
1345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
1346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1348965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughesstatic int
1349965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughespcap_add_if_win32(pcap_if_t **devlist, char *name, bpf_u_int32 flags,
1350965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes    const char *description, char *errbuf)
1351965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes{
1352965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	pcap_if_t *curdev;
1353965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
1354965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	LONG if_addr_size;
1355965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int res = 0;
1356965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1357965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if_addr_size = MAX_NETWORK_ADDRESSES;
1358965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1359965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
1360965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Add an entry for this interface, with no addresses.
1361965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
1362965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (add_or_find_if(&curdev, devlist, name, flags, description,
1363965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	    errbuf) == -1) {
1364965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
1365965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Failure.
1366965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
1367965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
1368965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1369965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1370965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
1371965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Get the list of addresses for the interface.
1372965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
1373965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) {
1374965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
1375965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Failure.
1376965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 *
1377965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * We don't return an error, because this can happen with
1378965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * NdisWan interfaces, and we want to supply them even
1379965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * if we can't supply their addresses.
1380965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 *
1381965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * We return an entry with an empty address list.
1382965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
1383965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (0);
1384965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1385965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1386965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
1387965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Now add the addresses.
1388965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
1389965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	while (if_addr_size-- > 0) {
1390965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
1391965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * "curdev" is an entry for this interface; add an entry for
1392965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * this address to its list of addresses.
1393965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
1394965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if(curdev == NULL)
1395965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			break;
1396965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		res = add_addr_to_dev(curdev,
1397965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    (struct sockaddr *)&if_addrs[if_addr_size].IPAddress,
1398965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    sizeof (struct sockaddr_storage),
1399965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask,
1400965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    sizeof (struct sockaddr_storage),
1401965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    (struct sockaddr *)&if_addrs[if_addr_size].Broadcast,
1402965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    sizeof (struct sockaddr_storage),
1403965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    NULL,
1404965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    0,
1405965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    errbuf);
1406965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (res == -1) {
1407965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			/*
1408965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			 * Failure.
1409965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			 */
1410965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			break;
1411965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
1412965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1413965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1414965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (res);
1415965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes}
1416965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint
1418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
1419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1420965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	pcap_if_t *devlist = NULL;
1421965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	int ret = 0;
1422965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	const char *desc;
1423965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char *AdaptersName;
1424965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	ULONG NameLength;
1425965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char *name;
1426965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	char our_errbuf[PCAP_ERRBUF_SIZE+1];
1427965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1428965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
1429965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Find out how big a buffer we need.
1430965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 *
1431965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * This call should always return FALSE; if the error is
1432965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
1433965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * the size of the buffer we need, otherwise there's a
1434965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * problem, and NameLength should be set to 0.
1435965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 *
1436965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * It shouldn't require NameLength to be set, but,
1437965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * at least as of WinPcap 4.1.3, it checks whether
1438965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * NameLength is big enough before it checks for a
1439965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * NULL buffer argument, so, while it'll still do
1440965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * the right thing if NameLength is uninitialized and
1441965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * whatever junk happens to be there is big enough
1442965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * (because the pointer argument will be null), it's
1443965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * still reading an uninitialized variable.
1444965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
1445965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	NameLength = 0;
1446965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!PacketGetAdapterNames(NULL, &NameLength))
1447965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	{
1448965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		DWORD last_error = GetLastError();
1449965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1450965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (last_error != ERROR_INSUFFICIENT_BUFFER)
1451965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		{
1452965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_win32_err_to_str(last_error, our_errbuf);
1453965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
1454965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			    "PacketGetAdapterNames: %s", our_errbuf);
1455965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			return (-1);
1456965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
1457965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1458965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1459965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (NameLength > 0)
1460965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		AdaptersName = (char*) malloc(NameLength);
1461965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	else
1462965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	{
1463965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		*alldevsp = NULL;
1464965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return 0;
1465965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1466965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (AdaptersName == NULL)
1467965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	{
1468965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
1469965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
1470965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1471965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1472965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
1473965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_win32_err_to_str(GetLastError(), our_errbuf);
1474965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames: %s",
1475965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    our_errbuf);
1476965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		free(AdaptersName);
1477965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		return (-1);
1478965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1479965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1480965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
1481965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * "PacketGetAdapterNames()" returned a list of
1482965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * null-terminated ASCII interface name strings,
1483965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * terminated by a null string, followed by a list
1484965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * of null-terminated ASCII interface description
1485965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * strings, terminated by a null string.
1486965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * This means there are two ASCII nulls at the end
1487965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * of the first list.
1488965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 *
1489965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Find the end of the first list; that's the
1490965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * beginning of the second list.
1491965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
1492965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	desc = &AdaptersName[0];
1493965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	while (*desc != '\0' || *(desc + 1) != '\0')
1494965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		desc++;
1495965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1496965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
1497965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 	 * Found it - "desc" points to the first of the two
1498965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * nulls at the end of the list of names, so the
1499965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * first byte of the list of descriptions is two bytes
1500965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * after it.
1501965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
1502965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	desc += 2;
1503965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1504965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	/*
1505965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 * Loop over the elements in the first list.
1506965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	 */
1507965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	name = &AdaptersName[0];
1508965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	while (*name != '\0') {
1509965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		bpf_u_int32 flags = 0;
1510965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef HAVE_PACKET_IS_LOOPBACK_ADAPTER
1511965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
1512965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Is this a loopback interface?
1513965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
1514965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (PacketIsLoopbackAdapter(name)) {
1515965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			/* Yes */
1516965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			flags |= PCAP_IF_LOOPBACK;
1517965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
1518965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif
1519965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1520965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
1521965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * Add an entry for this interface.
1522965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
1523965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (pcap_add_if_win32(&devlist, name, flags, desc,
1524965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		    errbuf) == -1) {
1525965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			/*
1526965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			 * Failure.
1527965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			 */
1528965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			ret = -1;
1529965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			break;
1530965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
1531965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		name += strlen(name) + 1;
1532965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		desc += strlen(desc) + 1;
1533965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1534965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1535965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	if (ret == -1) {
1536965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		/*
1537965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 * We had an error; free the list we've been constructing.
1538965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		 */
1539965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		if (devlist != NULL) {
1540965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			pcap_freealldevs(devlist);
1541965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes			devlist = NULL;
1542965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes		}
1543965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	}
1544965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes
1545965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	*alldevsp = devlist;
1546965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	free(AdaptersName);
1547965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes	return (ret);
1548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1549