1190214Srpaulo/* 2190214Srpaulo * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 3190214Srpaulo * The Regents of the University of California. All rights reserved. 4190214Srpaulo * 5190214Srpaulo * Redistribution and use in source and binary forms, with or without 6190214Srpaulo * modification, are permitted provided that: (1) source code distributions 7190214Srpaulo * retain the above copyright notice and this paragraph in its entirety, (2) 8190214Srpaulo * distributions including binary code include the above copyright notice and 9190214Srpaulo * this paragraph in its entirety in the documentation or other materials 10190214Srpaulo * provided with the distribution, and (3) all advertising materials mentioning 11190214Srpaulo * features or use of this software display the following acknowledgement: 12190214Srpaulo * ``This product includes software developed by the University of California, 13190214Srpaulo * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14190214Srpaulo * the University nor the names of its contributors may be used to endorse 15190214Srpaulo * or promote products derived from this software without specific prior 16190214Srpaulo * written permission. 17190214Srpaulo * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18190214Srpaulo * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19190214Srpaulo * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20190214Srpaulo */ 21190214Srpaulo 22190214Srpaulo#ifndef lint 23190214Srpaulostatic const char copyright[] _U_ = 24190214Srpaulo "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ 25190214SrpauloThe Regents of the University of California. All rights reserved.\n"; 26190214Srpaulostatic const char rcsid[] _U_ = 27214455Srpaulo "@(#) $Header: /tcpdump/master/libpcap/filtertest.c,v 1.2 2005-08-08 17:50:13 guy Exp $ (LBL)"; 28190214Srpaulo#endif 29190214Srpaulo 30190214Srpaulo#ifdef HAVE_CONFIG_H 31190214Srpaulo#include "config.h" 32190214Srpaulo#endif 33190214Srpaulo 34190214Srpaulo#include <pcap.h> 35190214Srpaulo#include <stdio.h> 36190214Srpaulo#include <stdlib.h> 37190214Srpaulo#include <string.h> 38190214Srpaulo#include <stdarg.h> 39190214Srpaulo#include <unistd.h> 40190214Srpaulo#include <fcntl.h> 41190214Srpaulo#include <errno.h> 42214455Srpaulo#include <arpa/inet.h> 43190214Srpaulo#include <sys/types.h> 44190214Srpaulo#include <sys/stat.h> 45190214Srpaulo 46190214Srpaulo#ifndef HAVE___ATTRIBUTE__ 47190214Srpaulo#define __attribute__(x) 48190214Srpaulo#endif 49190214Srpaulo 50190214Srpaulostatic char *program_name; 51190214Srpaulo 52190214Srpaulo/* Forwards */ 53190214Srpaulostatic void usage(void) __attribute__((noreturn)); 54190214Srpaulostatic void error(const char *, ...) 55190214Srpaulo __attribute__((noreturn, format (printf, 1, 2))); 56190214Srpaulo 57190214Srpauloextern int optind; 58190214Srpauloextern int opterr; 59190214Srpauloextern char *optarg; 60190214Srpaulo 61190214Srpaulo/* 62190214Srpaulo * On Windows, we need to open the file in binary mode, so that 63190214Srpaulo * we get all the bytes specified by the size we get from "fstat()". 64190214Srpaulo * On UNIX, that's not necessary. O_BINARY is defined on Windows; 65190214Srpaulo * we define it as 0 if it's not defined, so it does nothing. 66190214Srpaulo */ 67190214Srpaulo#ifndef O_BINARY 68190214Srpaulo#define O_BINARY 0 69190214Srpaulo#endif 70190214Srpaulo 71190214Srpaulostatic char * 72190214Srpauloread_infile(char *fname) 73190214Srpaulo{ 74190214Srpaulo register int i, fd, cc; 75190214Srpaulo register char *cp; 76190214Srpaulo struct stat buf; 77190214Srpaulo 78190214Srpaulo fd = open(fname, O_RDONLY|O_BINARY); 79190214Srpaulo if (fd < 0) 80190214Srpaulo error("can't open %s: %s", fname, pcap_strerror(errno)); 81190214Srpaulo 82190214Srpaulo if (fstat(fd, &buf) < 0) 83190214Srpaulo error("can't stat %s: %s", fname, pcap_strerror(errno)); 84190214Srpaulo 85190214Srpaulo cp = malloc((u_int)buf.st_size + 1); 86190214Srpaulo if (cp == NULL) 87190214Srpaulo error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1, 88190214Srpaulo fname, pcap_strerror(errno)); 89190214Srpaulo cc = read(fd, cp, (u_int)buf.st_size); 90190214Srpaulo if (cc < 0) 91190214Srpaulo error("read %s: %s", fname, pcap_strerror(errno)); 92190214Srpaulo if (cc != buf.st_size) 93190214Srpaulo error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); 94190214Srpaulo 95190214Srpaulo close(fd); 96190214Srpaulo /* replace "# comment" with spaces */ 97190214Srpaulo for (i = 0; i < cc; i++) { 98190214Srpaulo if (cp[i] == '#') 99190214Srpaulo while (i < cc && cp[i] != '\n') 100190214Srpaulo cp[i++] = ' '; 101190214Srpaulo } 102190214Srpaulo cp[cc] = '\0'; 103190214Srpaulo return (cp); 104190214Srpaulo} 105190214Srpaulo 106190214Srpaulo/* VARARGS */ 107190214Srpaulostatic void 108190214Srpauloerror(const char *fmt, ...) 109190214Srpaulo{ 110190214Srpaulo va_list ap; 111190214Srpaulo 112190214Srpaulo (void)fprintf(stderr, "%s: ", program_name); 113190214Srpaulo va_start(ap, fmt); 114190214Srpaulo (void)vfprintf(stderr, fmt, ap); 115190214Srpaulo va_end(ap); 116190214Srpaulo if (*fmt) { 117190214Srpaulo fmt += strlen(fmt); 118190214Srpaulo if (fmt[-1] != '\n') 119190214Srpaulo (void)fputc('\n', stderr); 120190214Srpaulo } 121190214Srpaulo exit(1); 122190214Srpaulo /* NOTREACHED */ 123190214Srpaulo} 124190214Srpaulo 125190214Srpaulo/* 126190214Srpaulo * Copy arg vector into a new buffer, concatenating arguments with spaces. 127190214Srpaulo */ 128190214Srpaulostatic char * 129190214Srpaulocopy_argv(register char **argv) 130190214Srpaulo{ 131190214Srpaulo register char **p; 132190214Srpaulo register u_int len = 0; 133190214Srpaulo char *buf; 134190214Srpaulo char *src, *dst; 135190214Srpaulo 136190214Srpaulo p = argv; 137190214Srpaulo if (*p == 0) 138190214Srpaulo return 0; 139190214Srpaulo 140190214Srpaulo while (*p) 141190214Srpaulo len += strlen(*p++) + 1; 142190214Srpaulo 143190214Srpaulo buf = (char *)malloc(len); 144190214Srpaulo if (buf == NULL) 145190214Srpaulo error("copy_argv: malloc"); 146190214Srpaulo 147190214Srpaulo p = argv; 148190214Srpaulo dst = buf; 149190214Srpaulo while ((src = *p++) != NULL) { 150190214Srpaulo while ((*dst++ = *src++) != '\0') 151190214Srpaulo ; 152190214Srpaulo dst[-1] = ' '; 153190214Srpaulo } 154190214Srpaulo dst[-1] = '\0'; 155190214Srpaulo 156190214Srpaulo return buf; 157190214Srpaulo} 158190214Srpaulo 159190214Srpauloint 160190214Srpaulomain(int argc, char **argv) 161190214Srpaulo{ 162190214Srpaulo char *cp; 163190214Srpaulo int op; 164190214Srpaulo int dflag; 165190214Srpaulo char *infile; 166190214Srpaulo int Oflag; 167190214Srpaulo long snaplen; 168190214Srpaulo int dlt; 169214455Srpaulo bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN; 170190214Srpaulo char *cmdbuf; 171190214Srpaulo pcap_t *pd; 172190214Srpaulo struct bpf_program fcode; 173190214Srpaulo 174190214Srpaulo#ifdef WIN32 175190214Srpaulo if(wsockinit() != 0) return 1; 176190214Srpaulo#endif /* WIN32 */ 177190214Srpaulo 178190214Srpaulo dflag = 1; 179190214Srpaulo infile = NULL; 180190214Srpaulo Oflag = 1; 181190214Srpaulo snaplen = 68; 182190214Srpaulo 183190214Srpaulo if ((cp = strrchr(argv[0], '/')) != NULL) 184190214Srpaulo program_name = cp + 1; 185190214Srpaulo else 186190214Srpaulo program_name = argv[0]; 187190214Srpaulo 188190214Srpaulo opterr = 0; 189214455Srpaulo while ((op = getopt(argc, argv, "dF:m:Os:")) != -1) { 190190214Srpaulo switch (op) { 191190214Srpaulo 192190214Srpaulo case 'd': 193190214Srpaulo ++dflag; 194190214Srpaulo break; 195190214Srpaulo 196190214Srpaulo case 'F': 197190214Srpaulo infile = optarg; 198190214Srpaulo break; 199190214Srpaulo 200190214Srpaulo case 'O': 201190214Srpaulo Oflag = 0; 202190214Srpaulo break; 203190214Srpaulo 204214455Srpaulo case 'm': { 205214455Srpaulo in_addr_t addr; 206214455Srpaulo 207214455Srpaulo addr = inet_addr(optarg); 208214455Srpaulo if (addr == INADDR_NONE) 209214455Srpaulo error("invalid netmask %s", optarg); 210214455Srpaulo netmask = addr; 211214455Srpaulo break; 212214455Srpaulo } 213214455Srpaulo 214190214Srpaulo case 's': { 215190214Srpaulo char *end; 216190214Srpaulo 217190214Srpaulo snaplen = strtol(optarg, &end, 0); 218190214Srpaulo if (optarg == end || *end != '\0' 219190214Srpaulo || snaplen < 0 || snaplen > 65535) 220190214Srpaulo error("invalid snaplen %s", optarg); 221190214Srpaulo else if (snaplen == 0) 222190214Srpaulo snaplen = 65535; 223190214Srpaulo break; 224190214Srpaulo } 225190214Srpaulo 226190214Srpaulo default: 227190214Srpaulo usage(); 228190214Srpaulo /* NOTREACHED */ 229190214Srpaulo } 230190214Srpaulo } 231190214Srpaulo 232190214Srpaulo if (optind >= argc) { 233190214Srpaulo usage(); 234190214Srpaulo /* NOTREACHED */ 235190214Srpaulo } 236190214Srpaulo 237190214Srpaulo dlt = pcap_datalink_name_to_val(argv[optind]); 238190214Srpaulo if (dlt < 0) 239190214Srpaulo error("invalid data link type %s", argv[optind]); 240190214Srpaulo 241190214Srpaulo if (infile) 242190214Srpaulo cmdbuf = read_infile(infile); 243190214Srpaulo else 244190214Srpaulo cmdbuf = copy_argv(&argv[optind+1]); 245190214Srpaulo 246190214Srpaulo pd = pcap_open_dead(dlt, snaplen); 247190214Srpaulo if (pd == NULL) 248190214Srpaulo error("Can't open fake pcap_t"); 249190214Srpaulo 250214455Srpaulo if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) 251190214Srpaulo error("%s", pcap_geterr(pd)); 252190214Srpaulo bpf_dump(&fcode, dflag); 253190214Srpaulo pcap_close(pd); 254190214Srpaulo exit(0); 255190214Srpaulo} 256190214Srpaulo 257190214Srpaulostatic void 258190214Srpaulousage(void) 259190214Srpaulo{ 260190214Srpaulo (void)fprintf(stderr, "%s, with %s\n", program_name, 261190214Srpaulo pcap_lib_version()); 262190214Srpaulo (void)fprintf(stderr, 263214455Srpaulo "Usage: %s [-dO] [ -F file ] [ -m netmask] [ -s snaplen ] dlt [ expression ]\n", 264190214Srpaulo program_name); 265190214Srpaulo exit(1); 266190214Srpaulo} 267