xref: /aosp_15_r20/external/libpcap/testprogs/valgrindtest.c (revision 8b26181f966a6af5cf6981a6f474313de533bb28)
1*8b26181fSAndroid Build Coastguard Worker /*
2*8b26181fSAndroid Build Coastguard Worker  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3*8b26181fSAndroid Build Coastguard Worker  *	The Regents of the University of California.  All rights reserved.
4*8b26181fSAndroid Build Coastguard Worker  *
5*8b26181fSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*8b26181fSAndroid Build Coastguard Worker  * modification, are permitted provided that: (1) source code distributions
7*8b26181fSAndroid Build Coastguard Worker  * retain the above copyright notice and this paragraph in its entirety, (2)
8*8b26181fSAndroid Build Coastguard Worker  * distributions including binary code include the above copyright notice and
9*8b26181fSAndroid Build Coastguard Worker  * this paragraph in its entirety in the documentation or other materials
10*8b26181fSAndroid Build Coastguard Worker  * provided with the distribution, and (3) all advertising materials mentioning
11*8b26181fSAndroid Build Coastguard Worker  * features or use of this software display the following acknowledgement:
12*8b26181fSAndroid Build Coastguard Worker  * ``This product includes software developed by the University of California,
13*8b26181fSAndroid Build Coastguard Worker  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*8b26181fSAndroid Build Coastguard Worker  * the University nor the names of its contributors may be used to endorse
15*8b26181fSAndroid Build Coastguard Worker  * or promote products derived from this software without specific prior
16*8b26181fSAndroid Build Coastguard Worker  * written permission.
17*8b26181fSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*8b26181fSAndroid Build Coastguard Worker  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*8b26181fSAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*8b26181fSAndroid Build Coastguard Worker  */
21*8b26181fSAndroid Build Coastguard Worker 
22*8b26181fSAndroid Build Coastguard Worker #include "varattrs.h"
23*8b26181fSAndroid Build Coastguard Worker 
24*8b26181fSAndroid Build Coastguard Worker /*
25*8b26181fSAndroid Build Coastguard Worker  * This doesn't actually test libpcap itself; it tests whether
26*8b26181fSAndroid Build Coastguard Worker  * valgrind properly handles the APIs libpcap uses.  If it doesn't,
27*8b26181fSAndroid Build Coastguard Worker  * we end up getting patches submitted to "fix" references that
28*8b26181fSAndroid Build Coastguard Worker  * valgrind claims are being made to uninitialized data, when, in
29*8b26181fSAndroid Build Coastguard Worker  * fact, the OS isn't making any such references - or we get
30*8b26181fSAndroid Build Coastguard Worker  * valgrind *not* detecting *actual* incorrect references.
31*8b26181fSAndroid Build Coastguard Worker  *
32*8b26181fSAndroid Build Coastguard Worker  * Both BPF and Linux socket filters aren't handled correctly
33*8b26181fSAndroid Build Coastguard Worker  * by some versions of valgrind.  See valgrind bug 318203 for
34*8b26181fSAndroid Build Coastguard Worker  * Linux:
35*8b26181fSAndroid Build Coastguard Worker  *
36*8b26181fSAndroid Build Coastguard Worker  *	https://bugs.kde.org/show_bug.cgi?id=318203
37*8b26181fSAndroid Build Coastguard Worker  *
38*8b26181fSAndroid Build Coastguard Worker  * and valgrind bug 312989 for macOS:
39*8b26181fSAndroid Build Coastguard Worker  *
40*8b26181fSAndroid Build Coastguard Worker  *	https://bugs.kde.org/show_bug.cgi?id=312989
41*8b26181fSAndroid Build Coastguard Worker  *
42*8b26181fSAndroid Build Coastguard Worker  * The fixes for both of those are checked into the official valgrind
43*8b26181fSAndroid Build Coastguard Worker  * repository.
44*8b26181fSAndroid Build Coastguard Worker  *
45*8b26181fSAndroid Build Coastguard Worker  * The unofficial FreeBSD port has similar issues to the official macOS
46*8b26181fSAndroid Build Coastguard Worker  * port, for similar reasons.
47*8b26181fSAndroid Build Coastguard Worker  */
48*8b26181fSAndroid Build Coastguard Worker #ifndef lint
49*8b26181fSAndroid Build Coastguard Worker static const char copyright[] _U_ =
50*8b26181fSAndroid Build Coastguard Worker     "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
51*8b26181fSAndroid Build Coastguard Worker The Regents of the University of California.  All rights reserved.\n";
52*8b26181fSAndroid Build Coastguard Worker #endif
53*8b26181fSAndroid Build Coastguard Worker 
54*8b26181fSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
55*8b26181fSAndroid Build Coastguard Worker #include <config.h>
56*8b26181fSAndroid Build Coastguard Worker #endif
57*8b26181fSAndroid Build Coastguard Worker 
58*8b26181fSAndroid Build Coastguard Worker #include <stdio.h>
59*8b26181fSAndroid Build Coastguard Worker #include <stdlib.h>
60*8b26181fSAndroid Build Coastguard Worker #include <string.h>
61*8b26181fSAndroid Build Coastguard Worker #include <stdarg.h>
62*8b26181fSAndroid Build Coastguard Worker #include <limits.h>
63*8b26181fSAndroid Build Coastguard Worker #include <unistd.h>
64*8b26181fSAndroid Build Coastguard Worker #include <fcntl.h>
65*8b26181fSAndroid Build Coastguard Worker #include <errno.h>
66*8b26181fSAndroid Build Coastguard Worker #include <arpa/inet.h>
67*8b26181fSAndroid Build Coastguard Worker #include <sys/types.h>
68*8b26181fSAndroid Build Coastguard Worker #include <sys/stat.h>
69*8b26181fSAndroid Build Coastguard Worker 
70*8b26181fSAndroid Build Coastguard Worker #include "pcap/funcattrs.h"
71*8b26181fSAndroid Build Coastguard Worker 
72*8b26181fSAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(_AIX) || defined(sun)
73*8b26181fSAndroid Build Coastguard Worker /* OS with BPF - use BPF */
74*8b26181fSAndroid Build Coastguard Worker #define USE_BPF
75*8b26181fSAndroid Build Coastguard Worker #elif defined(linux)
76*8b26181fSAndroid Build Coastguard Worker /* Linux - use socket filters */
77*8b26181fSAndroid Build Coastguard Worker #define USE_SOCKET_FILTERS
78*8b26181fSAndroid Build Coastguard Worker #else
79*8b26181fSAndroid Build Coastguard Worker #error "Unknown platform or platform that doesn't support Valgrind"
80*8b26181fSAndroid Build Coastguard Worker #endif
81*8b26181fSAndroid Build Coastguard Worker 
82*8b26181fSAndroid Build Coastguard Worker #if defined(USE_BPF)
83*8b26181fSAndroid Build Coastguard Worker 
84*8b26181fSAndroid Build Coastguard Worker #include <sys/ioctl.h>
85*8b26181fSAndroid Build Coastguard Worker #include <net/bpf.h>
86*8b26181fSAndroid Build Coastguard Worker 
87*8b26181fSAndroid Build Coastguard Worker /*
88*8b26181fSAndroid Build Coastguard Worker  * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the
89*8b26181fSAndroid Build Coastguard Worker  * native OS version, as we're going to be doing our own ioctls to
90*8b26181fSAndroid Build Coastguard Worker  * make sure that, in the uninitialized-data tests, the filters aren't
91*8b26181fSAndroid Build Coastguard Worker  * checked by libpcap before being handed to BPF.
92*8b26181fSAndroid Build Coastguard Worker  */
93*8b26181fSAndroid Build Coastguard Worker #define PCAP_DONT_INCLUDE_PCAP_BPF_H
94*8b26181fSAndroid Build Coastguard Worker 
95*8b26181fSAndroid Build Coastguard Worker #elif defined(USE_SOCKET_FILTERS)
96*8b26181fSAndroid Build Coastguard Worker 
97*8b26181fSAndroid Build Coastguard Worker #include <sys/socket.h>
98*8b26181fSAndroid Build Coastguard Worker #include <linux/types.h>
99*8b26181fSAndroid Build Coastguard Worker #include <linux/filter.h>
100*8b26181fSAndroid Build Coastguard Worker 
101*8b26181fSAndroid Build Coastguard Worker #endif
102*8b26181fSAndroid Build Coastguard Worker 
103*8b26181fSAndroid Build Coastguard Worker /*
104*8b26181fSAndroid Build Coastguard Worker  * Squelch a warning.
105*8b26181fSAndroid Build Coastguard Worker  *
106*8b26181fSAndroid Build Coastguard Worker  * We include system headers to be able to directly set the filter to
107*8b26181fSAndroid Build Coastguard Worker  * a program with uninitialized content, to make sure what we're testing
108*8b26181fSAndroid Build Coastguard Worker  * is Valgrind's checking of the system call to set the filter, and we
109*8b26181fSAndroid Build Coastguard Worker  * also include <pcap.h> to open the device in the first place, and that
110*8b26181fSAndroid Build Coastguard Worker  * means that we may get collisions between their definitions of
111*8b26181fSAndroid Build Coastguard Worker  * BPF_STMT and BPF_JUMP - and do, in fact, get them on Linux (the
112*8b26181fSAndroid Build Coastguard Worker  * definitions may be semantically the same, but that's not sufficient to
113*8b26181fSAndroid Build Coastguard Worker  * avoid the warnings, as the preprocessor doesn't know that u_short is
114*8b26181fSAndroid Build Coastguard Worker  * just unsigned short).
115*8b26181fSAndroid Build Coastguard Worker  *
116*8b26181fSAndroid Build Coastguard Worker  * So we undefine BPF_STMT and BPF_JUMP to avoid the warning.
117*8b26181fSAndroid Build Coastguard Worker  */
118*8b26181fSAndroid Build Coastguard Worker #undef BPF_STMT
119*8b26181fSAndroid Build Coastguard Worker #undef BPF_JUMP
120*8b26181fSAndroid Build Coastguard Worker #include <pcap.h>
121*8b26181fSAndroid Build Coastguard Worker 
122*8b26181fSAndroid Build Coastguard Worker static char *program_name;
123*8b26181fSAndroid Build Coastguard Worker 
124*8b26181fSAndroid Build Coastguard Worker /* Forwards */
125*8b26181fSAndroid Build Coastguard Worker static void PCAP_NORETURN usage(void);
126*8b26181fSAndroid Build Coastguard Worker static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
127*8b26181fSAndroid Build Coastguard Worker static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
128*8b26181fSAndroid Build Coastguard Worker 
129*8b26181fSAndroid Build Coastguard Worker /*
130*8b26181fSAndroid Build Coastguard Worker  * On Windows, we need to open the file in binary mode, so that
131*8b26181fSAndroid Build Coastguard Worker  * we get all the bytes specified by the size we get from "fstat()".
132*8b26181fSAndroid Build Coastguard Worker  * On UNIX, that's not necessary.  O_BINARY is defined on Windows;
133*8b26181fSAndroid Build Coastguard Worker  * we define it as 0 if it's not defined, so it does nothing.
134*8b26181fSAndroid Build Coastguard Worker  */
135*8b26181fSAndroid Build Coastguard Worker #ifndef O_BINARY
136*8b26181fSAndroid Build Coastguard Worker #define O_BINARY	0
137*8b26181fSAndroid Build Coastguard Worker #endif
138*8b26181fSAndroid Build Coastguard Worker 
139*8b26181fSAndroid Build Coastguard Worker static char *
read_infile(char * fname)140*8b26181fSAndroid Build Coastguard Worker read_infile(char *fname)
141*8b26181fSAndroid Build Coastguard Worker {
142*8b26181fSAndroid Build Coastguard Worker 	register int i, fd, cc;
143*8b26181fSAndroid Build Coastguard Worker 	register char *cp;
144*8b26181fSAndroid Build Coastguard Worker 	struct stat buf;
145*8b26181fSAndroid Build Coastguard Worker 
146*8b26181fSAndroid Build Coastguard Worker 	fd = open(fname, O_RDONLY|O_BINARY);
147*8b26181fSAndroid Build Coastguard Worker 	if (fd < 0)
148*8b26181fSAndroid Build Coastguard Worker 		error("can't open %s: %s", fname, pcap_strerror(errno));
149*8b26181fSAndroid Build Coastguard Worker 
150*8b26181fSAndroid Build Coastguard Worker 	if (fstat(fd, &buf) < 0)
151*8b26181fSAndroid Build Coastguard Worker 		error("can't stat %s: %s", fname, pcap_strerror(errno));
152*8b26181fSAndroid Build Coastguard Worker 
153*8b26181fSAndroid Build Coastguard Worker 	/*
154*8b26181fSAndroid Build Coastguard Worker 	 * _read(), on Windows, has an unsigned int byte count and an
155*8b26181fSAndroid Build Coastguard Worker 	 * int return value, so we can't handle a file bigger than
156*8b26181fSAndroid Build Coastguard Worker 	 * INT_MAX - 1 bytes (and have no reason to do so; a filter *that*
157*8b26181fSAndroid Build Coastguard Worker 	 * big will take forever to compile).  (The -1 is for the '\0' at
158*8b26181fSAndroid Build Coastguard Worker 	 * the end of the string.)
159*8b26181fSAndroid Build Coastguard Worker 	 */
160*8b26181fSAndroid Build Coastguard Worker 	if (buf.st_size > INT_MAX - 1)
161*8b26181fSAndroid Build Coastguard Worker 		error("%s is larger than %d bytes; that's too large", fname,
162*8b26181fSAndroid Build Coastguard Worker 		    INT_MAX - 1);
163*8b26181fSAndroid Build Coastguard Worker 	cp = malloc((u_int)buf.st_size + 1);
164*8b26181fSAndroid Build Coastguard Worker 	if (cp == NULL)
165*8b26181fSAndroid Build Coastguard Worker 		error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
166*8b26181fSAndroid Build Coastguard Worker 			fname, pcap_strerror(errno));
167*8b26181fSAndroid Build Coastguard Worker 	cc = (int)read(fd, cp, (u_int)buf.st_size);
168*8b26181fSAndroid Build Coastguard Worker 	if (cc < 0)
169*8b26181fSAndroid Build Coastguard Worker 		error("read %s: %s", fname, pcap_strerror(errno));
170*8b26181fSAndroid Build Coastguard Worker 	if (cc != buf.st_size)
171*8b26181fSAndroid Build Coastguard Worker 		error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
172*8b26181fSAndroid Build Coastguard Worker 
173*8b26181fSAndroid Build Coastguard Worker 	close(fd);
174*8b26181fSAndroid Build Coastguard Worker 	/* replace "# comment" with spaces */
175*8b26181fSAndroid Build Coastguard Worker 	for (i = 0; i < cc; i++) {
176*8b26181fSAndroid Build Coastguard Worker 		if (cp[i] == '#')
177*8b26181fSAndroid Build Coastguard Worker 			while (i < cc && cp[i] != '\n')
178*8b26181fSAndroid Build Coastguard Worker 				cp[i++] = ' ';
179*8b26181fSAndroid Build Coastguard Worker 	}
180*8b26181fSAndroid Build Coastguard Worker 	cp[cc] = '\0';
181*8b26181fSAndroid Build Coastguard Worker 	return (cp);
182*8b26181fSAndroid Build Coastguard Worker }
183*8b26181fSAndroid Build Coastguard Worker 
184*8b26181fSAndroid Build Coastguard Worker /* VARARGS */
185*8b26181fSAndroid Build Coastguard Worker static void
error(const char * fmt,...)186*8b26181fSAndroid Build Coastguard Worker error(const char *fmt, ...)
187*8b26181fSAndroid Build Coastguard Worker {
188*8b26181fSAndroid Build Coastguard Worker 	va_list ap;
189*8b26181fSAndroid Build Coastguard Worker 
190*8b26181fSAndroid Build Coastguard Worker 	(void)fprintf(stderr, "%s: ", program_name);
191*8b26181fSAndroid Build Coastguard Worker 	va_start(ap, fmt);
192*8b26181fSAndroid Build Coastguard Worker 	(void)vfprintf(stderr, fmt, ap);
193*8b26181fSAndroid Build Coastguard Worker 	va_end(ap);
194*8b26181fSAndroid Build Coastguard Worker 	if (*fmt) {
195*8b26181fSAndroid Build Coastguard Worker 		fmt += strlen(fmt);
196*8b26181fSAndroid Build Coastguard Worker 		if (fmt[-1] != '\n')
197*8b26181fSAndroid Build Coastguard Worker 			(void)fputc('\n', stderr);
198*8b26181fSAndroid Build Coastguard Worker 	}
199*8b26181fSAndroid Build Coastguard Worker 	exit(1);
200*8b26181fSAndroid Build Coastguard Worker 	/* NOTREACHED */
201*8b26181fSAndroid Build Coastguard Worker }
202*8b26181fSAndroid Build Coastguard Worker 
203*8b26181fSAndroid Build Coastguard Worker /* VARARGS */
204*8b26181fSAndroid Build Coastguard Worker static void
warning(const char * fmt,...)205*8b26181fSAndroid Build Coastguard Worker warning(const char *fmt, ...)
206*8b26181fSAndroid Build Coastguard Worker {
207*8b26181fSAndroid Build Coastguard Worker 	va_list ap;
208*8b26181fSAndroid Build Coastguard Worker 
209*8b26181fSAndroid Build Coastguard Worker 	(void)fprintf(stderr, "%s: WARNING: ", program_name);
210*8b26181fSAndroid Build Coastguard Worker 	va_start(ap, fmt);
211*8b26181fSAndroid Build Coastguard Worker 	(void)vfprintf(stderr, fmt, ap);
212*8b26181fSAndroid Build Coastguard Worker 	va_end(ap);
213*8b26181fSAndroid Build Coastguard Worker 	if (*fmt) {
214*8b26181fSAndroid Build Coastguard Worker 		fmt += strlen(fmt);
215*8b26181fSAndroid Build Coastguard Worker 		if (fmt[-1] != '\n')
216*8b26181fSAndroid Build Coastguard Worker 			(void)fputc('\n', stderr);
217*8b26181fSAndroid Build Coastguard Worker 	}
218*8b26181fSAndroid Build Coastguard Worker }
219*8b26181fSAndroid Build Coastguard Worker 
220*8b26181fSAndroid Build Coastguard Worker /*
221*8b26181fSAndroid Build Coastguard Worker  * Copy arg vector into a new buffer, concatenating arguments with spaces.
222*8b26181fSAndroid Build Coastguard Worker  */
223*8b26181fSAndroid Build Coastguard Worker static char *
copy_argv(register char ** argv)224*8b26181fSAndroid Build Coastguard Worker copy_argv(register char **argv)
225*8b26181fSAndroid Build Coastguard Worker {
226*8b26181fSAndroid Build Coastguard Worker 	register char **p;
227*8b26181fSAndroid Build Coastguard Worker 	register size_t len = 0;
228*8b26181fSAndroid Build Coastguard Worker 	char *buf;
229*8b26181fSAndroid Build Coastguard Worker 	char *src, *dst;
230*8b26181fSAndroid Build Coastguard Worker 
231*8b26181fSAndroid Build Coastguard Worker 	p = argv;
232*8b26181fSAndroid Build Coastguard Worker 	if (*p == 0)
233*8b26181fSAndroid Build Coastguard Worker 		return 0;
234*8b26181fSAndroid Build Coastguard Worker 
235*8b26181fSAndroid Build Coastguard Worker 	while (*p)
236*8b26181fSAndroid Build Coastguard Worker 		len += strlen(*p++) + 1;
237*8b26181fSAndroid Build Coastguard Worker 
238*8b26181fSAndroid Build Coastguard Worker 	buf = (char *)malloc(len);
239*8b26181fSAndroid Build Coastguard Worker 	if (buf == NULL)
240*8b26181fSAndroid Build Coastguard Worker 		error("copy_argv: malloc");
241*8b26181fSAndroid Build Coastguard Worker 
242*8b26181fSAndroid Build Coastguard Worker 	p = argv;
243*8b26181fSAndroid Build Coastguard Worker 	dst = buf;
244*8b26181fSAndroid Build Coastguard Worker 	while ((src = *p++) != NULL) {
245*8b26181fSAndroid Build Coastguard Worker 		while ((*dst++ = *src++) != '\0')
246*8b26181fSAndroid Build Coastguard Worker 			;
247*8b26181fSAndroid Build Coastguard Worker 		dst[-1] = ' ';
248*8b26181fSAndroid Build Coastguard Worker 	}
249*8b26181fSAndroid Build Coastguard Worker 	dst[-1] = '\0';
250*8b26181fSAndroid Build Coastguard Worker 
251*8b26181fSAndroid Build Coastguard Worker 	return buf;
252*8b26181fSAndroid Build Coastguard Worker }
253*8b26181fSAndroid Build Coastguard Worker 
254*8b26181fSAndroid Build Coastguard Worker #define INSN_COUNT	17
255*8b26181fSAndroid Build Coastguard Worker 
256*8b26181fSAndroid Build Coastguard Worker int
main(int argc,char ** argv)257*8b26181fSAndroid Build Coastguard Worker main(int argc, char **argv)
258*8b26181fSAndroid Build Coastguard Worker {
259*8b26181fSAndroid Build Coastguard Worker 	char *cp, *device;
260*8b26181fSAndroid Build Coastguard Worker 	int op;
261*8b26181fSAndroid Build Coastguard Worker 	int dorfmon, useactivate;
262*8b26181fSAndroid Build Coastguard Worker 	char ebuf[PCAP_ERRBUF_SIZE];
263*8b26181fSAndroid Build Coastguard Worker 	char *infile;
264*8b26181fSAndroid Build Coastguard Worker 	const char *cmdbuf;
265*8b26181fSAndroid Build Coastguard Worker 	pcap_if_t *devlist;
266*8b26181fSAndroid Build Coastguard Worker 	pcap_t *pd;
267*8b26181fSAndroid Build Coastguard Worker 	int status = 0;
268*8b26181fSAndroid Build Coastguard Worker 	int pcap_fd;
269*8b26181fSAndroid Build Coastguard Worker #if defined(USE_BPF)
270*8b26181fSAndroid Build Coastguard Worker 	struct bpf_program bad_fcode;
271*8b26181fSAndroid Build Coastguard Worker 	struct bpf_insn uninitialized[INSN_COUNT];
272*8b26181fSAndroid Build Coastguard Worker #elif defined(USE_SOCKET_FILTERS)
273*8b26181fSAndroid Build Coastguard Worker 	struct sock_fprog bad_fcode;
274*8b26181fSAndroid Build Coastguard Worker 	struct sock_filter uninitialized[INSN_COUNT];
275*8b26181fSAndroid Build Coastguard Worker #endif
276*8b26181fSAndroid Build Coastguard Worker 	struct bpf_program fcode;
277*8b26181fSAndroid Build Coastguard Worker 
278*8b26181fSAndroid Build Coastguard Worker 	device = NULL;
279*8b26181fSAndroid Build Coastguard Worker 	dorfmon = 0;
280*8b26181fSAndroid Build Coastguard Worker 	useactivate = 0;
281*8b26181fSAndroid Build Coastguard Worker 	infile = NULL;
282*8b26181fSAndroid Build Coastguard Worker 
283*8b26181fSAndroid Build Coastguard Worker 	if ((cp = strrchr(argv[0], '/')) != NULL)
284*8b26181fSAndroid Build Coastguard Worker 		program_name = cp + 1;
285*8b26181fSAndroid Build Coastguard Worker 	else
286*8b26181fSAndroid Build Coastguard Worker 		program_name = argv[0];
287*8b26181fSAndroid Build Coastguard Worker 
288*8b26181fSAndroid Build Coastguard Worker 	opterr = 0;
289*8b26181fSAndroid Build Coastguard Worker 	while ((op = getopt(argc, argv, "aF:i:I")) != -1) {
290*8b26181fSAndroid Build Coastguard Worker 		switch (op) {
291*8b26181fSAndroid Build Coastguard Worker 
292*8b26181fSAndroid Build Coastguard Worker 		case 'a':
293*8b26181fSAndroid Build Coastguard Worker 			useactivate = 1;
294*8b26181fSAndroid Build Coastguard Worker 			break;
295*8b26181fSAndroid Build Coastguard Worker 
296*8b26181fSAndroid Build Coastguard Worker 		case 'F':
297*8b26181fSAndroid Build Coastguard Worker 			infile = optarg;
298*8b26181fSAndroid Build Coastguard Worker 			break;
299*8b26181fSAndroid Build Coastguard Worker 
300*8b26181fSAndroid Build Coastguard Worker 		case 'i':
301*8b26181fSAndroid Build Coastguard Worker 			device = optarg;
302*8b26181fSAndroid Build Coastguard Worker 			break;
303*8b26181fSAndroid Build Coastguard Worker 
304*8b26181fSAndroid Build Coastguard Worker 		case 'I':
305*8b26181fSAndroid Build Coastguard Worker 			dorfmon = 1;
306*8b26181fSAndroid Build Coastguard Worker 			useactivate = 1;	/* required for rfmon */
307*8b26181fSAndroid Build Coastguard Worker 			break;
308*8b26181fSAndroid Build Coastguard Worker 
309*8b26181fSAndroid Build Coastguard Worker 		default:
310*8b26181fSAndroid Build Coastguard Worker 			usage();
311*8b26181fSAndroid Build Coastguard Worker 			/* NOTREACHED */
312*8b26181fSAndroid Build Coastguard Worker 		}
313*8b26181fSAndroid Build Coastguard Worker 	}
314*8b26181fSAndroid Build Coastguard Worker 
315*8b26181fSAndroid Build Coastguard Worker 	if (device == NULL) {
316*8b26181fSAndroid Build Coastguard Worker 		/*
317*8b26181fSAndroid Build Coastguard Worker 		 * No interface specified; get whatever pcap_lookupdev()
318*8b26181fSAndroid Build Coastguard Worker 		 * finds.
319*8b26181fSAndroid Build Coastguard Worker 		 */
320*8b26181fSAndroid Build Coastguard Worker 		if (pcap_findalldevs(&devlist, ebuf) == -1)
321*8b26181fSAndroid Build Coastguard Worker 			error("%s", ebuf);
322*8b26181fSAndroid Build Coastguard Worker 		if (devlist == NULL)
323*8b26181fSAndroid Build Coastguard Worker 			error("no interfaces available for capture");
324*8b26181fSAndroid Build Coastguard Worker 		device = strdup(devlist->name);
325*8b26181fSAndroid Build Coastguard Worker 		pcap_freealldevs(devlist);
326*8b26181fSAndroid Build Coastguard Worker 	}
327*8b26181fSAndroid Build Coastguard Worker 
328*8b26181fSAndroid Build Coastguard Worker 	if (infile != NULL) {
329*8b26181fSAndroid Build Coastguard Worker 		/*
330*8b26181fSAndroid Build Coastguard Worker 		 * Filter specified with "-F" and a file containing
331*8b26181fSAndroid Build Coastguard Worker 		 * a filter.
332*8b26181fSAndroid Build Coastguard Worker 		 */
333*8b26181fSAndroid Build Coastguard Worker 		cmdbuf = read_infile(infile);
334*8b26181fSAndroid Build Coastguard Worker 	} else {
335*8b26181fSAndroid Build Coastguard Worker 		if (optind < argc) {
336*8b26181fSAndroid Build Coastguard Worker 			/*
337*8b26181fSAndroid Build Coastguard Worker 			 * Filter specified with arguments on the
338*8b26181fSAndroid Build Coastguard Worker 			 * command line.
339*8b26181fSAndroid Build Coastguard Worker 			 */
340*8b26181fSAndroid Build Coastguard Worker 			cmdbuf = copy_argv(&argv[optind+1]);
341*8b26181fSAndroid Build Coastguard Worker 		} else {
342*8b26181fSAndroid Build Coastguard Worker 			/*
343*8b26181fSAndroid Build Coastguard Worker 			 * No filter specified; use an empty string, which
344*8b26181fSAndroid Build Coastguard Worker 			 * compiles to an "accept all" filter.
345*8b26181fSAndroid Build Coastguard Worker 			 */
346*8b26181fSAndroid Build Coastguard Worker 			cmdbuf = "";
347*8b26181fSAndroid Build Coastguard Worker 		}
348*8b26181fSAndroid Build Coastguard Worker 	}
349*8b26181fSAndroid Build Coastguard Worker 
350*8b26181fSAndroid Build Coastguard Worker 	if (useactivate) {
351*8b26181fSAndroid Build Coastguard Worker 		pd = pcap_create(device, ebuf);
352*8b26181fSAndroid Build Coastguard Worker 		if (pd == NULL)
353*8b26181fSAndroid Build Coastguard Worker 			error("%s: pcap_create() failed: %s", device, ebuf);
354*8b26181fSAndroid Build Coastguard Worker 		status = pcap_set_snaplen(pd, 65535);
355*8b26181fSAndroid Build Coastguard Worker 		if (status != 0)
356*8b26181fSAndroid Build Coastguard Worker 			error("%s: pcap_set_snaplen failed: %s",
357*8b26181fSAndroid Build Coastguard Worker 			    device, pcap_statustostr(status));
358*8b26181fSAndroid Build Coastguard Worker 		status = pcap_set_promisc(pd, 1);
359*8b26181fSAndroid Build Coastguard Worker 		if (status != 0)
360*8b26181fSAndroid Build Coastguard Worker 			error("%s: pcap_set_promisc failed: %s",
361*8b26181fSAndroid Build Coastguard Worker 			    device, pcap_statustostr(status));
362*8b26181fSAndroid Build Coastguard Worker 		if (dorfmon) {
363*8b26181fSAndroid Build Coastguard Worker 			status = pcap_set_rfmon(pd, 1);
364*8b26181fSAndroid Build Coastguard Worker 			if (status != 0)
365*8b26181fSAndroid Build Coastguard Worker 				error("%s: pcap_set_rfmon failed: %s",
366*8b26181fSAndroid Build Coastguard Worker 				    device, pcap_statustostr(status));
367*8b26181fSAndroid Build Coastguard Worker 		}
368*8b26181fSAndroid Build Coastguard Worker 		status = pcap_set_timeout(pd, 1000);
369*8b26181fSAndroid Build Coastguard Worker 		if (status != 0)
370*8b26181fSAndroid Build Coastguard Worker 			error("%s: pcap_set_timeout failed: %s",
371*8b26181fSAndroid Build Coastguard Worker 			    device, pcap_statustostr(status));
372*8b26181fSAndroid Build Coastguard Worker 		status = pcap_activate(pd);
373*8b26181fSAndroid Build Coastguard Worker 		if (status < 0) {
374*8b26181fSAndroid Build Coastguard Worker 			/*
375*8b26181fSAndroid Build Coastguard Worker 			 * pcap_activate() failed.
376*8b26181fSAndroid Build Coastguard Worker 			 */
377*8b26181fSAndroid Build Coastguard Worker 			error("%s: %s\n(%s)", device,
378*8b26181fSAndroid Build Coastguard Worker 			    pcap_statustostr(status), pcap_geterr(pd));
379*8b26181fSAndroid Build Coastguard Worker 		} else if (status > 0) {
380*8b26181fSAndroid Build Coastguard Worker 			/*
381*8b26181fSAndroid Build Coastguard Worker 			 * pcap_activate() succeeded, but it's warning us
382*8b26181fSAndroid Build Coastguard Worker 			 * of a problem it had.
383*8b26181fSAndroid Build Coastguard Worker 			 */
384*8b26181fSAndroid Build Coastguard Worker 			warning("%s: %s\n(%s)", device,
385*8b26181fSAndroid Build Coastguard Worker 			    pcap_statustostr(status), pcap_geterr(pd));
386*8b26181fSAndroid Build Coastguard Worker 		}
387*8b26181fSAndroid Build Coastguard Worker 	} else {
388*8b26181fSAndroid Build Coastguard Worker 		*ebuf = '\0';
389*8b26181fSAndroid Build Coastguard Worker 		pd = pcap_open_live(device, 65535, 1, 1000, ebuf);
390*8b26181fSAndroid Build Coastguard Worker 		if (pd == NULL)
391*8b26181fSAndroid Build Coastguard Worker 			error("%s", ebuf);
392*8b26181fSAndroid Build Coastguard Worker 		else if (*ebuf)
393*8b26181fSAndroid Build Coastguard Worker 			warning("%s", ebuf);
394*8b26181fSAndroid Build Coastguard Worker 	}
395*8b26181fSAndroid Build Coastguard Worker 
396*8b26181fSAndroid Build Coastguard Worker 	pcap_fd = pcap_fileno(pd);
397*8b26181fSAndroid Build Coastguard Worker 
398*8b26181fSAndroid Build Coastguard Worker 	/*
399*8b26181fSAndroid Build Coastguard Worker 	 * Try setting a filter with an uninitialized bpf_program
400*8b26181fSAndroid Build Coastguard Worker 	 * structure.  This should cause valgrind to report a
401*8b26181fSAndroid Build Coastguard Worker 	 * problem.
402*8b26181fSAndroid Build Coastguard Worker 	 *
403*8b26181fSAndroid Build Coastguard Worker 	 * We don't check for errors, because it could get an
404*8b26181fSAndroid Build Coastguard Worker 	 * error due to a bad pointer or count.
405*8b26181fSAndroid Build Coastguard Worker 	 */
406*8b26181fSAndroid Build Coastguard Worker #if defined(USE_BPF)
407*8b26181fSAndroid Build Coastguard Worker 	ioctl(pcap_fd, BIOCSETF, &bad_fcode);
408*8b26181fSAndroid Build Coastguard Worker #elif defined(USE_SOCKET_FILTERS)
409*8b26181fSAndroid Build Coastguard Worker 	setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode,
410*8b26181fSAndroid Build Coastguard Worker 	    sizeof(bad_fcode));
411*8b26181fSAndroid Build Coastguard Worker #endif
412*8b26181fSAndroid Build Coastguard Worker 
413*8b26181fSAndroid Build Coastguard Worker 	/*
414*8b26181fSAndroid Build Coastguard Worker 	 * Try setting a filter with an initialized bpf_program
415*8b26181fSAndroid Build Coastguard Worker 	 * structure that points to an uninitialized program.
416*8b26181fSAndroid Build Coastguard Worker 	 * That should also cause valgrind to report a problem.
417*8b26181fSAndroid Build Coastguard Worker 	 *
418*8b26181fSAndroid Build Coastguard Worker 	 * We don't check for errors, because it could get an
419*8b26181fSAndroid Build Coastguard Worker 	 * error due to a bad pointer or count.
420*8b26181fSAndroid Build Coastguard Worker 	 */
421*8b26181fSAndroid Build Coastguard Worker #if defined(USE_BPF)
422*8b26181fSAndroid Build Coastguard Worker 	bad_fcode.bf_len = INSN_COUNT;
423*8b26181fSAndroid Build Coastguard Worker 	bad_fcode.bf_insns = uninitialized;
424*8b26181fSAndroid Build Coastguard Worker 	ioctl(pcap_fd, BIOCSETF, &bad_fcode);
425*8b26181fSAndroid Build Coastguard Worker #elif defined(USE_SOCKET_FILTERS)
426*8b26181fSAndroid Build Coastguard Worker 	bad_fcode.len = INSN_COUNT;
427*8b26181fSAndroid Build Coastguard Worker 	bad_fcode.filter = uninitialized;
428*8b26181fSAndroid Build Coastguard Worker 	setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode,
429*8b26181fSAndroid Build Coastguard Worker 	    sizeof(bad_fcode));
430*8b26181fSAndroid Build Coastguard Worker #endif
431*8b26181fSAndroid Build Coastguard Worker 
432*8b26181fSAndroid Build Coastguard Worker 	/*
433*8b26181fSAndroid Build Coastguard Worker 	 * Now compile a filter and set the filter with that.
434*8b26181fSAndroid Build Coastguard Worker 	 * That should *not* cause valgrind to report a
435*8b26181fSAndroid Build Coastguard Worker 	 * problem.
436*8b26181fSAndroid Build Coastguard Worker 	 */
437*8b26181fSAndroid Build Coastguard Worker 	if (pcap_compile(pd, &fcode, cmdbuf, 1, 0) < 0)
438*8b26181fSAndroid Build Coastguard Worker 		error("can't compile filter: %s", pcap_geterr(pd));
439*8b26181fSAndroid Build Coastguard Worker 	if (pcap_setfilter(pd, &fcode) < 0)
440*8b26181fSAndroid Build Coastguard Worker 		error("can't set filter: %s", pcap_geterr(pd));
441*8b26181fSAndroid Build Coastguard Worker 
442*8b26181fSAndroid Build Coastguard Worker 	pcap_close(pd);
443*8b26181fSAndroid Build Coastguard Worker 	exit(status < 0 ? 1 : 0);
444*8b26181fSAndroid Build Coastguard Worker }
445*8b26181fSAndroid Build Coastguard Worker 
446*8b26181fSAndroid Build Coastguard Worker static void
usage(void)447*8b26181fSAndroid Build Coastguard Worker usage(void)
448*8b26181fSAndroid Build Coastguard Worker {
449*8b26181fSAndroid Build Coastguard Worker 	(void)fprintf(stderr, "%s, with %s\n", program_name,
450*8b26181fSAndroid Build Coastguard Worker 	    pcap_lib_version());
451*8b26181fSAndroid Build Coastguard Worker 	(void)fprintf(stderr,
452*8b26181fSAndroid Build Coastguard Worker 	    "Usage: %s [-aI] [ -F file ] [ -i interface ] [ expression ]\n",
453*8b26181fSAndroid Build Coastguard Worker 	    program_name);
454*8b26181fSAndroid Build Coastguard Worker 	exit(1);
455*8b26181fSAndroid Build Coastguard Worker }
456