X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/90c94a826593a4c543f11ba4cefa71eafb7ae1c0..8c63baec6f9524d8308ef5553d5bae789b1e47b7:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index 7e1f1299..d524b016 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -30,7 +30,7 @@ static const char copyright[] _U_ = "@(#) 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[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.269 2006-05-05 23:13:01 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.283 2008-09-25 21:45:50 guy Exp $ (LBL)"; #endif /* @@ -66,14 +66,15 @@ extern int SIZE_BUF; #include #include #include -#include -#include #ifndef WIN32 +#include +#include #include #include #include #endif /* WIN32 */ + #include "netdissect.h" #include "interface.h" #include "addrtoname.h" @@ -191,7 +192,7 @@ static struct printer printers[] = { #ifdef DLT_LTALK { ltalk_if_print, DLT_LTALK }, #endif -#ifdef DLT_PFLOG +#if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H) { pflog_if_print, DLT_PFLOG }, #endif #ifdef DLT_FR @@ -221,6 +222,9 @@ static struct printer printers[] = { #ifdef DLT_APPLE_IP_OVER_IEEE1394 { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, #endif +#ifdef DLT_IEEE802_11_RADIO_AVS + { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, +#endif #ifdef DLT_JUNIPER_ATM1 { juniper_atm1_print, DLT_JUNIPER_ATM1 }, #endif @@ -268,6 +272,9 @@ static struct printer printers[] = { #endif #ifdef DLT_MFR { mfr_if_print, DLT_MFR }, +#endif +#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) + { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, #endif { NULL, 0 }, }; @@ -327,10 +334,10 @@ show_dlts_and_exit(pcap_t *pd) * OK, does tcpdump handle that type? */ if (lookup_printer(dlts[n_dlts]) == NULL) - (void) fprintf(stderr, " (not supported)"); + (void) fprintf(stderr, " (printing not supported)"); putchar('\n'); } else { - (void) fprintf(stderr, " DLT %d (not supported)\n", + (void) fprintf(stderr, " DLT %d (printing not supported)\n", dlts[n_dlts]); } } @@ -342,13 +349,19 @@ show_dlts_and_exit(pcap_t *pd) * Set up flags that might or might not be supported depending on the * version of libpcap we're using. */ -#ifdef WIN32 +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) #define B_FLAG "B:" #define B_FLAG_USAGE " [ -B size ]" -#else /* WIN32 */ +#else /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ #define B_FLAG #define B_FLAG_USAGE -#endif /* WIN32 */ +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ + +#ifdef HAVE_PCAP_CREATE +#define I_FLAG "I" +#else /* HAVE_PCAP_CREATE */ +#define I_FLAG +#endif /* HAVE_PCAP_CREATE */ #ifdef HAVE_PCAP_FINDALLDEVS #ifndef HAVE_PCAP_IF_T @@ -491,7 +504,6 @@ main(int argc, char **argv) #endif int status; #ifdef WIN32 - u_int UserBufferSize = 1000000; if(wsockinit() != 0) return 1; #endif /* WIN32 */ @@ -523,7 +535,7 @@ main(int argc, char **argv) opterr = 0; while ( - (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) + (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) switch (op) { case 'a': @@ -533,14 +545,17 @@ main(int argc, char **argv) case 'A': ++Aflag; break; + case 'b': + ++bflag; + break; -#ifdef WIN32 +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) case 'B': - UserBufferSize = atoi(optarg)*1024; - if (UserBufferSize < 0) + Bflag = atoi(optarg)*1024; + if (Bflag <= 0) error("invalid packet buffer size %s", optarg); break; -#endif /* WIN32 */ +#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */ case 'c': cnt = atoi(optarg); @@ -647,6 +662,12 @@ main(int argc, char **argv) device = optarg; break; +#ifdef HAVE_PCAP_CREATE + case 'I': + ++Iflag; + break; +#endif /* HAVE_PCAP_CREATE */ + case 'l': #ifdef WIN32 /* @@ -690,7 +711,7 @@ main(int argc, char **argv) #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - tcpmd5secret = optarg; + sigsecret = optarg; break; case 'n': @@ -727,10 +748,10 @@ main(int argc, char **argv) snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' - || snaplen < 0 || snaplen > 65535) + || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); else if (snaplen == 0) - snaplen = 65535; + snaplen = MAXIMUM_SNAPLEN; break; } @@ -935,12 +956,74 @@ main(int argc, char **argv) fflush(stderr); #endif /* WIN32 */ +#ifdef HAVE_PCAP_CREATE + pd = pcap_create(device, ebuf); + if (pd == NULL) + error("%s", ebuf); + status = pcap_set_snaplen(pd, snaplen); + if (status != 0) + error("%s: pcap_set_snaplen failed: %s", + device, pcap_statustostr(status)); + status = pcap_set_promisc(pd, !pflag); + if (status != 0) + error("%s: pcap_set_promisc failed: %s", + device, pcap_statustostr(status)); + if (Iflag) { + status = pcap_set_rfmon(pd, 1); + if (status != 0) + error("%s: pcap_set_rfmon failed: %s", + device, pcap_statustostr(status)); + } + status = pcap_set_timeout(pd, 1000); + if (status != 0) + error("%s: pcap_set_timeout failed: %s", + device, pcap_statustostr(status)); + if (Bflag != 0) { + status = pcap_set_buffer_size(pd, Bflag); + if (status != 0) + error("%s: pcap_set_buffer_size failed: %s", + device, pcap_statustostr(status)); + } + status = pcap_activate(pd); + if (status < 0) { + /* + * pcap_activate() failed. + */ + cp = pcap_geterr(pd); + if (status == PCAP_ERROR) + error("%s", cp); + else if ((status == PCAP_ERROR_NO_SUCH_DEVICE || + status == PCAP_ERROR_PERM_DENIED) && + *cp != '\0') + error("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + error("%s: %s", device, + pcap_statustostr(status)); + } else if (status > 0) { + /* + * pcap_activate() succeeded, but it's warning us + * of a problem it had. + */ + cp = pcap_geterr(pd); + if (status == PCAP_WARNING) + warning("%s", cp); + else if (status == PCAP_WARNING_PROMISC_NOTSUP && + *cp != '\0') + warning("%s: %s\n(%s)", device, + pcap_statustostr(status), cp); + else + warning("%s: %s", device, + pcap_statustostr(status)); + } +#else *ebuf = '\0'; pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); if (pd == NULL) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf); +#endif /* HAVE_PCAP_CREATE */ /* * Let user own process after socket has been opened. */ @@ -948,12 +1031,12 @@ main(int argc, char **argv) if (setgid(getgid()) != 0 || setuid(getuid()) != 0) fprintf(stderr, "Warning: setgid/setuid failed !\n"); #endif /* WIN32 */ -#ifdef WIN32 - if(UserBufferSize != 1000000) - if(pcap_setbuff(pd, UserBufferSize)==-1){ +#if !defined(HAVE_PCAP_CREATE) && defined(WIN32) + if(Bflag != 0) + if(pcap_setbuff(pd, Bflag)==-1){ error("%s", pcap_geterr(pd)); } -#endif /* WIN32 */ +#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ if (Lflag) show_dlts_and_exit(pd); if (gndo->ndo_dlt >= 0) { @@ -1003,10 +1086,10 @@ main(int argc, char **argv) #ifndef WIN32 (void)setsignal(SIGPIPE, cleanup); -#endif /* WIN32 */ (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); (void)setsignal(SIGCHLD, child_cleanup); +#endif /* WIN32 */ /* Cooperate with nohup(1) */ #ifndef WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) @@ -1067,7 +1150,12 @@ main(int argc, char **argv) } #endif /* WIN32 */ #ifdef SIGINFO - (void)setsignal(SIGINFO, requestinfo); + /* + * We can't get statistics when reading from a file rather + * than capturing from a device. + */ + if (RFileName == NULL) + (void)setsignal(SIGINFO, requestinfo); #endif if (vflag > 0 && WFileName) { @@ -1185,11 +1273,17 @@ cleanup(int signo _U_) #endif } +/* + On windows, we do not use a fork, so we do not care less about + waiting a child processes to die + */ +#ifndef WIN32 static RETSIGTYPE child_cleanup(int signo _U_) { wait(NULL); } +#endif /* WIN32 */ static void info(register int verbose) @@ -1198,6 +1292,7 @@ info(register int verbose) if (pcap_stats(pd, &stat) < 0) { (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); + infoprint = 0; return; } @@ -1218,6 +1313,7 @@ info(register int verbose) infoprint = 0; } +#ifndef WIN32 static void compress_savefile(const char *filename) { @@ -1238,6 +1334,14 @@ compress_savefile(const char *filename) filename, strerror(errno)); } +#else /* WIN32 */ +static void +compress_savefile(const char *filename) +{ + fprintf(stderr, + "compress_savefile failed. Functionality not implemented under windows\n"); +} +#endif /* WIN32 */ static void dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) @@ -1571,13 +1675,15 @@ usage(void) #endif /* WIN32 */ #endif /* HAVE_PCAP_LIB_VERSION */ (void)fprintf(stderr, -"Usage: %s [-aAd" D_FLAG "efKlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name); +"Usage: %s [-aAd" D_FLAG "ef" I_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name); (void)fprintf(stderr, -"\t\t[ -E algo:secret ] [ -F file ] [ -G seconds ] [ -i interface ]\n"); +"\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); (void)fprintf(stderr, -"\t\t[ -M secret ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]\n"); +"\t\t[ -i interface ] [ -M secret ] [ -r file ]\n"); (void)fprintf(stderr, -"\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ] [ -Z user ]\n"); +"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n"); + (void)fprintf(stderr, +"\t\t[ -y datalinktype ] [ -z command ] [ -Z user ]\n"); (void)fprintf(stderr, "\t\t[ expression ]\n"); exit(1); @@ -1620,4 +1726,3 @@ ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) (void)fputc('\n', stderr); } } -