Macro 32 Ramblings

Mind Archive

DSCP & TOS

From: http://www.tucny.com/Home/dscp-tos

DSCP & TOS

Note: I’m perfectly happy for this table and associated information to be used anywhere by anyone, that’s why it’s been published here, I couldn’t find an easy reference, so I created one and published it for everyone, but, if you do republish the information, please attribute the source and don’t try to pass it off as original work. Thanks.
 
You’re trying to get QoS working smoothly on your network and you have a DSCP tag on your packets, but, you can only see ToS when capturing packets? How do you work out which ToS value equates to which DSCP value? Or… You are tagging using DSCP/PHB classes but only seeing DSCP hex or decimal tags on your packets? What does it all mean? 
 
The following table shows common decimal, hex and binary values for TOS, broken down into the meaning of the parts of that byte including DSCP values when interpretting that byte as DSCP.
 
TOS (Dec)TOS (Hex)TOS (Bin)TOS Precedence (Bin)TOS Precedence (Dec)TOS Precedence NameTOS Delay flagTOS Throughput flagTOS Reliability flagDSCP (Bin)DSCP (Hex)DSCP (Dec)DSCP/PHB Class
00x00000000000000Routine0000000000x000none
40x04000001000000Routine0010000010x011none
80x08000010000000Routine0100000100x022none
120x0C000011000000Routine0110000110x033none
160x10000100000000Routine1000001000x044none
320x20001000000011Priority0000010000x088cs1
400x28001010000011Priority0100010100x0A10af11
480x30001100000011Priority1000011000x0C12af12
560x38001110000011Priority1100011100x0E14af13
640x40010000000102Immediate0000100000x1016cs2
720x48010010000102Immediate0100100100x1218af21
800x50010100000102Immediate1000101000x1420af22
880x58010110000102Immediate1100101100x1622af23
960x60011000000113Flash0000110000x1824cs3
1040x68011010000113Flash0100110100x1A26af31
1120x70011100000113Flash1000111000x1C28af32
1200x78011110000113Flash1100111100x1E30af33
1280x80100000001004FlashOverride0001000000x2032cs4
1360x88100010001004FlashOverride0101000100x2234af41
1440x90100100001004FlashOverride1001001000x2436af42
1520x98100110001004FlashOverride1101001100x2638af43
1600xA0101000001015Critical0001010000x2840cs5
1760xB0101100001015Critical1001011000x2C44voice-admit
1840xB8101110001015Critical1101011100x2E46ef
1920xC0110000001106InterNetworkControl0001100000x3048cs6
2240xE0111000001117NetworkControl0001110000x3856cs7

So, there you have it, one byte in a packet header, two ways to look at it…
If dealing with TOS (Type of Service), the first 3 bits indicate the precedence, the 4th bit indicates the whether or not low delay is preferred, the 5th bit indicates whether or not high throughput is preferred, the 6th bit indicates whether or not high reliability is preferred and the 7th and 8th bits are reserved… More info can be found in RFC 791, written in 1981, which defines IP.
If dealing with DSCP (Differentiated Services (Diffserv) Codepoint) only the first 6 bits are used and the last 2 are ignored, these can be used for ECN (Explicit Congestion Notification) RFC 3168 … More info can be found in RFC 2474, written in 1998, which defines the Differentiated Services Field (DS Field) which is what the TOS byte is referred to when talking about differentiated services and specifically DSCP. Also, RFC 2597 and RFC 3246 which define some of the PHB (Per-hop Behaviour) classes may be useful reading…
Update 2013-04-21: Added voice-admit as defined in RFC 5865 and listed at the IANA DSCP Registry. Added various TOS flag only options as used in certain software, e.g. openssh and old versions of asterisk.

Examples

tcpdump

I want to capture IPv4 packets using tcpdump that have had the DSCP class ‘af21’ set, but, tcpdump doesn’t have a filter for DSCP and doesn’t decode values to DSCP classes, what can I do?
$ tcpdump -v -n -i ppp0 'ip and ip[1] & 0xfc == 72'
What this does run tcpdump with verbose output (-v), no name lookups (-n) on the interface ppp0 (-i ppp0), the filter, specified in quotes, says to only include packets that are ip (ip) and (and) where the second byte in the ip header (ip[1]) has a decimal value of 72 which we took from the table above as being the TOS decimal value equivalent to the DSCP class ‘af21’ (== 72) ignoring the last 2 bits in that byte as they may contain ECN flags (& 0xfc).
The result:
17:50:20.207827 IP (tos 0x48, ttl 108, id 12190, offset 0, flags [none], proto UDP (17), length 116)
    124.123.123.123.22238 > 180.123.123.123.51420: UDP, length 88

tcpdump shows packets that match our filter, it prefers to use a hex TOS value in it’s display, so, showing ‘tos 0x48’.
If we instead want to capture IPv6 traffic with the same class set, we’d do:
$ tcpdump -v -n -i he-ipv6 'ip6 and (ip6[0:2] & 0xfc0) >> 4  == 72'
Here, it’s a little more complex, with IPv6 the traffic class byte straddles the first and second bytes of the header, so, we look at the first two bytes of the header (ip6[0:2]), ignore the first 4 bits and the last 6 bits (& 0xfc0) then shift the value 4 bits to the right (>> 4) to remove the 4 right hand ignored bits that are outside the traffic class byte from the value and leave us with the value we want.
In both these examples, you can use TOS hex values instead of TOS decimal values, e.g. == 0x48. Alternatively, if you want to use DSCP hex or DSCP decimal values, you can shift the result, for the first example, this would give, as exact equivalents of those above:
$ tcpdump -v -n -i ppp0 'ip and (ip[1] & 0xfc) >> 2 == 0x12'
and for the second example:
$ tcpdump -v -n -i he-ipv6 'ip6 and (ip6[0:2] & 0xfc0) >> 6  == 0x12'
In both cases, using the DSCP hex value of 0x12 which as you can see from the table above is equivalent to the TOS decimal value 72.
Note the quotes around the filter string above, while you don’t need quotes when specifying simple filters with tcpdump, without them in this case the shell would likely interpret ‘&’ and ‘>>’ executing a partial command as a background task and trying to execute the rest with output redirected, something that you likely don’t want to do…

ping

Ping can be used to generate some outbound packets to test your QoS configuration or tcpdump filters. Ping has a ‘-Q’ option to specify the value you want to set on your packets, for IPv4, this takes either a TOS hex or TOS decimal value, for IPv6, it only takes a TOS hex value. 
To generate packets that our tcpdump filters above would capture, for IPv4 these two are equivalent:
$ ping -Q 72 8.8.8.8
$ ping -Q 0x48 8.8.8.8

For IPv6, these two are equivalent:
$ ping6 -Q 48 2404:6800:4003:801::1014
$ ping6 -Q 0x48 2404:6800:4003:801::1014
As mentioned, ping6 only takes a hex value, while 48 in this case may appear to be decimal as we didn’t explicitly specify it was hex with ‘0x’, it is interpreted as hex.