X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/6bb10ee1e5d9beca128f30b75003052a853a87eb..9da64383b97c7eb5e93a44eff5acf10ff991967e:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index a93699af..93a77558 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.240 2004-04-05 00:15:52 mcr Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.253.2.10 2005-07-07 01:24:40 guy Exp $ (LBL)"; #endif /* @@ -68,6 +68,7 @@ extern int SIZE_BUF; #ifndef WIN32 #include #include +#include #endif /* WIN32 */ #include "netdissect.h" @@ -89,7 +90,8 @@ netdissect_options *gndo = &Gndo; #define MAX_CFLAG 1000000 #define MAX_CFLAG_CHARS 6 -int Lflag; /* list available data link types and exit */ +int dflag; /* print filter code */ +int Lflag; /* list available data link types and exit */ static int infodelay; static int infoprint; @@ -104,6 +106,7 @@ static void usage(void) __attribute__((noreturn)); static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn)); static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); +static void ndo_default_print(netdissect_options *, const u_char *, u_int); 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 *); @@ -153,6 +156,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 @@ -213,6 +219,39 @@ static struct printer printers[] = { #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 +#ifdef DLT_JUNIPER_MFR + { juniper_mfr_print, DLT_JUNIPER_MFR }, +#endif +#ifdef DLT_JUNIPER_MLFR + { juniper_mlfr_print, DLT_JUNIPER_MLFR }, +#endif +#ifdef DLT_JUNIPER_MLPPP + { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, +#endif +#ifdef DLT_JUNIPER_PPPOE + { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, +#endif +#ifdef DLT_JUNIPER_PPPOE_ATM + { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, +#endif +#ifdef DLT_JUNIPER_GGSN + { juniper_ggsn_print, DLT_JUNIPER_GGSN }, +#endif +#ifdef DLT_JUNIPER_ES + { juniper_es_print, DLT_JUNIPER_ES }, +#endif +#ifdef DLT_JUNIPER_MONITOR + { juniper_monitor_print, DLT_JUNIPER_MONITOR }, +#endif +#ifdef DLT_JUNIPER_SERVICES + { juniper_services_print, DLT_JUNIPER_SERVICES }, #endif { NULL, 0 }, }; @@ -320,7 +359,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); } @@ -328,19 +367,24 @@ 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); } } @@ -382,7 +426,7 @@ static int tcpdump_printf(netdissect_options *ndo _U_, va_end(args); return ret; -}; +} int main(int argc, char **argv) @@ -414,8 +458,8 @@ main(int argc, char **argv) gndo->ndo_Oflag=1; gndo->ndo_Rflag=1; - gndo->ndo_tflag=1; gndo->ndo_dlt=-1; + gndo->ndo_default_print=ndo_default_print; gndo->ndo_printf=tcpdump_printf; gndo->ndo_error=ndo_error; gndo->ndo_warning=ndo_warning; @@ -448,8 +492,6 @@ main(int argc, char **argv) break; case 'A': - ++xflag; - ++Xflag; ++Aflag; break; @@ -611,6 +653,7 @@ main(int argc, char **argv) case 'q': ++qflag; + ++suppress_default_print; break; case 'r': @@ -638,7 +681,7 @@ main(int argc, char **argv) break; case 't': - --tflag; + ++tflag; break; case 'T': @@ -691,11 +734,12 @@ main(int argc, char **argv) case 'x': ++xflag; + ++suppress_default_print; break; case 'X': - ++xflag; ++Xflag; + ++suppress_default_print; break; case 'y': @@ -735,8 +779,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 */ @@ -798,11 +856,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 @@ -1097,7 +1152,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s * larger than Cflag - the last packet written to the * file could put it over Cflag. */ - if (ftell((FILE *)dump_info->p) > Cflag) { + if (pcap_dump_ftell(dump_info->p) > Cflag) { /* * Close the current file and open a new one. */ @@ -1170,15 +1225,34 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) snapend = sp + h->caplen; hdrlen = (*print_info->printer)(h, sp); - if (xflag) { + if (Xflag) { + /* + * Print the raw packet data in hex and ASCII. + */ + if (Xflag > 1) { + /* + * Include the link-layer header. + */ + hex_and_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) + hex_and_ascii_print("\n\t", sp + hdrlen, + h->caplen - hdrlen); + } + } else if (xflag) { /* - * Print the raw packet data. + * Print the raw packet data in hex. */ if (xflag > 1) { /* * 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 @@ -1186,9 +1260,27 @@ 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 (Aflag) { + /* + * Print the raw packet data in ASCII. + */ + if (Aflag > 1) { + /* + * Include the link-layer header. + */ + ascii_print(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(sp + hdrlen, h->caplen - hdrlen); + } } putchar('\n'); @@ -1222,16 +1314,22 @@ 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 /* - * By default, print the specified data out in hex. + * By default, print the specified data out in hex and ASCII. */ +static void +ndo_default_print(netdissect_options *ndo _U_, const u_char *bp, u_int length) +{ + hex_and_ascii_print("\n\t", bp, length); /* pass on lf and identation string */ +} + void -default_print(register const u_char *bp, register u_int length) +default_print(const u_char *bp, u_int length) { - ascii_print("\n\t", bp, length); /* pass on lf and identation string */ + ndo_default_print(gndo, bp, length); } #ifdef SIGINFO @@ -1280,8 +1378,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); @@ -1296,9 +1398,9 @@ usage(void) (void)fprintf(stderr, "\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]\n"); (void)fprintf(stderr, -"\t\t[ -r file ] [ -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); @@ -1307,7 +1409,7 @@ usage(void) /* VARARGS */ -void +static void ndo_error(netdissect_options *ndo _U_, const char *fmt, ...) { va_list ap; @@ -1326,7 +1428,7 @@ ndo_error(netdissect_options *ndo _U_, const char *fmt, ...) } /* VARARGS */ -void +static void ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) { va_list ap;