Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix --time-stamp-precision when used with -V #1078

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 55 additions & 56 deletions tcpdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,57 @@ get_next_file(FILE *VFile, char *ptr)
return ret;
}

static int
open_pcap_file(const char *path, const netdissect_options *ndo)
{
int dlt;
const char *dlt_name;
char ebuf[PCAP_ERRBUF_SIZE];
#ifdef DLT_LINUX_SLL2
static int sll_warning_printed = 0;
#endif /* DLT_LINUX_SLL2 */
#ifdef HAVE_CAPSICUM
cap_rights_t rights;
#endif /* HAVE_CAPSICUM */

#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
pd = pcap_open_offline_with_tstamp_precision(path,
ndo->ndo_tstamp_precision, ebuf);
#else
pd = pcap_open_offline(path, ebuf);
(void)ndo; /* placate -Wunused-parameter */
#endif

if (pd == NULL)
error("%s", ebuf);
#ifdef HAVE_CAPSICUM
cap_rights_init(&rights, CAP_READ);
if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
#endif
dlt = pcap_datalink(pd);
dlt_name = pcap_datalink_val_to_name(dlt);
fprintf(stderr, "reading from file %s", path);
if (dlt_name == NULL) {
fprintf(stderr, ", link-type %u", dlt);
} else {
fprintf(stderr, ", link-type %s (%s)", dlt_name,
pcap_datalink_val_to_description(dlt));
}
fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
#ifdef DLT_LINUX_SLL2
if (!sll_warning_printed && dlt == DLT_LINUX_SLL2)
{
fprintf(stderr, "Warning: interface names might be incorrect\n");
sll_warning_printed = 1;
}
#endif

return dlt;
}

#ifdef HAVE_CASPER
static cap_channel_t *
capdns_setup(void)
Expand Down Expand Up @@ -1476,7 +1527,6 @@ main(int argc, char **argv)
char *endp;
pcap_handler callback;
int dlt;
const char *dlt_name;
struct bpf_program fcode;
#ifndef _WIN32
void (*oldhandler)(int);
Expand Down Expand Up @@ -2121,36 +2171,7 @@ main(int argc, char **argv)
RFileName = VFileLine;
}

#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
pd = pcap_open_offline_with_tstamp_precision(RFileName,
ndo->ndo_tstamp_precision, ebuf);
#else
pd = pcap_open_offline(RFileName, ebuf);
#endif

if (pd == NULL)
error("%s", ebuf);
#ifdef HAVE_CAPSICUM
cap_rights_init(&rights, CAP_READ);
if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
#endif
dlt = pcap_datalink(pd);
dlt_name = pcap_datalink_val_to_name(dlt);
fprintf(stderr, "reading from file %s", RFileName);
if (dlt_name == NULL) {
fprintf(stderr, ", link-type %u", dlt);
} else {
fprintf(stderr, ", link-type %s (%s)", dlt_name,
pcap_datalink_val_to_description(dlt));
}
fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
#ifdef DLT_LINUX_SLL2
if (dlt == DLT_LINUX_SLL2)
fprintf(stderr, "Warning: interface names might be incorrect\n");
#endif
dlt = open_pcap_file(RFileName, ndo);
} else if (dflag && !device) {
int dump_dlt = DLT_EN10MB;
/*
Expand Down Expand Up @@ -2604,6 +2625,8 @@ DIAG_ON_ASSIGN_ENUM
* to a file from the -V file). Print a message to
* the standard error on UN*X.
*/
const char *dlt_name;

if (!ndo->ndo_vflag && !WFileName) {
(void)fprintf(stderr,
"%s: verbose output suppressed, use -v[v]... for full protocol decode\n",
Expand Down Expand Up @@ -2683,17 +2706,7 @@ DIAG_ON_ASSIGN_ENUM
int new_dlt;

RFileName = VFileLine;
pd = pcap_open_offline(RFileName, ebuf);
if (pd == NULL)
error("%s", ebuf);
#ifdef HAVE_CAPSICUM
cap_rights_init(&rights, CAP_READ);
if (cap_rights_limit(fileno(pcap_file(pd)),
&rights) < 0 && errno != ENOSYS) {
error("unable to limit pcap descriptor");
}
#endif
new_dlt = pcap_datalink(pd);
new_dlt = open_pcap_file(RFileName, ndo);
if (new_dlt != dlt) {
/*
* The new file has a different
Expand Down Expand Up @@ -2735,20 +2748,6 @@ DIAG_ON_ASSIGN_ENUM
*/
if (pcap_setfilter(pd, &fcode) < 0)
error("%s", pcap_geterr(pd));

/*
* Report the new file.
*/
dlt_name = pcap_datalink_val_to_name(dlt);
fprintf(stderr, "reading from file %s", RFileName);
if (dlt_name == NULL) {
fprintf(stderr, ", link-type %u", dlt);
} else {
fprintf(stderr, ", link-type %s (%s)",
dlt_name,
pcap_datalink_val_to_description(dlt));
}
fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions tests/TESTLIST
Original file line number Diff line number Diff line change
Expand Up @@ -933,3 +933,8 @@ ip6-snmp-oid-unsigned ip6-snmp-oid-unsigned.pcap ip6-snmp-oid-unsigned.out
lwres-pointer-arithmetic-ub lwres-pointer-arithmetic-ub.pcap lwres-pointer-arithmetic-ub.out
ospf-signed-integer-ubsan ospf-signed-integer-ubsan.pcap ospf-signed-integer-ubsan.out -vv
bgp-ub bgp-ub.pcap bgp-ub.out -v

# Multi-file tests
# Note the input is not a pcap file, but a file that contains a list of pcap files
multifile-timestamp multifile-timestamp.pcap-list multifile-timestamp.out -V --nano

43 changes: 30 additions & 13 deletions tests/TESTrun
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,44 @@ sub showfile {
}

sub runtest {
local($name, $input, $output, $options) = @_;
local($name, $input, $outputbase, $options) = @_;
my $r;

$outputbase = basename($output);
my $output = "$testsdir/$outputbase";
my $coredump = false;
my $status = 0;
my $linecount = 0;
my $rawstderrlog = "tests/NEW/${outputbase}.raw.stderr";
my $stderrlog = "tests/NEW/${outputbase}.stderr";
my $diffstat = 0;
my $errdiffstat = 0;
my $inputswitch = '-r';

# we used to do this as a nice pipeline, but the problem is that $r fails to
# to be set properly if the tcpdump core dumps.
#
# Furthermore, on Windows, fc can't read the standard input, so we
# can't do it as a pipeline in any case.
$r = system "$TCPDUMP -# -n -r $input $options >tests/NEW/${outputbase} 2>${rawstderrlog}";
# EXPAND any occurrences of @TESTDIR@ to $testsdir
$options =~ s/\@TESTDIR\@/$testsdir/;

if ($options =~ s/(^|\s+)-V\b//) {
# If the options contains '-V', the $input file is a file that itself
# contains a list of pcap file paths. We need to process that here to
# rewrite each relative path into an absolute path into $testsdir.
open(my $pcaplist, '<', "$testsdir/$input") or die "Can't read input: $!";
my @lines = <$pcaplist>;
chomp(@lines);
my $filenames = join("\\n", map { "$testsdir/$_" } @lines);

# We don't pass the original input file directly; instead we write the
# munged version to stdin, and use '-V -' to read it.
$r = system "printf \"$filenames\" | $TCPDUMP -# -n -V - $options >tests/NEW/${outputbase} 2>${rawstderrlog}";
} else {
# Otherwise, $input is the pcap file to read with '-r'.
#
# we used to do this as a nice pipeline, but the problem is that $r fails to
# to be set properly if the tcpdump core dumps.
#
# Furthermore, on Windows, fc can't read the standard input, so we
# can't do it as a pipeline in any case.
$r = system "$TCPDUMP -# -n -r $testsdir/$input $options >tests/NEW/${outputbase} 2>${rawstderrlog}";
}
if($r != 0) {
#
# Something other than "tcpdump opened the file, read it, and
Expand Down Expand Up @@ -417,12 +437,9 @@ sub runOneComplexTest {
#use Data::Dumper;
#print Dumper($testconfig);

# EXPAND any occurrences of @TESTDIR@ to $testsdir
$options =~ s/\@TESTDIR\@/$testsdir/;

my $result = runtest($name,
$testsdir . "/" . $input,
$testsdir . "/" . $output,
$input,
$output,
$options);

if($result == 0) {
Expand Down
2 changes: 2 additions & 0 deletions tests/multifile-timestamp.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1 01:10:59.680304000 IP 48.48.48.48.69 > 48.48.48.48.12336: TFTP, length 12308, RRQ "00" [|tftp]
2 01:10:59.680304000 IP 48.48.48.48.69 > 48.48.48.48.12336: TFTP, length 12308, RRQ "00" [|tftp]
2 changes: 2 additions & 0 deletions tests/multifile-timestamp.pcap-list
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tftp-heapoverflow.pcap
tftp-heapoverflow.pcap
12 changes: 10 additions & 2 deletions update-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,24 @@ TZ=GMT0; export TZ
for TEST in "$@"; do
PREFIX=tests
MATCH=0
while read -r name input output options
while read -r name input output raw_options
do
[ -z "$name" ] && continue # ignore empty lines
[ "${name#\#}" != "$name" ] && continue # ignore comment lines
[ "$name" != "$TEST" ] && continue # not the requested test
[ -z "$output" ] && continue # ignore incomplete lines
MATCH=1
options=$(echo "$raw_options" | sed "s/\(^\|\s\+\)-V\b//")
if [ "$options" = "$raw_options" ]
then
inputswitch=-r
else
inputswitch=-V
fi

# Word splitting is intentional for $options.
# shellcheck disable=SC2086
./tcpdump -# -n -r "$PREFIX/$input" $options >"$PREFIX/$output"
./tcpdump -# -n $inputswitch "$PREFIX/$input" $options >"$PREFIX/$output"
done < $PREFIX/TESTLIST
[ $MATCH = 0 ] && echo "test $TEST not found" >&2
done