X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/73a1c3892c1b33aa5dd4ede34cb686f90676ed29..3e12b0b42cd8d08df77a02374ffae47c23748bf1:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index 785dce7a..8f2e5e3a 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -30,7 +30,7 @@ static const char copyright[] = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ The Regents of the University of California. All rights reserved.\n"; static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.174 2002-02-05 10:07:40 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.186 2002-09-05 21:25:51 guy Exp $ (LBL)"; #endif /* @@ -45,18 +45,22 @@ static const char rcsid[] = #include "config.h" #endif -#include -#include +#include -#include +#ifdef WIN32 +#include "getopt.h" +#include "w32_fzs.h" +extern int strcasecmp (const char *__s1, const char *__s2); +extern int SIZE_BUF; +#define off_t long +#define uint UINT +#endif /* WIN32 */ #include #include #include #include #include -#include -#include #include "interface.h" @@ -83,6 +87,7 @@ int vflag; /* verbose */ int xflag; /* print packet in hex */ int Xflag; /* print packet in ascii as well as hex */ off_t Cflag = 0; /* rotate dump files after this many bytes */ +int Aflag = 0; /* print packet only in ascii observing LF, CR, TAB, SPACE */ char *espsecret = NULL; /* ESP secret key */ @@ -160,6 +165,15 @@ static struct printer printers[] = { #endif #ifdef DLT_PFLOG { pflog_if_print, DLT_PFLOG }, +#endif +#ifdef DLT_FR + { fr_if_print, DLT_FR }, +#endif +#ifdef DLT_FRELAY + { fr_if_print, DLT_FRELAY }, +#endif +#ifdef DLT_SUNATM + { sunatm_if_print, DLT_SUNATM }, #endif { NULL, 0 }, }; @@ -197,10 +211,27 @@ main(int argc, char **argv) register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName; pcap_handler printer; struct bpf_program fcode; +#ifndef WIN32 RETSIGTYPE (*oldhandler)(int); +#endif struct dump_info dumpinfo; u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; +#ifdef HAVE_PCAP_FINDALLDEVS + pcap_if_t *devpointer; + int devnum; +#endif +#ifdef WIN32 + DWORD dwVersion; + DWORD dwWindowsMajorVersion; + u_int UserBufferSize=1000000; +#endif + +#ifdef WIN32 + dwVersion=GetVersion(); /* get the OS version */ + dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); + if(wsockinit()!=0) return 1; +#endif /* WIN32 */ cnt = -1; device = NULL; @@ -218,16 +249,38 @@ main(int argc, char **argv) #ifdef LIBSMI smiInit("tcpdump"); #endif - + opterr = 0; while ( - (op = getopt(argc, argv, "ac:C:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1) +#ifdef WIN32 + (op = getopt(argc, argv, "aAB:c:C:dDeE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1) +#else /* WIN32 */ +#ifdef HAVE_PCAP_FINDALLDEVS + (op = getopt(argc, argv, "aAc:C:dDeE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1) +#else /* HAVE_PCAP_FINDALLDEVS */ + (op = getopt(argc, argv, "aAc:C:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1) +#endif /* HAVE_PCAP_FINDALLDEVS */ +#endif /* WIN32 */ switch (op) { case 'a': ++aflag; break; + case 'A': + ++xflag; + ++Xflag; + ++Aflag; + break; + +#ifdef WIN32 + case 'B': + UserBufferSize = atoi(optarg)*1024; + if (UserBufferSize < 0) + error("invalid packet buffer size %s", optarg); + break; +#endif /* WIN32 */ + case 'c': cnt = atoi(optarg); if (cnt <= 0) @@ -236,7 +289,7 @@ main(int argc, char **argv) case 'C': Cflag = atoi(optarg) * 1000000; - if (Cflag < 0) + if (Cflag < 0) error("invalid file size %s", optarg); break; @@ -244,6 +297,22 @@ main(int argc, char **argv) ++dflag; break; +#ifdef HAVE_PCAP_FINDALLDEVS + case 'D': + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + for (i = 0; devpointer != 0; i++) { + printf("%d.%s", i+1, devpointer->name); + if (devpointer->description != NULL) + printf(" (%s)", devpointer->description); + printf("\n"); + devpointer = devpointer->next; + } + } + return 0; +#endif /* HAVE_PCAP_FINDALLDEVS */ + case 'e': ++eflag; break; @@ -264,6 +333,37 @@ main(int argc, char **argv) break; case 'i': + if (optarg[0] == '0' && optarg[1] == 0) + error("Invalid adapter index"); + +#ifdef HAVE_PCAP_FINDALLDEVS + /* + * If the argument is a number, treat it as + * an index into the list of adapters, as + * printed by "tcpdump -D". + * + * This should be OK on UNIX systems, as interfaces + * shouldn't have names that begin with digits. + * It can be useful on Windows, where more than + * one interface can have the same name. + */ + if ((devnum = atoi(optarg)) != 0) { + if (devnum < 0) + error("Invalid adapter index"); + + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + for (i = 0; i < devnum-1; i++){ + devpointer = devpointer->next; + if (devpointer == NULL) + error("Invalid adapter index"); + } + } + device = devpointer->name; + break; + } +#endif /* HAVE_PCAP_FINDALLDEVS */ device = optarg; break; @@ -294,7 +394,7 @@ main(int argc, char **argv) program_name, optarg); (void)fprintf(stderr, "(no libsmi support)\n"); #endif - + case 'O': Oflag = 0; break; @@ -357,7 +457,7 @@ main(int argc, char **argv) case 'u': ++uflag; break; - + case 'v': ++vflag; break; @@ -371,16 +471,21 @@ main(int argc, char **argv) break; case 'X': - ++xflag; + ++xflag; ++Xflag; break; -#ifdef YYDEBUG +#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) case 'Y': { /* Undocumented flag */ +#ifdef HAVE_PCAP_DEBUG + extern int pcap_debug; + pcap_debug = 1; +#else extern int yydebug; yydebug = 1; +#endif } break; #endif @@ -401,7 +506,9 @@ main(int argc, char **argv) * Also, this prevents the user from reading anyone's * trace file. */ +#ifndef WIN32 setuid(getuid()); +#endif /* WIN32 */ pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) @@ -416,12 +523,21 @@ main(int argc, char **argv) if (device == NULL) error("%s", ebuf); } +#ifdef WIN32 + PrintCapBegins(program_name,device); +#endif /* WIN32 */ *ebuf = '\0'; pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); if (pd == NULL) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf); +#ifdef WIN32 + if(UserBufferSize != 1000000) + if(pcap_setbuff(pd, UserBufferSize)==-1){ + error("%s", pcap_geterr(pd)); + } +#endif /* WIN32 */ i = pcap_snapshot(pd); if (snaplen < i) { warning("snaplen raised from %d to %d", snaplen, i); @@ -435,7 +551,9 @@ main(int argc, char **argv) /* * Let user own process after socket has been opened. */ +#ifndef WIN32 setuid(getuid()); +#endif /* WIN32 */ } if (infile) cmdbuf = read_infile(infile); @@ -446,6 +564,7 @@ main(int argc, char **argv) error("%s", pcap_geterr(pd)); if (dflag) { bpf_dump(&fcode, dflag); + pcap_close(pd); exit(0); } init_addrtoname(localnet, netmask); @@ -453,8 +572,10 @@ main(int argc, char **argv) (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); /* Cooperate with nohup(1) */ +#ifndef WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); +#endif /* WIN32 */ if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); @@ -479,14 +600,18 @@ main(int argc, char **argv) (void)setsignal(SIGINFO, requestinfo); #endif } +#ifndef WIN32 if (RFileName == NULL) { (void)fprintf(stderr, "%s: listening on %s\n", program_name, device); (void)fflush(stderr); } +#endif /* WIN32 */ if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) { (void)fprintf(stderr, "%s: pcap_loop: %s\n", program_name, pcap_geterr(pd)); + cleanup(0); + pcap_close(pd); exit(1); } if (RFileName == NULL) @@ -506,7 +631,8 @@ cleanup(int signo) putc('\n', stderr); info(1); } - exit(0); + if (signo) + exit(0); } void @@ -518,8 +644,10 @@ info(register int verbose) (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); return; } + if (!verbose) fprintf(stderr, "%s: ", program_name); + (void)fprintf(stderr, "%d packets received by filter", stat.ps_recv); if (!verbose) fputs(", ", stderr); @@ -564,7 +692,7 @@ dump_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) char *name; info = (struct dump_info *)user; - + /* * XXX - this won't prevent capture files from getting * larger than Cflag - the last packet written to the @@ -613,6 +741,31 @@ default_print_unaligned(register const u_char *cp, register u_int length) } } +#ifdef WIN32 + /* + * XXX - there should really be libpcap calls to get the version + * number as a string (the string would be generated from #defines + * at run time, so that it's not generated from string constants + * in the library, as, on many UNIX systems, those constants would + * be statically linked into the application executable image, and + * would thus reflect the version of libpcap on the system on + * which the application was *linked*, not the system on which it's + * *running*. + * + * That routine should be documented, unlike the "version[]" + * string, so that UNIX vendors providing their own libpcaps + * don't omit it (as a couple of vendors have...). + * + * Packet.dll should perhaps also export a routine to return the + * version number of the Packet.dll code, to supply the + * "Wpcap_version" information on Windows. + */ + char WDversion[]="current-cvs.tcpdump.org"; + char version[]="current-cvs.tcpdump.org"; + char pcap_version[]="current-cvs.tcpdump.org"; + char Wpcap_version[]="3.0 alpha"; +#endif + /* * By default, print the packet out in hex. */ @@ -623,7 +776,7 @@ default_print(register const u_char *bp, register u_int length) } #ifdef SIGINFO -RETSIGTYPE requestinfo(int signo) +RETSIGTYPE requestinfo(int signo _U_) { if (infodelay) ++infoprint; @@ -636,12 +789,29 @@ static void usage(void) { extern char version[]; +#if defined(WIN32) || defined(HAVE_PCAP_VERSION) extern char pcap_version[]; +#else + static char pcap_version[] = "unknown"; +#endif +#ifdef WIN32 + (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); + (void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version); +#else (void)fprintf(stderr, "%s version %s\n", program_name, version); (void)fprintf(stderr, "libpcap version %s\n", pcap_version); +#endif /* WIN32 */ (void)fprintf(stderr, -"Usage: %s [-adeflnNOpqRStuvxX] [ -c count ] [ -C file_size ]\n", program_name); +#ifdef WIN32 +"Usage: %s [-aAdDeflnNOpqRStuvxX] [-B size] [-c count] [ -C file_size ]\n", program_name); +#else /* WIN32 */ +#ifdef HAVE_PCAP_FINDALLDEVS +"Usage: %s [-aAdDeflnNOpqRStuvxX] [-c count] [ -C file_size ]\n", program_name); +#else /* HAVE_PCAP_FINDALLDEVS */ +"Usage: %s [-aAdeflnNOpqRStuvxX] [-c count] [ -C file_size ]\n", program_name); +#endif /* HAVE_PCAP_FINDALLDEVS */ +#endif /* WIN32 */ (void)fprintf(stderr, "\t\t[ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ]\n"); (void)fprintf(stderr,