X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/5738b2ed06f62bcd16f295d639e5144ad4e3ac30..d44f963e59ead8486d097f890ec8ca7c3000a8af:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index e47b95f2..1145d198 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -105,6 +105,9 @@ static int Lflag; /* list available data link types and exit */ #ifdef HAVE_PCAP_SET_TSTAMP_TYPE static int Jflag; /* list available time stamp types */ #endif +#ifdef HAVE_PCAP_SETDIRECTION +int Pflag = PCAP_D_INOUT; /* Restrict captured packet by sent/receive direction */ +#endif static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */ static int infodelay; @@ -330,6 +333,9 @@ static struct ndo_printer ndo_printers[] = { #endif #ifdef DLT_NETANALYZER_TRANSPARENT { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, +#endif +#ifdef DLT_NFLOG + { nflog_if_print, DLT_NFLOG}, #endif { NULL, 0 }, }; @@ -517,6 +523,12 @@ show_dlts_and_exit(const char *device, pcap_t *pd) #define U_FLAG #endif +#ifdef HAVE_PCAP_SETDIRECTION +#define P_FLAG "P:" +#else +#define P_FLAG +#endif + #ifndef WIN32 /* Drop root privileges and chroot if necessary */ static void @@ -632,7 +644,9 @@ static int tcpdump_printf(netdissect_options *ndo _U_, return ret; } -struct print_info get_print_info(int type) { +static struct print_info +get_print_info(int type) +{ struct print_info printinfo; printinfo.ndo_type = 1; @@ -653,10 +667,12 @@ struct print_info get_print_info(int type) { return (printinfo); } -char *get_next_file(FILE *VFile, char *ptr) { +static char * +get_next_file(FILE *VFile, char *ptr) +{ char *ret; - ret = fgets(ptr, NAME_MAX, VFile); + ret = fgets(ptr, PATH_MAX, VFile); if (!ret) return NULL; @@ -685,7 +701,7 @@ main(int argc, char **argv) struct dump_info dumpinfo; u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; - char VFileLine[NAME_MAX + 1]; + char VFileLine[PATH_MAX + 1]; char *username = NULL; char *chroot_dir = NULL; char *ret = NULL; @@ -715,7 +731,9 @@ main(int argc, char **argv) infile = NULL; RFileName = NULL; VFileName = NULL; + VFile = NULL; WFileName = NULL; + dlt = -1; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else @@ -729,7 +747,7 @@ main(int argc, char **argv) #endif while ( - (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "V:vw:W:xXy:Yz:Z:")) != -1) + (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOp" P_FLAG "qr:Rs:StT:u" U_FLAG "V:vw:W:xXy:Yz:Z:")) != -1) switch (op) { case 'a': @@ -951,7 +969,18 @@ main(int argc, char **argv) case 'p': ++pflag; break; - +#ifdef HAVE_PCAP_SETDIRECTION + case 'P': + if (strcasecmp(optarg, "in") == 0) + Pflag = PCAP_D_IN; + else if (strcasecmp(optarg, "out") == 0) + Pflag = PCAP_D_OUT; + else if (strcasecmp(optarg, "inout") == 0) + Pflag = PCAP_D_INOUT; + else + error("unknown capture direction `%s'", optarg); + break; +#endif /* HAVE_PCAP_SETDIRECTION */ case 'q': ++qflag; ++suppress_default_print; @@ -1005,6 +1034,16 @@ main(int argc, char **argv) packettype = PT_CARP; else if (strcasecmp(optarg, "radius") == 0) packettype = PT_RADIUS; + else if (strcasecmp(optarg, "zmtp1") == 0) + packettype = PT_ZMTP1; + else if (strcasecmp(optarg, "vxlan") == 0) + packettype = PT_VXLAN; + else if (strcasecmp(optarg, "pgm") == 0) + packettype = PT_PGM; + else if (strcasecmp(optarg, "pgm_zmtp1") == 0) + packettype = PT_PGM_ZMTP1; + else if (strcasecmp(optarg, "lmp") == 0) + packettype = PT_LMP; else error("unknown packet type `%s'", optarg); break; @@ -1137,6 +1176,15 @@ main(int argc, char **argv) #endif if (RFileName != NULL || VFileName != NULL) { + /* + * If RFileName is non-null, it's the pathname of a + * savefile to read. If VFileName is non-null, it's + * the pathname of a file containing a list of pathnames + * (one per line) of savefiles to read. + * + * In either case, we're reading a savefile, not doing + * a live capture. + */ #ifndef WIN32 /* * We don't need network access, so relinquish any set-UID @@ -1182,14 +1230,21 @@ main(int argc, char **argv) localnet = 0; netmask = 0; } else { + /* + * We're doing a live capture. + */ if (device == NULL) { device = pcap_lookupdev(ebuf); if (device == NULL) error("%s", ebuf); } #ifdef WIN32 - 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) + /* + * Print a message to the standard error on Windows. + * XXX - why do it here, with a different message? + */ + 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 @@ -1278,6 +1333,12 @@ main(int argc, char **argv) warning("%s: %s", device, pcap_statustostr(status)); } +#ifdef HAVE_PCAP_SETDIRECTION + status = pcap_setdirection(pd, Pflag); + if (status != 0) + error("%s: pcap_set_direction failed: %s", + device, pcap_geterr(pd)); +#endif #else *ebuf = '\0'; pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); @@ -1478,6 +1539,11 @@ main(int argc, char **argv) #ifndef WIN32 if (RFileName == NULL) { + /* + * Live capture (if -V was specified, we set RFileName + * to a file from the -V file). Print a message to + * the standard error on UN*X. + */ if (!vflag && !WFileName) { (void)fprintf(stderr, "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", @@ -1514,6 +1580,14 @@ main(int argc, char **argv) } (void)fflush(stdout); } + if (status == -2) { + /* + * We got interrupted. If we are reading multiple + * files (via -V) set these so that we stop. + */ + VFileName = NULL; + ret = NULL; + } if (status == -1) { /* * Error. Report it. @@ -2050,6 +2124,10 @@ usage(void) "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); (void)fprintf(stderr, "\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n"); +#ifdef HAVE_PCAP_SETDIRECTION + (void)fprintf(stderr, +"\t\t[ -P in|out|inout ]\n"); +#endif (void)fprintf(stderr, "\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -V file ] [ -w file ]\n"); (void)fprintf(stderr,