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