X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/6d605cea6d44577717311d651f579e6fd795f057..3a0c6efa53b5200e6df9dc2e7513a32503af3ca6:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index e3693e73..35c11532 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.232 2004-02-25 14:23:32 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.250 2004-11-07 22:05:20 guy Exp $ (LBL)"; #endif /* @@ -65,9 +65,13 @@ extern int SIZE_BUF; #include #include #include +#ifndef WIN32 #include #include +#include +#endif /* WIN32 */ +#include "netdissect.h" #include "interface.h" #include "addrtoname.h" #include "machdep.h" @@ -75,30 +79,8 @@ extern int SIZE_BUF; #include "gmt2local.h" #include "pcap-missing.h" -int dflag; /* print filter code */ -int eflag; /* print ethernet header */ -int fflag; /* don't translate "foreign" IP address */ -static int Lflag; /* list available data link types and exit */ -int nflag; /* leave addresses as numbers */ -int Nflag; /* remove domains from printed host names */ -static int Oflag = 1; /* run filter code optimizer */ -static int pflag; /* don't go promiscuous */ -int qflag; /* quick (shorter) output */ -int Rflag = 1; /* print sequence # field in AH/ESP*/ -int sflag = 0; /* use the libsmi to translate OIDs */ -int Sflag; /* print raw TCP sequence numbers */ -int tflag = 1; /* print packet arrival time */ -int Uflag = 0; /* "unbuffered" output of dump files */ -int uflag = 0; /* Print undecoded NFS handles */ -int vflag; /* verbose */ -int xflag; /* print packet in hex */ -int Xflag; /* print packet in ascii as well as hex */ -static off_t Cflag = 0; /* rotate dump files after this many bytes */ -int Aflag = 0; /* print packet only in ascii observing LF, CR, TAB, SPACE */ -static int dlt = -1; /* if != -1, ask libpcap for the DLT it names */ -static int Cflag_count = 0; /* Keep track of which file number we're writing */ -static int Wflag = 0; /* recycle output files after this number of files */ -static int WflagChars = 0; +netdissect_options Gndo; +netdissect_options *gndo = &Gndo; /* * Define the maximum number of files for the -C flag, and how many @@ -108,11 +90,8 @@ static int WflagChars = 0; #define MAX_CFLAG 1000000 #define MAX_CFLAG_CHARS 6 -const char *dlt_name = NULL; - -char *espsecret = NULL; /* ESP secret key */ - -int packettype; +int dflag; /* print filter code */ +int Lflag; /* list available data link types and exit */ static int infodelay; static int infoprint; @@ -130,6 +109,8 @@ static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void droproot(const char *, const char *); +static void ndo_error(netdissect_options *ndo, const char *fmt, ...); +static void ndo_warning(netdissect_options *ndo, const char *fmt, ...); #ifdef SIGINFO RETSIGTYPE requestinfo(int); @@ -146,9 +127,6 @@ RETSIGTYPE requestinfo(int); static void info(int); static u_int packets_captured; -/* Length of saved portion of packet. */ -int snaplen = DEFAULT_SNAPLEN; - typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); struct printer { @@ -177,6 +155,9 @@ static struct printer printers[] = { { sl_bsdos_if_print, DLT_SLIP_BSDOS }, #endif { ppp_if_print, DLT_PPP }, +#ifdef DLT_PPP_WITHDIRECTION + { ppp_if_print, DLT_PPP_WITHDIRECTION }, +#endif #ifdef DLT_PPP_BSDOS { ppp_bsdos_if_print, DLT_PPP_BSDOS }, #endif @@ -231,6 +212,18 @@ static struct printer printers[] = { #endif #ifdef DLT_ENC { enc_if_print, DLT_ENC }, +#endif +#ifdef DLT_SYMANTEC_FIREWALL + { symantec_if_print, DLT_SYMANTEC_FIREWALL }, +#endif +#ifdef DLT_APPLE_IP_OVER_IEEE1394 + { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, +#endif +#ifdef DLT_JUNIPER_ATM1 + { juniper_atm1_print, DLT_JUNIPER_ATM1 }, +#endif +#ifdef DLT_JUNIPER_ATM2 + { juniper_atm2_print, DLT_JUNIPER_ATM2 }, #endif { NULL, 0 }, }; @@ -312,6 +305,12 @@ show_dlts_and_exit(pcap_t *pd) #define B_FLAG_USAGE #endif /* WIN32 */ +#ifdef HAVE_PCAP_FINDALLDEVS +#ifndef HAVE_PCAP_IF_T +#undef HAVE_PCAP_FINDALLDEVS +#endif +#endif + #ifdef HAVE_PCAP_FINDALLDEVS #define D_FLAG "D" #else @@ -324,6 +323,7 @@ show_dlts_and_exit(pcap_t *pd) #define U_FLAG #endif +#ifndef WIN32 /* Drop root privileges and chroot if necessary */ static void droproot(const char *username, const char *chroot_dir) @@ -331,7 +331,7 @@ droproot(const char *username, const char *chroot_dir) struct passwd *pw = NULL; if (chroot_dir && !username) { - fprintf(stderr, "Chroot without dropping root is insecure\n"); + fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n"); exit(1); } @@ -339,22 +339,28 @@ droproot(const char *username, const char *chroot_dir) if (pw) { if (chroot_dir) { if (chroot(chroot_dir) != 0 || chdir ("/") != 0) { - fprintf(stderr, "Couldn't chroot/chdir to '%.64s'\n", chroot_dir); + fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n", + chroot_dir, pcap_strerror(errno)); exit(1); } } - if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || - setuid(pw->pw_uid) != 0) { - fprintf(stderr, "Couldn't change to '%.32s' uid=%d gid=%d\n", username, - pw->pw_uid, pw->pw_gid); + if (initgroups(pw->pw_name, pw->pw_gid) != 0 || + setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { + fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", + username, + (unsigned long)pw->pw_uid, + (unsigned long)pw->pw_gid, + pcap_strerror(errno)); exit(1); } } else { - fprintf(stderr, "Couldn't find user '%.32s'\n", username); + fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n", + username); exit(1); } } +#endif /* WIN32 */ static int getWflagChars(int x) @@ -380,6 +386,20 @@ MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) sprintf(buffer, "%s%0*d", orig_name, max_chars, cnt); } +static int tcpdump_printf(netdissect_options *ndo _U_, + const char *fmt, ...) +{ + + va_list args; + int ret; + + va_start(args, fmt); + ret=vfprintf(stdout, fmt, args); + va_end(args); + + return ret; +} + int main(int argc, char **argv) { @@ -408,6 +428,14 @@ main(int argc, char **argv) if(wsockinit() != 0) return 1; #endif /* WIN32 */ + gndo->ndo_Oflag=1; + gndo->ndo_Rflag=1; + gndo->ndo_dlt=-1; + gndo->ndo_printf=tcpdump_printf; + gndo->ndo_error=ndo_error; + gndo->ndo_warning=ndo_warning; + gndo->ndo_snaplen = DEFAULT_SNAPLEN; + cnt = -1; device = NULL; infile = NULL; @@ -427,7 +455,7 @@ main(int argc, char **argv) opterr = 0; while ( - (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:YZ:")) != -1) + (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:YZ:")) != -1) switch (op) { case 'a': @@ -492,7 +520,7 @@ main(int argc, char **argv) #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - espsecret = optarg; + gndo->ndo_espsecret = optarg; break; case 'f': @@ -580,6 +608,14 @@ main(int argc, char **argv) #endif break; + case 'M': + /* TCP-MD5 shared secret */ +#ifndef HAVE_LIBCRYPTO + warning("crypto code not compiled in"); +#endif + tcpmd5secret = optarg; + break; + case 'O': Oflag = 0; break; @@ -617,7 +653,7 @@ main(int argc, char **argv) break; case 't': - --tflag; + ++tflag; break; case 'T': @@ -673,15 +709,15 @@ main(int argc, char **argv) break; case 'X': - ++xflag; ++Xflag; break; case 'y': - dlt_name = optarg; - dlt = pcap_datalink_name_to_val(dlt_name); - if (dlt < 0) - error("invalid data link type %s", dlt_name); + gndo->ndo_dltname = optarg; + gndo->ndo_dlt = + pcap_datalink_name_to_val(gndo->ndo_dltname); + if (gndo->ndo_dlt < 0) + error("invalid data link type %s", gndo->ndo_dltname); break; #if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) @@ -713,8 +749,22 @@ main(int argc, char **argv) /* NOTREACHED */ } - if (tflag > 0) + switch (tflag) { + + case 0: /* Default */ + case 4: /* Default + Date*/ thiszone = gmt2local(0); + break; + + case 1: /* No time stamp */ + case 2: /* Unix timeval style */ + case 3: /* Microseconds since previous packet */ + break; + + default: /* Not supported */ + error("only -t, -tt, -ttt, and -tttt are supported"); + break; + } #ifdef WITH_CHROOT /* if run as root, prepare for chrooting */ @@ -776,11 +826,8 @@ main(int argc, char **argv) error("%s", ebuf); } #ifdef WIN32 - if(IsTextUnicode(device, - wcslen((short*)device), // Device always ends with a double \0, so this way to determine its - // length should be always valid - NULL)) - { + if(strlen(device) == 1) //we assume that an ASCII string is always longer than 1 char + { //a Unicode string has a \0 as second byte (so strlen() is 1) fprintf(stderr, "%s: listening on %ws\n", program_name, device); } else @@ -811,9 +858,9 @@ main(int argc, char **argv) #endif /* WIN32 */ if (Lflag) show_dlts_and_exit(pd); - if (dlt >= 0) { + if (gndo->ndo_dlt >= 0) { #ifdef HAVE_PCAP_SET_DATALINK - if (pcap_set_datalink(pd, dlt) < 0) + if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) error("%s", pcap_geterr(pd)); #else /* @@ -821,13 +868,13 @@ main(int argc, char **argv) * data link type, so we only let them * set it to what it already is. */ - if (dlt != pcap_datalink(pd)) { + if (gndo->ndo_dlt != pcap_datalink(pd)) { error("%s is not one of the DLTs supported by this device\n", - dlt_name); + gndo->ndo_dltname); } #endif (void)fprintf(stderr, "%s: data link type %s\n", - program_name, dlt_name); + program_name, gndo->ndo_dltname); (void)fflush(stderr); } i = pcap_snapshot(pd); @@ -892,9 +939,10 @@ main(int argc, char **argv) type = pcap_datalink(pd); printinfo.printer = lookup_printer(type); if (printinfo.printer == NULL) { - dlt_name = pcap_datalink_val_to_name(type); - if (dlt_name != NULL) - error("unsupported data link type %s", dlt_name); + gndo->ndo_dltname = pcap_datalink_val_to_name(type); + if (gndo->ndo_dltname != NULL) + error("unsupported data link type %s", + gndo->ndo_dltname); else error("unsupported data link type %d", type); } @@ -906,8 +954,10 @@ main(int argc, char **argv) * We cannot do this earlier, because we want to be able to open * the file (if done) for writing before giving up permissions. */ - if (username || chroot_dir) - droproot(username, chroot_dir); + if (getuid() == 0 || geteuid() == 0) { + if (username || chroot_dir) + droproot(username, chroot_dir); + } #endif /* WIN32 */ #ifdef SIGINFO (void)setsignal(SIGINFO, requestinfo); @@ -1153,7 +1203,7 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) /* * Include the link-layer header. */ - default_print(sp, h->caplen); + hex_print("\n\t", sp, h->caplen); } else { /* * Don't include the link-layer header - and if @@ -1161,7 +1211,26 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) * print nothing. */ if (h->caplen > hdrlen) - default_print(sp + hdrlen, + hex_print("\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (Xflag) { + /* + * Print the raw packet data. + */ + if (Xflag > 1) { + /* + * Include the link-layer header. + */ + ascii_print("\n\t", sp, h->caplen); + } else { + /* + * Don't include the link-layer header - and if + * we have nothing past the link-layer header, + * print nothing. + */ + if (h->caplen > hdrlen) + ascii_print("\n\t", sp + hdrlen, h->caplen - hdrlen); } } @@ -1197,7 +1266,7 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) char version[]="current-cvs.tcpdump.org"; #endif char pcap_version[]="current-cvs.tcpdump.org"; - char Wpcap_version[]="3.0 alpha"; + char Wpcap_version[]="3.1"; #endif /* @@ -1206,7 +1275,7 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) void default_print(register const u_char *bp, register u_int length) { - ascii_print("\n\t", bp, length); /* pass on lf and identation string */ + ascii_print("\n\t", bp, length); /* pass on lf and identation string */ } #ifdef SIGINFO @@ -1255,8 +1324,12 @@ usage(void) #endif /* HAVE_PCAP_LIB_VERSION */ #ifdef HAVE_PCAP_LIB_VERSION +#ifdef WIN32 + (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); +#else /* WIN32 */ (void)fprintf(stderr, "%s version %s\n", program_name, version); - (void)fprintf(stderr, "%s\n", pcap_lib_version()); +#endif /* WIN32 */ + (void)fprintf(stderr, "%s\n",pcap_lib_version()); #else /* HAVE_PCAP_LIB_VERSION */ #ifdef WIN32 (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); @@ -1269,12 +1342,51 @@ usage(void) (void)fprintf(stderr, "Usage: %s [-aAd" D_FLAG "eflLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name); (void)fprintf(stderr, -"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -r file ]\n"); +"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]\n"); (void)fprintf(stderr, -"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n"); +"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]\n"); (void)fprintf(stderr, -"\t\t[ -y datalinktype ] [ -Z user ]\n"); +"\t\t[ -W filecount ] [ -y datalinktype ] [ -Z user ]\n"); (void)fprintf(stderr, "\t\t[ expression ]\n"); exit(1); } + + + +/* VARARGS */ +static void +ndo_error(netdissect_options *ndo _U_, const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } + exit(1); + /* NOTREACHED */ +} + +/* VARARGS */ +static void +ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) +{ + va_list ap; + + (void)fprintf(stderr, "%s: WARNING: ", program_name); + va_start(ap, fmt); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + if (*fmt) { + fmt += strlen(fmt); + if (fmt[-1] != '\n') + (void)fputc('\n', stderr); + } +} +