X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/6d6270c6b45def7bffa1c87aba1b5ffb8b53e92e..3e12b0b42cd8d08df77a02374ffae47c23748bf1:/tcpdump.c?ds=sidebyside diff --git a/tcpdump.c b/tcpdump.c index 30fdce8b..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.178 2002-07-11 08:09:47 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" @@ -167,6 +171,9 @@ static struct printer printers[] = { #endif #ifdef DLT_FRELAY { fr_if_print, DLT_FRELAY }, +#endif +#ifdef DLT_SUNATM + { sunatm_if_print, DLT_SUNATM }, #endif { NULL, 0 }, }; @@ -204,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; @@ -228,7 +252,15 @@ main(int argc, char **argv) opterr = 0; while ( +#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': @@ -241,6 +273,14 @@ main(int argc, char **argv) ++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) @@ -257,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; @@ -277,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; @@ -388,12 +475,17 @@ main(int argc, char **argv) ++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 @@ -414,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) @@ -429,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); @@ -448,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); @@ -459,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); @@ -466,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)); @@ -492,11 +600,13 @@ 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)); @@ -534,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); @@ -629,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. */ @@ -639,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; @@ -652,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 [-aAdeflnNOpqRStuvxX] [ -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,