Skip to content

Commit 87501b7

Browse files
committed
Fix --time-stamp-precision when used with -V
Capture files were opened in two different bits of code. Only the first bit of code acquired support for --time-stamp-precision, so the 2nd and subsequent files opened with -V would always have the default timestamp precision. This fix unifies file opening into a single routine, ensuring consistent behavior for each opened file.
1 parent e570e6b commit 87501b7

File tree

5 files changed

+71
-57
lines changed

5 files changed

+71
-57
lines changed

tcpdump.c

+54-56
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,56 @@ get_next_file(FILE *VFile, char *ptr)
895895
return ret;
896896
}
897897

898+
static int
899+
open_pcap_file(const char *path, const netdissect_options *ndo)
900+
{
901+
int dlt;
902+
const char *dlt_name;
903+
char ebuf[PCAP_ERRBUF_SIZE];
904+
#ifdef DLT_LINUX_SLL2
905+
static int sll_warning_printed = 0;
906+
#endif /* DLT_LINUX_SLL2 */
907+
#ifdef HAVE_CAPSICUM
908+
cap_rights_t rights;
909+
#endif /* HAVE_CAPSICUM */
910+
911+
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
912+
pd = pcap_open_offline_with_tstamp_precision(path,
913+
ndo->ndo_tstamp_precision, ebuf);
914+
#else
915+
pd = pcap_open_offline(path, ebuf);
916+
#endif
917+
918+
if (pd == NULL)
919+
error("%s", ebuf);
920+
#ifdef HAVE_CAPSICUM
921+
cap_rights_init(&rights, CAP_READ);
922+
if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
923+
errno != ENOSYS) {
924+
error("unable to limit pcap descriptor");
925+
}
926+
#endif
927+
dlt = pcap_datalink(pd);
928+
dlt_name = pcap_datalink_val_to_name(dlt);
929+
fprintf(stderr, "reading from file %s", path);
930+
if (dlt_name == NULL) {
931+
fprintf(stderr, ", link-type %u", dlt);
932+
} else {
933+
fprintf(stderr, ", link-type %s (%s)", dlt_name,
934+
pcap_datalink_val_to_description(dlt));
935+
}
936+
fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
937+
#ifdef DLT_LINUX_SLL2
938+
if (!sll_warning_printed && dlt == DLT_LINUX_SLL2)
939+
{
940+
fprintf(stderr, "Warning: interface names might be incorrect\n");
941+
sll_warning_printed = 1;
942+
}
943+
#endif
944+
945+
return dlt;
946+
}
947+
898948
#ifdef HAVE_CASPER
899949
static cap_channel_t *
900950
capdns_setup(void)
@@ -1476,7 +1526,6 @@ main(int argc, char **argv)
14761526
char *endp;
14771527
pcap_handler callback;
14781528
int dlt;
1479-
const char *dlt_name;
14801529
struct bpf_program fcode;
14811530
#ifndef _WIN32
14821531
void (*oldhandler)(int);
@@ -2121,36 +2170,7 @@ main(int argc, char **argv)
21212170
RFileName = VFileLine;
21222171
}
21232172

2124-
#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
2125-
pd = pcap_open_offline_with_tstamp_precision(RFileName,
2126-
ndo->ndo_tstamp_precision, ebuf);
2127-
#else
2128-
pd = pcap_open_offline(RFileName, ebuf);
2129-
#endif
2130-
2131-
if (pd == NULL)
2132-
error("%s", ebuf);
2133-
#ifdef HAVE_CAPSICUM
2134-
cap_rights_init(&rights, CAP_READ);
2135-
if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
2136-
errno != ENOSYS) {
2137-
error("unable to limit pcap descriptor");
2138-
}
2139-
#endif
2140-
dlt = pcap_datalink(pd);
2141-
dlt_name = pcap_datalink_val_to_name(dlt);
2142-
fprintf(stderr, "reading from file %s", RFileName);
2143-
if (dlt_name == NULL) {
2144-
fprintf(stderr, ", link-type %u", dlt);
2145-
} else {
2146-
fprintf(stderr, ", link-type %s (%s)", dlt_name,
2147-
pcap_datalink_val_to_description(dlt));
2148-
}
2149-
fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
2150-
#ifdef DLT_LINUX_SLL2
2151-
if (dlt == DLT_LINUX_SLL2)
2152-
fprintf(stderr, "Warning: interface names might be incorrect\n");
2153-
#endif
2173+
dlt = open_pcap_file(RFileName, ndo);
21542174
} else if (dflag && !device) {
21552175
int dump_dlt = DLT_EN10MB;
21562176
/*
@@ -2604,6 +2624,8 @@ DIAG_ON_ASSIGN_ENUM
26042624
* to a file from the -V file). Print a message to
26052625
* the standard error on UN*X.
26062626
*/
2627+
const char *dlt_name;
2628+
26072629
if (!ndo->ndo_vflag && !WFileName) {
26082630
(void)fprintf(stderr,
26092631
"%s: verbose output suppressed, use -v[v]... for full protocol decode\n",
@@ -2683,17 +2705,7 @@ DIAG_ON_ASSIGN_ENUM
26832705
int new_dlt;
26842706

26852707
RFileName = VFileLine;
2686-
pd = pcap_open_offline(RFileName, ebuf);
2687-
if (pd == NULL)
2688-
error("%s", ebuf);
2689-
#ifdef HAVE_CAPSICUM
2690-
cap_rights_init(&rights, CAP_READ);
2691-
if (cap_rights_limit(fileno(pcap_file(pd)),
2692-
&rights) < 0 && errno != ENOSYS) {
2693-
error("unable to limit pcap descriptor");
2694-
}
2695-
#endif
2696-
new_dlt = pcap_datalink(pd);
2708+
new_dlt = open_pcap_file(RFileName, ndo);
26972709
if (new_dlt != dlt) {
26982710
/*
26992711
* The new file has a different
@@ -2735,20 +2747,6 @@ DIAG_ON_ASSIGN_ENUM
27352747
*/
27362748
if (pcap_setfilter(pd, &fcode) < 0)
27372749
error("%s", pcap_geterr(pd));
2738-
2739-
/*
2740-
* Report the new file.
2741-
*/
2742-
dlt_name = pcap_datalink_val_to_name(dlt);
2743-
fprintf(stderr, "reading from file %s", RFileName);
2744-
if (dlt_name == NULL) {
2745-
fprintf(stderr, ", link-type %u", dlt);
2746-
} else {
2747-
fprintf(stderr, ", link-type %s (%s)",
2748-
dlt_name,
2749-
pcap_datalink_val_to_description(dlt));
2750-
}
2751-
fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
27522750
}
27532751
}
27542752
}

tests/TESTLIST

+5
Original file line numberDiff line numberDiff line change
@@ -933,3 +933,8 @@ ip6-snmp-oid-unsigned ip6-snmp-oid-unsigned.pcap ip6-snmp-oid-unsigned.out
933933
lwres-pointer-arithmetic-ub lwres-pointer-arithmetic-ub.pcap lwres-pointer-arithmetic-ub.out
934934
ospf-signed-integer-ubsan ospf-signed-integer-ubsan.pcap ospf-signed-integer-ubsan.out -vv
935935
bgp-ub bgp-ub.pcap bgp-ub.out -v
936+
937+
# Multi-file tests
938+
# Note the input is not a pcap file, but a file that contains a list of pcap files
939+
multifile-timestamp multifile-timestamp.pcap-list multifile-timestamp.out -V --nano
940+

tests/TESTrun

+8-1
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,20 @@ sub runtest {
101101
my $stderrlog = "tests/NEW/${outputbase}.stderr";
102102
my $diffstat = 0;
103103
my $errdiffstat = 0;
104+
my $inputswitch = '-r';
105+
106+
if ($options =~ s/(^|\s+)-V\b//) {
107+
# If the options contains '-V', remove it from there and place it
108+
# before the input file name.
109+
$inputswitch = '-V';
110+
}
104111

105112
# we used to do this as a nice pipeline, but the problem is that $r fails to
106113
# to be set properly if the tcpdump core dumps.
107114
#
108115
# Furthermore, on Windows, fc can't read the standard input, so we
109116
# can't do it as a pipeline in any case.
110-
$r = system "$TCPDUMP -# -n -r $input $options >tests/NEW/${outputbase} 2>${rawstderrlog}";
117+
$r = system "$TCPDUMP -# -n $inputswitch $input $options >tests/NEW/${outputbase} 2>${rawstderrlog}";
111118
if($r != 0) {
112119
#
113120
# Something other than "tcpdump opened the file, read it, and

tests/multifile-timestamp.out

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
1 06:15:22.659099 1.0 Mb/s 2412 MHz 11b 100 sq antenna 0 57dB signal DeAuthentication (00:0d:93:82:36:3a): Reserved
2+
2 06:15:22.659099 1.0 Mb/s 2412 MHz 11b 100 sq antenna 0 57dB signal DeAuthentication (00:0d:93:82:36:3a): Reserved

tests/multifile-timestamp.pcap-list

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tests/reason_code-0.pcap
2+
tests/reason_code-0.pcap

0 commit comments

Comments
 (0)