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 struct bpf_program fcode; 61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char ebuf[PCAP_ERRBUF_SIZE]; 62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int status; 63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int packet_count; 64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall device = NULL; 66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((cp = strrchr(argv[0], '/')) != NULL) 67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall program_name = cp + 1; 68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else 69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall program_name = argv[0]; 70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall opterr = 0; 72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while ((op = getopt(argc, argv, "i:")) != -1) { 73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (op) { 74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case 'i': 76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall device = optarg; 77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall usage(); 81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (device == NULL) { 86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall device = pcap_lookupdev(ebuf); 87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (device == NULL) 88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error("%s", ebuf); 89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *ebuf = '\0'; 91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pd = pcap_open_live(device, 65535, 0, 1000, ebuf); 92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pd == NULL) 93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error("%s", ebuf); 94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall else if (*ebuf) 95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall warning("%s", ebuf); 96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { 97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall localnet = 0; 98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall netmask = 0; 99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall warning("%s", ebuf); 100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall cmdbuf = copy_argv(&argv[optind]); 102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0) 104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error("%s", pcap_geterr(pd)); 105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_setfilter(pd, &fcode) < 0) 107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error("%s", pcap_geterr(pd)); 108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (pcap_setnonblock(pd, 1, ebuf) == -1) 109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error("pcap_setnonblock failed: %s", ebuf); 110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall printf("Listening on %s\n", device); 111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall for (;;) { 112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall packet_count = 0; 113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall status = pcap_dispatch(pd, -1, countme, 114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (u_char *)&packet_count); 115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (status < 0) 116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (status != 0) { 118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall printf("%d packets seen, %d packets counted after pcap_dispatch returns\n", 119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall status, packet_count); 120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (status == -2) { 123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * We got interrupted, so perhaps we didn't 125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * manage to finish a line we were printing. 126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Print an extra newline, just in case. 127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall putchar('\n'); 129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)fflush(stdout); 131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (status == -1) { 132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Error. Report it. 134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)fprintf(stderr, "%s: pcap_loop: %s\n", 136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall program_name, pcap_geterr(pd)); 137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_close(pd); 139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall exit(status == -1 ? 1 : 0); 140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcountme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int *counterp = (int *)user; 146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (*counterp)++; 148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallusage(void) 152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)fprintf(stderr, "Usage: %s [ -sptn ] [ -i interface ] [expression]\n", 154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall program_name); 155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall exit(1); 156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* VARARGS */ 159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallerror(const char *fmt, ...) 161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall va_list ap; 163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)fprintf(stderr, "%s: ", program_name); 165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall va_start(ap, fmt); 166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)vfprintf(stderr, fmt, ap); 167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall va_end(ap); 168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (*fmt) { 169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall fmt += strlen(fmt); 170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (fmt[-1] != '\n') 171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)fputc('\n', stderr); 172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall exit(1); 174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* NOTREACHED */ 175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* VARARGS */ 178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallwarning(const char *fmt, ...) 180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall va_list ap; 182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)fprintf(stderr, "%s: WARNING: ", program_name); 184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall va_start(ap, fmt); 185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)vfprintf(stderr, fmt, ap); 186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall va_end(ap); 187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (*fmt) { 188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall fmt += strlen(fmt); 189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (fmt[-1] != '\n') 190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void)fputc('\n', stderr); 191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copy arg vector into a new buffer, concatenating arguments with spaces. 196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic char * 198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcopy_argv(register char **argv) 199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall register char **p; 201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall register u_int len = 0; 202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *buf; 203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall char *src, *dst; 204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p = argv; 206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (*p == 0) 207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return 0; 208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while (*p) 210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall len += strlen(*p++) + 1; 211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall buf = (char *)malloc(len); 213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (buf == NULL) 214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall error("copy_argv: malloc"); 215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p = argv; 217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall dst = buf; 218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while ((src = *p++) != NULL) { 219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while ((*dst++ = *src++) != '\0') 220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ; 221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall dst[-1] = ' '; 222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall dst[-1] = '\0'; 224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return buf; 226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 227