Home | History | Annotate | Download | only in tests
      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
     23 static const char copyright[] =
     24     "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
     25 The 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 
     38 static char *program_name;
     39 
     40 /* Forwards */
     41 static void usage(void) __attribute__((noreturn));
     42 static void error(const char *, ...);
     43 static void warning(const char *, ...);
     44 
     45 extern int optind;
     46 extern int opterr;
     47 extern char *optarg;
     48 
     49 int
     50 main(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 
     59 	device = NULL;
     60 	dorfmon = 0;
     61 	dopromisc = 0;
     62 	snaplen = MAXIMUM_SNAPLEN;
     63 	bufsize = 0;
     64 	useactivate = 0;
     65 	if ((cp = strrchr(argv[0], '/')) != NULL)
     66 		program_name = cp + 1;
     67 	else
     68 		program_name = argv[0];
     69 
     70 	opterr = 0;
     71 	while ((op = getopt(argc, argv, "i:Ips:aB:")) != -1) {
     72 		switch (op) {
     73 
     74 		case 'i':
     75 			device = optarg;
     76 			break;
     77 
     78 		case 'I':
     79 			dorfmon = 1;
     80 			useactivate = 1;	/* required for rfmon */
     81 			break;
     82 
     83 		case 'p':
     84 			dopromisc = 1;
     85 			break;
     86 
     87 		case 's': {
     88 			char *end;
     89 
     90 			snaplen = strtol(optarg, &end, 0);
     91 			if (optarg == end || *end != '\0'
     92 			    || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN)
     93 				error("invalid snaplen %s", optarg);
     94 			else if (snaplen == 0)
     95 				snaplen = MAXIMUM_SNAPLEN;
     96 			break;
     97 		}
     98 
     99 		case 'B':
    100 			bufsize = atoi(optarg)*1024;
    101 			if (bufsize <= 0)
    102 				error("invalid packet buffer size %s", optarg);
    103 			useactivate = 1;	/* required for bufsize */
    104 			break;
    105 
    106 		case 'a':
    107 			useactivate = 1;
    108 			break;
    109 
    110 		default:
    111 			usage();
    112 			/* NOTREACHED */
    113 		}
    114 	}
    115 
    116 	if (useactivate) {
    117 		pd = pcap_create(device, ebuf);
    118 		if (pd == NULL)
    119 			error("%s", ebuf);
    120 		status = pcap_set_snaplen(pd, snaplen);
    121 		if (status != 0)
    122 			error("%s: pcap_set_snaplen failed: %s",
    123 			    device, pcap_statustostr(status));
    124 		if (dopromisc) {
    125 			status = pcap_set_promisc(pd, 1);
    126 			if (status != 0)
    127 				error("%s: pcap_set_promisc failed: %s",
    128 				    device, pcap_statustostr(status));
    129 		}
    130 		if (dorfmon) {
    131 			status = pcap_set_rfmon(pd, 1);
    132 			if (status != 0)
    133 				error("%s: pcap_set_rfmon failed: %s",
    134 				    device, pcap_statustostr(status));
    135 		}
    136 		status = pcap_set_timeout(pd, 1000);
    137 		if (status != 0)
    138 			error("%s: pcap_set_timeout failed: %s",
    139 			    device, pcap_statustostr(status));
    140 		if (bufsize != 0) {
    141 			status = pcap_set_buffer_size(pd, bufsize);
    142 			if (status != 0)
    143 				error("%s: pcap_set_buffer_size failed: %s",
    144 				    device, pcap_statustostr(status));
    145 		}
    146 		status = pcap_activate(pd);
    147 		if (status < 0) {
    148 			/*
    149 			 * pcap_activate() failed.
    150 			 */
    151 			error("%s: %s\n(%s)", device,
    152 			    pcap_statustostr(status), pcap_geterr(pd));
    153 		} else if (status > 0) {
    154 			/*
    155 			 * pcap_activate() succeeded, but it's warning us
    156 			 * of a problem it had.
    157 			 */
    158 			warning("%s: %s\n(%s)", device,
    159 			    pcap_statustostr(status), pcap_geterr(pd));
    160 		}
    161 	} else {
    162 		*ebuf = '\0';
    163 		pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
    164 		if (pd == NULL)
    165 			error("%s", ebuf);
    166 		else if (*ebuf)
    167 			warning("%s", ebuf);
    168 	}
    169 	pcap_close(pd);
    170 	exit(status < 0 ? 1 : 0);
    171 }
    172 
    173 static void
    174 usage(void)
    175 {
    176 	(void)fprintf(stderr,
    177 	    "Usage: %s [ -Ipa ] [ -i interface ] [ -s snaplen ] [ -B bufsize ]\n",
    178 	    program_name);
    179 	exit(1);
    180 }
    181 
    182 /* VARARGS */
    183 static void
    184 error(const char *fmt, ...)
    185 {
    186 	va_list ap;
    187 
    188 	(void)fprintf(stderr, "%s: ", program_name);
    189 	va_start(ap, fmt);
    190 	(void)vfprintf(stderr, fmt, ap);
    191 	va_end(ap);
    192 	if (*fmt) {
    193 		fmt += strlen(fmt);
    194 		if (fmt[-1] != '\n')
    195 			(void)fputc('\n', stderr);
    196 	}
    197 	exit(1);
    198 	/* NOTREACHED */
    199 }
    200 
    201 /* VARARGS */
    202 static void
    203 warning(const char *fmt, ...)
    204 {
    205 	va_list ap;
    206 
    207 	(void)fprintf(stderr, "%s: WARNING: ", program_name);
    208 	va_start(ap, fmt);
    209 	(void)vfprintf(stderr, fmt, ap);
    210 	va_end(ap);
    211 	if (*fmt) {
    212 		fmt += strlen(fmt);
    213 		if (fmt[-1] != '\n')
    214 			(void)fputc('\n', stderr);
    215 	}
    216 }
    217