1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *	The Regents of the University of California.  All rights reserved.
4511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
5511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Redistribution and use in source and binary forms, with or without
6511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * modification, are permitted provided that: (1) source code distributions
7511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * retain the above copyright notice and this paragraph in its entirety, (2)
8511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * distributions including binary code include the above copyright notice and
9511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this paragraph in its entirety in the documentation or other materials
10511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * provided with the distribution, and (3) all advertising materials mentioning
11511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * features or use of this software display the following acknowledgement:
12511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * ``This product includes software developed by the University of California,
13511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the University nor the names of its contributors may be used to endorse
15511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * or promote products derived from this software without specific prior
16511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * written permission.
17511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
21511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
22511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef lint
23511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic const char copyright[] =
24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
25511eca30a483e912c274e1d8ba3a0f8f081e2227JP AbgrallThe Regents of the University of California.  All rights reserved.\n";
26511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
28511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pcap.h>
29511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdio.h>
30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdlib.h>
31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h>
32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdarg.h>
33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <unistd.h>
34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <errno.h>
35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/types.h>
36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/select.h>
37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <poll.h>
38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallchar *program_name;
40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* Forwards */
42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void usage(void) __attribute__((noreturn));
44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void error(const char *, ...);
45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void warning(const char *, ...);
46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic char *copy_argv(char **);
47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic pcap_t *pd;
49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallextern int optind;
51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallextern int opterr;
52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallextern char *optarg;
53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint
55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallmain(int argc, char **argv)
56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register int op;
58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	bpf_u_int32 localnet, netmask;
59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register char *cp, *cmdbuf, *device;
60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int doselect, dopoll, dotimeout, dononblock;
61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct bpf_program fcode;
62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	char ebuf[PCAP_ERRBUF_SIZE];
63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int selectable_fd;
64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int status;
65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int packet_count;
66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	device = NULL;
68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	doselect = 0;
69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dopoll = 0;
70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dotimeout = 0;
71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dononblock = 0;
72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if ((cp = strrchr(argv[0], '/')) != NULL)
73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		program_name = cp + 1;
74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	else
75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		program_name = argv[0];
76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	opterr = 0;
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while ((op = getopt(argc, argv, "i:sptn")) != -1) {
79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		switch (op) {
80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case 'i':
82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			device = optarg;
83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case 's':
86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			doselect = 1;
87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case 'p':
90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dopoll = 1;
91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case 't':
94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dotimeout = 1;
95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		case 'n':
98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dononblock = 1;
99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			break;
100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		default:
102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			usage();
103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* NOTREACHED */
104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (doselect && dopoll) {
108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		fprintf(stderr, "selpolltest: choose select (-s) or poll (-p), but not both\n");
109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return 1;
110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (dotimeout && !doselect && !dopoll) {
112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		fprintf(stderr, "selpolltest: timeout (-t) requires select (-s) or poll (-p)\n");
113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return 1;
114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (device == NULL) {
116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		device = pcap_lookupdev(ebuf);
117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (device == NULL)
118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			error("%s", ebuf);
119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	*ebuf = '\0';
121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pd == NULL)
123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("%s", ebuf);
124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	else if (*ebuf)
125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		warning("%s", ebuf);
126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		localnet = 0;
128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		netmask = 0;
129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		warning("%s", ebuf);
130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	cmdbuf = copy_argv(&argv[optind]);
132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("%s", pcap_geterr(pd));
135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_setfilter(pd, &fcode) < 0)
137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("%s", pcap_geterr(pd));
138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_get_selectable_fd(pd) == -1)
139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("pcap_get_selectable_fd() fails");
140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (dononblock) {
141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (pcap_setnonblock(pd, 1, ebuf) == -1)
142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			error("pcap_setnonblock failed: %s", ebuf);
143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	selectable_fd = pcap_get_selectable_fd(pd);
145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	printf("Listening on %s\n", device);
146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (doselect) {
147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		for (;;) {
148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			fd_set setread, setexcept;
149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			struct timeval seltimeout;
150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			FD_ZERO(&setread);
152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			FD_SET(selectable_fd, &setread);
153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			FD_ZERO(&setexcept);
154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			FD_SET(selectable_fd, &setexcept);
155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (dotimeout) {
156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				seltimeout.tv_sec = 0;
157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				seltimeout.tv_usec = 1000;
158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				status = select(selectable_fd + 1, &setread,
159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    NULL, &setexcept, &seltimeout);
160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			} else {
161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				status = select(selectable_fd + 1, &setread,
162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    NULL, &setexcept, NULL);
163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (status == -1) {
165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				printf("Select returns error (%s)\n",
166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    strerror(errno));
167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			} else {
168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				if (status == 0)
169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("Select timed out: ");
170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				else
171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("Select returned a descriptor: ");
172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				if (FD_ISSET(selectable_fd, &setread))
173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("readable, ");
174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				else
175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("not readable, ");
176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				if (FD_ISSET(selectable_fd, &setexcept))
177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("exceptional condition\n");
178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				else
179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("no exceptional condition\n");
180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				packet_count = 0;
181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				status = pcap_dispatch(pd, -1, countme,
182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    (u_char *)&packet_count);
183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				if (status < 0)
184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					break;
185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				printf("%d packets seen, %d packets counted after select returns\n",
186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    status, packet_count);
187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else if (dopoll) {
190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		for (;;) {
191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			struct pollfd fd;
192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			int polltimeout;
193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			fd.fd = selectable_fd;
195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			fd.events = POLLIN;
196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (dotimeout)
197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				polltimeout = 1;
198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			else
199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				polltimeout = -1;
200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			status = poll(&fd, 1, polltimeout);
201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (status == -1) {
202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				printf("Poll returns error (%s)\n",
203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    strerror(errno));
204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			} else {
205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				if (status == 0)
206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("Poll timed out\n");
207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				else {
208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					printf("Poll returned a descriptor: ");
209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					if (fd.revents & POLLIN)
210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("readable, ");
211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					else
212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("not readable, ");
213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					if (fd.revents & POLLERR)
214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("exceptional condition, ");
215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					else
216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("no exceptional condition, ");
217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					if (fd.revents & POLLHUP)
218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("disconnect, ");
219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					else
220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("no disconnect, ");
221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					if (fd.revents & POLLNVAL)
222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("invalid\n");
223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					else
224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall						printf("not invalid\n");
225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				}
226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				packet_count = 0;
227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				status = pcap_dispatch(pd, -1, countme,
228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    (u_char *)&packet_count);
229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				if (status < 0)
230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall					break;
231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				printf("%d packets seen, %d packets counted after poll returns\n",
232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				    status, packet_count);
233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else {
236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		for (;;) {
237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			packet_count = 0;
238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			status = pcap_dispatch(pd, -1, countme,
239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    (u_char *)&packet_count);
240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (status < 0)
241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				break;
242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			    status, packet_count);
244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (status == -2) {
247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * We got interrupted, so perhaps we didn't
249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * manage to finish a line we were printing.
250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Print an extra newline, just in case.
251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		putchar('\n');
253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fflush(stdout);
255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (status == -1) {
256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Error.  Report it.
258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    program_name, pcap_geterr(pd));
261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_close(pd);
263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	exit(status == -1 ? 1 : 0);
264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcountme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int *counterp = (int *)user;
270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(*counterp)++;
272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallusage(void)
276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fprintf(stderr, "Usage: %s [ -sptn ] [ -i interface ] [expression]\n",
278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	    program_name);
279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	exit(1);
280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* VARARGS */
283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallerror(const char *fmt, ...)
285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_list ap;
287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fprintf(stderr, "%s: ", program_name);
289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_start(ap, fmt);
290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)vfprintf(stderr, fmt, ap);
291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_end(ap);
292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (*fmt) {
293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		fmt += strlen(fmt);
294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (fmt[-1] != '\n')
295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			(void)fputc('\n', stderr);
296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	exit(1);
298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* NOTREACHED */
299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* VARARGS */
302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallwarning(const char *fmt, ...)
304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_list ap;
306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)fprintf(stderr, "%s: WARNING: ", program_name);
308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_start(ap, fmt);
309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	(void)vfprintf(stderr, fmt, ap);
310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	va_end(ap);
311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (*fmt) {
312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		fmt += strlen(fmt);
313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (fmt[-1] != '\n')
314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			(void)fputc('\n', stderr);
315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copy arg vector into a new buffer, concatenating arguments with spaces.
320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic char *
322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcopy_argv(register char **argv)
323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register char **p;
325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	register u_int len = 0;
326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	char *buf;
327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	char *src, *dst;
328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p = argv;
330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (*p == 0)
331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return 0;
332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while (*p)
334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		len += strlen(*p++) + 1;
335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	buf = (char *)malloc(len);
337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (buf == NULL)
338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		error("copy_argv: malloc");
339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p = argv;
341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dst = buf;
342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while ((src = *p++) != NULL) {
343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		while ((*dst++ = *src++) != '\0')
344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			;
345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		dst[-1] = ' ';
346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dst[-1] = '\0';
348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return buf;
350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
351