1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
22#ifndef lint
23static const char copyright[] =
24    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
25The Regents of the University of California.  All rights reserved.\n";
26#endif
27
28#include <pcap.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <stdarg.h>
33#include <unistd.h>
34#include <errno.h>
35
36#define MAXIMUM_SNAPLEN		65535
37
38static char *program_name;
39
40/* Forwards */
41static void usage(void) __attribute__((noreturn));
42static void error(const char *, ...);
43static void warning(const char *, ...);
44
45extern int optind;
46extern int opterr;
47extern char *optarg;
48
49int
50main(int argc, char **argv)
51{
52	register int op;
53	register char *cp, *device;
54	int dorfmon, dopromisc, snaplen, useactivate, bufsize;
55	char ebuf[PCAP_ERRBUF_SIZE];
56	pcap_t *pd;
57	int status = 0;
58    int getiftapcount = 0;
59
60	device = NULL;
61	dorfmon = 0;
62	dopromisc = 0;
63	snaplen = MAXIMUM_SNAPLEN;
64	bufsize = 0;
65	useactivate = 0;
66	if ((cp = strrchr(argv[0], '/')) != NULL)
67		program_name = cp + 1;
68	else
69		program_name = argv[0];
70
71	opterr = 0;
72	while ((op = getopt(argc, argv, "gi:Ips:aB:")) != -1) {
73		switch (op) {
74
75		case 'i':
76			device = optarg;
77			break;
78
79        case 'g':
80                getiftapcount = 1;
81                break;
82
83		case 'I':
84			dorfmon = 1;
85			useactivate = 1;	/* required for rfmon */
86			break;
87
88		case 'p':
89			dopromisc = 1;
90			break;
91
92		case 's': {
93			char *end;
94
95			snaplen = strtol(optarg, &end, 0);
96			if (optarg == end || *end != '\0'
97			    || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN)
98				error("invalid snaplen %s", optarg);
99			else if (snaplen == 0)
100				snaplen = MAXIMUM_SNAPLEN;
101			break;
102		}
103
104		case 'B':
105			bufsize = atoi(optarg)*1024;
106			if (bufsize <= 0)
107				error("invalid packet buffer size %s", optarg);
108			useactivate = 1;	/* required for bufsize */
109			break;
110
111		case 'a':
112			useactivate = 1;
113			break;
114
115		default:
116			usage();
117			/* NOTREACHED */
118		}
119	}
120
121	if (useactivate) {
122		pd = pcap_create(device, ebuf);
123		if (pd == NULL)
124			error("%s", ebuf);
125		status = pcap_set_snaplen(pd, snaplen);
126		if (status != 0)
127			error("%s: pcap_set_snaplen failed: %s",
128			    device, pcap_statustostr(status));
129		if (dopromisc) {
130			status = pcap_set_promisc(pd, 1);
131			if (status != 0)
132				error("%s: pcap_set_promisc failed: %s",
133				    device, pcap_statustostr(status));
134		}
135		if (dorfmon) {
136			status = pcap_set_rfmon(pd, 1);
137			if (status != 0)
138				error("%s: pcap_set_rfmon failed: %s",
139				    device, pcap_statustostr(status));
140		}
141		status = pcap_set_timeout(pd, 1000);
142		if (status != 0)
143			error("%s: pcap_set_timeout failed: %s",
144			    device, pcap_statustostr(status));
145		if (bufsize != 0) {
146			status = pcap_set_buffer_size(pd, bufsize);
147			if (status != 0)
148				error("%s: pcap_set_buffer_size failed: %s",
149				    device, pcap_statustostr(status));
150		}
151		status = pcap_activate(pd);
152		if (status < 0) {
153			/*
154			 * pcap_activate() failed.
155			 */
156			error("%s: %s\n(%s)", device,
157			    pcap_statustostr(status), pcap_geterr(pd));
158		} else if (status > 0) {
159			/*
160			 * pcap_activate() succeeded, but it's warning us
161			 * of a problem it had.
162			 */
163			warning("%s: %s\n(%s)", device,
164			    pcap_statustostr(status), pcap_geterr(pd));
165		}
166	} else {
167		*ebuf = '\0';
168		pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
169		if (pd == NULL)
170			error("%s", ebuf);
171		else if (*ebuf)
172			warning("%s", ebuf);
173	}
174	pcap_close(pd);
175	exit(status < 0 ? 1 : 0);
176}
177
178static void
179usage(void)
180{
181	(void)fprintf(stderr,
182	    "Usage: %s [ -Ipa ] [ -i interface ] [ -s snaplen ] [ -B bufsize ]\n",
183	    program_name);
184	exit(1);
185}
186
187/* VARARGS */
188static void
189error(const char *fmt, ...)
190{
191	va_list ap;
192
193	(void)fprintf(stderr, "%s: ", program_name);
194	va_start(ap, fmt);
195	(void)vfprintf(stderr, fmt, ap);
196	va_end(ap);
197	if (*fmt) {
198		fmt += strlen(fmt);
199		if (fmt[-1] != '\n')
200			(void)fputc('\n', stderr);
201	}
202	exit(1);
203	/* NOTREACHED */
204}
205
206/* VARARGS */
207static void
208warning(const char *fmt, ...)
209{
210	va_list ap;
211
212	(void)fprintf(stderr, "%s: WARNING: ", program_name);
213	va_start(ap, fmt);
214	(void)vfprintf(stderr, fmt, ap);
215	va_end(ap);
216	if (*fmt) {
217		fmt += strlen(fmt);
218		if (fmt[-1] != '\n')
219			(void)fputc('\n', stderr);
220	}
221}
222