git: f1cfcfb2e51a - main - traceroute6: implement firewall evasion mode
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 16 Aug 2026 08:32:59 UTC
The branch main has been updated by eugen:
URL: https://cgit.FreeBSD.org/src/commit/?id=f1cfcfb2e51ae5afa8941342ad10f650db8279c5
commit f1cfcfb2e51ae5afa8941342ad10f650db8279c5
Author: Eugene Grosbein <eugen@FreeBSD.org>
AuthorDate: 2026-08-16 08:29:20 +0000
Commit: Eugene Grosbein <eugen@FreeBSD.org>
CommitDate: 2026-08-16 08:31:57 +0000
traceroute6: implement firewall evasion mode
Merge implementation of "traceroute -e" to traceroute6 for TCP/UDP/SCTP.
MFC-after: 2 weeks
---
usr.sbin/traceroute6/traceroute6.8 | 8 ++++++--
usr.sbin/traceroute6/traceroute6.c | 28 ++++++++++++++++------------
2 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/usr.sbin/traceroute6/traceroute6.8 b/usr.sbin/traceroute6/traceroute6.8
index 406a96a04424..7c6890d4de6a 100644
--- a/usr.sbin/traceroute6/traceroute6.8
+++ b/usr.sbin/traceroute6/traceroute6.8
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd November 12, 2024
+.Dd August 16, 2026
.Dt TRACEROUTE6 8
.Os
.\"
@@ -38,7 +38,7 @@
.Sh SYNOPSIS
.Nm
.Bk -words
-.Op Fl adEIlnNrSTUv
+.Op Fl adeEIlnNrSTUv
.Ek
.Bk -words
.Op Fl A Ar as_server
@@ -92,6 +92,10 @@ Turn on AS# lookups for each hop encountered.
Turn on AS# lookups and use the given server instead of the default.
.It Fl d
Debug mode.
+.It Fl e
+Firewall evasion mode.
+Use fixed destination ports for UDP, TCP and SCTP probes.
+The destination port does NOT increment with each packet sent.
.It Fl E
Detect ECN bleaching.
Set the
diff --git a/usr.sbin/traceroute6/traceroute6.c b/usr.sbin/traceroute6/traceroute6.c
index eb6086706f9f..7b821c11db38 100644
--- a/usr.sbin/traceroute6/traceroute6.c
+++ b/usr.sbin/traceroute6/traceroute6.c
@@ -333,6 +333,7 @@ static u_long max_hops = 30;
static u_int16_t srcport;
static u_int16_t port = 32768 + 666; /* start udp dest port # for probe packets */
static u_int16_t ident;
+static int fixedPort = 0; /* Use fixed destination port for TCP/UDP/SCTP */
static int tclass = -1;
static int options; /* socket options */
static int verbose;
@@ -402,7 +403,7 @@ main(int argc, char *argv[])
seq = 0;
ident = htons(getpid() & 0xffff); /* same as ping6 */
- while ((ch = getopt(argc, argv, "aA:dEf:g:Ilm:nNp:q:rs:St:TUvw:")) != -1)
+ while ((ch = getopt(argc, argv, "aA:deEf:g:Ilm:nNp:q:rs:St:TUvw:")) != -1)
switch (ch) {
case 'a':
as_path = 1;
@@ -414,6 +415,9 @@ main(int argc, char *argv[])
case 'd':
options |= SO_DEBUG;
break;
+ case 'e':
+ fixedPort = 1;
+ break;
case 'E':
ecnflag = 1;
break;
@@ -1136,8 +1140,8 @@ send_probe(int seq, u_long hops)
break;
case IPPROTO_UDP:
outudp = (struct udphdr *) outpacket;
- outudp->uh_sport = htons(ident);
- outudp->uh_dport = htons(port + seq);
+ outudp->uh_sport = htons(ident + (fixedPort ? seq : 0));
+ outudp->uh_dport = htons(port + (fixedPort ? 0 : seq));
outudp->uh_ulen = htons(datalen);
outudp->uh_sum = 0;
outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
@@ -1149,7 +1153,7 @@ send_probe(int seq, u_long hops)
sctp = (struct sctphdr *)outpacket;
sctp->src_port = htons(ident);
- sctp->dest_port = htons(port + seq);
+ sctp->dest_port = htons(port + (fixedPort ? 0 : seq));
if (datalen >= (u_long)(sizeof(struct sctphdr) +
sizeof(struct sctp_init_chunk))) {
sctp->v_tag = 0;
@@ -1215,7 +1219,7 @@ send_probe(int seq, u_long hops)
tcp = (struct tcphdr *)outpacket;
tcp->th_sport = htons(ident);
- tcp->th_dport = htons(port + seq);
+ tcp->th_dport = htons(port + (fixedPort ? 0 : seq));
tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
tcp->th_ack = 0;
tcp->th_off = 5;
@@ -1423,14 +1427,14 @@ packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code,
break;
case IPPROTO_UDP:
udp = (struct udphdr *)up;
- if (udp->uh_sport == htons(ident) &&
- udp->uh_dport == htons(port + seq))
+ if (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
+ ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq))
return (1);
break;
case IPPROTO_SCTP:
sctp = (struct sctphdr *)up;
- if (sctp->src_port != htons(ident) ||
- sctp->dest_port != htons(port + seq)) {
+ if (ntohs(sctp->src_port) != ident ||
+ ntohs(sctp->dest_port) != port + (fixedPort ? 0 : seq)) {
break;
}
if (datalen >= (u_long)(sizeof(struct sctphdr) +
@@ -1457,8 +1461,8 @@ packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code,
break;
case IPPROTO_TCP:
tcp = (struct tcphdr *)up;
- if (tcp->th_sport == htons(ident) &&
- tcp->th_dport == htons(port + seq) &&
+ if (ntohs(tcp->th_sport) == ident &&
+ ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq) &&
tcp->th_seq ==
(tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
return (1);
@@ -1842,7 +1846,7 @@ void
usage(void)
{
fprintf(stderr,
-"Usage: traceroute6 [-adEIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
+"Usage: traceroute6 [-adeEIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
"\t[-m hoplimit] [-p port] [-q probes] [-s src] [-t tclass]\n"
"\t[-w waittime] target [datalen]\n");
exit(1);