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

Bug 863: fix nansecond timestamp regression #865

Merged
merged 2 commits into from
Jun 3, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/github-actions-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ jobs:
- name: List files in the repository
run: ls ${{ github.workspace }}
- name: tests
run: sudo make test || cat test/test.log
run: sudo make test || (cat test/test.log; false)
- run: echo "This test's status is ${{ job.status }}."
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,11 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[

if test $have_pcap_open_offline_with_tstamp_precision = yes ; then
AC_DEFINE([HAVE_PCAP_OPEN_OFFLINE_WITH_TSTAMP_PRECISION], [1], [Does libpcap have pcap_open_offline_with_tstamp_precision?])
AC_DEFINE([PCAP_TSTAMP_US_TO_NS_MULTIPLIER], [1], [Multiplier for conversion from PCAP usec to nsec])
AC_DEFINE([PCAP_TSTAMP_US_TO_US_DIVISOR], [1000], [Divisor for conversion from PCAP usec to usec])
else
AC_DEFINE([PCAP_TSTAMP_US_TO_NS_MULTIPLIER], [1000], [Multiplier for conversion from PCAP usec to nsec])
AC_DEFINE([PCAP_TSTAMP_US_TO_US_DIVISOR], [1], [Divisor for conversion from PCAP usec to usec])
fi


Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
06/01/2024 Version 4.5.0-beta1
- fix nansecond timestamp regression bug (#863)
- --fixhdrlen option added to control action on packet length changes (#846)
- incorrect checksum for certain IPv4 packets - fixed by #846 (#844)
- add check for IPv6 extension header length (#827 #842)
Expand Down
3 changes: 2 additions & 1 deletion src/common/fakepcapnav.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
* libpcapnav installed on their system, and to keep the code maintainable.
*/

#include "defines.h"

Check failure on line 26 in src/common/fakepcapnav.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/common/fakepcapnav.c:26:10 [clang-diagnostic-error]

'defines.h' file not found
#include "config.h"
#include "common.h"
#include "utils.h"
#include <stdlib.h>

#ifndef HAVE_PCAPNAV
Expand All @@ -52,7 +53,7 @@
err(-1, "malloc() error: unable to malloc pcapnav_t");
}

pcapnav->pcap = pcap_open_offline(filename, errbuf);
pcapnav->pcap = tcpr_pcap_open(filename, errbuf);
if (pcapnav->pcap == NULL) {
errx(-1, "Error opening pcap file %s: %s", filename, errbuf);
}
Expand Down
2 changes: 1 addition & 1 deletion src/common/tcpdump.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
* Lawrence Berkeley Laboratory and its contributors
*/

#include "defines.h"

Check failure on line 35 in src/common/tcpdump.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/common/tcpdump.c:35:10 [clang-diagnostic-error]

'defines.h' file not found
#include "config.h"
#include "common.h"
#include <errno.h>
Expand Down Expand Up @@ -75,7 +75,7 @@

/* convert header to file-format packet header */
actual_pkthdr.ts.ts_sec = (uint32_t)pkthdr->ts.tv_sec;
actual_pkthdr.ts.ts_usec = (uint32_t)pkthdr->ts.tv_sec;
actual_pkthdr.ts.ts_usec = (uint32_t)(pkthdr->ts.tv_usec / PCAP_TSTAMP_US_TO_US_DIVISOR);
actual_pkthdr.caplen = pkthdr->caplen;
actual_pkthdr.len = pkthdr->len;

Expand Down
11 changes: 11 additions & 0 deletions src/common/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
*/

#include "defines.h"

Check failure on line 21 in src/common/utils.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/common/utils.c:21:10 [clang-diagnostic-error]

'defines.h' file not found
#include "config.h"
#include "common.h"
#include <stdlib.h>
Expand Down Expand Up @@ -97,6 +97,17 @@
return newstr;
}

pcap_t*
tcpr_pcap_open(const char *path, char *ebuf)
{
#ifdef HAVE_PCAP_OPEN_OFFLINE_WITH_TSTAMP_PRECISION
return pcap_open_offline_with_tstamp_precision(path, PCAP_TSTAMP_PRECISION_NANO, ebuf);
#else
return pcap_open_offline(path, ebuf);

Check warning on line 106 in src/common/utils.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/common/utils.c:106:12 [performance-no-int-to-ptr]

integer to pointer cast pessimizes optimization opportunities
#endif
}


/**
* calls free and sets to NULL.
*/
Expand Down
1 change: 1 addition & 0 deletions src/common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#pragma once

#include "defines.h"

Check failure on line 23 in src/common/utils.h

View workflow job for this annotation

GitHub Actions / cpp-linter

src/common/utils.h:23:10 [clang-diagnostic-error]

'defines.h' file not found
#include "config.h"
#include "common.h"

Expand All @@ -47,6 +47,7 @@
int format_date_time(struct timespec *when, char *buf, size_t len);
uint32_t tcpr_random(uint32_t *seed);
void restore_stdin(void);
pcap_t* tcpr_pcap_open(const char *path, char *ebuf);

/* our "safe" implimentations of functions which allocate memory */
#define safe_malloc(x) our_safe_malloc(x, __FUNCTION__, __LINE__, __FILE__)
Expand Down
22 changes: 16 additions & 6 deletions src/defines.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,24 @@ typedef u_int8_t uint8_t typedef u_int16_t uint16_t typedef u_int32_t uint32_t
(a)->tv_nsec = (b)->tv_nsec; \
} while (0)

/* libpcap puts nanosec values in tv_usec when pcap file is read with nanosec precision*/
#define TIMEVAL_AS_TIMESPEC_SET(a, b) \
do { \
(a)->tv_sec = (b)->tv_sec; \
(a)->tv_nsec = (b)->tv_usec * 1000; \
/* libpcap that supports it, puts nanosecond values in tv_usec when pcap file is read with nanosec precision,
* and so tv_usec is directly copied to tv_nsec.
* But older versions do that do not support nanosecond precision need to multiply tv_usec by 1000 to convert
* to tv_nsec.
*/
#define PCAP_TIMEVAL_TO_TIMESPEC_SET(a, b) \
do { \
(b)->tv_sec = (a)->tv_sec; \
(b)->tv_nsec = (a)->tv_usec * PCAP_TSTAMP_US_TO_NS_MULTIPLIER; \
} while(0)

#define PCAP_TIMEVAL_TO_TIMEVAL_SET(a, b) \
do { \
(b)->tv_sec = (a)->tv_sec; \
(b)->tv_usec = (a)->tv_usec / PCAP_TSTAMP_US_TO_US_DIVISOR; \
} while(0)

/*
/*
* Help suppress some compiler warnings
* No problem if variable is actually used
*/
Expand Down
10 changes: 0 additions & 10 deletions src/replay.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,6 @@ tcpr_replay_index(tcpreplay_t *ctx)
return rcode;
}

static pcap_t *
tcpr_pcap_open(const char *path, char *ebuf)
{
#ifdef HAVE_PCAP_OPEN_OFFLINE_WITH_TSTAMP_PRECISION
return pcap_open_offline_with_tstamp_precision(path, PCAP_TSTAMP_PRECISION_NANO, ebuf);
#else
return pcap_open_offline(path, ebuf);
#endif
}

/**
* \brief replay a pcap file out interface(s)
*
Expand Down
8 changes: 4 additions & 4 deletions src/send_packets.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@
if (close(1) == -1)
warnx("unable to close stdin: %s", strerror(errno));

if ((pcap = pcap_open_offline(path, ebuf)) == NULL)
if ((pcap = tcpr_pcap_open(path, ebuf)) == NULL)

Check warning on line 302 in src/send_packets.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/send_packets.c:302:53 [readability-braces-around-statements]

statement should be inside braces
errx(-1, "Error opening pcap file: %s", ebuf);

dlt = pcap_datalink(pcap);
Expand Down Expand Up @@ -333,7 +333,7 @@
* what to do with each packet
*/
void
send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)

Check warning on line 336 in src/send_packets.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/send_packets.c:336:1 [readability-function-cognitive-complexity]

function 'send_packets' has cognitive complexity of 146 (threshold 25)
{
struct timespec now, print_delta, last_pkt_ts;
tcpreplay_opt_t *options = ctx->options;
Expand Down Expand Up @@ -388,7 +388,7 @@
while (!ctx->abort && read_next_packet &&
(pktdata = get_next_packet(options, pcap, &pkthdr, idx, prev_packet)) != NULL) {
struct timespec pkthdr_ts;
TIMEVAL_AS_TIMESPEC_SET(&pkthdr_ts, &pkthdr.ts); // libpcap puts nanosec values in tv_usec
PCAP_TIMEVAL_TO_TIMESPEC_SET(&pkthdr.ts, &pkthdr_ts);
now_is_now = false;
packetnum++;
#if defined TCPREPLAY || defined TCPREPLAY_EDIT
Expand Down Expand Up @@ -605,7 +605,7 @@
* what to do with each packet when processing two files a the same time
*/
void
send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *pcap2, int cache_file_idx2)

Check warning on line 608 in src/send_packets.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/send_packets.c:608:1 [readability-function-cognitive-complexity]

function 'send_dual_packets' has cognitive complexity of 155 (threshold 25)
{
struct timespec now, print_delta, last_pkt_ts;
tcpreplay_opt_t *options = ctx->options;
Expand Down Expand Up @@ -739,9 +739,9 @@

if (options->speed.mode == speed_multiplier) {
struct timespec pkthdr_ts;
TIMEVAL_TO_TIMESPEC(&pkthdr_ptr->ts, &pkthdr_ts);
PCAP_TIMEVAL_TO_TIMESPEC_SET(&pkthdr_ptr->ts, &pkthdr_ts);
if (!timesisset(&last_pkt_ts)) {
TIMEVAL_TO_TIMESPEC(&pkthdr_ptr->ts, &last_pkt_ts);
PCAP_TIMEVAL_TO_TIMESPEC_SET(&pkthdr_ptr->ts, &last_pkt_ts);
} else if (timescmp(&pkthdr_ts, &last_pkt_ts, >)) {
struct timespec delta;

Expand Down
4 changes: 3 additions & 1 deletion src/tcpedit/tcpedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
*/

#include "defines.h"

Check failure on line 21 in src/tcpedit/tcpedit.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/tcpedit/tcpedit.c:21:10 [clang-diagnostic-error]

'defines.h' file not found
#include "config.h"
#include "common.h"
#include "edit_packet.h"
Expand Down Expand Up @@ -185,8 +185,10 @@
volatile uint16_t oldval = *((uint16_t *)ip_hdr);
volatile uint16_t newval;

ip_hdr->ip_tos = tcpedit->tos;
newval = *((uint16_t *)ip_hdr);
newval = htons((ntohs(newval) & 0xff00) | (tcpedit->tos & 0xff));
*((uint16_t *)ip_hdr) = newval;
static uint32_t cnt;
csum_replace2(&ip_hdr->ip_sum, oldval, newval);
}

Expand Down
2 changes: 1 addition & 1 deletion src/tcpprep.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
* main()
*/
int
main(int argc, char *argv[])

Check warning on line 71 in src/tcpprep.c

View workflow job for this annotation

GitHub Actions / cpp-linter

src/tcpprep.c:71:1 [readability-function-cognitive-complexity]

function 'main' has cognitive complexity of 41 (threshold 25)
{
int out_file;
COUNTER totpackets;
Expand All @@ -91,7 +91,7 @@

readpcap:
/* open the pcap file */
if ((options->pcap = pcap_open_offline(OPT_ARG(PCAP), errbuf)) == NULL) {
if ((options->pcap = tcpr_pcap_open(OPT_ARG(PCAP), errbuf)) == NULL) {
close(out_file);
tcpprep_close(tcpprep);
errx(-1, "Error opening libpcap: %s", errbuf);
Expand Down
Loading