TCP flags and IPv4 ToS format

78 views
Skip to first unread message

Dmitry Kozlyuk

unread,
Apr 22, 2023, 10:27:09 AM4/22/23
to sf...@googlegroups.com
Hello,

The fields in question are specified as "unsigned int" [1]:

struct sampled_ipv4 {
unsigned int length; /* The length of the IP packet excluding
lower layer encapsulations */
unsigned int protocol; /* IP Protocol type
(for example, TCP = 6, UDP = 17) */
ip_v4 src_ip; /* Source IP Address */
ip_v4 dst_ip; /* Destination IP Address */
unsigned int src_port; /* TCP/UDP source port number or equivalent */
unsigned int dst_port; /* TCP/UDP destination port number or equivalent */
unsigned int tcp_flags; /* TCP flags */
unsigned int tos; /* IP type of service */
}

All other "unsigned int" fields in this structure are big-endian.
However, in practice they are treated as little-endian [2, 3].
One may call it "bit string of length 32".
Is this what specification really meant to describe?
If so, should we add this to errata?

[1]: https://sflow.org/SFLOW-STRUCTS5.txt
[2]: https://github.com/wireshark/wireshark/blob/master/epan/dissectors/packet-sflow.c#L1070
[3]: https://github.com/sflow/sflowtool/blob/7299efd21c8a0b09ae48616bd53e9e38c99a5ed2/src/sflowtool.c#L3293

neil....@inmon.com

unread,
Apr 22, 2023, 1:32:49 PM4/22/23
to sFlow
In the XDR encoding that sFlow uses,  unsigned int is always encoded on the wire in network byte order (big endian).  So if there were a tcp_flags field indicating ACK+SYN+FIN then I would expect to see an integer with the value 16 + 2 + 1 = 19 = 0x13.  And on the wire I would expect to see the hex byes 00-00-00-13.   In [3] this looks like it would be read correctly.   I'm not sure what will happen in [2].

This structure is very rarely used.  It was only defined in the standard for an agent that, for some reason,  is unable to export the original packet header.  Do you have an example where it appears but is populated incorrectly?  Or does the problem lie with decoders [2] and/or [3]?

Dmitry Kozlyuk

unread,
Apr 22, 2023, 4:13:03 PM4/22/23
to neil....@inmon.com, sf...@googlegroups.com
2023-04-22 10:32 (UTC-0700), neil....@inmon.com:
> In the XDR encoding that sFlow uses, unsigned int is always encoded on the
> wire in network byte order (big endian). So if there were a tcp_flags
> field indicating ACK+SYN+FIN then I would expect to see an integer with the
> value 16 + 2 + 1 = 19 = 0x13.

So would I, thanks for confirming.

> And on the wire I would expect to see the hex byes 00-00-00-13.
> In [3] this looks like it would be read correctly.
> I'm not sure what will happen in [2].

Yes, sorry, looking at sflowtool ([3]) code more closely,
I now see that it works according to the spec.

> This structure is very rarely used. It was only defined in the standard
> for an agent that, for some reason, is unable to export the original
> packet header.

This is surprising to hear.
Don't collectors benefit from not having to parse L3/L4 headers?

> Do you have an example where it appears but is populated incorrectly?
> Or does the problem lie with decoders [2] and/or [3]?

We are trying to implement an sFlow exporter.
It exports TCP flags 0x10 = ACK as 00 00 00 10
and ToS 0x70 = DSCP 28 as 00 00 00 70.
Wireshark ([2]) shows this as no TCP flags set (0) and no ToS (0),
because it expects the values to be in the first octet of each field
as they are on the wire ("tcp_flags 00 00 00" and "tos 00 00 00").
I'm attaching the capture (IP addresses redacted) and the dissection.
So Wireshark is wrong that their dissector is buggy?
sflow.pcap
sflow_dissection.txt

Peter Phaal

unread,
Apr 22, 2023, 5:03:20 PM4/22/23
to sFlow
If you are trying to implement an sFlow exporter, you might want to take a look at Host sFlow as a starting point:
It's open source, easily extended, and widely used in open source network operating systems.

The sFlow Version 5 Spec (https://sflow.org/sflow_version_5.txt) states on page 34:

/* Flow Data Types

   A flow_sample must contain packet header information. The
   prefered format for reporting packet header information is
   the sampled_header. However, if the packet header is not
   available to the sampling process then one or more of
   sampled_ethernet, sampled_ipv4, sampled_ipv6 may be used. */

All sFlow agents I am aware of export the sampled_header structure and this is going to be the most widely supported by sFlow collectors (as you have seen, Wireshark does a poor job with the sampled_ipv4 structure - probably because it has never been used).

Exporting packet headers future proofs the agent since the agent does not need to understand the packets it is reporting on. Every sFlow agent deployed over the last 20 years can be used to report on IP / IPv6 / MPLS / VxLAN / GRE etc. and any future protocol defined to run over Ethernet.  Packet headers ensure maximum interoperability between agents and allows flexiblity in the collectors, for example, allowing a collector to expose the IPv6 flowlabel (which isn't specified in the sFlow sampled_ipv6 header structure) across a multi-vendor network in an science network, https://blog.sflow.com/2022/11/scientific-network-tags-scitags.html

On Saturday, April 22, 2023 at 1:13:03 PM UTC-7 dmitry....@gmail.com wrote:
2023-04-22 10:32 (UTC-0700), neil....@inmon.com:
Reply all
Reply to author
Forward
0 new messages