From: Wesley Shields Date: Mon, 10 Sep 2012 17:05:53 +0000 (-0400) Subject: Merge remote-tracking branch 'upstream/master' X-Git-Tag: tcpdump-4.4.0~22^2~2 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/1afd3f308e25f7bf070f3932a28ed6b2be8173f6?hp=-c Merge remote-tracking branch 'upstream/master' --- 1afd3f308e25f7bf070f3932a28ed6b2be8173f6 diff --combined tcpdump.c index 59aae527,98ec2d5d..c43ab854 --- a/tcpdump.c +++ b/tcpdump.c @@@ -589,6 -589,8 +589,8 @@@ static voi MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) { char *filename = malloc(NAME_MAX + 1); + if (filename == NULL) + error("Makefilename: malloc); /* Process with strftime if Gflag is set. */ if (Gflag != 0) { @@@ -630,51 -632,14 +632,51 @@@ static int tcpdump_printf(netdissect_op return ret; } +struct print_info get_print_info(int type) { + struct print_info printinfo; + + printinfo.ndo_type = 1; + printinfo.ndo = gndo; + printinfo.p.ndo_printer = lookup_ndo_printer(type); + if (printinfo.p.ndo_printer == NULL) { + printinfo.p.printer = lookup_printer(type); + printinfo.ndo_type = 0; + if (printinfo.p.printer == NULL) { + gndo->ndo_dltname = pcap_datalink_val_to_name(type); + if (gndo->ndo_dltname != NULL) + error("packet printing is not supported for link type %s: use -w", + gndo->ndo_dltname); + else + error("packet printing is not supported for link type %d: use -w", type); + } + } + return (printinfo); +} + +char *get_next_file(FILE *VFile, char *ptr) { + char *ret; + + ret = fgets(ptr, NAME_MAX, VFile); + if (!ret) + return NULL; + + if (ptr[strlen(ptr) - 1] == '\n') + ptr[strlen(ptr) - 1] = '\0'; + + return ret; +} + int main(int argc, char **argv) { register int cnt, op, i; bpf_u_int32 localnet, netmask; - register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName; + register char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName; pcap_handler callback; int type; + int dlt; + int new_dlt; + const char *dlt_name; struct bpf_program fcode; #ifndef WIN32 RETSIGTYPE (*oldhandler)(int); @@@ -683,16 -648,13 +685,16 @@@ struct dump_info dumpinfo; u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; + char VFileLine[NAME_MAX + 1]; char *username = NULL; char *chroot_dir = NULL; + char *ret = NULL; #ifdef HAVE_PCAP_FINDALLDEVS pcap_if_t *devpointer; int devnum; #endif int status; + FILE *VFile; #ifdef WIN32 if(wsockinit() != 0) return 1; #endif /* WIN32 */ @@@ -711,7 -673,6 +713,7 @@@ device = NULL; infile = NULL; RFileName = NULL; + VFileName = NULL; WFileName = NULL; if ((cp = strrchr(argv[0], '/')) != NULL) program_name = cp + 1; @@@ -726,7 -687,7 +728,7 @@@ #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 "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:nNOpqr:Rs:StT:u" U_FLAG "V:vw:W:xXy:Yz:Z:")) != -1) switch (op) { case 'a': @@@ -1022,10 -983,6 +1024,10 @@@ ++vflag; break; + case 'V': + VFileName = optarg; + break; + case 'w': WFileName = optarg; break; @@@ -1111,12 -1068,6 +1113,12 @@@ break; } + if (fflag != 0 && (VFileName != NULL || RFileName != NULL)) + error("-f can not be used with -V or -r"); + + if (VFileName != NULL && RFileName != NULL) + error("-V and -r are mutually exclusive."); + #ifdef WITH_CHROOT /* if run as root, prepare for chrooting */ if (getuid() == 0 || geteuid() == 0) { @@@ -1135,7 -1086,10 +1137,7 @@@ } #endif - if (RFileName != NULL) { - int dlt; - const char *dlt_name; - + if (RFileName != NULL || VFileName != NULL) { #ifndef WIN32 /* * We don't need network access, so relinquish any set-UID @@@ -1149,21 -1103,6 +1151,21 @@@ if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) fprintf(stderr, "Warning: setgid/setuid failed !\n"); #endif /* WIN32 */ + if (VFileName != NULL) { + if (VFileName[0] == '-' && VFileName[1] == '\0') + VFile = stdin; + else + VFile = fopen(VFileName, "r"); + + if (VFile == NULL) + error("Unable to open file: %s\n", strerror(errno)); + + ret = get_next_file(VFile, VFileLine); + if (!ret) + error("Nothing in %s\n", VFileName); + RFileName = VFileLine; + } + pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) error("%s", ebuf); @@@ -1180,6 -1119,8 +1182,6 @@@ } localnet = 0; netmask = 0; - if (fflag != 0) - error("-f and -r options are incompatible"); } else { if (device == NULL) { device = pcap_lookupdev(ebuf); @@@ -1337,10 -1278,10 +1339,10 @@@ if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) error("%s", pcap_geterr(pd)); - free(cmdbuf); if (dflag) { bpf_dump(&fcode, dflag); pcap_close(pd); + free(cmdbuf); exit(0); } init_addrtoname(localnet, netmask); @@@ -1445,7 -1386,21 +1447,7 @@@ #endif } else { type = pcap_datalink(pd); - printinfo.ndo_type = 1; - printinfo.ndo = gndo; - printinfo.p.ndo_printer = lookup_ndo_printer(type); - if (printinfo.p.ndo_printer == NULL) { - printinfo.p.printer = lookup_printer(type); - printinfo.ndo_type = 0; - if (printinfo.p.printer == NULL) { - gndo->ndo_dltname = pcap_datalink_val_to_name(type); - if (gndo->ndo_dltname != NULL) - error("packet printing is not supported for link type %s: use -w", - gndo->ndo_dltname); - else - error("packet printing is not supported for link type %d: use -w", type); - } - } + printinfo = get_print_info(type); callback = print_packet; pcap_userdata = (u_char *)&printinfo; } @@@ -1477,6 -1432,9 +1479,6 @@@ #ifndef WIN32 if (RFileName == NULL) { - int dlt; - const char *dlt_name; - if (!vflag && !WFileName) { (void)fprintf(stderr, "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", @@@ -1496,69 -1454,37 +1498,69 @@@ (void)fflush(stderr); } #endif /* WIN32 */ - status = pcap_loop(pd, cnt, callback, pcap_userdata); - if (WFileName == NULL) { - /* - * We're printing packets. Flush the printed output, - * so it doesn't get intermingled with error output. - */ - if (status == -2) { + do { + status = pcap_loop(pd, cnt, callback, pcap_userdata); + if (WFileName == NULL) { /* - * We got interrupted, so perhaps we didn't - * manage to finish a line we were printing. - * Print an extra newline, just in case. + * We're printing packets. Flush the printed output, + * so it doesn't get intermingled with error output. */ - putchar('\n'); + if (status == -2) { + /* + * We got interrupted, so perhaps we didn't + * manage to finish a line we were printing. + * Print an extra newline, just in case. + */ + putchar('\n'); + } + (void)fflush(stdout); + } + if (status == -1) { + /* + * Error. Report it. + */ + (void)fprintf(stderr, "%s: pcap_loop: %s\n", + program_name, pcap_geterr(pd)); + } + if (RFileName == NULL) { + /* + * We're doing a live capture. Report the capture + * statistics. + */ + info(1); + } + pcap_close(pd); + if (VFileName != NULL) { + ret = get_next_file(VFile, VFileLine); + if (ret) { + RFileName = VFileLine; + pd = pcap_open_offline(RFileName, ebuf); + if (pd == NULL) + error("%s", ebuf); + new_dlt = pcap_datalink(pd); + if (WFileName && new_dlt != dlt) + error("%s: new dlt does not match original", RFileName); + printinfo = get_print_info(new_dlt); + dlt_name = pcap_datalink_val_to_name(new_dlt); + if (dlt_name == NULL) { + fprintf(stderr, "reading from file %s, link-type %u\n", + RFileName, new_dlt); + } else { + fprintf(stderr, + "reading from file %s, link-type %s (%s)\n", + RFileName, dlt_name, + pcap_datalink_val_to_description(new_dlt)); + } + if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) + error("%s", pcap_geterr(pd)); + if (pcap_setfilter(pd, &fcode) < 0) + error("%s", pcap_geterr(pd)); + } } - (void)fflush(stdout); - } - if (status == -1) { - /* - * Error. Report it. - */ - (void)fprintf(stderr, "%s: pcap_loop: %s\n", - program_name, pcap_geterr(pd)); - } - if (RFileName == NULL) { - /* - * We're doing a live capture. Report the capture - * statistics. - */ - info(1); } - pcap_close(pd); + while (ret != NULL); + + free(cmdbuf); exit(status == -1 ? 1 : 0); } @@@ -2050,7 -1976,7 +2052,7 @@@ usage(void (void)fprintf(stderr, "\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n"); (void)fprintf(stderr, -"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]\n"); +"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -V file ] [ -w file ]\n"); (void)fprintf(stderr, "\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ]\n"); (void)fprintf(stderr,