Browse Source

Import upstream version 4.5.3

Fred Klassen 6 days ago
parent
commit
169a05ccf7
100 changed files with 659 additions and 282 deletions
  1. 10 0
      README.md
  2. 17 21
      configure
  3. 30 12
      configure.ac
  4. 74 0
      docs/CHANGELOG
  5. 14 0
      docs/CREDIT
  6. 1 1
      lib/strlcpy.h
  7. 1 1
      src/bridge.c
  8. 1 1
      src/bridge.h
  9. 1 1
      src/common.h
  10. 1 1
      src/common/cache.c
  11. 1 1
      src/common/cache.h
  12. 1 1
      src/common/cidr.c
  13. 1 1
      src/common/cidr.h
  14. 1 1
      src/common/err.c
  15. 1 1
      src/common/err.h
  16. 1 1
      src/common/fakepcap.c
  17. 1 1
      src/common/fakepcap.h
  18. 1 1
      src/common/fakepcapnav.c
  19. 1 1
      src/common/fakepcapnav.h
  20. 1 1
      src/common/flows.c
  21. 1 1
      src/common/flows.h
  22. 1 1
      src/common/get.c
  23. 1 1
      src/common/get.h
  24. 1 1
      src/common/git_version.c
  25. 1 1
      src/common/interface.c
  26. 1 1
      src/common/interface.h
  27. 1 1
      src/common/list.c
  28. 1 1
      src/common/list.h
  29. 1 1
      src/common/mac.c
  30. 1 1
      src/common/mac.h
  31. 9 4
      src/common/netmap.c
  32. 1 1
      src/common/pcap_dlt.h
  33. 113 5
      src/common/sendpacket.c
  34. 1 1
      src/common/sendpacket.h
  35. 1 1
      src/common/services.c
  36. 1 1
      src/common/services.h
  37. 1 1
      src/common/tcpdump.c
  38. 1 1
      src/common/tcpdump.h
  39. 1 1
      src/common/timer.c
  40. 1 1
      src/common/timer.h
  41. 2 2
      src/common/utils.c
  42. 3 1
      src/common/utils.h
  43. 1 1
      src/common/xX.c
  44. 1 1
      src/common/xX.h
  45. 9 1
      src/fragroute/fragroute.c
  46. 1 1
      src/fragroute/fragroute.h
  47. 10 2
      src/fragroute/mod.c
  48. 1 1
      src/replay.c
  49. 1 1
      src/replay.h
  50. 117 78
      src/send_packets.c
  51. 1 1
      src/send_packets.h
  52. 1 1
      src/signal_handler.c
  53. 1 1
      src/signal_handler.h
  54. 1 1
      src/sleep.c
  55. 1 1
      src/sleep.h
  56. 11 3
      src/tcpbridge.1
  57. 1 1
      src/tcpbridge.c
  58. 1 1
      src/tcpbridge.h
  59. 12 7
      src/tcpbridge_opts.c
  60. 4 4
      src/tcpbridge_opts.def
  61. 1 1
      src/tcpbridge_opts.h
  62. 1 1
      src/tcpcapinfo.1
  63. 1 1
      src/tcpcapinfo.c
  64. 1 1
      src/tcpcapinfo_opts.c
  65. 2 2
      src/tcpcapinfo_opts.def
  66. 1 1
      src/tcpedit/checksum.c
  67. 1 1
      src/tcpedit/checksum.h
  68. 1 1
      src/tcpedit/dlt.c
  69. 1 1
      src/tcpedit/dlt.h
  70. 97 47
      src/tcpedit/edit_packet.c
  71. 1 1
      src/tcpedit/edit_packet.h
  72. 1 1
      src/tcpedit/parse_args.c
  73. 1 1
      src/tcpedit/parse_args.h
  74. 1 1
      src/tcpedit/plugins.h
  75. 31 10
      src/tcpedit/plugins/dlt_en10mb/en10mb.c
  76. 1 1
      src/tcpedit/plugins/dlt_en10mb/en10mb.h
  77. 1 1
      src/tcpedit/plugins/dlt_en10mb/en10mb_api.c
  78. 1 1
      src/tcpedit/plugins/dlt_en10mb/en10mb_api.h
  79. 14 3
      src/tcpedit/plugins/dlt_en10mb/en10mb_opts.def
  80. 1 1
      src/tcpedit/plugins/dlt_en10mb/en10mb_types.h
  81. 1 1
      src/tcpedit/plugins/dlt_hdlc/hdlc.c
  82. 1 1
      src/tcpedit/plugins/dlt_hdlc/hdlc.h
  83. 1 1
      src/tcpedit/plugins/dlt_hdlc/hdlc_api.c
  84. 1 1
      src/tcpedit/plugins/dlt_hdlc/hdlc_api.h
  85. 1 1
      src/tcpedit/plugins/dlt_hdlc/hdlc_types.h
  86. 1 1
      src/tcpedit/plugins/dlt_ieee80211/ieee80211.c
  87. 1 1
      src/tcpedit/plugins/dlt_ieee80211/ieee80211.h
  88. 1 1
      src/tcpedit/plugins/dlt_ieee80211/ieee80211_hdr.c
  89. 1 1
      src/tcpedit/plugins/dlt_ieee80211/ieee80211_hdr.h
  90. 1 1
      src/tcpedit/plugins/dlt_ieee80211/ieee80211_types.h
  91. 1 1
      src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c
  92. 1 1
      src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.h
  93. 1 1
      src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_api.h
  94. 1 1
      src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_types.h
  95. 1 1
      src/tcpedit/plugins/dlt_linuxsll/linuxsll.c
  96. 1 1
      src/tcpedit/plugins/dlt_linuxsll/linuxsll.h
  97. 1 1
      src/tcpedit/plugins/dlt_loop/loop.c
  98. 1 1
      src/tcpedit/plugins/dlt_loop/loop.h
  99. 1 1
      src/tcpedit/plugins/dlt_null/null.c
  100. 0 0
      src/tcpedit/plugins/dlt_null/null.h

+ 10 - 0
README.md

@@ -78,12 +78,22 @@ for detailed download and installation instructions.
 
 
 Simple directions for Unix users:
 Simple directions for Unix users:
 ---------------------------------
 ---------------------------------
+If you're building from a release tarball, `configure` is already generated:
 ```
 ```
 ./configure 
 ./configure 
 make
 make
 sudo make install
 sudo make install
 ```
 ```
 
 
+If you're building from a git checkout, `configure` doesn't exist yet - generate it
+first with `autogen.sh` (requires `autoconf`, `automake`, `libtool`, and `autogen`):
+```
+./autogen.sh
+./configure
+make
+sudo make install
+```
+
 Build netmap feature
 Build netmap feature
 --------------------
 --------------------
 This feature will detect [netmap](http://info.iet.unipi.it/~luigi/netmap/)
 This feature will detect [netmap](http://info.iet.unipi.it/~luigi/netmap/)

+ 17 - 21
configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for tcpreplay 4.5.2.
+# Generated by GNU Autoconf 2.72 for tcpreplay 4.5.3.
 #
 #
 # Report bugs to <https://github.com/appneta/tcpreplay/issues>.
 # Report bugs to <https://github.com/appneta/tcpreplay/issues>.
 #
 #
@@ -614,8 +614,8 @@ MAKEFLAGS=
 # Identity of this package.
 # Identity of this package.
 PACKAGE_NAME='tcpreplay'
 PACKAGE_NAME='tcpreplay'
 PACKAGE_TARNAME='tcpreplay'
 PACKAGE_TARNAME='tcpreplay'
-PACKAGE_VERSION='4.5.2'
-PACKAGE_STRING='tcpreplay 4.5.2'
+PACKAGE_VERSION='4.5.3'
+PACKAGE_STRING='tcpreplay 4.5.3'
 PACKAGE_BUGREPORT='https://github.com/appneta/tcpreplay/issues'
 PACKAGE_BUGREPORT='https://github.com/appneta/tcpreplay/issues'
 PACKAGE_URL='http://tcpreplay.sourceforge.net/'
 PACKAGE_URL='http://tcpreplay.sourceforge.net/'
 
 
@@ -1477,7 +1477,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
   cat <<_ACEOF
-'configure' configures tcpreplay 4.5.2 to adapt to many kinds of systems.
+'configure' configures tcpreplay 4.5.3 to adapt to many kinds of systems.
 
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
 
@@ -1549,7 +1549,7 @@ fi
 
 
 if test -n "$ac_init_help"; then
 if test -n "$ac_init_help"; then
   case $ac_init_help in
   case $ac_init_help in
-     short | recursive ) echo "Configuration of tcpreplay 4.5.2:";;
+     short | recursive ) echo "Configuration of tcpreplay 4.5.3:";;
    esac
    esac
   cat <<\_ACEOF
   cat <<\_ACEOF
 
 
@@ -1726,7 +1726,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
 if $ac_init_version; then
   cat <<\_ACEOF
   cat <<\_ACEOF
-tcpreplay configure 4.5.2
+tcpreplay configure 4.5.3
 generated by GNU Autoconf 2.72
 generated by GNU Autoconf 2.72
 
 
 Copyright (C) 2023 Free Software Foundation, Inc.
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -2673,7 +2673,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 running configure, to aid debugging if configure makes a mistake.
 
 
-It was created by tcpreplay $as_me 4.5.2, which was
+It was created by tcpreplay $as_me 4.5.3, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
 
   $ $0$ac_configure_args_raw
   $ $0$ac_configure_args_raw
@@ -4684,7 +4684,7 @@ fi
 
 
 # Define the identity of the package.
 # Define the identity of the package.
  PACKAGE='tcpreplay'
  PACKAGE='tcpreplay'
- VERSION='4.5.2'
+ VERSION='4.5.3'
 
 
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -26331,8 +26331,7 @@ for testdir in $NETMAP_SEARCH_DIRS; do
 
 
     if test "$have_netmap" != no ; then
     if test "$have_netmap" != no ; then
         NETMAPFLAGS="-DHAVE_NETMAP"
         NETMAPFLAGS="-DHAVE_NETMAP"
-        OLDCFLAGS="$CFLAGS -I$NETMAPINCDIR"
-        CFLAGS="$CFLAGS -DNETMAP_WITH_LIBS -DND -I$NETMAPINCDIR"
+                                                                                                                                                NETMAP_CFLAGS="-DNETMAP_WITH_LIBS -I$NETMAPINCDIR"
 
 
 
 
 
 
@@ -26362,7 +26361,7 @@ fi
 
 
 if test "x$NETMAPINCDIR" != "x"; then
 if test "x$NETMAPINCDIR" != "x"; then
     OLDCPPFLAGS="$CPPFLAGS"
     OLDCPPFLAGS="$CPPFLAGS"
-    CPPFLAGS="$CPPFLAGS -DNETMAP_WITH_LIBS -DND -I$NETMAPINCDIR"
+        CPPFLAGS="$CPPFLAGS -DNETMAP_WITH_LIBS -I$NETMAPINCDIR"
 
 
     have_nm_open=no
     have_nm_open=no
     have_nm_nr_reg_mask=no
     have_nm_nr_reg_mask=no
@@ -26636,14 +26635,7 @@ int
 main (void)
 main (void)
 {
 {
 
 
-    struct xsk_socket {
-        struct xsk_ring_cons *rx;
-        struct xsk_ring_prod *tx;
-        struct xsk_ctx *ctx;
-        struct xsk_socket_config config;
-        int fd;
-    };
-    struct xsk_socket xsk;
+    struct xsk_socket *xsk = NULL;
 	struct xsk_ring_cons *rxr = NULL;
 	struct xsk_ring_cons *rxr = NULL;
 	struct xsk_ring_prod *txr = NULL;
 	struct xsk_ring_prod *txr = NULL;
     int queue_id = 0;
     int queue_id = 0;
@@ -29525,6 +29517,10 @@ printf "%s\n" "#define NO_OPTIONAL_OPT_ARGS 1" >>confdefs.h
 
 
 
 
 
 
+if test "x$NETMAP_CFLAGS" != "x"; then
+    CFLAGS="$CFLAGS $NETMAP_CFLAGS"
+fi
+
 ac_config_files="$ac_config_files Makefile doxygen.cfg lib/Makefile docs/Makefile src/Makefile src/tcpedit/Makefile src/fragroute/Makefile src/common/Makefile src/defines.h test/Makefile test/config scripts/Makefile"
 ac_config_files="$ac_config_files Makefile doxygen.cfg lib/Makefile docs/Makefile src/Makefile src/tcpedit/Makefile src/fragroute/Makefile src/common/Makefile src/defines.h test/Makefile test/config scripts/Makefile"
 
 
 
 
@@ -30129,7 +30125,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 # values after options handling.
 ac_log="
 ac_log="
-This file was extended by tcpreplay $as_me 4.5.2, which was
+This file was extended by tcpreplay $as_me 4.5.3, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_FILES    = $CONFIG_FILES
@@ -30198,7 +30194,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
 ac_cs_version="\\
-tcpreplay config.status 4.5.2
+tcpreplay config.status 4.5.3
 configured by $0, generated by GNU Autoconf 2.72,
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
   with options \\"\$ac_cs_config\\"
 
 

+ 30 - 12
configure.ac

@@ -4,7 +4,7 @@ dnl $Id$
 AC_PREREQ([2.69])
 AC_PREREQ([2.69])
 
 
 dnl Set version info here!
 dnl Set version info here!
-AC_INIT([tcpreplay],[4.5.2],[https://github.com/appneta/tcpreplay/issues],[tcpreplay],[http://tcpreplay.sourceforge.net/])
+AC_INIT([tcpreplay],[4.5.3],[https://github.com/appneta/tcpreplay/issues],[tcpreplay],[http://tcpreplay.sourceforge.net/])
 AC_CONFIG_SRCDIR([src/tcpreplay.c])
 AC_CONFIG_SRCDIR([src/tcpreplay.c])
 AC_CONFIG_HEADERS([src/config.h])
 AC_CONFIG_HEADERS([src/config.h])
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_AUX_DIR(config)
@@ -1334,8 +1334,24 @@ for testdir in $NETMAP_SEARCH_DIRS; do
 
 
     if test "$have_netmap" != no ; then
     if test "$have_netmap" != no ; then
         NETMAPFLAGS="-DHAVE_NETMAP"
         NETMAPFLAGS="-DHAVE_NETMAP"
-        OLDCFLAGS="$CFLAGS -I$NETMAPINCDIR"
-        CFLAGS="$CFLAGS -DNETMAP_WITH_LIBS -DND -I$NETMAPINCDIR"
+        dnl Don't add -I$NETMAPINCDIR to CFLAGS here: CFLAGS is shared by every
+        dnl AC_CHECK_HEADERS/AC_COMPILE_IFELSE test for the rest of this script,
+        dnl and a netmap checkout's sys/ tree mirrors a BSD kernel source layout
+        dnl (including its own sys/net/bpf.h). Adding it now makes later,
+        dnl unrelated checks - e.g. the net/bpf.h check below - find netmap's
+        dnl vendored BSD-compat header instead of a real system one, wrongly
+        dnl setting have_bpf=yes even on Linux and causing a struct bpf_insn
+        dnl redefinition conflict against the system libpcap headers at build
+        dnl time. Save it in NETMAP_CFLAGS and apply it to CFLAGS just once,
+        dnl right before AC_OUTPUT, after all other detection has finished.
+        dnl
+        dnl Deliberately NOT passing -DND: netmap_user.h defines its own
+        dnl ND(...) debug-print macro guarded by #ifndef ND. A bare -DND (no
+        dnl value) makes the compiler define ND as the literal 1, so that
+        dnl guard sees ND as already defined and skips its own function-like
+        dnl macro - every ND(...) call site then expands to 1(...), "call
+        dnl the integer 1 as a function", a hard compile error (#1015).
+        NETMAP_CFLAGS="-DNETMAP_WITH_LIBS -I$NETMAPINCDIR"
 
 
         AC_SUBST(NETMAPINC)
         AC_SUBST(NETMAPINC)
         AC_SUBST(NETMAPUSERINC)
         AC_SUBST(NETMAPUSERINC)
@@ -1360,7 +1376,8 @@ dnl ###########################################################
 
 
 if test "x$NETMAPINCDIR" != "x"; then
 if test "x$NETMAPINCDIR" != "x"; then
     OLDCPPFLAGS="$CPPFLAGS"
     OLDCPPFLAGS="$CPPFLAGS"
-    CPPFLAGS="$CPPFLAGS -DNETMAP_WITH_LIBS -DND -I$NETMAPINCDIR"
+    dnl No -DND here either - see the NETMAP_CFLAGS comment above (#1015).
+    CPPFLAGS="$CPPFLAGS -DNETMAP_WITH_LIBS -I$NETMAPINCDIR"
 
 
     have_nm_open=no
     have_nm_open=no
     have_nm_nr_reg_mask=no
     have_nm_nr_reg_mask=no
@@ -1476,14 +1493,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
 #include <xdp/xsk.h>
 #include <xdp/xsk.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
 ]], [[
 ]], [[
-    struct xsk_socket {
-        struct xsk_ring_cons *rx;
-        struct xsk_ring_prod *tx;
-        struct xsk_ctx *ctx;
-        struct xsk_socket_config config;
-        int fd;
-    };
-    struct xsk_socket xsk;
+    struct xsk_socket *xsk = NULL;
 	struct xsk_ring_cons *rxr = NULL;
 	struct xsk_ring_cons *rxr = NULL;
 	struct xsk_ring_prod *txr = NULL;
 	struct xsk_ring_prod *txr = NULL;
     int queue_id = 0;
     int queue_id = 0;
@@ -2018,6 +2028,14 @@ fi
 LIBOPTS_CHECK(libopts)
 LIBOPTS_CHECK(libopts)
 
 
 
 
+dnl Apply the netmap include path (see the have_netmap block above) to CFLAGS
+dnl now, after every other detection in this script has already run, so the
+dnl real build can find netmap's headers without that path having been able
+dnl to shadow unrelated system headers (e.g. net/bpf.h) during configure.
+if test "x$NETMAP_CFLAGS" != "x"; then
+    CFLAGS="$CFLAGS $NETMAP_CFLAGS"
+fi
+
 AC_CONFIG_FILES([Makefile
 AC_CONFIG_FILES([Makefile
            doxygen.cfg
            doxygen.cfg
            lib/Makefile
            lib/Makefile

+ 74 - 0
docs/CHANGELOG

@@ -1,3 +1,77 @@
+07/18/2026 Version 4.5.3
+    - configure: fix --with-netmap=DIR permanently leaking -I<DIR>/sys onto CFLAGS for the rest of
+      the script, with no restore (unlike the equivalent, correctly-scoped CPPFLAGS addition a few
+      lines later) - a netmap checkout's sys/ tree mirrors a BSD kernel source layout including
+      its own sys/net/bpf.h, so later unrelated checks (e.g. the net/bpf.h feature check) could
+      pick up netmap's vendored header instead of a real system one, wrongly setting HAVE_BPF=1 on
+      Linux and causing a struct bpf_insn redefinition conflict against the system libpcap headers
+      at build time; the netmap include path is now only applied to CFLAGS once, right before
+      AC_OUTPUT, after all other detection has finished
+    - configure: drop the bare -DND passed alongside --with-netmap=DIR's CFLAGS/CPPFLAGS - netmap's
+      own netmap_user.h defines a function-like ND(...) debug-print macro guarded by #ifndef ND, but
+      a valueless -DND makes the compiler predefine ND as the literal 1, so that guard sees ND as
+      already defined and every real ND(...) call site in netmap's headers expands to 1(...),
+      "called object is not a function or function pointer" (found while verifying the fix above,
+      #1015)
+    - tcpedit: fix --tcp-sequence and --portmap/-r silently having zero effect on some platforms
+      (confirmed on macOS arm64) - rewrite_ipv4_tcp_sequence()/rewrite_ipv6_tcp_sequence()
+      (rewrite_sequence.c) and rewrite_ipv4_ports()/rewrite_ipv6_ports() (portmap.c) computed the
+      L4 "end of buffer" bounds pointer from the address of their own ipv4_hdr_t**/ipv6_hdr_t**
+      parameter instead of the packet buffer address it pointed to ((u_char *)ip_hdr instead of
+      (u_char *)(*ip_hdr)); get_layer4_v4()/v6()'s bounds check against that garbage pointer then
+      either always passed (silently correct by luck) or always failed (silently rewriting
+      nothing), depending on platform-specific stack layout (#1011)
+    - tcpr_random: fix signed left-shift undefined behavior in this "consistent across all
+      platforms" PRNG - left-shifting a signed int such that a set bit crosses the sign bit is
+      undefined behavior in C, which different compiler backends are free to resolve differently;
+      switched the accumulator to unsigned so the shift is well-defined everywhere
+    - tcpliveplay: fix catch_alarm() not calling pcap_breakloop(), which left pcap_dispatch()
+      blocked for the full buffer timeout (or indefinitely, on libpcap implementations where the
+      timeout only starts once a packet arrives) instead of returning promptly when the alarm
+      fires - the visible symptom was a spurious "remote host is not responding" timeout up to 10s
+      after a response had actually arrived (#540)
+    - tcprewrite: rewrite IPv6 addresses embedded in ICMPv6 error messages (Destination
+      Unreachable, Packet Too Big, Time Exceeded, Parameter Problem) - RFC4443 has these embed the
+      original ("invoking") packet's IP header, which tcprewrite left untouched, leaking the
+      original addresses through capture sanitization/anonymization; also fixed a related
+      pre-existing bug where the ICMPv6 checksum was never fixed up when an outer IPv6 address
+      changed, unless --fixcsum was also passed (#818)
+    - sendpacket: fix "zc:<ifname>"-style PF_RING ZC device names failing with "ioctl: No such
+      device" - the default PF_PACKET path did a plain SIOCGIFINDEX lookup on the literal "zc:"
+      string, which the kernel doesn't recognize; route zc: devices through libpcap instead, which
+      is PF_RING-aware when built against PF_RING's patched libpcap (#913)
+    - netmap: fix --netmap failing to switch the driver to bypass mode with a bogus "nm_do_ioctl:
+      No such file or directory" error on real NICs (not VALE ports); a stray switch default case
+      made nm_do_ioctl() report failure - and leak the ioctl socket fd - for SIOCSIFFLAGS/ethtool
+      SET requests even when the underlying ioctl succeeded, regressed since 4.4.3 (#810)
+    - tcpreplay: bound and make abortable the netmap TX-ring drain wait at the end of --loop
+      replays; some netmap/driver combinations never report the ring empty, which used to hang
+      tcpreplay at 100% CPU with no way to Ctrl+C out (#560)
+    - tcpreplay: fix cumulative timing drift with --multiplier - each packet's sleep was computed
+      from the previous packet's actual send time instead of a fixed start-of-replay anchor, so
+      per-packet scheduling/syscall overhead accumulated over a long replay (100k packets sent in
+      10.37s instead of the targeted 10.00s). Also fixes the same drift in dual-interface (-I)
+      replay, which the original patch didn't cover. (#724, #915)
+    - sendpacket (Linux): warn when sending on an interface with no carrier (cable unplugged /
+      link down); sendto() on a down interface can report local success even though nothing
+      reaches the wire, making "successful packets" stats meaningless (#109)
+    - sendpacket: fix --xdp AF_XDP zero-copy TX failing with EINVAL on drivers (i40e, ixgbe)
+      that require a native XDP program attached before ndo_xdp_xmit works; let libbpf
+      auto-load its default program instead of inhibiting it (#956, #1002)
+    - configure: fix LIBXDP feature probe rejecting every real libxdp install due to a
+      pointer-indirection mismatch in the xsk_socket__create() compile check (#1002)
+    - fragroute: fix build failure on macOS 13/14 from TAILQ_FOREACH_REVERSE argument-order
+      collision between bundled lib/queue.h and system <sys/queue.h> (#981, #1001)
+    - tcpprep: fix buffer overflow in check_dst_port() reading TCP/UDP dest port on truncated
+      packets with incomplete L4 headers (#985, #995)
+    - tcprewrite: fix --enet-vlan=add silently truncating output packets by 4 bytes when
+      --enet-vlan-pri and/or --enet-vlan-cfi were omitted on untagged input (#990, #994)
+    - fragroute: fix heap-buffer-overflow in fragroute_process() when a crafted packet's MPLS label
+      stack produces an L2 header longer than the fixed 50-byte buffer (#992, #993)
+    - send_packets: fix miscalibrated overflow guards in calc_sleep_time() causing tcpreplay to stop
+      pacing (-M/-p) and blast remaining packets at full speed on long/high-count replays (#974, #989)
+    - sendpacket: bounded retry on EAGAIN/ENOBUFS to prevent endless retry loop / 100% CPU hang (#984, #986)
+
 08/26/2025 Version 4.5.2
 08/26/2025 Version 4.5.2
     - C23 standard support (#977)
     - C23 standard support (#977)
     - --fixlen use-after-free (#970)
     - --fixlen use-after-free (#970)

+ 14 - 0
docs/CREDIT

@@ -147,3 +147,17 @@ Brad Smith <GitHub brad0>
 
 
 Mark Yang <GitHub markyang92>
 Mark Yang <GitHub markyang92>
     - TX_RING compile issue
     - TX_RING compile issue
+
+Yaroslav <GitHub @d3156>
+    - sendpacket: bounded retry on EAGAIN/ENOBUFS to prevent endless retry loop (#986)
+
+blaa <GitHub @blaa>
+    - reported Mbps pacing overflow on long replays (#974)
+
+ABcoders <GitHub @AB-Coder96>
+    - diagnosed and validated the calc_sleep_time() overflow, prototype fix (#989)
+
+Gabriel Ganne <GitHub @GabrielGanne>
+    - fragroute: fix heap-buffer-overflow on packets with too many MPLS labels (#993)
+    - tcprewrite: fix vlan tag add silently truncating output when --enet-vlan-pri/-cfi omitted (#994)
+    - tcpprep: fix buffer overflow in check_dst_port() on truncated L4 headers (#995)

+ 1 - 1
lib/strlcpy.h

@@ -1,6 +1,6 @@
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/bridge.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/bridge.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/cache.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/cache.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/common/cidr.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/cidr.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/err.c

@@ -7,7 +7,7 @@
  *
  *
  * Copyright (c) 2001-2010 Aaron Turner.
  * Copyright (c) 2001-2010 Aaron Turner.
  *
  *
- * Copyright (c) 2013-2025 Fred Klassen - AppNeta
+ * Copyright (c) 2013-2026 Fred Klassen - AppNeta
  *
  *
  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
  *
  *

+ 1 - 1
src/common/err.h

@@ -7,7 +7,7 @@
  *
  *
  * Copyright (c) 2001-2010 Aaron Turner.
  * Copyright (c) 2001-2010 Aaron Turner.
  *
  *
- * Copyright (c) 2013-2025 Fred Klassen - AppNeta
+ * Copyright (c) 2013-2026 Fred Klassen - AppNeta
  *
  *
  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
  *
  *

+ 1 - 1
src/common/fakepcap.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/fakepcap.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/common/fakepcapnav.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/fakepcapnav.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/flows.c

@@ -1,6 +1,6 @@
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/common/flows.h

@@ -1,6 +1,6 @@
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/get.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/get.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/common/git_version.c

@@ -1,4 +1,4 @@
-const char GIT_Version[] = "git:v4.5.2";
+const char GIT_Version[] = "git:v4.5.3-1-g60888f71";
 const char *git_version(void) {
 const char *git_version(void) {
     return GIT_Version;
     return GIT_Version;
 }
 }

+ 1 - 1
src/common/interface.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/interface.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/list.c

@@ -1,6 +1,6 @@
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/list.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/mac.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/mac.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 9 - 4
src/common/netmap.c

@@ -124,6 +124,15 @@ nm_do_ioctl(sendpacket_t *sp, u_long what, int subcmd)
     if (error)
     if (error)
         goto done;
         goto done;
 
 
+    /*
+     * No default case here on purpose: this switch only extracts read-back
+     * results for GET-style requests (SIOCGIFFLAGS, ETHTOOL_Gxxx). SET-style
+     * requests (SIOCSIFFLAGS, ETHTOOL_Sxxx) have nothing to parse and are
+     * meant to fall through - the real success/failure is `error` from the
+     * ioctl() call above. Adding "default: return -1;" here previously made
+     * every SIOCSIFFLAGS call (setting IFF_UP/IFF_PROMISC) look like a
+     * failure despite the ioctl succeeding, breaking --netmap entirely (#810).
+     */
     switch (what) {
     switch (what) {
     case SIOCGIFFLAGS:
     case SIOCGIFFLAGS:
         sp->if_flags = (ifr.ifr_flags << 16) | (0xffff & ifr.ifr_flags);
         sp->if_flags = (ifr.ifr_flags << 16) | (0xffff & ifr.ifr_flags);
@@ -152,13 +161,9 @@ nm_do_ioctl(sendpacket_t *sp, u_long what, int subcmd)
             sp->txcsum = eval.data;
             sp->txcsum = eval.data;
             dbgx(1, "ioctl SIOCETHTOOL ETHTOOL_GTXCSUM=%u", eval.data);
             dbgx(1, "ioctl SIOCETHTOOL ETHTOOL_GTXCSUM=%u", eval.data);
             break;
             break;
-        default:
-            return -1;
         }
         }
         break;
         break;
 #endif
 #endif
-    default:
-        return -1;
     }
     }
 
 
 done:
 done:

+ 1 - 1
src/common/pcap_dlt.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 113 - 5
src/common/sendpacket.c

@@ -50,6 +50,7 @@
 #include "config.h"
 #include "config.h"
 #include "common.h"
 #include "common.h"
 #include <errno.h>
 #include <errno.h>
+#include <net/if.h>
 #include <stdarg.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdio.h>
 #include <string.h>
 #include <string.h>
@@ -212,7 +213,7 @@ static struct tcpr_ether_addr *sendpacket_get_hwaddr_libdnet(sendpacket_t *) _U_
 #endif /* HAVE_LIBDNET */
 #endif /* HAVE_LIBDNET */
 
 
 #if (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) &&                                                      \
 #if (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) &&                                                      \
-        !(defined HAVE_PF_PACKET || defined BPF || defined HAVE_LIBDNET)
+        (defined HAVE_PF_RING_PCAP || !(defined HAVE_PF_PACKET || defined BPF || defined HAVE_LIBDNET))
 static sendpacket_t *sendpacket_open_pcap(const char *, char *) _U_;
 static sendpacket_t *sendpacket_open_pcap(const char *, char *) _U_;
 static struct tcpr_ether_addr *sendpacket_get_hwaddr_pcap(sendpacket_t *) _U_;
 static struct tcpr_ether_addr *sendpacket_get_hwaddr_pcap(sendpacket_t *) _U_;
 #endif /* HAVE_PCAP_INJECT || HAVE_PACKET_SENDPACKET */
 #endif /* HAVE_PCAP_INJECT || HAVE_PACKET_SENDPACKET */
@@ -257,6 +258,13 @@ sendpacket(sendpacket_t *sp, const u_char *data, size_t len, struct pcap_pkthdr
                                   * prevent page misses on stack
                                   * prevent page misses on stack
                                   */
                                   */
     static const size_t buffer_payload_size = sizeof(buffer) + sizeof(struct pcap_pkthdr);
     static const size_t buffer_payload_size = sizeof(buffer) + sizeof(struct pcap_pkthdr);
+    /* Bound the EAGAIN/ENOBUFS retry loop below so sustained buffer pressure (e.g. very
+     * large frames) can't spin forever at 100% CPU; a short sleep between retries keeps
+     * that spin from hammering the kernel while we wait for buffer space to free up.
+     */
+    size_t retry_count = 0;
+    const size_t max_retry_count = 100;
+    const useconds_t retry_sleep_usec = 100;
 
 
     assert(sp);
     assert(sp);
 #ifndef HAVE_LIBXDP
 #ifndef HAVE_LIBXDP
@@ -268,6 +276,16 @@ sendpacket(sendpacket_t *sp, const u_char *data, size_t len, struct pcap_pkthdr
         return -1;
         return -1;
 
 
 TRY_SEND_AGAIN:
 TRY_SEND_AGAIN:
+    if (retry_count > 0)
+        usleep(retry_sleep_usec);
+
+    if (++retry_count > max_retry_count) {
+        sendpacket_seterr(sp,
+                          "Giving up after " COUNTER_SPEC " retries on EAGAIN/ENOBUFS",
+                          (COUNTER)max_retry_count);
+        goto EXIT_MAX_RETRIES;
+    }
+
     sp->attempt++;
     sp->attempt++;
 
 
     switch (sp->handle_type) {
     switch (sp->handle_type) {
@@ -498,6 +516,7 @@ TRY_SEND_AGAIN:
         errx(-1, "Unsupported sp->handle_type = %d", sp->handle_type);
         errx(-1, "Unsupported sp->handle_type = %d", sp->handle_type);
     } /* end case */
     } /* end case */
 
 
+EXIT_MAX_RETRIES:
     if (retcode < 0) {
     if (retcode < 0) {
         sp->failed++;
         sp->failed++;
     } else if (sp->abort) {
     } else if (sp->abort) {
@@ -519,6 +538,45 @@ TRY_SEND_AGAIN:
     return retcode;
     return retcode;
 }
 }
 
 
+#if defined linux && defined SIOCGIFFLAGS && defined IFF_RUNNING
+/**
+ * Best-effort check of whether "device" currently has carrier (IFF_RUNNING).
+ * Returns 1 if it does, 0 if it's definitely down (e.g. cable unplugged), or
+ * -1 if the check couldn't be performed (not a real/queryable interface -
+ * khial, tuntap, etc.) and should be treated as "unknown, assume fine".
+ *
+ * Linux-only: the kernel's linkwatch subsystem clears IFF_RUNNING when there's
+ * no carrier, which is what makes this check meaningful. On macOS/BSD,
+ * IFF_RUNNING only reflects "interface resources allocated" and stays set even
+ * when a real carrier check (ifconfig's "status: inactive", via SIOCGIFMEDIA)
+ * says the link is down - so this check would be silently wrong there. #109
+ * was reported and reproduced on Linux; a BSD/macOS equivalent needs the
+ * SIOCGIFMEDIA path and is left for a follow-up.
+ */
+static int
+sendpacket_is_running(const char *device)
+{
+    struct ifreq ifr;
+    int mysocket = socket(AF_INET, SOCK_DGRAM, 0);
+    int ret = -1;
+
+    if (mysocket < 0) {
+        return -1;
+    }
+
+    memset(&ifr, 0, sizeof(ifr));
+    strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+    ret = ioctl(mysocket, SIOCGIFFLAGS, &ifr);
+    close(mysocket);
+
+    if (ret < 0) {
+        return -1;
+    }
+
+    return (ifr.ifr_flags & IFF_RUNNING) ? 1 : 0;
+}
+#endif /* linux && SIOCGIFFLAGS && IFF_RUNNING */
+
 /**
 /**
  * Open the given network device name and returns a sendpacket_t struct
  * Open the given network device name and returns a sendpacket_t struct
  * pass the error buffer (in case there's a problem) and the direction
  * pass the error buffer (in case there's a problem) and the direction
@@ -568,6 +626,21 @@ sendpacket_open(const char *device,
             sp = sendpacket_open_tuntap(device, errbuf);
             sp = sendpacket_open_tuntap(device, errbuf);
 #endif
 #endif
         } else {
         } else {
+#if defined HAVE_PF_RING_PCAP && (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET)
+            /*
+             * "zc:<ifname>"-style device names are PF_RING ZC's own virtual
+             * device addressing, resolved by PF_RING's patched libpcap - not
+             * by the kernel. The PF_PACKET path below does a plain
+             * SIOCGIFINDEX lookup on the literal device string, which always
+             * fails with ENODEV for these ("ioctl: No such device"), even
+             * though the interface itself is working (confirmed via
+             * PF_RING's own pfsend utility - see #913). Route zc: devices
+             * through libpcap instead, which is PF_RING-aware in this build.
+             */
+            if (strncmp(device, "zc:", 3) == 0)
+                sp = sendpacket_open_pcap(device, errbuf);
+            else
+#endif
 #ifdef HAVE_NETMAP
 #ifdef HAVE_NETMAP
             if (sendpacket_type == SP_TYPE_NETMAP)
             if (sendpacket_type == SP_TYPE_NETMAP)
                 sp = (sendpacket_t *)sendpacket_open_netmap(device, errbuf, arg);
                 sp = (sendpacket_t *)sendpacket_open_netmap(device, errbuf, arg);
@@ -595,6 +668,33 @@ sendpacket_open(const char *device,
     if (sp) {
     if (sp) {
         sp->open = 1;
         sp->open = 1;
         sp->cache_dir = direction;
         sp->cache_dir = direction;
+
+#if defined linux && defined SIOCGIFFLAGS && defined IFF_RUNNING
+        /*
+         * khial/tuntap/pcap-dump aren't real, carrier-having interfaces, and netmap does
+         * its own IFF_RUNNING check (and errors out) before we'd ever get here. For
+         * everything else, warn loudly if there's no carrier: sendto() on a down/unplugged
+         * interface can still report success locally even though nothing reaches the wire
+         * (#109), so tcpreplay's own "successful packets" stats would otherwise be
+         * silently meaningless.
+         */
+        switch (sp->handle_type) {
+        case SP_TYPE_PF_PACKET:
+        case SP_TYPE_TX_RING:
+        case SP_TYPE_BPF:
+        case SP_TYPE_LIBDNET:
+        case SP_TYPE_LIBPCAP:
+        case SP_TYPE_LIBXDP:
+            if (sendpacket_is_running(sp->device) == 0) {
+                warnx("WARNING: %s has no carrier (cable unplugged or link down). Packets will "
+                      "appear to send successfully but will not reach the wire.",
+                      sp->device);
+            }
+            break;
+        default:
+            break;
+        }
+#endif /* linux && SIOCGIFFLAGS && IFF_RUNNING */
     } else {
     } else {
         errx(-1, "failed to open device %s: %s", device, errbuf);
         errx(-1, "failed to open device %s: %s", device, errbuf);
     }
     }
@@ -674,9 +774,7 @@ sendpacket_close(sendpacket_t *sp)
         break;
         break;
 
 
     case SP_TYPE_LIBPCAP:
     case SP_TYPE_LIBPCAP:
-#ifdef HAVE_LIBPCAP
         pcap_close(sp->handle.pcap);
         pcap_close(sp->handle.pcap);
-#endif
         break;
         break;
 
 
     case SP_TYPE_LIBPCAP_DUMP:
     case SP_TYPE_LIBPCAP_DUMP:
@@ -782,7 +880,7 @@ sendpacket_seterr(sendpacket_t *sp, const char *fmt, ...)
 }
 }
 
 
 #if (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) &&                                                      \
 #if (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET) &&                                                      \
-        !(defined HAVE_PF_PACKET || defined BPF || defined HAVE_LIBDNET)
+        (defined HAVE_PF_RING_PCAP || !(defined HAVE_PF_PACKET || defined BPF || defined HAVE_LIBDNET))
 /**
 /**
  * Inner sendpacket_open() method for using libpcap
  * Inner sendpacket_open() method for using libpcap
  */
  */
@@ -1507,7 +1605,17 @@ create_xsk_socket(struct xsk_umem_info *umem_info,
 
 
     socket_config->rx_size = nb_of_rx_queue_desc;
     socket_config->rx_size = nb_of_rx_queue_desc;
     socket_config->tx_size = nb_of_tx_queue_desc;
     socket_config->tx_size = nb_of_tx_queue_desc;
-    socket_config->libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
+    /*
+     * Some NIC drivers (i40e, ixgbe, virtio_net, ...) only set up their XDP TX
+     * datapath (ndo_xdp_xmit) once a native XDP program is attached to the
+     * interface; without one, xsk_socket__create() binds successfully but the
+     * later zero-copy send fails with EINVAL. XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD
+     * skips libbpf's default program auto-load, which avoided that trigger.
+     * tcpreplay doesn't need the auto-loaded program's RX behavior, only the
+     * side effect of a program being attached, so let libbpf load its default
+     * one (#956).
+     */
+    socket_config->libbpf_flags = 0;
     socket_config->bind_flags = 0; // XDP_FLAGS_SKB_MODE (1U << 1) or XDP_FLAGS_DRV_MODE (1U << 2)
     socket_config->bind_flags = 0; // XDP_FLAGS_SKB_MODE (1U << 1) or XDP_FLAGS_DRV_MODE (1U << 2)
     xsk_info = xsk_configure_socket(umem_info, socket_config, queue_id, device);
     xsk_info = xsk_configure_socket(umem_info, socket_config, queue_id, device);
     safe_free(socket_config);
     safe_free(socket_config);

+ 1 - 1
src/common/sendpacket.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/services.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/common/services.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/tcpdump.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/tcpdump.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/timer.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/timer.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 2 - 2
src/common/utils.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as
@@ -436,7 +436,7 @@ uint32_t
 tcpr_random(uint32_t *seed)
 tcpr_random(uint32_t *seed)
 {
 {
     unsigned int next = *seed;
     unsigned int next = *seed;
-    int result;
+    unsigned int result;
 
 
     next *= 1103515245;
     next *= 1103515245;
     next += 12345;
     next += 12345;

+ 3 - 1
src/common/utils.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as
@@ -34,6 +34,8 @@ typedef struct {
     struct timespec end_time;
     struct timespec end_time;
     struct timespec pkt_ts_delta;
     struct timespec pkt_ts_delta;
     struct timespec last_print;
     struct timespec last_print;
+    struct timespec first_packet_time;
+    struct timespec first_packet_wall_time;
     COUNTER flow_non_flow_packets;
     COUNTER flow_non_flow_packets;
     COUNTER flows;
     COUNTER flows;
     COUNTER flows_unique;
     COUNTER flows_unique;

+ 1 - 1
src/common/xX.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/common/xX.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 9 - 1
src/fragroute/fragroute.c

@@ -3,7 +3,7 @@
  *
  *
  * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  * Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  * Copyright (c) 2007-2008 Aaron Turner.
  * Copyright (c) 2007-2008 Aaron Turner.
- * Copyright (c) 2013-2025 Fred Klassen - AppNeta
+ * Copyright (c) 2013-2026 Fred Klassen - AppNeta
  * $Id$
  * $Id$
  */
  */
 
 
@@ -52,6 +52,14 @@ fragroute_process(fragroute_t *ctx, void *buf, size_t len)
     ctx->first_packet = 0;
     ctx->first_packet = 0;
     /* save the l2 header of the original packet for later */
     /* save the l2 header of the original packet for later */
     ctx->l2len = get_l2len(buf, (int)len, ctx->dlt);
     ctx->l2len = get_l2len(buf, (int)len, ctx->dlt);
+    if (ctx->l2len < 0 || (size_t)ctx->l2len > len || (size_t)ctx->l2len > sizeof(ctx->l2header)) {
+        snprintf(ctx->errbuf,
+                 sizeof(ctx->errbuf),
+                 "invalid L2 header length %d for packet length %zu",
+                 ctx->l2len,
+                 len);
+        return -1;
+    }
     memcpy(ctx->l2header, buf, ctx->l2len);
     memcpy(ctx->l2header, buf, ctx->l2len);
 
 
     if ((pkt = pkt_new(len)) == NULL) {
     if ((pkt = pkt_new(len)) == NULL) {

+ 1 - 1
src/fragroute/fragroute.h

@@ -3,7 +3,7 @@
 /*
 /*
  *   Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  *   Copyright (c) 2001 Dug Song <dugsong@monkey.org>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 10 - 2
src/fragroute/mod.c

@@ -177,8 +177,16 @@ mod_close(void)
 {
 {
     struct rule *rule;
     struct rule *rule;
 
 
-    TAILQ_FOREACH_REVERSE(rule, &rules, next, head)
-    {
+    /*
+     * Not using TAILQ_FOREACH_REVERSE: its (field, headname) argument order is
+     * not standardized across BSD queue.h implementations, and this file's
+     * bundled lib/queue.h can lose that macro to a system <sys/queue.h> pulled
+     * in transitively (e.g. via net/if.h on macOS), silently flipping the
+     * argument order tcpreplay was compiled against (#981). TAILQ_LAST/
+     * TAILQ_PREV/TAILQ_END have a consistent signature everywhere, so iterate
+     * with those directly instead.
+     */
+    for (rule = TAILQ_LAST(&rules, head); rule != TAILQ_END(&rules); rule = TAILQ_PREV(rule, head, next)) {
         if (rule->mod->close != NULL)
         if (rule->mod->close != NULL)
             rule->data = rule->mod->close(rule->data);
             rule->data = rule->mod->close(rule->data);
         TAILQ_REMOVE(&rules, rule, next);
         TAILQ_REMOVE(&rules, rule, next);

+ 1 - 1
src/replay.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/replay.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 117 - 78
src/send_packets.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as
@@ -80,6 +80,44 @@ wake_send_queues(sendpacket_t *sp _U_, tcpreplay_opt_t *options _U_)
     if (options->netmap)
     if (options->netmap)
         ioctl(sp->handle.fd, NIOCTXSYNC, NULL); /* flush TX buffer */
         ioctl(sp->handle.fd, NIOCTXSYNC, NULL); /* flush TX buffer */
 }
 }
+
+/* how long to wait for a netmap TX ring to report empty before giving up */
+#define NETMAP_TX_DRAIN_TIMEOUT_SEC 2
+
+/**
+ * Wait for a netmap TX ring to fully drain at the end of a replay.
+ *
+ * Bounded and abortable: some netmap/driver combinations never flip the
+ * ring's empty flag (external bug - see #560), which used to make this an
+ * unkillable, uninterruptible 100% CPU spin since neither a timeout nor
+ * ctx->abort were checked. Give up after NETMAP_TX_DRAIN_TIMEOUT_SEC with a
+ * warning instead of hanging forever, and let SIGINT (ctx->abort) break out
+ * immediately.
+ */
+static void
+netmap_wait_tx_drain(tcpreplay_t *ctx, sendpacket_t *sp, struct timespec *now, bool *now_is_now)
+{
+    struct timespec start, elapsed;
+
+    if (!sp)
+        return;
+
+    TIMESPEC_SET(&start, now);
+
+    while (!ctx->abort && !netmap_tx_queues_empty(sp)) {
+        get_current_time(now);
+        *now_is_now = true;
+
+        timessub(now, &start, &elapsed);
+        if (elapsed.tv_sec >= NETMAP_TX_DRAIN_TIMEOUT_SEC) {
+            warnx("netmap TX ring on %s did not drain after %d seconds - the netmap driver may not "
+                  "be flushing correctly. Giving up waiting.",
+                  sp->device,
+                  NETMAP_TX_DRAIN_TIMEOUT_SEC);
+            break;
+        }
+    }
+}
 #endif
 #endif
 
 
 static inline int
 static inline int
@@ -341,6 +379,7 @@ void
 send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
 send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
 {
 {
     struct timespec now, print_delta, last_pkt_ts;
     struct timespec now, print_delta, last_pkt_ts;
+    bool first_packet = true;
     tcpreplay_opt_t *options = ctx->options;
     tcpreplay_opt_t *options = ctx->options;
     tcpreplay_stats_t *stats = &ctx->stats;
     tcpreplay_stats_t *stats = &ctx->stats;
     COUNTER packetnum = 0;
     COUNTER packetnum = 0;
@@ -465,23 +504,25 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
             skip_length = 0;
             skip_length = 0;
             ctx->skip_packets = 0;
             ctx->skip_packets = 0;
 
 
+            if (!top_speed) {
+                now_is_now = true;
+                get_current_time(&now);
+            }
+
             if (options->speed.mode == speed_multiplier) {
             if (options->speed.mode == speed_multiplier) {
-                if (!timesisset(&last_pkt_ts)) {
+                if (first_packet) {
+                    TIMESPEC_SET(&stats->first_packet_time, &pkthdr_ts);
                     TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
                     TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
+                    TIMESPEC_SET(&stats->first_packet_wall_time, &now);
+                    first_packet = false;
                 } else if (timescmp(&pkthdr_ts, &last_pkt_ts, >)) {
                 } else if (timescmp(&pkthdr_ts, &last_pkt_ts, >)) {
-                    struct timespec delta;
-
-                    timessub(&pkthdr_ts, &last_pkt_ts, &delta);
-                    timeradd_timespec(&stats->pkt_ts_delta, &delta, &stats->pkt_ts_delta);
                     TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
                     TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
+                    timessub(&pkthdr_ts, &stats->first_packet_time, &stats->pkt_ts_delta);
+                    timessub(&now, &stats->first_packet_wall_time, &stats->time_delta);
+                    timesdiv_float(&stats->pkt_ts_delta, options->speed.multiplier);
                 }
                 }
             }
             }
 
 
-            if (!top_speed) {
-                now_is_now = true;
-                get_current_time(&now);
-            }
-
             /*
             /*
              * Only if the current packet is not late.
              * Only if the current packet is not late.
              *
              *
@@ -499,15 +540,6 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
                             &skip_length);
                             &skip_length);
 
 
             /*
             /*
-             * Track the time of the "last packet sent".
-             *
-             * A number of 3rd party tools generate bad timestamps which go backwards
-             * in time.  Hence, don't update the "last" unless pkthdr.ts > last
-             */
-            if (timescmp(&stats->time_delta, &stats->pkt_ts_delta, <))
-                TIMESPEC_SET(&stats->time_delta, &stats->pkt_ts_delta);
-
-            /*
              * we know how long to sleep between sends, now do it.
              * we know how long to sleep between sends, now do it.
              */
              */
             if (!top_speed) {
             if (!top_speed) {
@@ -596,15 +628,8 @@ send_packets(tcpreplay_t *ctx, pcap_t *pcap, int idx)
 #ifdef HAVE_NETMAP
 #ifdef HAVE_NETMAP
     /* when completing test, wait until the last packet is sent */
     /* when completing test, wait until the last packet is sent */
     if (options->netmap && (ctx->abort || options->loop == 1)) {
     if (options->netmap && (ctx->abort || options->loop == 1)) {
-        while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
-            now_is_now = true;
-            get_current_time(&now);
-        }
-
-        while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
-            now_is_now = true;
-            get_current_time(&now);
-        }
+        netmap_wait_tx_drain(ctx, ctx->intf1, &now, &now_is_now);
+        netmap_wait_tx_drain(ctx, ctx->intf2, &now, &now_is_now);
     }
     }
 #endif /* HAVE_NETMAP */
 #endif /* HAVE_NETMAP */
 
 
@@ -624,6 +649,7 @@ void
 send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *pcap2, int cache_file_idx2)
 send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *pcap2, int cache_file_idx2)
 {
 {
     struct timespec now, print_delta, last_pkt_ts;
     struct timespec now, print_delta, last_pkt_ts;
+    bool first_packet = true;
     tcpreplay_opt_t *options = ctx->options;
     tcpreplay_opt_t *options = ctx->options;
     tcpreplay_stats_t *stats = &ctx->stats;
     tcpreplay_stats_t *stats = &ctx->stats;
     COUNTER packetnum = 0;
     COUNTER packetnum = 0;
@@ -763,26 +789,25 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
             skip_length = 0;
             skip_length = 0;
             ctx->skip_packets = 0;
             ctx->skip_packets = 0;
 
 
+            if (!top_speed) {
+                get_current_time(&now);
+                now_is_now = true;
+            }
+
             if (options->speed.mode == speed_multiplier) {
             if (options->speed.mode == speed_multiplier) {
                 struct timespec pkthdr_ts;
                 struct timespec pkthdr_ts;
                 PCAP_TIMEVAL_TO_TIMESPEC_SET(&pkthdr_ptr->ts, &pkthdr_ts);
                 PCAP_TIMEVAL_TO_TIMESPEC_SET(&pkthdr_ptr->ts, &pkthdr_ts);
-                if (!timesisset(&last_pkt_ts)) {
-                    PCAP_TIMEVAL_TO_TIMESPEC_SET(&pkthdr_ptr->ts, &last_pkt_ts);
+                if (first_packet) {
+                    TIMESPEC_SET(&stats->first_packet_time, &pkthdr_ts);
+                    TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
+                    TIMESPEC_SET(&stats->first_packet_wall_time, &now);
+                    first_packet = false;
                 } else if (timescmp(&pkthdr_ts, &last_pkt_ts, >)) {
                 } else if (timescmp(&pkthdr_ts, &last_pkt_ts, >)) {
-                    struct timespec delta;
-
-                    timessub(&pkthdr_ts, &last_pkt_ts, &delta);
-                    timeradd_timespec(&stats->pkt_ts_delta, &delta, &stats->pkt_ts_delta);
                     TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
                     TIMESPEC_SET(&last_pkt_ts, &pkthdr_ts);
+                    timessub(&pkthdr_ts, &stats->first_packet_time, &stats->pkt_ts_delta);
+                    timessub(&now, &stats->first_packet_wall_time, &stats->time_delta);
+                    timesdiv_float(&stats->pkt_ts_delta, options->speed.multiplier);
                 }
                 }
-
-                if (!timesisset(&stats->time_delta))
-                    TIMESPEC_SET(&stats->pkt_ts_delta, &stats->pkt_ts_delta);
-            }
-
-            if (!top_speed) {
-                get_current_time(&now);
-                now_is_now = true;
             }
             }
 
 
             /*
             /*
@@ -802,15 +827,6 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
                             &skip_length);
                             &skip_length);
 
 
             /*
             /*
-             * Track the time of the "last packet sent".
-             *
-             * A number of 3rd party tools generate bad timestamps which go backwards
-             * in time.  Hence, don't update the "last" unless pkthdr_ptr->ts > last
-             */
-            if (timescmp(&stats->time_delta, &stats->pkt_ts_delta, <))
-                TIMESPEC_SET(&stats->time_delta, &stats->pkt_ts_delta);
-
-            /*
              * we know how long to sleep between sends, now do it.
              * we know how long to sleep between sends, now do it.
              */
              */
             if (!top_speed)
             if (!top_speed)
@@ -877,15 +893,8 @@ send_dual_packets(tcpreplay_t *ctx, pcap_t *pcap1, int cache_file_idx1, pcap_t *
 #ifdef HAVE_NETMAP
 #ifdef HAVE_NETMAP
     /* when completing test, wait until the last packet is sent */
     /* when completing test, wait until the last packet is sent */
     if (options->netmap && (ctx->abort || options->loop == 1)) {
     if (options->netmap && (ctx->abort || options->loop == 1)) {
-        while (ctx->intf1 && !netmap_tx_queues_empty(ctx->intf1)) {
-            get_current_time(&now);
-            now_is_now = true;
-        }
-
-        while (ctx->intf2 && !netmap_tx_queues_empty(ctx->intf2)) {
-            get_current_time(&now);
-            now_is_now = true;
-        }
+        netmap_wait_tx_drain(ctx, ctx->intf1, &now, &now_is_now);
+        netmap_wait_tx_drain(ctx, ctx->intf2, &now, &now_is_now);
     }
     }
 #endif /* HAVE_NETMAP */
 #endif /* HAVE_NETMAP */
 
 
@@ -1062,9 +1071,6 @@ calc_sleep_time(tcpreplay_t *ctx,
             /* pkt_time_delta has increased, so handle normally */
             /* pkt_time_delta has increased, so handle normally */
             timessub(pkt_ts_delta, time_delta, &nap_for);
             timessub(pkt_ts_delta, time_delta, &nap_for);
             TIMESPEC_SET(&ctx->nap, &nap_for);
             TIMESPEC_SET(&ctx->nap, &nap_for);
-            dbgx(3, "original packet delta time: " TIMESPEC_FORMAT, ctx->nap.tv_sec, ctx->nap.tv_nsec);
-            timesdiv_float(&ctx->nap, options->speed.multiplier);
-            dbgx(3, "original packet delta/div: " TIMESPEC_FORMAT, ctx->nap.tv_sec, ctx->nap.tv_nsec);
         }
         }
         break;
         break;
 
 
@@ -1081,14 +1087,32 @@ calc_sleep_time(tcpreplay_t *ctx,
             COUNTER tx_ns = now_ns - start_ns;
             COUNTER tx_ns = now_ns - start_ns;
 
 
             /*
             /*
-             * bits * 1000000000 divided by bps = nanosecond
+             * next_tx_ns = bits_sent * 1000000000 / bps (nanoseconds)
              *
              *
-             * ensure there is no overflow in cases where bits_sent is very high
+             * bits_sent * 1000000000 overflows a 64-bit COUNTER once
+             * bits_sent exceeds ~1.8e10 (~2.3GB sent, at any bps) -- e.g.
+             * a multi-GB/multi-million-packet replay at a constant -M
+             * rate. The previous COUNTER_OVERFLOW_RISK guard (COUNTER_MAX
+             * >> 23, ~2.2e12) was ~119x too high to ever catch this, so
+             * long replays silently overflowed into a small/garbage
+             * next_tx_ns and stopped sleeping (#974).
+             *
+             * Do the multiply in a wider-than-COUNTER type so it can't
+             * overflow for any COUNTER-representable bits_sent/bps.
              */
              */
-            if (bits_sent > COUNTER_OVERFLOW_RISK)
-                next_tx_ns = (bits_sent * 1000) / bps * 1000000;
-            else
-                next_tx_ns = (bits_sent * 1000000000) / bps;
+#if defined(__SIZEOF_INT128__)
+            next_tx_ns = (COUNTER)(((unsigned __int128)bits_sent * 1000000000ULL) / bps);
+#else
+            /*
+             * No 128-bit integer type available. Split the *1e9 around
+             * the division (*1000 before, *1000000 after) so the
+             * intermediate is bits_sent * 1000, which only overflows
+             * COUNTER at ~1.8e16 bits (~2.3 petabytes) sent -- unlike the
+             * old code, this is applied unconditionally, not gated by a
+             * miscalibrated threshold.
+             */
+            next_tx_ns = (bits_sent * 1000ULL) / bps * 1000000ULL;
+#endif
 
 
             if (next_tx_ns > tx_ns) {
             if (next_tx_ns > tx_ns) {
                 NANOSEC_TO_TIMESPEC(next_tx_ns - tx_ns, &ctx->nap);
                 NANOSEC_TO_TIMESPEC(next_tx_ns - tx_ns, &ctx->nap);
@@ -1115,16 +1139,31 @@ calc_sleep_time(tcpreplay_t *ctx,
             COUNTER pkts_sent = ctx->stats.pkts_sent;
             COUNTER pkts_sent = ctx->stats.pkts_sent;
             COUNTER tx_ns = now_ns - start_ns;
             COUNTER tx_ns = now_ns - start_ns;
             /*
             /*
-             * packets * 1000000 divided by pps = microseconds
-             * packets per sec (pps) = packets per hour / (60 * 60)
+             * next_tx_ns = pkts_sent * 1000000000 * 3600 / pph (nanoseconds)
+             * packets per sec (pps) = packets per hour (pph) / (60 * 60)
              *
              *
-             * Adjust for long running tests with high PPS to prevent overflow.
-             * When active, adjusted calculation may add a bit of jitter.
+             * pkts_sent * 1000000000 * 3600 (~3.6e12) overflows a 64-bit
+             * COUNTER once pkts_sent exceeds ~5.1 million packets -- well
+             * within range for a long packetrate-limited replay, and far
+             * below the previous COUNTER_OVERFLOW_RISK guard's ~2.2e12
+             * threshold, which never actually protected this multiply
+             * (same miscalibration as the speed_mbpsrate case, #974).
+             *
+             * Do the multiply in a wider-than-COUNTER type so it can't
+             * overflow for any COUNTER-representable pkts_sent/pph.
              */
              */
-            if ((pkts_sent < COUNTER_OVERFLOW_RISK))
-                next_tx_ns = (pkts_sent * 1000000000) * (60 * 60) / pph;
-            else
-                next_tx_ns = ((pkts_sent * 1000000) / pph * 1000) * (60 * 60);
+#if defined(__SIZEOF_INT128__)
+            next_tx_ns = (COUNTER)(((unsigned __int128)pkts_sent * 1000000000ULL * 3600ULL) / pph);
+#else
+            /*
+             * No 128-bit integer type available. Split the *1e9*3600
+             * around the division (*1e6 before, *1e3*3600 after) so the
+             * intermediate is pkts_sent * 1e6, which only overflows
+             * COUNTER at ~1.8e13 packets -- applied unconditionally,
+             * unlike the old miscalibrated-threshold version.
+             */
+            next_tx_ns = ((pkts_sent * 1000000ULL) / pph * 1000ULL) * 3600ULL;
+#endif
 
 
             if (next_tx_ns > tx_ns)
             if (next_tx_ns > tx_ns)
                 NANOSEC_TO_TIMESPEC(next_tx_ns - tx_ns, &ctx->nap);
                 NANOSEC_TO_TIMESPEC(next_tx_ns - tx_ns, &ctx->nap);

+ 1 - 1
src/send_packets.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/signal_handler.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/signal_handler.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/sleep.c

@@ -1,6 +1,6 @@
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/sleep.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 11 - 3
src/tcpbridge.1

@@ -10,7 +10,7 @@
 .ds B-Font B
 .ds B-Font B
 .ds I-Font I
 .ds I-Font I
 .ds R-Font R
 .ds R-Font R
-.TH tcpbridge 1 "26 Aug 2025" "tcpbridge" "User Commands"
+.TH tcpbridge 1 "19 Jul 2026" "tcpbridge" "User Commands"
 .\"
 .\"
 .\" DO NOT EDIT THIS FILE (in-mem file)
 .\" DO NOT EDIT THIS FILE (in-mem file)
 .\"
 .\"
@@ -483,6 +483,8 @@ in the range  0 through 4095
 .fi
 .fi
 .in -4
 .in -4
 .sp
 .sp
+Mandatory when \fB--enet-vlan=add\fP is used on packets that are not already
+VLAN tagged.
 .TP
 .TP
 .NOP \f\*[B-Font]\-\-enet\-vlan\-cfi\f[]=\f\*[I-Font]number\f[]
 .NOP \f\*[B-Font]\-\-enet\-vlan\-cfi\f[]=\f\*[I-Font]number\f[]
 Specify the ethernet 802.1q VLAN CFI value.
 Specify the ethernet 802.1q VLAN CFI value.
@@ -500,6 +502,9 @@ in the range  0 through 1
 .fi
 .fi
 .in -4
 .in -4
 .sp
 .sp
+When omitted, the CFI bit of an existing VLAN header is preserved; a newly
+added tag on a previously untagged packet defaults to 0 (a one-time notice
+is printed).
 .TP
 .TP
 .NOP \f\*[B-Font]\-\-enet\-vlan\-pri\f[]=\f\*[I-Font]number\f[]
 .NOP \f\*[B-Font]\-\-enet\-vlan\-pri\f[]=\f\*[I-Font]number\f[]
 Specify the ethernet 802.1q VLAN priority.
 Specify the ethernet 802.1q VLAN priority.
@@ -517,6 +522,9 @@ in the range  0 through 7
 .fi
 .fi
 .in -4
 .in -4
 .sp
 .sp
+When omitted, the priority of an existing VLAN header is preserved; a newly
+added tag on a previously untagged packet defaults to 0 (a one-time notice
+is printed).
 .TP
 .TP
 .NOP \f\*[B-Font]\-\-enet\-vlan\-proto\f[]=\f\*[I-Font]string\f[]
 .NOP \f\*[B-Font]\-\-enet\-vlan\-proto\f[]=\f\*[I-Font]string\f[]
 Specify VLAN tag protocol 802.1q or 802.1ad.
 Specify VLAN tag protocol 802.1q or 802.1ad.
@@ -796,13 +804,13 @@ libopts had an internal operational error.  Please report
 it to autogen-users@lists.sourceforge.net.  Thank you.
 it to autogen-users@lists.sourceforge.net.  Thank you.
 .PP
 .PP
 .SH "AUTHORS"
 .SH "AUTHORS"
-Copyright 2013-2025 Fred Klassen \- AppNeta
+Copyright 2013-2026 Fred Klassen \- AppNeta
 Copyright 2000-2012 Aaron Turner
 Copyright 2000-2012 Aaron Turner
 For support please use the tcpreplay-users@lists.sourceforge.net mailing list.
 For support please use the tcpreplay-users@lists.sourceforge.net mailing list.
 The latest version of this software is always available from:
 The latest version of this software is always available from:
 http://tcpreplay.appneta.com/
 http://tcpreplay.appneta.com/
 .SH "COPYRIGHT"
 .SH "COPYRIGHT"
-Copyright (C) 2000-2025 Aaron Turner and Fred Klassen all rights reserved.
+Copyright (C) 2000-2026 Aaron Turner and Fred Klassen all rights reserved.
 This program is released under the terms of the GNU General Public License, version 3 or later.
 This program is released under the terms of the GNU General Public License, version 3 or later.
 .SH "BUGS"
 .SH "BUGS"
 Please send bug reports to: tcpreplay-users@lists.sourceforge.net
 Please send bug reports to: tcpreplay-users@lists.sourceforge.net

+ 1 - 1
src/tcpbridge.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpbridge.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 12 - 7
src/tcpbridge_opts.c

@@ -19,7 +19,7 @@
  * The tcpbridge program is copyrighted and licensed
  * The tcpbridge program is copyrighted and licensed
  * under the following terms:
  * under the following terms:
  *
  *
- *  Copyright (C) 2000-2025 Aaron Turner and Fred Klassen, all rights reserved.
+ *  Copyright (C) 2000-2026 Aaron Turner and Fred Klassen, all rights reserved.
  *  This is free software. It is licensed for use, modification and
  *  This is free software. It is licensed for use, modification and
  *  redistribution under the terms of the GNU General Public License,
  *  redistribution under the terms of the GNU General Public License,
  *  version 3 or later <http://gnu.org/licenses/gpl.html>
  *  version 3 or later <http://gnu.org/licenses/gpl.html>
@@ -82,7 +82,7 @@ extern tcpbridge_opt_t options;
  */
  */
 static char const tcpbridge_opt_strs[4731] =
 static char const tcpbridge_opt_strs[4731] =
 /*     0 */ "tcpbridge (tcpbridge)\n"
 /*     0 */ "tcpbridge (tcpbridge)\n"
-            "Copyright (C) 2000-2025 Aaron Turner and Fred Klassen, all rights reserved.\n"
+            "Copyright (C) 2000-2026 Aaron Turner and Fred Klassen, all rights reserved.\n"
             "This is free software. It is licensed for use, modification and\n"
             "This is free software. It is licensed for use, modification and\n"
             "redistribution under the terms of the GNU General Public License,\n"
             "redistribution under the terms of the GNU General Public License,\n"
             "version 3 or later <http://gnu.org/licenses/gpl.html>\n\0"
             "version 3 or later <http://gnu.org/licenses/gpl.html>\n\0"
@@ -2136,7 +2136,8 @@ optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1);
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 /**
 /**
  * Code to handle the enet-vlan-tag option.
  * Code to handle the enet-vlan-tag option.
- *
+ * Mandatory when @var{--enet-vlan=add} is used on packets that are not already
+ * VLAN tagged.
  * @param[in] pOptions the tcpbridge options data structure
  * @param[in] pOptions the tcpbridge options data structure
  * @param[in,out] pOptDesc the option descriptor for this option.
  * @param[in,out] pOptDesc the option descriptor for this option.
  */
  */
@@ -2171,7 +2172,9 @@ optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1);
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 /**
 /**
  * Code to handle the enet-vlan-cfi option.
  * Code to handle the enet-vlan-cfi option.
- *
+ * When omitted, the CFI bit of an existing VLAN header is preserved; a newly
+ * added tag on a previously untagged packet defaults to 0 (a one-time notice
+ * is printed).
  * @param[in] pOptions the tcpbridge options data structure
  * @param[in] pOptions the tcpbridge options data structure
  * @param[in,out] pOptDesc the option descriptor for this option.
  * @param[in,out] pOptDesc the option descriptor for this option.
  */
  */
@@ -2206,7 +2209,9 @@ optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1);
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 /**
 /**
  * Code to handle the enet-vlan-pri option.
  * Code to handle the enet-vlan-pri option.
- *
+ * When omitted, the priority of an existing VLAN header is preserved; a newly
+ * added tag on a previously untagged packet defaults to 0 (a one-time notice
+ * is printed).
  * @param[in] pOptions the tcpbridge options data structure
  * @param[in] pOptions the tcpbridge options data structure
  * @param[in,out] pOptDesc the option descriptor for this option.
  * @param[in,out] pOptDesc the option descriptor for this option.
  */
  */
@@ -2494,7 +2499,7 @@ doOptVersion(tOptions* pOptions, tOptDesc* pOptDesc)
     fprintf(stderr, " (debug)");
     fprintf(stderr, " (debug)");
 #endif
 #endif
     fprintf(stderr, "\n");
     fprintf(stderr, "\n");
-    fprintf(stderr, "Copyright 2013-2025 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
+    fprintf(stderr, "Copyright 2013-2026 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
     fprintf(stderr, "Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
 #ifdef HAVE_LIBDNET
 #ifdef HAVE_LIBDNET
@@ -2749,7 +2754,7 @@ static void bogus_function(void) {
    */
    */
   /* referenced via tcpbridgeOptions.pzCopyright */
   /* referenced via tcpbridgeOptions.pzCopyright */
   puts(_("tcpbridge (tcpbridge)\n\
   puts(_("tcpbridge (tcpbridge)\n\
-Copyright (C) 2000-2025 Aaron Turner and Fred Klassen, all rights reserved.\n\
+Copyright (C) 2000-2026 Aaron Turner and Fred Klassen, all rights reserved.\n\
 This is free software. It is licensed for use, modification and\n\
 This is free software. It is licensed for use, modification and\n\
 redistribution under the terms of the GNU General Public License,\n\
 redistribution under the terms of the GNU General Public License,\n\
 version 3 or later <http://gnu.org/licenses/gpl.html>\n"));
 version 3 or later <http://gnu.org/licenses/gpl.html>\n"));

+ 4 - 4
src/tcpbridge_opts.def

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as
@@ -23,12 +23,12 @@ autogen definitions options;
 
 
 
 
 copyright = {
 copyright = {
-    date        = "2000-2025";
+    date        = "2000-2026";
     owner       = "Aaron Turner and Fred Klassen";
     owner       = "Aaron Turner and Fred Klassen";
     eaddr       = "tcpreplay-users@lists.sourceforge.net";
     eaddr       = "tcpreplay-users@lists.sourceforge.net";
     type        = gpl;
     type        = gpl;
     author      = <<- EOText
     author      = <<- EOText
-Copyright 2013-2025 Fred Klassen - AppNeta
+Copyright 2013-2026 Fred Klassen - AppNeta
 
 
 Copyright 2000-2012 Aaron Turner
 Copyright 2000-2012 Aaron Turner
 
 
@@ -366,7 +366,7 @@ flag = {
     fprintf(stderr, " (debug)");
     fprintf(stderr, " (debug)");
 #endif
 #endif
     fprintf(stderr, "\n");
     fprintf(stderr, "\n");
-    fprintf(stderr, "Copyright 2013-2025 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
+    fprintf(stderr, "Copyright 2013-2026 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
     fprintf(stderr, "Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "Copyright 2000-2012 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
 #ifdef HAVE_LIBDNET
 #ifdef HAVE_LIBDNET

+ 1 - 1
src/tcpbridge_opts.h

@@ -19,7 +19,7 @@
  * The tcpbridge program is copyrighted and licensed
  * The tcpbridge program is copyrighted and licensed
  * under the following terms:
  * under the following terms:
  *
  *
- *  Copyright (C) 2000-2025 Aaron Turner and Fred Klassen, all rights reserved.
+ *  Copyright (C) 2000-2026 Aaron Turner and Fred Klassen, all rights reserved.
  *  This is free software. It is licensed for use, modification and
  *  This is free software. It is licensed for use, modification and
  *  redistribution under the terms of the GNU General Public License,
  *  redistribution under the terms of the GNU General Public License,
  *  version 3 or later <http://gnu.org/licenses/gpl.html>
  *  version 3 or later <http://gnu.org/licenses/gpl.html>

+ 1 - 1
src/tcpcapinfo.1

@@ -10,7 +10,7 @@
 .ds B-Font B
 .ds B-Font B
 .ds I-Font I
 .ds I-Font I
 .ds R-Font R
 .ds R-Font R
-.TH tcpcapinfo 1 "26 Aug 2025" "Tcpreplay Suite" "User Commands"
+.TH tcpcapinfo 1 "19 Jul 2026" "Tcpreplay Suite" "User Commands"
 .\"
 .\"
 .\" DO NOT EDIT THIS FILE (in-mem file)
 .\" DO NOT EDIT THIS FILE (in-mem file)
 .\"
 .\"

+ 1 - 1
src/tcpcapinfo.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2012 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2012 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpcapinfo_opts.c

@@ -349,7 +349,7 @@ doOptVersion(tOptions* pOptions, tOptDesc* pOptDesc)
     fprintf(stderr, " (debug)");
     fprintf(stderr, " (debug)");
 #endif
 #endif
     fprintf(stderr, "\n");
     fprintf(stderr, "\n");
-    fprintf(stderr, "Copyright 2013-2025 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
+    fprintf(stderr, "Copyright 2013-2026 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
     fprintf(stderr, "Copyright 2000-2010 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "Copyright 2000-2010 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
     exit(0);
     exit(0);

+ 2 - 2
src/tcpcapinfo_opts.def

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 
@@ -102,7 +102,7 @@ flag = {
     fprintf(stderr, " (debug)");
     fprintf(stderr, " (debug)");
 #endif
 #endif
     fprintf(stderr, "\n");
     fprintf(stderr, "\n");
-    fprintf(stderr, "Copyright 2013-2025 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
+    fprintf(stderr, "Copyright 2013-2026 by Fred Klassen <tcpreplay at appneta dot com> - AppNeta\n");
     fprintf(stderr, "Copyright 2000-2010 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "Copyright 2000-2010 by Aaron Turner <aturner at synfin dot net>\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
     fprintf(stderr, "The entire Tcpreplay Suite is licensed under the GPLv3\n");
     exit(0);
     exit(0);

+ 1 - 1
src/tcpedit/checksum.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/checksum.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/dlt.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/dlt.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 97 - 47
src/tcpedit/edit_packet.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as
@@ -309,6 +309,14 @@ ipv6_addr_csum_replace(ipv6_hdr_t *ip6_hdr, struct tcpr_in6_addr *old_ip, struct
     switch (protocol) {
     switch (protocol) {
     case IPPROTO_UDP:
     case IPPROTO_UDP:
     case IPPROTO_TCP:
     case IPPROTO_TCP:
+    case IPPROTO_ICMP6:
+        /*
+         * ICMPv6's checksum covers a pseudo-header (src/dst IP) same as
+         * TCP/UDP, per RFC 4443 2.3 - so it needs the same fixup when an
+         * outer address changes. This case was missing, so rewriting the
+         * IPv6 address on any ICMPv6 packet left a stale checksum unless
+         * --fixcsum was also passed (#818).
+         */
         l4 = get_layer4_v6(ip6_hdr, (u_char *)ip6_hdr + l3len);
         l4 = get_layer4_v6(ip6_hdr, (u_char *)ip6_hdr + l3len);
         break;
         break;
     default:
     default:
@@ -908,59 +916,101 @@ rewrite_ipv6l3(tcpedit_t *tcpedit, ipv6_hdr_t *ip6_hdr, tcpr_dir_t direction, in
     }
     }
 
 
     /* anything else to rewrite? */
     /* anything else to rewrite? */
-    if (tcpedit->cidrmap1 == NULL)
-        return (0);
+    if (tcpedit->cidrmap1 != NULL) {
+        /* don't play with the main pointers */
+        if (direction == TCPR_DIR_C2S) {
+            cidrmap1 = tcpedit->cidrmap1;
+            cidrmap2 = tcpedit->cidrmap2;
+        } else {
+            cidrmap1 = tcpedit->cidrmap2;
+            cidrmap2 = tcpedit->cidrmap1;
+        }
 
 
-    /* don't play with the main pointers */
-    if (direction == TCPR_DIR_C2S) {
-        cidrmap1 = tcpedit->cidrmap1;
-        cidrmap2 = tcpedit->cidrmap2;
-    } else {
-        cidrmap1 = tcpedit->cidrmap2;
-        cidrmap2 = tcpedit->cidrmap1;
-    }
+        /* loop through the cidrmap to rewrite */
+        do {
+            if ((!diddst) && ip6_in_cidr(cidrmap2->from, &ip6_hdr->ip_dst)) {
+                struct tcpr_in6_addr old_ip6;
+                memcpy(&old_ip6, &ip6_hdr->ip_dst, sizeof(old_ip6));
+                remap_ipv6(tcpedit, cidrmap2->to, &ip6_hdr->ip_dst);
+                ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_dst, l3len);
+                dbgx(2, "Remapped dst addr to: %s", get_addr2name6(&ip6_hdr->ip_dst, RESOLVE));
+                diddst = 1;
+            }
+            if ((!didsrc) && ip6_in_cidr(cidrmap1->from, &ip6_hdr->ip_src)) {
+                struct tcpr_in6_addr old_ip6;
+                memcpy(&old_ip6, &ip6_hdr->ip_src, sizeof(old_ip6));
+                remap_ipv6(tcpedit, cidrmap1->to, &ip6_hdr->ip_src);
+                ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_src, l3len);
+                dbgx(2, "Remapped src addr to: %s", get_addr2name6(&ip6_hdr->ip_src, RESOLVE));
+                didsrc = 1;
+            }
 
 
-    /* loop through the cidrmap to rewrite */
-    do {
-        if ((!diddst) && ip6_in_cidr(cidrmap2->from, &ip6_hdr->ip_dst)) {
-            struct tcpr_in6_addr old_ip6;
-            memcpy(&old_ip6, &ip6_hdr->ip_dst, sizeof(old_ip6));
-            remap_ipv6(tcpedit, cidrmap2->to, &ip6_hdr->ip_dst);
-            ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_dst, l3len);
-            dbgx(2, "Remapped dst addr to: %s", get_addr2name6(&ip6_hdr->ip_dst, RESOLVE));
-            diddst = 1;
-        }
-        if ((!didsrc) && ip6_in_cidr(cidrmap1->from, &ip6_hdr->ip_src)) {
-            struct tcpr_in6_addr old_ip6;
-            memcpy(&old_ip6, &ip6_hdr->ip_src, sizeof(old_ip6));
-            remap_ipv6(tcpedit, cidrmap1->to, &ip6_hdr->ip_src);
-            ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_src, l3len);
-            dbgx(2, "Remapped src addr to: %s", get_addr2name6(&ip6_hdr->ip_src, RESOLVE));
-            didsrc = 1;
-        }
+            /*
+             * loop while we haven't modified both src/dst AND
+             * at least one of the cidr maps have a next pointer
+             */
+            if ((!(diddst && didsrc)) && (!((cidrmap1->next == NULL) && (cidrmap2->next == NULL)))) {
+                /* increment our ptr's if possible */
+                if (cidrmap1->next != NULL)
+                    cidrmap1 = cidrmap1->next;
 
 
-        /*
-         * loop while we haven't modified both src/dst AND
-         * at least one of the cidr maps have a next pointer
-         */
-        if ((!(diddst && didsrc)) && (!((cidrmap1->next == NULL) && (cidrmap2->next == NULL)))) {
-            /* increment our ptr's if possible */
-            if (cidrmap1->next != NULL)
-                cidrmap1 = cidrmap1->next;
+                if (cidrmap2->next != NULL)
+                    cidrmap2 = cidrmap2->next;
 
 
-            if (cidrmap2->next != NULL)
-                cidrmap2 = cidrmap2->next;
+            } else {
+                loop = 0;
+            }
 
 
-        } else {
-            loop = 0;
-        }
+            /* Later on we should support various IP protocols which embed
+             * the IP address in the application layer.  Things like
+             * DNS and FTP.
+             */
 
 
-        /* Later on we should support various IP protocols which embed
-         * the IP address in the application layer.  Things like
-         * DNS and FTP.
-         */
+        } while (loop);
+    }
 
 
-    } while (loop);
+    /*
+     * RFC4443 ICMPv6 error messages (Destination Unreachable, Packet Too
+     * Big, Time Exceeded, Parameter Problem) embed as much of the
+     * "invoking" packet as fits, including its IPv6 header. Recurse into
+     * it so those addresses get rewritten too - otherwise sanitizing a
+     * capture with tcprewrite silently leaks the original addresses in
+     * every ICMPv6 error response (#818). Informational types (echo,
+     * neighbor discovery, MLD, ...) don't embed a packet and are skipped.
+     *
+     * The embedded header's own checksum fixup piggybacks on whatever this
+     * recursive call does for its own L4 (e.g. a TCP/UDP checksum inside
+     * the embedded packet, if fully present). The outer ICMPv6 checksum
+     * covering the whole message (header + embedded packet) is not
+     * incrementally patched here - use --fixcsum for a fully correct
+     * checksum, same as the reproduction steps in #818.
+     */
+    if (l3len > 0) {
+        const u_char *end_ptr = (const u_char *)ip6_hdr + l3len;
+        uint8_t l4proto = get_ipv6_l4proto(ip6_hdr, end_ptr);
+
+        if (l4proto == IPPROTO_ICMP6) {
+            icmpv6_hdr_t *icmp6 = (icmpv6_hdr_t *)get_layer4_v6(ip6_hdr, end_ptr);
+
+            if (icmp6 != NULL && (const u_char *)icmp6 + sizeof(*icmp6) <= end_ptr) {
+                switch (icmp6->icmp_type) {
+                case ICMP6_UNREACH:
+                case ICMP6_PKTTOOBIG:
+                case ICMP6_TIMXCEED:
+                case ICMP6_PARAMPROB: {
+                    ipv6_hdr_t *embedded = (ipv6_hdr_t *)((u_char *)icmp6 + sizeof(*icmp6));
+                    int embedded_len = (int)(end_ptr - (const u_char *)embedded);
+
+                    if (embedded_len >= (int)sizeof(ipv6_hdr_t) && ((ipv4_hdr_t *)embedded)->ip_v == 6)
+                        rewrite_ipv6l3(tcpedit, embedded, direction, embedded_len);
+                    break;
+                }
+                default:
+                    break;
+                }
+            }
+        }
+    }
 
 
     /* return how many changes we require checksum updates
     /* return how many changes we require checksum updates
      * (none required - checksum is already updated)
      * (none required - checksum is already updated)

+ 1 - 1
src/tcpedit/edit_packet.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/parse_args.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/parse_args.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 31 - 10
src/tcpedit/plugins/dlt_en10mb/en10mb.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as
@@ -364,6 +364,19 @@ dlt_en10mb_parse_opts(tcpeditdlt_t *ctx)
 
 
                 if (HAVE_OPT(ENET_VLAN_CFI))
                 if (HAVE_OPT(ENET_VLAN_CFI))
                     config->vlan_cfi = OPT_VALUE_ENET_VLAN_CFI;
                     config->vlan_cfi = OPT_VALUE_ENET_VLAN_CFI;
+
+                /*
+                 * Warn once if priority and/or CFI were not supplied: for
+                 * packets that are not already VLAN tagged there is no
+                 * existing value to preserve, so they default to 0.
+                 */
+                if (!HAVE_OPT(ENET_VLAN_PRI) || !HAVE_OPT(ENET_VLAN_CFI)) {
+                    notice("%s%s%s not specified; previously untagged "
+                           "packets will be tagged with priority 0 and/or CFI 0.",
+                           HAVE_OPT(ENET_VLAN_PRI) ? "" : "--enet-vlan-pri",
+                           (!HAVE_OPT(ENET_VLAN_PRI) && !HAVE_OPT(ENET_VLAN_CFI)) ? " and " : "",
+                           HAVE_OPT(ENET_VLAN_CFI) ? "" : "--enet-vlan-cfi");
+                }
             }
             }
 
 
             if (HAVE_OPT(ENET_VLAN_PROTO)) {
             if (HAVE_OPT(ENET_VLAN_PROTO)) {
@@ -496,6 +509,17 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir)
     if (ctx->decoded_extra_size < sizeof(*extra))
     if (ctx->decoded_extra_size < sizeof(*extra))
         return TCPEDIT_ERROR;
         return TCPEDIT_ERROR;
 
 
+    /*
+     * Validate VLAN options *before* mutating the packet buffer below.
+     * A previously untagged packet has no existing VLAN info to fall
+     * back on, so a tag must be supplied by the user in that case
+     * (priority and CFI default to 0).
+     */
+    if (config->vlan == TCPEDIT_VLAN_ADD && !extra->vlan && config->vlan_tag == 65535) {
+        tcpedit_seterr(ctx->tcpedit, "%s", "Non-VLAN tagged packet requires --enet-vlan-tag");
+        return TCPEDIT_ERROR;
+    }
+
     /* figure out the new layer2 length, first for the case: ethernet -> ethernet? */
     /* figure out the new layer2 length, first for the case: ethernet -> ethernet? */
     if (ctx->decoder->dlt == dlt_value) {
     if (ctx->decoder->dlt == dlt_value) {
         switch (config->vlan) {
         switch (config->vlan) {
@@ -683,28 +707,25 @@ dlt_en10mb_encode(tcpeditdlt_t *ctx, u_char *packet, int pktlen, tcpr_dir_t dir)
             vlan_hdr->vlan_tci = htons((uint16_t)config->vlan_tag & TCPR_802_1Q_VIDMASK);
             vlan_hdr->vlan_tci = htons((uint16_t)config->vlan_tag & TCPR_802_1Q_VIDMASK);
         } else if (extra->vlan) {
         } else if (extra->vlan) {
             vlan_hdr->vlan_tci = htons(extra->vlan_tag);
             vlan_hdr->vlan_tci = htons(extra->vlan_tag);
-        } else {
-            tcpedit_seterr(ctx->tcpedit, "%s", "Non-VLAN tagged packet requires --enet-vlan-tag");
-            return TCPEDIT_ERROR;
         }
         }
+        /* else: a previously-untagged packet without a tag is rejected early
+         * in dlt_en10mb_encode(), before the buffer is mutated */
 
 
         if (config->vlan_pri < 255) {
         if (config->vlan_pri < 255) {
             vlan_hdr->vlan_tci += htons((uint16_t)config->vlan_pri << 13);
             vlan_hdr->vlan_tci += htons((uint16_t)config->vlan_pri << 13);
         } else if (extra->vlan) {
         } else if (extra->vlan) {
             vlan_hdr->vlan_tci += htons(extra->vlan_pri);
             vlan_hdr->vlan_tci += htons(extra->vlan_pri);
-        } else {
-            tcpedit_seterr(ctx->tcpedit, "%s", "Non-VLAN tagged packet requires --enet-vlan-pri");
-            return TCPEDIT_ERROR;
         }
         }
+        /* else: previously-untagged packet, priority defaults to 0
+         * (warned about once in dlt_en10mb_parse_opts) */
 
 
         if (config->vlan_cfi < 255) {
         if (config->vlan_cfi < 255) {
             vlan_hdr->vlan_tci += htons((uint16_t)config->vlan_cfi << 12);
             vlan_hdr->vlan_tci += htons((uint16_t)config->vlan_cfi << 12);
         } else if (extra->vlan) {
         } else if (extra->vlan) {
             vlan_hdr->vlan_tci += htons(extra->vlan_cfi);
             vlan_hdr->vlan_tci += htons(extra->vlan_cfi);
-        } else {
-            tcpedit_seterr(ctx->tcpedit, "%s", "Non-VLAN tagged packet requires --enet-vlan-cfi");
-            return TCPEDIT_ERROR;
         }
         }
+        /* else: previously-untagged packet, CFI defaults to 0
+         * (warned about once in dlt_en10mb_parse_opts) */
 
 
     } else if (config->vlan == TCPEDIT_VLAN_DEL && newl2len > 0) {
     } else if (config->vlan == TCPEDIT_VLAN_DEL && newl2len > 0) {
         /* all we need for 802.3 is the proto */
         /* all we need for 802.3 is the proto */

+ 1 - 1
src/tcpedit/plugins/dlt_en10mb/en10mb.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/tcpedit/plugins/dlt_en10mb/en10mb_api.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_en10mb/en10mb_api.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 14 - 3
src/tcpedit/plugins/dlt_en10mb/en10mb_opts.def

@@ -114,7 +114,10 @@ flag = {
     arg-type    = number;
     arg-type    = number;
     flags-must  = enet-vlan;
     flags-must  = enet-vlan;
     arg-range   = "0->4095"; /* VID's are 12bit unsigned int's */
     arg-range   = "0->4095"; /* VID's are 12bit unsigned int's */
-    doc         = "";
+    doc         = <<- EOText
+Mandatory when @var{--enet-vlan=add} is used on packets that are not already
+VLAN tagged.
+EOText;
 };
 };
 
 
 flag = {
 flag = {
@@ -124,7 +127,11 @@ flag = {
     arg-type    = number;
     arg-type    = number;
     flags-must  = enet-vlan;
     flags-must  = enet-vlan;
     arg-range   = "0->1"; /* one bit */
     arg-range   = "0->1"; /* one bit */
-    doc         = "";
+    doc         = <<- EOText
+When omitted, the CFI bit of an existing VLAN header is preserved; a newly
+added tag on a previously untagged packet defaults to 0 (a one-time notice
+is printed).
+EOText;
 };
 };
 
 
 flag = {
 flag = {
@@ -134,7 +141,11 @@ flag = {
     flags-must  = enet-vlan;
     flags-must  = enet-vlan;
     arg-type    = number;
     arg-type    = number;
     arg-range   = "0->7"; /* one byte */
     arg-range   = "0->7"; /* one byte */
-    doc         = "";
+    doc         = <<- EOText
+When omitted, the priority of an existing VLAN header is preserved; a newly
+added tag on a previously untagged packet defaults to 0 (a one-time notice
+is printed).
+EOText;
 };
 };
 
 
 flag = {
 flag = {

+ 1 - 1
src/tcpedit/plugins/dlt_en10mb/en10mb_types.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_hdlc/hdlc.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_hdlc/hdlc.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_hdlc/hdlc_api.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_hdlc/hdlc_api.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_hdlc/hdlc_types.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_ieee80211/ieee80211.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_ieee80211/ieee80211.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_ieee80211/ieee80211_hdr.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_ieee80211/ieee80211_hdr.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_ieee80211/ieee80211_types.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  * Copyright (c) 2006-2007 Aaron Turner.
  * Copyright (c) 2006-2007 Aaron Turner.
- * Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ * Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  * All rights reserved.
  * All rights reserved.
  *
  *
  * Redistribution and use in source and binary forms, with or without
  * Redistribution and use in source and binary forms, with or without

+ 1 - 1
src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_api.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_jnpr_ether/jnpr_ether_types.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_linuxsll/linuxsll.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_linuxsll/linuxsll.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   The Tcpreplay Suite of tools is free software: you can redistribute it 
  *   and/or modify it under the terms of the GNU General Public License as 
  *   and/or modify it under the terms of the GNU General Public License as 

+ 1 - 1
src/tcpedit/plugins/dlt_loop/loop.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_loop/loop.h

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 1 - 1
src/tcpedit/plugins/dlt_null/null.c

@@ -2,7 +2,7 @@
 
 
 /*
 /*
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  *   Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
- *   Copyright (c) 2013-2025 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
+ *   Copyright (c) 2013-2026 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  *
  *
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   The Tcpreplay Suite of tools is free software: you can redistribute it
  *   and/or modify it under the terms of the GNU General Public License as
  *   and/or modify it under the terms of the GNU General Public License as

+ 0 - 0
src/tcpedit/plugins/dlt_null/null.h


Some files were not shown because too many files changed in this diff