From 94978a49d45340529f366c6c036fbc0e9e01dbf8 Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Tue, 22 Oct 2024 08:53:29 +0200 Subject: [PATCH 1/8] add missing stdbool include Signed-off-by: Gabriel Ganne --- src/common/get.h | 1 + src/common/sendpacket.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/common/get.h b/src/common/get.h index fda59b3e..c7f51a06 100644 --- a/src/common/get.h +++ b/src/common/get.h @@ -19,6 +19,7 @@ */ #pragma once +#include #include "config.h" #include "defines.h" diff --git a/src/common/sendpacket.h b/src/common/sendpacket.h index 06047a2e..6a3880e6 100644 --- a/src/common/sendpacket.h +++ b/src/common/sendpacket.h @@ -20,6 +20,8 @@ #pragma once +#include + #include "defines.h" #include "config.h" #include From 8058cca189e5df124ac9ce15aa5b71cc52091d23 Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Mon, 15 Jun 2026 15:41:44 +0200 Subject: [PATCH 2/8] use __func__ instead of __FUNCTION__ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit __func__ is the standard since c99, it should be safe to use. This silences some pedantic warnings like this one: > ISO C does not support ‘__FUNCTION__’ predefined identifier Signed-off-by: Gabriel Ganne --- src/common/err.h | 21 ++++++++------------- src/common/utils.h | 12 ++++++------ src/tcpedit/tcpedit.h | 2 +- src/tcpreplay_api.h | 2 +- 4 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/common/err.h b/src/common/err.h index 9c717757..19e80011 100644 --- a/src/common/err.h +++ b/src/common/err.h @@ -67,53 +67,48 @@ extern int debug; * notice() - Informational only via stderr, format string, one or more variables */ -/* gcc accepts __FUNCTION__, but C99 says use __func__. Necessary for SunPro compiler */ -#if !defined(__GNUC__) && !defined(__FUNCTION__) -# define __FUNCTION__ __func__ -#endif - void notice(const char *fmt, ...); #ifdef DEBUG /* then err, errx, warn, warnx print file, func, line */ #define dbg(x, y) do { \ if (debug >= x) \ - fprintf(stderr, "DEBUG%d in %s:%s() line %d: %s\n", x, __FILE__, __FUNCTION__, __LINE__, y); \ + fprintf(stderr, "DEBUG%d in %s:%s() line %d: %s\n", x, __FILE__, __func__, __LINE__, y); \ } while(0) #define dbgx(x, y, ...) do { \ if (debug >= x) { \ - fprintf(stderr, "DEBUG%d in %s:%s() line %d: " y "\n", x, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \ + fprintf(stderr, "DEBUG%d in %s:%s() line %d: " y "\n", x, __FILE__, __func__, __LINE__, __VA_ARGS__); \ } \ } while(0) #define warn(x) \ if (print_warnings) \ - fprintf(stderr, "Warning in %s:%s() line %d:\n%s\n", __FILE__, __FUNCTION__, __LINE__, x) + fprintf(stderr, "Warning in %s:%s() line %d:\n%s\n", __FILE__, __func__, __LINE__, x) #define warnx(x, ...) \ if (print_warnings) \ - fprintf(stderr, "Warning in %s:%s() line %d:\n" x "\n", __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__) + fprintf(stderr, "Warning in %s:%s() line %d:\n" x "\n", __FILE__, __func__, __LINE__, __VA_ARGS__) #define err(x, y) do { \ - fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n%s\n", __FILE__, __FUNCTION__, __LINE__, y); \ + fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n%s\n", __FILE__, __func__, __LINE__, y); \ fflush(NULL); \ exit(x); \ } while (0) #define errx(x, y, ...) do {\ - fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n " y "\n", __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \ + fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n " y "\n", __FILE__, __func__, __LINE__, __VA_ARGS__); \ fflush(NULL); \ exit(x); \ } while (0) #define err_no_exit(y) do { \ - fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n%s\n", __FILE__, __FUNCTION__, __LINE__, y); \ + fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n%s\n", __FILE__, __func__, __LINE__, y); \ fflush(NULL); \ } while (0) #define err_no_exitx(y, ...) do {\ - fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n " y "\n", __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__); \ + fprintf(stderr, "\nFatal Error in %s:%s() line %d:\n " y "\n", __FILE__, __func__, __LINE__, __VA_ARGS__); \ fflush(NULL); \ } while (0) diff --git a/src/common/utils.h b/src/common/utils.h index 83eb2a0c..801f1e1f 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -53,23 +53,23 @@ pcap_t* tcpr_pcap_open(const char *path, char *ebuf); int tcpr_pcap_file_precision(const char *path); /* our "safe" implimentations of functions which allocate memory */ -#define safe_malloc(x) our_safe_malloc(x, __FUNCTION__, __LINE__, __FILE__) +#define safe_malloc(x) our_safe_malloc(x, __func__, __LINE__, __FILE__) void *our_safe_malloc(size_t len, const char *, int, const char *); -#define safe_realloc(x, y) our_safe_realloc(x, y, __FUNCTION__, __LINE__, __FILE__) +#define safe_realloc(x, y) our_safe_realloc(x, y, __func__, __LINE__, __FILE__) void *our_safe_realloc(void *ptr, size_t len, const char *, int, const char *); -#define safe_strdup(x) our_safe_strdup(x, __FUNCTION__, __LINE__, __FILE__) +#define safe_strdup(x) our_safe_strdup(x, __func__, __LINE__, __FILE__) char *our_safe_strdup(const char *str, const char *, int, const char *); -#define safe_free(x) our_safe_free(x, __FUNCTION__, __LINE__, __FILE__) +#define safe_free(x) our_safe_free(x, __func__, __LINE__, __FILE__) void our_safe_free(void *ptr, const char *, int, const char *); -#define safe_pcap_next(x, y) our_safe_pcap_next(x, y, __FUNCTION__, __LINE__, __FILE__) +#define safe_pcap_next(x, y) our_safe_pcap_next(x, y, __func__, __LINE__, __FILE__) u_char * our_safe_pcap_next(pcap_t *pcap, struct pcap_pkthdr *pkthdr, const char *funcname, int line, const char *file); -#define safe_pcap_next_ex(x, y, z) our_safe_pcap_next_ex(x, y, z, __FUNCTION__, __LINE__, __FILE__) +#define safe_pcap_next_ex(x, y, z) our_safe_pcap_next_ex(x, y, z, __func__, __LINE__, __FILE__) int our_safe_pcap_next_ex(pcap_t *pcap, struct pcap_pkthdr **pkthdr, const u_char **pktdata, diff --git a/src/tcpedit/tcpedit.h b/src/tcpedit/tcpedit.h index d6d8d31f..90f34610 100644 --- a/src/tcpedit/tcpedit.h +++ b/src/tcpedit/tcpedit.h @@ -59,7 +59,7 @@ COUNTER tcpedit_get_pkts_edited(tcpedit_t *tcpedit); * outside of internal tcpedit functions */ -#define tcpedit_seterr(x, y, ...) __tcpedit_seterr(x, __FUNCTION__, __LINE__, __FILE__, y, __VA_ARGS__) +#define tcpedit_seterr(x, y, ...) __tcpedit_seterr(x, __func__, __LINE__, __FILE__, y, __VA_ARGS__) void __tcpedit_seterr(tcpedit_t *tcpedit, const char *func, int line, const char *file, const char *fmt, ...); void tcpedit_setwarn(tcpedit_t *tcpedit, const char *fmt, ...); diff --git a/src/tcpreplay_api.h b/src/tcpreplay_api.h index 2e323ad5..55d977f6 100644 --- a/src/tcpreplay_api.h +++ b/src/tcpreplay_api.h @@ -296,7 +296,7 @@ int tcpreplay_set_tcpdump(tcpreplay_t *, tcpdump_t *); * outside of internal tcpreplay API functions */ -#define tcpreplay_seterr(x, y, ...) __tcpreplay_seterr(x, __FUNCTION__, __LINE__, __FILE__, y, __VA_ARGS__) +#define tcpreplay_seterr(x, y, ...) __tcpreplay_seterr(x, __func__, __LINE__, __FILE__, y, __VA_ARGS__) void __tcpreplay_seterr(tcpreplay_t *ctx, const char *func, const int line, const char *file, const char *fmt, ...); void tcpreplay_setwarn(tcpreplay_t *ctx, const char *fmt, ...); From fb67e3ad5d7cc3182090dfc879679b07a68b6523 Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Mon, 15 Jun 2026 16:02:31 +0200 Subject: [PATCH 3/8] expand ternary operator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "x?: y" is a gnu extension that behaves almost the same as "x? x : y". The difference being that x can be evaluated twice, but here this should not change anything. In addition to silencing a warning, I find that I'm more used to this syntax which is easier to read. This silences warning: > warning: ISO C forbids omitting the middle term of a ‘?:’ expression Signed-off-by: Gabriel Ganne --- src/tcpedit/plugins/dlt_hdlc/hdlc.c | 2 +- src/tcpedit/plugins/dlt_ieee80211/ieee80211.c | 2 +- src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c | 2 +- src/tcpedit/plugins/dlt_linuxsll/linuxsll.c | 2 +- src/tcpedit/plugins/dlt_linuxsll2/linuxsll2.c | 2 +- src/tcpedit/plugins/dlt_null/null.c | 2 +- src/tcpedit/plugins/dlt_pppserial/pppserial.c | 2 +- src/tcpedit/plugins/dlt_radiotap/radiotap.c | 2 +- src/tcpedit/plugins/dlt_user/user.c | 2 +- src/tcpreplay.c | 4 +++- 10 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/tcpedit/plugins/dlt_hdlc/hdlc.c b/src/tcpedit/plugins/dlt_hdlc/hdlc.c index 80bc1d09..bbcaac30 100644 --- a/src/tcpedit/plugins/dlt_hdlc/hdlc.c +++ b/src/tcpedit/plugins/dlt_hdlc/hdlc.c @@ -346,7 +346,7 @@ dlt_hdlc_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char *ipv if (l2len == -1 || pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c b/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c index 640c467f..6e6a04a6 100644 --- a/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c +++ b/src/tcpedit/plugins/dlt_ieee80211/ieee80211.c @@ -313,7 +313,7 @@ dlt_ieee80211_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char if (l2len == -1 || pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c index 7777d2cd..8df4449e 100644 --- a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c +++ b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c @@ -385,7 +385,7 @@ dlt_jnpr_ether_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_cha if (l2len == -1 || pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c b/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c index 30af8f6b..da87083f 100644 --- a/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c +++ b/src/tcpedit/plugins/dlt_linuxsll/linuxsll.c @@ -260,7 +260,7 @@ dlt_linuxsll_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char if (l2len == -1 || pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_linuxsll2/linuxsll2.c b/src/tcpedit/plugins/dlt_linuxsll2/linuxsll2.c index 851ac0bf..05a21956 100644 --- a/src/tcpedit/plugins/dlt_linuxsll2/linuxsll2.c +++ b/src/tcpedit/plugins/dlt_linuxsll2/linuxsll2.c @@ -273,7 +273,7 @@ dlt_linuxsll2_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char if (l2len == -1 || pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_null/null.c b/src/tcpedit/plugins/dlt_null/null.c index 2131993c..ed4bb701 100644 --- a/src/tcpedit/plugins/dlt_null/null.c +++ b/src/tcpedit/plugins/dlt_null/null.c @@ -270,7 +270,7 @@ dlt_null_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char *ipv if (pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_pppserial/pppserial.c b/src/tcpedit/plugins/dlt_pppserial/pppserial.c index acf6effc..052f5810 100644 --- a/src/tcpedit/plugins/dlt_pppserial/pppserial.c +++ b/src/tcpedit/plugins/dlt_pppserial/pppserial.c @@ -317,7 +317,7 @@ dlt_pppserial_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char if (l2len == -1 || pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_radiotap/radiotap.c b/src/tcpedit/plugins/dlt_radiotap/radiotap.c index db3871ee..9f942d8a 100644 --- a/src/tcpedit/plugins/dlt_radiotap/radiotap.c +++ b/src/tcpedit/plugins/dlt_radiotap/radiotap.c @@ -276,7 +276,7 @@ dlt_radiotap_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char radiolen = dlt_radiotap_l2len(ctx, packet, pktlen); data = dlt_radiotap_get_80211(ctx, packet, pktlen, radiolen); l2len = dlt_ieee80211_l2len(ctx, data, pktlen); - return tcpedit_dlt_l3data_merge(ctx, data, pktlen - radiolen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, data, pktlen - radiolen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpedit/plugins/dlt_user/user.c b/src/tcpedit/plugins/dlt_user/user.c index bcf29ac4..96b8e413 100644 --- a/src/tcpedit/plugins/dlt_user/user.c +++ b/src/tcpedit/plugins/dlt_user/user.c @@ -316,7 +316,7 @@ dlt_user_merge_layer3(tcpeditdlt_t *ctx, u_char *packet, int pktlen, u_char *ipv if (l2len == TCPEDIT_ERROR || pktlen < l2len) return NULL; - return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ?: ipv6_data, l2len); + return tcpedit_dlt_l3data_merge(ctx, packet, pktlen, ipv4_data ? ipv4_data : ipv6_data, l2len); } /* diff --git a/src/tcpreplay.c b/src/tcpreplay.c index d5aae08b..0bacd3c1 100644 --- a/src/tcpreplay.c +++ b/src/tcpreplay.c @@ -249,7 +249,9 @@ static void flow_stats(const tcpreplay_t *tcpr_ctx) flow_non_flow_packets *= tcpr_ctx->last_unique_iteration; } else { /* adjust for --unique-ip-loops */ - flow_packets = (flow_packets * (tcpr_ctx->last_unique_iteration ?: tcpr_ctx->iteration)) / tcpr_ctx->iteration; + flow_packets = (flow_packets * + (tcpr_ctx->last_unique_iteration ? tcpr_ctx->last_unique_iteration : tcpr_ctx->iteration)) / + tcpr_ctx->iteration; } #ifdef TCPREPLAY_EDIT From b646338f207e4d5970e91a7e4feffae4f780833f Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Mon, 15 Jun 2026 16:08:13 +0200 Subject: [PATCH 4/8] ISO C forbids an empty translation unit Assisted-by: Claude Opus 4.8 Signed-off-by: Gabriel Ganne --- src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_api.c | 3 +++ src/tcpedit/plugins/dlt_pppserial/pppserial_api.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_api.c b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_api.c index 94dd022c..6050da29 100644 --- a/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_api.c +++ b/src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_api.c @@ -46,3 +46,6 @@ #include "jnpr_ether_types.h" */ + +/* ISO C forbids an empty translation unit */ +typedef int jnpr_ether_api_unused_t; diff --git a/src/tcpedit/plugins/dlt_pppserial/pppserial_api.c b/src/tcpedit/plugins/dlt_pppserial/pppserial_api.c index a8bee47b..59f9c5bb 100644 --- a/src/tcpedit/plugins/dlt_pppserial/pppserial_api.c +++ b/src/tcpedit/plugins/dlt_pppserial/pppserial_api.c @@ -45,3 +45,6 @@ #include "tcpr.h" */ + +/* ISO C forbids an empty translation unit */ +typedef int pppserial_api_unused_t; From b2db08396763180a16f6bd182e75c935b100a87a Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Tue, 16 Jun 2026 07:49:47 +0200 Subject: [PATCH 5/8] do not return in a void-returning function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to silence warning: > warning: ISO C forbids ‘return’ with expression, in function returning void Signed-off-by: Gabriel Ganne --- src/fragroute/iputil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fragroute/iputil.c b/src/fragroute/iputil.c index febbc99f..4e6decc4 100644 --- a/src/fragroute/iputil.c +++ b/src/fragroute/iputil.c @@ -85,9 +85,9 @@ void inet_checksum(uint16_t eth_type, void *buf, size_t len) { if (eth_type == ETH_TYPE_IP) { - return ip_checksum(buf, len); + ip_checksum(buf, len); } else if (eth_type == ETH_TYPE_IPV6) { - return ip6_checksum(buf, len); + ip6_checksum(buf, len); } } From 4d7f8c46af72f78a048af86877c0852e144efdad Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Wed, 24 Jun 2026 15:40:46 +0200 Subject: [PATCH 6/8] fix timestamp-trace option * replace all timeval with timespec structures continuing the work of commit [1] * rename all "usec" -> "nsec" for coherency (commit [1]): struct timespec have replaced struct timeval. Those are nanosecond precision. * fix configure help string: "timestamp-trace" -> "enable-timestamp-trace" Note that if timestamp-trace is enabled, there's already a tcpreplay test with pps option enabled that will dump a meaningful trace and act as a smoke test for the feature. Refs: [1] 3b0934ecbe7f5276e2e700fb04ea3fef1da40282 Fixes: 3b0934ecbe7f5276e2e700fb04ea3fef1da40282 Assisted-by: Devin (GTP-5.6) Signed-off-by: Gabriel Ganne --- configure.ac | 2 +- src/send_packets.c | 4 +++ src/tcpreplay.c | 1 + src/timestamp_trace.h | 64 +++++++++++++++++++++++-------------------- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/configure.ac b/configure.ac index b60a65d6..a9421351 100644 --- a/configure.ac +++ b/configure.ac @@ -510,7 +510,7 @@ AC_SUBST(extra_debug_flag) dnl Enable timestamp_trace in code/compiler options timestamp_trace=no AC_ARG_ENABLE(timestamp-trace, - AS_HELP_STRING([--timestamp-trace],[Enable dumping of trace timestamps at the end of a test]), + AS_HELP_STRING([--enable-timestamp-trace],[Enable dumping of trace timestamps at the end of a test]), [ if test x$enableval = xyes; then timestamp_trace=yes CFLAGS="${CFLAGS} -DTIMESTAMP_TRACE" diff --git a/src/send_packets.c b/src/send_packets.c index b2045d62..b59f6914 100644 --- a/src/send_packets.c +++ b/src/send_packets.c @@ -23,6 +23,10 @@ #include "common.h" #include "tcpreplay_api.h" #include "timestamp_trace.h" +#ifdef TIMESTAMP_TRACE +uint32_t trace_num; +timestamp_trace_entry_t timestamp_trace_entry_array[TRACE_MAX_ENTRIES]; +#endif #include #include #include diff --git a/src/tcpreplay.c b/src/tcpreplay.c index 0bacd3c1..141abca3 100644 --- a/src/tcpreplay.c +++ b/src/tcpreplay.c @@ -45,6 +45,7 @@ tcpedit_t *tcpedit; #include "send_packets.h" #include "signal_handler.h" +#include "timestamp_trace.h" #ifdef DEBUG int debug = 0; diff --git a/src/timestamp_trace.h b/src/timestamp_trace.h index c908dcff..87828f2f 100644 --- a/src/timestamp_trace.h +++ b/src/timestamp_trace.h @@ -18,6 +18,8 @@ #pragma once +#include + #include "defines.h" #include "config.h" @@ -31,30 +33,30 @@ struct timestamp_trace_entry { COUNTER tx_ns; COUNTER next_tx_ns; COUNTER sent_bits; - struct timeval timestamp; + struct timespec timestamp; }; typedef struct timestamp_trace_entry timestamp_trace_entry_t; #ifdef TIMESTAMP_TRACE -uint32_t trace_num; -timestamp_trace_entry_t timestamp_trace_entry_array[TRACE_MAX_ENTRIES]; +extern uint32_t trace_num; +extern timestamp_trace_entry_t timestamp_trace_entry_array[TRACE_MAX_ENTRIES]; static inline void -update_current_timestamp_trace_entry(COUNTER bytes_sent, COUNTER now_us, COUNTER tx_us, COUNTER next_tx_us) +update_current_timestamp_trace_entry(COUNTER bytes_sent, COUNTER now_ns, COUNTER tx_ns, COUNTER next_tx_ns) { if (trace_num >= TRACE_MAX_ENTRIES) return; - if (!now_us) { + if (!now_ns) { struct timespec now; - get_current_time(now); - now_us = TIMESPEC_TO_MICROSEC(&now); + get_current_time(&now); + now_ns = TIMESPEC_TO_NANOSEC(&now); } timestamp_trace_entry_array[trace_num].bytes_sent = bytes_sent; - timestamp_trace_entry_array[trace_num].now_us = now_us; - timestamp_trace_entry_array[trace_num].tx_us = tx_us; - timestamp_trace_entry_array[trace_num].next_tx_us = next_tx_us; + timestamp_trace_entry_array[trace_num].now_ns = now_ns; + timestamp_trace_entry_array[trace_num].tx_ns = tx_ns; + timestamp_trace_entry_array[trace_num].next_tx_ns = next_tx_ns; } static inline void @@ -71,29 +73,31 @@ add_timestamp_trace_entry(COUNTER size, struct timespec *timestamp, COUNTER skip } static inline void -dump_timestamp_trace_array(const struct timeval *start, const struct timeval *stop, const COUNTER bps) +dump_timestamp_trace_array(const struct timespec *start, const struct timespec *stop, const COUNTER bps) { uint32_t i; - COUNTER start_us = TIMEVAL_TO_MICROSEC(start); + COUNTER start_ns = TIMESPEC_TO_NANOSEC(start); - printf("dump_timestamp_trace_array: start=%zd.%06zd stop=%zd.%06zd start_us=%llu traces=%u bps=%llu\n", - start->tv_sec, - start->tv_usec, - stop->tv_sec, - stop->tv_usec, - start_us, + printf("dump_timestamp_trace_array: start=%lld.%09lld stop=%lld.%09lld start_ns=" COUNTER_SPEC + " traces=%u bps=" COUNTER_SPEC "\n", + (long long int)start->tv_sec, + (long long int)start->tv_nsec, + (long long int)stop->tv_sec, + (long long int)stop->tv_nsec, + start_ns, trace_num, bps); for (i = 0; i < trace_num; ++i) { - long long int delta = timestamp_trace_entry_array[i].tx_us - timestamp_trace_entry_array[i].next_tx_us; + long long int delta = timestamp_trace_entry_array[i].tx_ns - timestamp_trace_entry_array[i].next_tx_ns; - printf("timestamp=%zd.%zd, size=%llu now_us=%llu tx_us=%llu next_tx_us=%llu delta=%lld bytes_sent=%llu skip=%llu\n", - timestamp_trace_entry_array[i].timestamp.tv_sec, - timestamp_trace_entry_array[i].timestamp.tv_usec, + printf("timestamp=%lld.%09lld, size=" COUNTER_SPEC " now_ns=" COUNTER_SPEC " tx_ns=" COUNTER_SPEC + " next_tx_ns=" COUNTER_SPEC " delta=%lld bytes_sent=" COUNTER_SPEC " skip=" COUNTER_SPEC "\n", + (long long int)timestamp_trace_entry_array[i].timestamp.tv_sec, + (long long int)timestamp_trace_entry_array[i].timestamp.tv_nsec, timestamp_trace_entry_array[i].size, - timestamp_trace_entry_array[i].now_us, - timestamp_trace_entry_array[i].tx_us, - timestamp_trace_entry_array[i].next_tx_us, + timestamp_trace_entry_array[i].now_ns, + timestamp_trace_entry_array[i].tx_ns, + timestamp_trace_entry_array[i].next_tx_ns, delta, timestamp_trace_entry_array[i].bytes_sent, timestamp_trace_entry_array[i].skip_length); @@ -102,16 +106,16 @@ dump_timestamp_trace_array(const struct timeval *start, const struct timeval *st #else static inline void update_current_timestamp_trace_entry(COUNTER UNUSED(bytes_sent), - COUNTER UNUSED(now_us), - COUNTER UNUSED(tx_us), - COUNTER UNUSED(next_tx_us)) + COUNTER UNUSED(now_ns), + COUNTER UNUSED(tx_ns), + COUNTER UNUSED(next_tx_ns)) {} static inline void add_timestamp_trace_entry(COUNTER UNUSED(size), struct timespec *UNUSED(timestamp), COUNTER UNUSED(skip_length)) {} static inline void -dump_timestamp_trace_array(const struct timeval *UNUSED(start), - const struct timeval *UNUSED(stop), +dump_timestamp_trace_array(const struct timespec *UNUSED(start), + const struct timespec *UNUSED(stop), const COUNTER UNUSED(bps)) {} #endif /* TIMESTAMP_TRACE */ From 22c26863b3b1ee17b689a8500371058e7dd17443 Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Thu, 30 Jul 2026 14:28:45 +0200 Subject: [PATCH 7/8] fix compilation warning SP_TYPE_SOCK_RAW is always defined Signed-off-by: Gabriel Ganne --- src/common/sendpacket.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/common/sendpacket.c b/src/common/sendpacket.c index a76cdec8..079f610e 100644 --- a/src/common/sendpacket.c +++ b/src/common/sendpacket.c @@ -932,9 +932,7 @@ sendpacket_close(sendpacket_t *sp) assert(sp); switch (sp->handle_type) { case SP_TYPE_KHIAL: -#ifdef HAVE_SOCK_RAW case SP_TYPE_SOCK_RAW: -#endif close(sp->handle.fd); break; From 78db2a8dbdb83adcbd73417f0e1c13e90138860b Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Thu, 25 Jun 2026 14:16:40 +0200 Subject: [PATCH 8/8] sendpacket - fix force-libxdp option This adds HAVE_LIBXDP as a terminal backend in the injection chain Signed-off-by: Gabriel Ganne --- src/common/sendpacket.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/sendpacket.c b/src/common/sendpacket.c index 079f610e..f65d59f3 100644 --- a/src/common/sendpacket.c +++ b/src/common/sendpacket.c @@ -755,7 +755,9 @@ sendpacket_open(const char *device, sp = sendpacket_open_tuntap(device, errbuf); #endif } else { -#ifdef HAVE_LIBXDP +#if defined HAVE_LIBXDP && \ + (defined HAVE_PF_PACKET || defined HAVE_LIBURING || defined HAVE_BPF \ + || defined HAVE_LIBDNET || defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) /* * AF_XDP is tried ahead of the chain below rather than inside it, * because it is the one method that may legitimately fail and hand @@ -831,6 +833,8 @@ sendpacket_open(const char *device, sp = sendpacket_open_libdnet(device, errbuf); #elif (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) sp = sendpacket_open_pcap(device, errbuf); +#elif defined HAVE_LIBXDP + sp = sendpacket_open_xsk(device, errbuf, arg); #else #error "No defined packet injection method for sendpacket_open()" #endif