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 #ifndef lint
25*8b26181fSAndroid Build Coastguard Worker static const char copyright[] _U_ =
26*8b26181fSAndroid Build Coastguard Worker "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
27*8b26181fSAndroid Build Coastguard Worker The Regents of the University of California. All rights reserved.\n";
28*8b26181fSAndroid Build Coastguard Worker #endif
29*8b26181fSAndroid Build Coastguard Worker
30*8b26181fSAndroid Build Coastguard Worker #include <stdio.h>
31*8b26181fSAndroid Build Coastguard Worker #include <stdlib.h>
32*8b26181fSAndroid Build Coastguard Worker #include <string.h>
33*8b26181fSAndroid Build Coastguard Worker #include <stdarg.h>
34*8b26181fSAndroid Build Coastguard Worker #include <limits.h>
35*8b26181fSAndroid Build Coastguard Worker #ifdef _WIN32
36*8b26181fSAndroid Build Coastguard Worker #include "getopt.h"
37*8b26181fSAndroid Build Coastguard Worker #else
38*8b26181fSAndroid Build Coastguard Worker #include <unistd.h>
39*8b26181fSAndroid Build Coastguard Worker #endif
40*8b26181fSAndroid Build Coastguard Worker #include <errno.h>
41*8b26181fSAndroid Build Coastguard Worker #ifndef _WIN32
42*8b26181fSAndroid Build Coastguard Worker #include <signal.h>
43*8b26181fSAndroid Build Coastguard Worker #endif
44*8b26181fSAndroid Build Coastguard Worker #include <sys/types.h>
45*8b26181fSAndroid Build Coastguard Worker
46*8b26181fSAndroid Build Coastguard Worker #include <pcap.h>
47*8b26181fSAndroid Build Coastguard Worker
48*8b26181fSAndroid Build Coastguard Worker #include "pcap/funcattrs.h"
49*8b26181fSAndroid Build Coastguard Worker
50*8b26181fSAndroid Build Coastguard Worker #ifdef _WIN32
51*8b26181fSAndroid Build Coastguard Worker #include "portability.h"
52*8b26181fSAndroid Build Coastguard Worker #endif
53*8b26181fSAndroid Build Coastguard Worker
54*8b26181fSAndroid Build Coastguard Worker static char *program_name;
55*8b26181fSAndroid Build Coastguard Worker
56*8b26181fSAndroid Build Coastguard Worker /* Forwards */
57*8b26181fSAndroid Build Coastguard Worker static void PCAP_NORETURN usage(void);
58*8b26181fSAndroid Build Coastguard Worker static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
59*8b26181fSAndroid Build Coastguard Worker static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
60*8b26181fSAndroid Build Coastguard Worker static char *copy_argv(char **);
61*8b26181fSAndroid Build Coastguard Worker
62*8b26181fSAndroid Build Coastguard Worker static pcap_t *pd;
63*8b26181fSAndroid Build Coastguard Worker
64*8b26181fSAndroid Build Coastguard Worker #ifdef _WIN32
65*8b26181fSAndroid Build Coastguard Worker static BOOL WINAPI
stop_capture(DWORD ctrltype _U_)66*8b26181fSAndroid Build Coastguard Worker stop_capture(DWORD ctrltype _U_)
67*8b26181fSAndroid Build Coastguard Worker {
68*8b26181fSAndroid Build Coastguard Worker pcap_breakloop(pd);
69*8b26181fSAndroid Build Coastguard Worker return TRUE;
70*8b26181fSAndroid Build Coastguard Worker }
71*8b26181fSAndroid Build Coastguard Worker #else
72*8b26181fSAndroid Build Coastguard Worker static void
stop_capture(int signum _U_)73*8b26181fSAndroid Build Coastguard Worker stop_capture(int signum _U_)
74*8b26181fSAndroid Build Coastguard Worker {
75*8b26181fSAndroid Build Coastguard Worker pcap_breakloop(pd);
76*8b26181fSAndroid Build Coastguard Worker }
77*8b26181fSAndroid Build Coastguard Worker #endif
78*8b26181fSAndroid Build Coastguard Worker
79*8b26181fSAndroid Build Coastguard Worker static long
parse_interface_number(const char * device)80*8b26181fSAndroid Build Coastguard Worker parse_interface_number(const char *device)
81*8b26181fSAndroid Build Coastguard Worker {
82*8b26181fSAndroid Build Coastguard Worker const char *p;
83*8b26181fSAndroid Build Coastguard Worker long devnum;
84*8b26181fSAndroid Build Coastguard Worker char *end;
85*8b26181fSAndroid Build Coastguard Worker
86*8b26181fSAndroid Build Coastguard Worker /*
87*8b26181fSAndroid Build Coastguard Worker * Search for a colon, terminating any scheme at the beginning
88*8b26181fSAndroid Build Coastguard Worker * of the device.
89*8b26181fSAndroid Build Coastguard Worker */
90*8b26181fSAndroid Build Coastguard Worker p = strchr(device, ':');
91*8b26181fSAndroid Build Coastguard Worker if (p != NULL) {
92*8b26181fSAndroid Build Coastguard Worker /*
93*8b26181fSAndroid Build Coastguard Worker * We found it. Is it followed by "//"?
94*8b26181fSAndroid Build Coastguard Worker */
95*8b26181fSAndroid Build Coastguard Worker p++; /* skip the : */
96*8b26181fSAndroid Build Coastguard Worker if (strncmp(p, "//", 2) == 0) {
97*8b26181fSAndroid Build Coastguard Worker /*
98*8b26181fSAndroid Build Coastguard Worker * Yes. Search for the next /, at the end of the
99*8b26181fSAndroid Build Coastguard Worker * authority part of the URL.
100*8b26181fSAndroid Build Coastguard Worker */
101*8b26181fSAndroid Build Coastguard Worker p += 2; /* skip the // */
102*8b26181fSAndroid Build Coastguard Worker p = strchr(p, '/');
103*8b26181fSAndroid Build Coastguard Worker if (p != NULL) {
104*8b26181fSAndroid Build Coastguard Worker /*
105*8b26181fSAndroid Build Coastguard Worker * OK, past the / is the path.
106*8b26181fSAndroid Build Coastguard Worker */
107*8b26181fSAndroid Build Coastguard Worker device = p + 1;
108*8b26181fSAndroid Build Coastguard Worker }
109*8b26181fSAndroid Build Coastguard Worker }
110*8b26181fSAndroid Build Coastguard Worker }
111*8b26181fSAndroid Build Coastguard Worker devnum = strtol(device, &end, 10);
112*8b26181fSAndroid Build Coastguard Worker if (device != end && *end == '\0') {
113*8b26181fSAndroid Build Coastguard Worker /*
114*8b26181fSAndroid Build Coastguard Worker * It's all-numeric, but is it a valid number?
115*8b26181fSAndroid Build Coastguard Worker */
116*8b26181fSAndroid Build Coastguard Worker if (devnum <= 0) {
117*8b26181fSAndroid Build Coastguard Worker /*
118*8b26181fSAndroid Build Coastguard Worker * No, it's not an ordinal.
119*8b26181fSAndroid Build Coastguard Worker */
120*8b26181fSAndroid Build Coastguard Worker error("Invalid adapter index");
121*8b26181fSAndroid Build Coastguard Worker }
122*8b26181fSAndroid Build Coastguard Worker return (devnum);
123*8b26181fSAndroid Build Coastguard Worker } else {
124*8b26181fSAndroid Build Coastguard Worker /*
125*8b26181fSAndroid Build Coastguard Worker * It's not all-numeric; return -1, so our caller
126*8b26181fSAndroid Build Coastguard Worker * knows that.
127*8b26181fSAndroid Build Coastguard Worker */
128*8b26181fSAndroid Build Coastguard Worker return (-1);
129*8b26181fSAndroid Build Coastguard Worker }
130*8b26181fSAndroid Build Coastguard Worker }
131*8b26181fSAndroid Build Coastguard Worker
132*8b26181fSAndroid Build Coastguard Worker static char *
find_interface_by_number(long devnum)133*8b26181fSAndroid Build Coastguard Worker find_interface_by_number(long devnum)
134*8b26181fSAndroid Build Coastguard Worker {
135*8b26181fSAndroid Build Coastguard Worker pcap_if_t *dev, *devlist;
136*8b26181fSAndroid Build Coastguard Worker long i;
137*8b26181fSAndroid Build Coastguard Worker char ebuf[PCAP_ERRBUF_SIZE];
138*8b26181fSAndroid Build Coastguard Worker char *device;
139*8b26181fSAndroid Build Coastguard Worker int status;
140*8b26181fSAndroid Build Coastguard Worker
141*8b26181fSAndroid Build Coastguard Worker status = pcap_findalldevs(&devlist, ebuf);
142*8b26181fSAndroid Build Coastguard Worker if (status < 0)
143*8b26181fSAndroid Build Coastguard Worker error("%s", ebuf);
144*8b26181fSAndroid Build Coastguard Worker /*
145*8b26181fSAndroid Build Coastguard Worker * Look for the devnum-th entry in the list of devices (1-based).
146*8b26181fSAndroid Build Coastguard Worker */
147*8b26181fSAndroid Build Coastguard Worker for (i = 0, dev = devlist; i < devnum-1 && dev != NULL;
148*8b26181fSAndroid Build Coastguard Worker i++, dev = dev->next)
149*8b26181fSAndroid Build Coastguard Worker ;
150*8b26181fSAndroid Build Coastguard Worker if (dev == NULL)
151*8b26181fSAndroid Build Coastguard Worker error("Invalid adapter index");
152*8b26181fSAndroid Build Coastguard Worker device = strdup(dev->name);
153*8b26181fSAndroid Build Coastguard Worker pcap_freealldevs(devlist);
154*8b26181fSAndroid Build Coastguard Worker return (device);
155*8b26181fSAndroid Build Coastguard Worker }
156*8b26181fSAndroid Build Coastguard Worker
157*8b26181fSAndroid Build Coastguard Worker static pcap_t *
open_interface(const char * device,int snaplen_set,int snaplen,char * ebuf)158*8b26181fSAndroid Build Coastguard Worker open_interface(const char *device, int snaplen_set, int snaplen, char *ebuf)
159*8b26181fSAndroid Build Coastguard Worker {
160*8b26181fSAndroid Build Coastguard Worker pcap_t *pc;
161*8b26181fSAndroid Build Coastguard Worker int status;
162*8b26181fSAndroid Build Coastguard Worker char *cp;
163*8b26181fSAndroid Build Coastguard Worker
164*8b26181fSAndroid Build Coastguard Worker pc = pcap_create(device, ebuf);
165*8b26181fSAndroid Build Coastguard Worker if (pc == NULL) {
166*8b26181fSAndroid Build Coastguard Worker /*
167*8b26181fSAndroid Build Coastguard Worker * If this failed with "No such device", that means
168*8b26181fSAndroid Build Coastguard Worker * the interface doesn't exist; return NULL, so that
169*8b26181fSAndroid Build Coastguard Worker * the caller can see whether the device name is
170*8b26181fSAndroid Build Coastguard Worker * actually an interface index.
171*8b26181fSAndroid Build Coastguard Worker */
172*8b26181fSAndroid Build Coastguard Worker if (strstr(ebuf, "No such device") != NULL)
173*8b26181fSAndroid Build Coastguard Worker return (NULL);
174*8b26181fSAndroid Build Coastguard Worker error("%s", ebuf);
175*8b26181fSAndroid Build Coastguard Worker }
176*8b26181fSAndroid Build Coastguard Worker if (snaplen_set) {
177*8b26181fSAndroid Build Coastguard Worker status = pcap_set_snaplen(pc, snaplen);
178*8b26181fSAndroid Build Coastguard Worker if (status != 0)
179*8b26181fSAndroid Build Coastguard Worker error("%s: pcap_set_snaplen failed: %s",
180*8b26181fSAndroid Build Coastguard Worker device, pcap_statustostr(status));
181*8b26181fSAndroid Build Coastguard Worker }
182*8b26181fSAndroid Build Coastguard Worker status = pcap_set_timeout(pc, 100);
183*8b26181fSAndroid Build Coastguard Worker if (status != 0)
184*8b26181fSAndroid Build Coastguard Worker error("%s: pcap_set_timeout failed: %s",
185*8b26181fSAndroid Build Coastguard Worker device, pcap_statustostr(status));
186*8b26181fSAndroid Build Coastguard Worker status = pcap_activate(pc);
187*8b26181fSAndroid Build Coastguard Worker if (status < 0) {
188*8b26181fSAndroid Build Coastguard Worker /*
189*8b26181fSAndroid Build Coastguard Worker * pcap_activate() failed.
190*8b26181fSAndroid Build Coastguard Worker */
191*8b26181fSAndroid Build Coastguard Worker cp = pcap_geterr(pc);
192*8b26181fSAndroid Build Coastguard Worker if (status == PCAP_ERROR)
193*8b26181fSAndroid Build Coastguard Worker error("%s", cp);
194*8b26181fSAndroid Build Coastguard Worker else if (status == PCAP_ERROR_NO_SUCH_DEVICE) {
195*8b26181fSAndroid Build Coastguard Worker /*
196*8b26181fSAndroid Build Coastguard Worker * Return an error for our caller to handle.
197*8b26181fSAndroid Build Coastguard Worker */
198*8b26181fSAndroid Build Coastguard Worker snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)",
199*8b26181fSAndroid Build Coastguard Worker device, pcap_statustostr(status), cp);
200*8b26181fSAndroid Build Coastguard Worker } else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0')
201*8b26181fSAndroid Build Coastguard Worker error("%s: %s\n(%s)", device,
202*8b26181fSAndroid Build Coastguard Worker pcap_statustostr(status), cp);
203*8b26181fSAndroid Build Coastguard Worker else
204*8b26181fSAndroid Build Coastguard Worker error("%s: %s", device,
205*8b26181fSAndroid Build Coastguard Worker pcap_statustostr(status));
206*8b26181fSAndroid Build Coastguard Worker pcap_close(pc);
207*8b26181fSAndroid Build Coastguard Worker return (NULL);
208*8b26181fSAndroid Build Coastguard Worker } else if (status > 0) {
209*8b26181fSAndroid Build Coastguard Worker /*
210*8b26181fSAndroid Build Coastguard Worker * pcap_activate() succeeded, but it's warning us
211*8b26181fSAndroid Build Coastguard Worker * of a problem it had.
212*8b26181fSAndroid Build Coastguard Worker */
213*8b26181fSAndroid Build Coastguard Worker cp = pcap_geterr(pc);
214*8b26181fSAndroid Build Coastguard Worker if (status == PCAP_WARNING)
215*8b26181fSAndroid Build Coastguard Worker warning("%s", cp);
216*8b26181fSAndroid Build Coastguard Worker else if (status == PCAP_WARNING_PROMISC_NOTSUP &&
217*8b26181fSAndroid Build Coastguard Worker *cp != '\0')
218*8b26181fSAndroid Build Coastguard Worker warning("%s: %s\n(%s)", device,
219*8b26181fSAndroid Build Coastguard Worker pcap_statustostr(status), cp);
220*8b26181fSAndroid Build Coastguard Worker else
221*8b26181fSAndroid Build Coastguard Worker warning("%s: %s", device,
222*8b26181fSAndroid Build Coastguard Worker pcap_statustostr(status));
223*8b26181fSAndroid Build Coastguard Worker }
224*8b26181fSAndroid Build Coastguard Worker return (pc);
225*8b26181fSAndroid Build Coastguard Worker }
226*8b26181fSAndroid Build Coastguard Worker
227*8b26181fSAndroid Build Coastguard Worker #define COMMAND_OPTIONS "DLi:s:w:y:"
228*8b26181fSAndroid Build Coastguard Worker
229*8b26181fSAndroid Build Coastguard Worker int
main(int argc,char ** argv)230*8b26181fSAndroid Build Coastguard Worker main(int argc, char **argv)
231*8b26181fSAndroid Build Coastguard Worker {
232*8b26181fSAndroid Build Coastguard Worker int op;
233*8b26181fSAndroid Build Coastguard Worker char *cp, *cmdbuf = NULL, *device, *end, *savefile = NULL;
234*8b26181fSAndroid Build Coastguard Worker int snaplen = 0;
235*8b26181fSAndroid Build Coastguard Worker int snaplen_set = 0;
236*8b26181fSAndroid Build Coastguard Worker pcap_if_t *devlist;
237*8b26181fSAndroid Build Coastguard Worker long devnum;
238*8b26181fSAndroid Build Coastguard Worker int show_interfaces = 0;
239*8b26181fSAndroid Build Coastguard Worker int show_dlt_types = 0;
240*8b26181fSAndroid Build Coastguard Worker int ndlts;
241*8b26181fSAndroid Build Coastguard Worker int *dlts;
242*8b26181fSAndroid Build Coastguard Worker bpf_u_int32 localnet, netmask;
243*8b26181fSAndroid Build Coastguard Worker struct bpf_program fcode;
244*8b26181fSAndroid Build Coastguard Worker char ebuf[PCAP_ERRBUF_SIZE];
245*8b26181fSAndroid Build Coastguard Worker #ifndef _WIN32
246*8b26181fSAndroid Build Coastguard Worker struct sigaction action;
247*8b26181fSAndroid Build Coastguard Worker #endif
248*8b26181fSAndroid Build Coastguard Worker int dlt;
249*8b26181fSAndroid Build Coastguard Worker const char *dlt_name = NULL;
250*8b26181fSAndroid Build Coastguard Worker int status;
251*8b26181fSAndroid Build Coastguard Worker pcap_dumper_t *pdd;
252*8b26181fSAndroid Build Coastguard Worker
253*8b26181fSAndroid Build Coastguard Worker device = NULL;
254*8b26181fSAndroid Build Coastguard Worker if ((cp = strrchr(argv[0], '/')) != NULL)
255*8b26181fSAndroid Build Coastguard Worker program_name = cp + 1;
256*8b26181fSAndroid Build Coastguard Worker else
257*8b26181fSAndroid Build Coastguard Worker program_name = argv[0];
258*8b26181fSAndroid Build Coastguard Worker
259*8b26181fSAndroid Build Coastguard Worker opterr = 0;
260*8b26181fSAndroid Build Coastguard Worker while ((op = getopt(argc, argv, COMMAND_OPTIONS)) != -1) {
261*8b26181fSAndroid Build Coastguard Worker switch (op) {
262*8b26181fSAndroid Build Coastguard Worker
263*8b26181fSAndroid Build Coastguard Worker case 'D':
264*8b26181fSAndroid Build Coastguard Worker show_interfaces = 1;
265*8b26181fSAndroid Build Coastguard Worker break;
266*8b26181fSAndroid Build Coastguard Worker
267*8b26181fSAndroid Build Coastguard Worker case 'L':
268*8b26181fSAndroid Build Coastguard Worker show_dlt_types = 1;
269*8b26181fSAndroid Build Coastguard Worker break;
270*8b26181fSAndroid Build Coastguard Worker
271*8b26181fSAndroid Build Coastguard Worker case 'i':
272*8b26181fSAndroid Build Coastguard Worker device = optarg;
273*8b26181fSAndroid Build Coastguard Worker break;
274*8b26181fSAndroid Build Coastguard Worker
275*8b26181fSAndroid Build Coastguard Worker case 's':
276*8b26181fSAndroid Build Coastguard Worker snaplen = (int)strtol(optarg, &end, 0);
277*8b26181fSAndroid Build Coastguard Worker if (optarg == end || *end != '\0' || snaplen < 0)
278*8b26181fSAndroid Build Coastguard Worker error("invalid snaplen %s (must be >= 0)",
279*8b26181fSAndroid Build Coastguard Worker optarg);
280*8b26181fSAndroid Build Coastguard Worker snaplen_set = 1;
281*8b26181fSAndroid Build Coastguard Worker break;
282*8b26181fSAndroid Build Coastguard Worker
283*8b26181fSAndroid Build Coastguard Worker case 'w':
284*8b26181fSAndroid Build Coastguard Worker savefile = optarg;
285*8b26181fSAndroid Build Coastguard Worker break;
286*8b26181fSAndroid Build Coastguard Worker
287*8b26181fSAndroid Build Coastguard Worker case 'y':
288*8b26181fSAndroid Build Coastguard Worker dlt_name = optarg;
289*8b26181fSAndroid Build Coastguard Worker break;
290*8b26181fSAndroid Build Coastguard Worker
291*8b26181fSAndroid Build Coastguard Worker default:
292*8b26181fSAndroid Build Coastguard Worker usage();
293*8b26181fSAndroid Build Coastguard Worker /* NOTREACHED */
294*8b26181fSAndroid Build Coastguard Worker }
295*8b26181fSAndroid Build Coastguard Worker }
296*8b26181fSAndroid Build Coastguard Worker
297*8b26181fSAndroid Build Coastguard Worker if (show_interfaces) {
298*8b26181fSAndroid Build Coastguard Worker pcap_if_t *dev;
299*8b26181fSAndroid Build Coastguard Worker int i;
300*8b26181fSAndroid Build Coastguard Worker
301*8b26181fSAndroid Build Coastguard Worker if (pcap_findalldevs(&devlist, ebuf) < 0)
302*8b26181fSAndroid Build Coastguard Worker error("%s", ebuf);
303*8b26181fSAndroid Build Coastguard Worker for (i = 0, dev = devlist; dev != NULL; i++, dev = dev->next) {
304*8b26181fSAndroid Build Coastguard Worker printf("%d.%s", i+1, dev->name);
305*8b26181fSAndroid Build Coastguard Worker if (dev->description != NULL)
306*8b26181fSAndroid Build Coastguard Worker printf(" (%s)", dev->description);
307*8b26181fSAndroid Build Coastguard Worker printf("\n");
308*8b26181fSAndroid Build Coastguard Worker }
309*8b26181fSAndroid Build Coastguard Worker pcap_freealldevs(devlist);
310*8b26181fSAndroid Build Coastguard Worker return (0);
311*8b26181fSAndroid Build Coastguard Worker }
312*8b26181fSAndroid Build Coastguard Worker
313*8b26181fSAndroid Build Coastguard Worker if (device == NULL) {
314*8b26181fSAndroid Build Coastguard Worker if (pcap_findalldevs(&devlist, ebuf) == -1)
315*8b26181fSAndroid Build Coastguard Worker error("%s", ebuf);
316*8b26181fSAndroid Build Coastguard Worker if (devlist == NULL)
317*8b26181fSAndroid Build Coastguard Worker error("no interfaces available for capture");
318*8b26181fSAndroid Build Coastguard Worker device = strdup(devlist->name);
319*8b26181fSAndroid Build Coastguard Worker pcap_freealldevs(devlist);
320*8b26181fSAndroid Build Coastguard Worker }
321*8b26181fSAndroid Build Coastguard Worker if (show_dlt_types) {
322*8b26181fSAndroid Build Coastguard Worker pd = pcap_create(device, ebuf);
323*8b26181fSAndroid Build Coastguard Worker if (pd == NULL)
324*8b26181fSAndroid Build Coastguard Worker error("%s", ebuf);
325*8b26181fSAndroid Build Coastguard Worker status = pcap_activate(pd);
326*8b26181fSAndroid Build Coastguard Worker if (status < 0) {
327*8b26181fSAndroid Build Coastguard Worker /*
328*8b26181fSAndroid Build Coastguard Worker * pcap_activate() failed.
329*8b26181fSAndroid Build Coastguard Worker */
330*8b26181fSAndroid Build Coastguard Worker error("%s: %s\n(%s)", device,
331*8b26181fSAndroid Build Coastguard Worker pcap_statustostr(status), pcap_geterr(pd));
332*8b26181fSAndroid Build Coastguard Worker }
333*8b26181fSAndroid Build Coastguard Worker ndlts = pcap_list_datalinks(pd, &dlts);
334*8b26181fSAndroid Build Coastguard Worker if (ndlts < 0) {
335*8b26181fSAndroid Build Coastguard Worker /*
336*8b26181fSAndroid Build Coastguard Worker * pcap_list_datalinks() failed.
337*8b26181fSAndroid Build Coastguard Worker */
338*8b26181fSAndroid Build Coastguard Worker error("%s: %s\n(%s)", device,
339*8b26181fSAndroid Build Coastguard Worker pcap_statustostr(status), pcap_geterr(pd));
340*8b26181fSAndroid Build Coastguard Worker }
341*8b26181fSAndroid Build Coastguard Worker for (int i = 0; i < ndlts; i++) {
342*8b26181fSAndroid Build Coastguard Worker dlt_name = pcap_datalink_val_to_name(dlts[i]);
343*8b26181fSAndroid Build Coastguard Worker if (dlt_name == NULL)
344*8b26181fSAndroid Build Coastguard Worker printf("DLT %d", dlts[i]);
345*8b26181fSAndroid Build Coastguard Worker else
346*8b26181fSAndroid Build Coastguard Worker printf("%s", dlt_name);
347*8b26181fSAndroid Build Coastguard Worker printf("\n");
348*8b26181fSAndroid Build Coastguard Worker }
349*8b26181fSAndroid Build Coastguard Worker pcap_free_datalinks(dlts);
350*8b26181fSAndroid Build Coastguard Worker pcap_close(pd);
351*8b26181fSAndroid Build Coastguard Worker return 0;
352*8b26181fSAndroid Build Coastguard Worker }
353*8b26181fSAndroid Build Coastguard Worker
354*8b26181fSAndroid Build Coastguard Worker if (savefile == NULL)
355*8b26181fSAndroid Build Coastguard Worker error("no savefile specified");
356*8b26181fSAndroid Build Coastguard Worker
357*8b26181fSAndroid Build Coastguard Worker *ebuf = '\0';
358*8b26181fSAndroid Build Coastguard Worker
359*8b26181fSAndroid Build Coastguard Worker pd = open_interface(device, snaplen_set, snaplen, ebuf);
360*8b26181fSAndroid Build Coastguard Worker if (pd == NULL) {
361*8b26181fSAndroid Build Coastguard Worker /*
362*8b26181fSAndroid Build Coastguard Worker * That failed because the interface couldn't be found.
363*8b26181fSAndroid Build Coastguard Worker *
364*8b26181fSAndroid Build Coastguard Worker * If we can get a list of interfaces, and the interface name
365*8b26181fSAndroid Build Coastguard Worker * is purely numeric, try to use it as a 1-based index
366*8b26181fSAndroid Build Coastguard Worker * in the list of interfaces.
367*8b26181fSAndroid Build Coastguard Worker */
368*8b26181fSAndroid Build Coastguard Worker devnum = parse_interface_number(device);
369*8b26181fSAndroid Build Coastguard Worker if (devnum == -1) {
370*8b26181fSAndroid Build Coastguard Worker /*
371*8b26181fSAndroid Build Coastguard Worker * It's not a number; just report
372*8b26181fSAndroid Build Coastguard Worker * the open error and fail.
373*8b26181fSAndroid Build Coastguard Worker */
374*8b26181fSAndroid Build Coastguard Worker error("%s", ebuf);
375*8b26181fSAndroid Build Coastguard Worker }
376*8b26181fSAndroid Build Coastguard Worker
377*8b26181fSAndroid Build Coastguard Worker /*
378*8b26181fSAndroid Build Coastguard Worker * OK, it's a number; try to find the
379*8b26181fSAndroid Build Coastguard Worker * interface with that index, and try
380*8b26181fSAndroid Build Coastguard Worker * to open it.
381*8b26181fSAndroid Build Coastguard Worker *
382*8b26181fSAndroid Build Coastguard Worker * find_interface_by_number() exits if it
383*8b26181fSAndroid Build Coastguard Worker * couldn't be found.
384*8b26181fSAndroid Build Coastguard Worker */
385*8b26181fSAndroid Build Coastguard Worker device = find_interface_by_number(devnum);
386*8b26181fSAndroid Build Coastguard Worker pd = open_interface(device, snaplen_set, snaplen, ebuf);
387*8b26181fSAndroid Build Coastguard Worker if (pd == NULL)
388*8b26181fSAndroid Build Coastguard Worker error("%s", ebuf);
389*8b26181fSAndroid Build Coastguard Worker }
390*8b26181fSAndroid Build Coastguard Worker
391*8b26181fSAndroid Build Coastguard Worker if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
392*8b26181fSAndroid Build Coastguard Worker localnet = 0;
393*8b26181fSAndroid Build Coastguard Worker netmask = 0;
394*8b26181fSAndroid Build Coastguard Worker warning("%s", ebuf);
395*8b26181fSAndroid Build Coastguard Worker }
396*8b26181fSAndroid Build Coastguard Worker
397*8b26181fSAndroid Build Coastguard Worker if (dlt_name != NULL) {
398*8b26181fSAndroid Build Coastguard Worker dlt = pcap_datalink_name_to_val(dlt_name);
399*8b26181fSAndroid Build Coastguard Worker if (dlt == PCAP_ERROR)
400*8b26181fSAndroid Build Coastguard Worker error("%s isn't a valid DLT name", dlt_name);
401*8b26181fSAndroid Build Coastguard Worker if (pcap_set_datalink(pd, dlt) == PCAP_ERROR)
402*8b26181fSAndroid Build Coastguard Worker error("%s: %s", device, pcap_geterr(pd));
403*8b26181fSAndroid Build Coastguard Worker }
404*8b26181fSAndroid Build Coastguard Worker
405*8b26181fSAndroid Build Coastguard Worker /*
406*8b26181fSAndroid Build Coastguard Worker * Don't set a filter unless we were given one on the
407*8b26181fSAndroid Build Coastguard Worker * command line; if capturing doesn't work, or doesn't
408*8b26181fSAndroid Build Coastguard Worker * use the snapshot length, without a filter, that's
409*8b26181fSAndroid Build Coastguard Worker * a bug.
410*8b26181fSAndroid Build Coastguard Worker */
411*8b26181fSAndroid Build Coastguard Worker if (optind < argc) {
412*8b26181fSAndroid Build Coastguard Worker cmdbuf = copy_argv(&argv[optind]);
413*8b26181fSAndroid Build Coastguard Worker
414*8b26181fSAndroid Build Coastguard Worker if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
415*8b26181fSAndroid Build Coastguard Worker error("%s", pcap_geterr(pd));
416*8b26181fSAndroid Build Coastguard Worker
417*8b26181fSAndroid Build Coastguard Worker if (pcap_setfilter(pd, &fcode) < 0)
418*8b26181fSAndroid Build Coastguard Worker error("%s", pcap_geterr(pd));
419*8b26181fSAndroid Build Coastguard Worker }
420*8b26181fSAndroid Build Coastguard Worker
421*8b26181fSAndroid Build Coastguard Worker pdd = pcap_dump_open(pd, savefile);
422*8b26181fSAndroid Build Coastguard Worker if (pdd == NULL)
423*8b26181fSAndroid Build Coastguard Worker error("%s", pcap_geterr(pd));
424*8b26181fSAndroid Build Coastguard Worker
425*8b26181fSAndroid Build Coastguard Worker #ifdef _WIN32
426*8b26181fSAndroid Build Coastguard Worker SetConsoleCtrlHandler(stop_capture, TRUE);
427*8b26181fSAndroid Build Coastguard Worker #else
428*8b26181fSAndroid Build Coastguard Worker action.sa_handler = stop_capture;
429*8b26181fSAndroid Build Coastguard Worker sigemptyset(&action.sa_mask);
430*8b26181fSAndroid Build Coastguard Worker action.sa_flags = 0;
431*8b26181fSAndroid Build Coastguard Worker if (sigaction(SIGINT, &action, NULL) == -1)
432*8b26181fSAndroid Build Coastguard Worker error("Can't catch SIGINT: %s\n", strerror(errno));
433*8b26181fSAndroid Build Coastguard Worker #endif
434*8b26181fSAndroid Build Coastguard Worker
435*8b26181fSAndroid Build Coastguard Worker printf("Listening on %s, link-type ", device);
436*8b26181fSAndroid Build Coastguard Worker dlt = pcap_datalink(pd);
437*8b26181fSAndroid Build Coastguard Worker dlt_name = pcap_datalink_val_to_name(dlt);
438*8b26181fSAndroid Build Coastguard Worker if (dlt_name == NULL)
439*8b26181fSAndroid Build Coastguard Worker printf("DLT %d", dlt);
440*8b26181fSAndroid Build Coastguard Worker else
441*8b26181fSAndroid Build Coastguard Worker printf("%s", dlt_name);
442*8b26181fSAndroid Build Coastguard Worker printf("\n");
443*8b26181fSAndroid Build Coastguard Worker for (;;) {
444*8b26181fSAndroid Build Coastguard Worker status = pcap_dispatch(pd, -1, pcap_dump, (u_char *)pdd);
445*8b26181fSAndroid Build Coastguard Worker if (status < 0)
446*8b26181fSAndroid Build Coastguard Worker break;
447*8b26181fSAndroid Build Coastguard Worker if (status != 0) {
448*8b26181fSAndroid Build Coastguard Worker printf("%d packets seen\n", status);
449*8b26181fSAndroid Build Coastguard Worker struct pcap_stat ps;
450*8b26181fSAndroid Build Coastguard Worker pcap_stats(pd, &ps);
451*8b26181fSAndroid Build Coastguard Worker printf("%d ps_recv, %d ps_drop, %d ps_ifdrop\n",
452*8b26181fSAndroid Build Coastguard Worker ps.ps_recv, ps.ps_drop, ps.ps_ifdrop);
453*8b26181fSAndroid Build Coastguard Worker }
454*8b26181fSAndroid Build Coastguard Worker }
455*8b26181fSAndroid Build Coastguard Worker if (status == -2) {
456*8b26181fSAndroid Build Coastguard Worker /*
457*8b26181fSAndroid Build Coastguard Worker * We got interrupted, so perhaps we didn't
458*8b26181fSAndroid Build Coastguard Worker * manage to finish a line we were printing.
459*8b26181fSAndroid Build Coastguard Worker * Print an extra newline, just in case.
460*8b26181fSAndroid Build Coastguard Worker */
461*8b26181fSAndroid Build Coastguard Worker putchar('\n');
462*8b26181fSAndroid Build Coastguard Worker printf("Broken out of loop from SIGINT handler\n");
463*8b26181fSAndroid Build Coastguard Worker }
464*8b26181fSAndroid Build Coastguard Worker (void)fflush(stdout);
465*8b26181fSAndroid Build Coastguard Worker if (status == -1) {
466*8b26181fSAndroid Build Coastguard Worker /*
467*8b26181fSAndroid Build Coastguard Worker * Error. Report it.
468*8b26181fSAndroid Build Coastguard Worker */
469*8b26181fSAndroid Build Coastguard Worker (void)fprintf(stderr, "%s: pcap_dispatch: %s\n",
470*8b26181fSAndroid Build Coastguard Worker program_name, pcap_geterr(pd));
471*8b26181fSAndroid Build Coastguard Worker }
472*8b26181fSAndroid Build Coastguard Worker pcap_close(pd);
473*8b26181fSAndroid Build Coastguard Worker if (cmdbuf != NULL) {
474*8b26181fSAndroid Build Coastguard Worker pcap_freecode(&fcode);
475*8b26181fSAndroid Build Coastguard Worker free(cmdbuf);
476*8b26181fSAndroid Build Coastguard Worker }
477*8b26181fSAndroid Build Coastguard Worker exit(status == -1 ? 1 : 0);
478*8b26181fSAndroid Build Coastguard Worker }
479*8b26181fSAndroid Build Coastguard Worker
480*8b26181fSAndroid Build Coastguard Worker static void
usage(void)481*8b26181fSAndroid Build Coastguard Worker usage(void)
482*8b26181fSAndroid Build Coastguard Worker {
483*8b26181fSAndroid Build Coastguard Worker (void)fprintf(stderr, "Usage: %s -D -L [ -i interface ] [ -s snaplen ] [ -w file ] [ -y dlt ] [expression]\n",
484*8b26181fSAndroid Build Coastguard Worker program_name);
485*8b26181fSAndroid Build Coastguard Worker exit(1);
486*8b26181fSAndroid Build Coastguard Worker }
487*8b26181fSAndroid Build Coastguard Worker
488*8b26181fSAndroid Build Coastguard Worker /* VARARGS */
489*8b26181fSAndroid Build Coastguard Worker static void
error(const char * fmt,...)490*8b26181fSAndroid Build Coastguard Worker error(const char *fmt, ...)
491*8b26181fSAndroid Build Coastguard Worker {
492*8b26181fSAndroid Build Coastguard Worker va_list ap;
493*8b26181fSAndroid Build Coastguard Worker
494*8b26181fSAndroid Build Coastguard Worker (void)fprintf(stderr, "%s: ", program_name);
495*8b26181fSAndroid Build Coastguard Worker va_start(ap, fmt);
496*8b26181fSAndroid Build Coastguard Worker (void)vfprintf(stderr, fmt, ap);
497*8b26181fSAndroid Build Coastguard Worker va_end(ap);
498*8b26181fSAndroid Build Coastguard Worker if (*fmt) {
499*8b26181fSAndroid Build Coastguard Worker fmt += strlen(fmt);
500*8b26181fSAndroid Build Coastguard Worker if (fmt[-1] != '\n')
501*8b26181fSAndroid Build Coastguard Worker (void)fputc('\n', stderr);
502*8b26181fSAndroid Build Coastguard Worker }
503*8b26181fSAndroid Build Coastguard Worker exit(1);
504*8b26181fSAndroid Build Coastguard Worker /* NOTREACHED */
505*8b26181fSAndroid Build Coastguard Worker }
506*8b26181fSAndroid Build Coastguard Worker
507*8b26181fSAndroid Build Coastguard Worker /* VARARGS */
508*8b26181fSAndroid Build Coastguard Worker static void
warning(const char * fmt,...)509*8b26181fSAndroid Build Coastguard Worker warning(const char *fmt, ...)
510*8b26181fSAndroid Build Coastguard Worker {
511*8b26181fSAndroid Build Coastguard Worker va_list ap;
512*8b26181fSAndroid Build Coastguard Worker
513*8b26181fSAndroid Build Coastguard Worker (void)fprintf(stderr, "%s: WARNING: ", program_name);
514*8b26181fSAndroid Build Coastguard Worker va_start(ap, fmt);
515*8b26181fSAndroid Build Coastguard Worker (void)vfprintf(stderr, fmt, ap);
516*8b26181fSAndroid Build Coastguard Worker va_end(ap);
517*8b26181fSAndroid Build Coastguard Worker if (*fmt) {
518*8b26181fSAndroid Build Coastguard Worker fmt += strlen(fmt);
519*8b26181fSAndroid Build Coastguard Worker if (fmt[-1] != '\n')
520*8b26181fSAndroid Build Coastguard Worker (void)fputc('\n', stderr);
521*8b26181fSAndroid Build Coastguard Worker }
522*8b26181fSAndroid Build Coastguard Worker }
523*8b26181fSAndroid Build Coastguard Worker
524*8b26181fSAndroid Build Coastguard Worker /*
525*8b26181fSAndroid Build Coastguard Worker * Copy arg vector into a new buffer, concatenating arguments with spaces.
526*8b26181fSAndroid Build Coastguard Worker */
527*8b26181fSAndroid Build Coastguard Worker static char *
copy_argv(register char ** argv)528*8b26181fSAndroid Build Coastguard Worker copy_argv(register char **argv)
529*8b26181fSAndroid Build Coastguard Worker {
530*8b26181fSAndroid Build Coastguard Worker register char **p;
531*8b26181fSAndroid Build Coastguard Worker register size_t len = 0;
532*8b26181fSAndroid Build Coastguard Worker char *buf;
533*8b26181fSAndroid Build Coastguard Worker char *src, *dst;
534*8b26181fSAndroid Build Coastguard Worker
535*8b26181fSAndroid Build Coastguard Worker p = argv;
536*8b26181fSAndroid Build Coastguard Worker if (*p == 0)
537*8b26181fSAndroid Build Coastguard Worker return 0;
538*8b26181fSAndroid Build Coastguard Worker
539*8b26181fSAndroid Build Coastguard Worker while (*p)
540*8b26181fSAndroid Build Coastguard Worker len += strlen(*p++) + 1;
541*8b26181fSAndroid Build Coastguard Worker
542*8b26181fSAndroid Build Coastguard Worker buf = (char *)malloc(len);
543*8b26181fSAndroid Build Coastguard Worker if (buf == NULL)
544*8b26181fSAndroid Build Coastguard Worker error("copy_argv: malloc");
545*8b26181fSAndroid Build Coastguard Worker
546*8b26181fSAndroid Build Coastguard Worker p = argv;
547*8b26181fSAndroid Build Coastguard Worker dst = buf;
548*8b26181fSAndroid Build Coastguard Worker while ((src = *p++) != NULL) {
549*8b26181fSAndroid Build Coastguard Worker while ((*dst++ = *src++) != '\0')
550*8b26181fSAndroid Build Coastguard Worker ;
551*8b26181fSAndroid Build Coastguard Worker dst[-1] = ' ';
552*8b26181fSAndroid Build Coastguard Worker }
553*8b26181fSAndroid Build Coastguard Worker dst[-1] = '\0';
554*8b26181fSAndroid Build Coastguard Worker
555*8b26181fSAndroid Build Coastguard Worker return buf;
556*8b26181fSAndroid Build Coastguard Worker }
557