2

I am trying to understand how tcpdump works and trying to read TCP header control flags SYN,ACK etc.

After researching online I came to know that the control flags are available at offset 13 and I need to use tcp[13] however I am not able to understand how this value 13 is been calculated.

Can anyone help?

1

TCP[13] is an array of bits (flags). When they're set to a 1 they're enabled, when they're a 0 they're disabled.

These tcpdump commands show how you can take the collection of TCP[13] bits and do bit-wise ands to test if the bits are enabled:

Show all URG packets:
# tcpdump 'tcp[13] & 32 != 0'

Show all ACK packets:
# tcpdump 'tcp[13] & 16 != 0'

Show all PSH packets:
# tcpdump 'tcp[13] & 8 != 0'

Show all RST packets:
# tcpdump 'tcp[13] & 4 != 0'

Show all SYN packets:
# tcpdump 'tcp[13] & 2 != 0'

Show all FIN packets:
# tcpdump 'tcp[13] & 1 != 0'

Show all SYN-ACK packets:
# tcpdump 'tcp[13] = 18

The referenced URL (below) had this bullet which explains it as well:

Keep in mind the reasons these filters work. The filters above find these various packets because tcp[13] looks at offset 13 in the TCP header, the number represents the location within the byte, and the !=0 means that the flag in question is set to 1, i.e. it’s on.

TCP Header

If you take a look at the RFC 793 3.1 as well as this article on tcpdump advanced filters it becomes more obvious.

TCP header
----------

    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |          Source Port          |       Destination Port        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                        Sequence Number                        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                    Acknowledgment Number                      |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  Data |       |C|E|U|A|P|R|S|F|                               |
    | Offset|  Res. |W|C|R|C|S|S|Y|I|            Window             | 
    |       |       |R|E|G|K|H|T|N|N|                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           Checksum            |         Urgent Pointer        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                    Options                    |    Padding    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                             data                              |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

- Matching any TCP traffic with a source port > 1024
# tcpdump -i eth1 'tcp[0:2] > 1024'

- Matching TCP traffic with particular flag combinations

The flags are defined in the 14th byte of the TCP header.

    +-+-+-+-+-+-+-+-+
    |C|E|U|A|P|R|S|F|
    |W|C|R|C|S|S|Y|I|
    |R|E|G|K|H|T|N|N|
    +-+-+-+-+-+-+-+-+

NOTE: These are the flags we're interested.

Calculating flag's position

You count the bytes (8 bits) from the top, numbering them at 0:

  • So "Source Port" & "Destination Port" would make up bytes 0, 1, 2, & 3.
  • The next row, "Sequence Number", would be 4-7.
  • "Acknowledge Number" would be bytes 8-11.
  • "Data Offset" & "Res." would be byte 12.
  • That takes you to byte 13, the bits in this byte are the flags.

Bit order

I'll also mention that the number stored in byte 13 is ordered such that:

  • bit 1 = FIN
  • bit 2 = SYN
  • bit 4 = RST
  • bit 8 = PSH
  • bit 16 = ACK
  • bit 32 = URG

References

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.