tcpdump mailing list archives

Re: Accurate ECN support in tcpdump/libpcap


From: Vadim Goncharov <vadimnuclight () gmail com>
Date: Sat, 15 Nov 2025 00:38:36 +0300

On Wed, 12 Nov 2025 18:52:20 +0000
Denis Ovsienko <denis () ovsienko info> wrote:


* "tcphf" -- same as "tcp[12:2] & 0x1FF"
* "tcphf & tcp-fin" -- same as "tcp[13] & tcp-fin"
* "tcphf & tcp-syn" -- same as "tcp[13] & tcp-syn"
* "tcphf & tcp-rst" -- same as "tcp[13] & tcp-rst"
* "tcphf & tcp-push" -- same as "tcp[13] & tcp-push"
* "tcphf & tcp-ack" -- same as "tcp[13] & tcp-ack"
* "tcphf & tcp-urg" -- same as "tcp[13] & tcp-urg"
* "tcphf & tcp-ece" -- same as "tcp[13] & tcp-ece"
* "tcphf & tcp-cwr" -- same as "tcp[13] & tcp-cwr"
* "tcphf & tcp-ae" -- same as "tcp[12] & tcp-ae"
* "tcphf & (tcp-syn | tcp-ack) != 0" -- true iff either SYN or ACK is
  set
* "tcphf & (tcp-fin | tcp-rst) == 0" -- true iff neither FIN nor RST is
  set
* "tcphf & (tcp-ece | tcp-cwr) == (tcp-ece | tcp-cwr)" -- true iff both
  ECE and CWR are set

Given that we do not know if they really will be flags, not the best variant.
 
[...]
A more generic potential solution could be introducing a new /type/
qualifier, making it valid for certain values of /proto/ qualifiers
including "tcp", but not for any explicit /dir/ qualifiers.  The
identifier for this regular primitive would be an integer, that is, a
bitmask:

* "tcp flags tcp-fin" -- true iff the flag is set
* "tcp flags tcp-syn" -- true iff the flag is set
* "tcp flags tcp-rst" -- true iff the flag is set
* "tcp flags tcp-push" -- true iff the flag is set
* "tcp flags tcp-ack" -- true iff the flag is set
* "tcp flags tcp-urg" -- true iff the flag is set
* "tcp flags tcp-ece" -- true iff the flag is set
* "tcp flags tcp-cwr" -- true iff the flag is set
* "tcp flags tcp-ae" -- true iff the flag is set
* "tcp flags tcp-syn or tcp-ack" -- true iff at least one of SYN and
  ACK is set
* "tcp flags tcp-syn | tcp-ack" -- ?
* "not tcp flags tcp-fin | tcp-rst" -- ?
* "tcp flags tcp-ece and tcp-cwr -- true iff both ECE and CWR are set
* "tcp flags tcp-ece & tcp-cwr -- formally true iff no flags set, but
  in practice most likely a user error

In this case, if the bitmask comprises more than one TCP header flag,
the meaning would depend on (and would not be immediately obvious)
whether "tcp flags NUM" tests for any bit set ("tcp[12:2] & 0x1ff & NUM
!= 0") or all bits set ("tcp[12:2] & 0x1ff & NUM == NUM").

This has advantage of not introducing new identifiers, but otherwise the last
variant is best:

Another potential syntax of the above could be using a string for the
identifier, which in this case would mean the flag names would be
scoped and would not need to keep the "tcp-" prefix:

* "tcp flag fin" -- true iff the flag is set
* "tcp flag syn" -- true iff the flag is set
* "tcp flag rst" -- true iff the flag is set
* "tcp flag push" -- true iff the flag is set
* "tcp flag ack" -- true iff the flag is set
* "tcp flag urg" -- true iff the flag is set
* "tcp flag ece" -- true iff the flag is set
* "tcp flag cwr" -- true iff the flag is set
* "tcp flag ae" -- true iff the flag is set
* "tcp flag syn or tcp flag ack" -- true iff at least one of SYN and
  ACK is set, equivalent to "tcp flag syn or ack"
* "not (tcp flag fin or rst)" -- true iff neither FIN nor

For user, it will be shortest to type and look much more natural than
current tcp[tcpflags] approach. If curious for other approaches, FreeBSD's
ipfw firewall has the following syntax:

     tcpflags spec
             TCP packets only.  Match if the TCP header contains the comma
             separated list of flags specified in spec.  The supported TCP
             flags are:

             fin, syn, rst, psh, ack and urg.  The absence of a particular
             flag may be denoted with a ‘!’.  A rule which contains a tcpflags
             specification can never match a fragmented packet which has a
             non-zero offset.  See the frag option for details on matching
             fragmented packets.

E.g. one can use “tcpflags syn,!ack” for session setup packets, non-listed flags
are not checked.

  RST is set, unfortunately, in the established grammar this would be
  equivalent to "not tcp flag fin and not tcp flag rst", but not to
  "not tcp flag fin or rst", which is a know and documented peculiarity

In which paragraph?

* "tcp flag ece and tcp flag cwr" -- true iff both ECE and CWR are set,
  equivalent to "tcp flag ece and cwr"

Using this approach, managing the forward compatibility would be as
simple as recognising (or not) specific strings as the flag names (i.e.
"tcp flag abc" would be invalid syntax and there would be no syntax to
specify a numeric value to try working around that, whether
successfully or not).

Which is a good thing - let's leave numeric values for direct byte access.

Speaking of "tcp flag ID" or "tcp flags NUM" with regard to other
existing protocol names and index operations, "ip" and "igrp"
potentially could also be a part of the same solution space, but I do
not immediately see any other protocols that could use it.

Sounds good.

-- 
WBR, @nuclight
_______________________________________________
tcpdump-workers mailing list -- tcpdump-workers () lists tcpdump org
To unsubscribe send an email to tcpdump-workers-leave () lists tcpdump org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Current thread: