The Moose and Squirrel Files

January 20, 2009

DSCP to Type of Service Mappings

Filed under: Code, Network — Tags: , , , — networknerd @ 11:45 am

When working with quality of service configurations you’ll inevitably come across the need to perform packet markings with DSCP.  With routers this is generally fairly simple.  Performing the same function on a host is not always that simple.  All the socket API’s were designed around type of service (ToS),as defined in RFC791, rather than DSCP as defined in RFC2474.

If you’re in a hurry, the conversion is simply ToS = DSCP * 4. If you have the time the rfc’s are full of interesting information. The DSCP field with the DS field contains six bits allowing for 64 possible codepoint values. RFC2474 defines 3 pools of DSCP values, one for standardised use and the other two for local/experimental use. The standardised pool has the least significant bit set to 0, which means only the even numbers from 0 to 62 are used. A cheat sheet with the standardised DSCP values and equivalent IP precedence and ToS values can be found here.

We can test the ToS/DSCP mapping using the ping program and specifying a ToS byte value. Using the windows ping program we specify the ToS byte as a numeric argument to the -v command line switch. In this example we specify the the ToS byte as 136 which corresponds to a DSCP value of 34  or AF41.

ping -n 1 -v 136 http://www.google.com

Performing a similar test for tcp connection requires a little bit of coding effort. Listing 1 shows some c# code to do a simple get request to http://www.google.com.au,  using the SetSocketOption function to set the ToS byte to 136.  The wireshark output for both tests is shown below.  The  lua script shown in listing 2 was used to extract the diffserv field and dscp values while running the capture with Tshark. It is worth noting that even though the socketoption is set prior to the connection, no dscp values are set on the two packets from the client during the TCP three way handshake (frame 5 and 7 below).

tshark  -X lua_script:getdscp.lua -i 2 host http://www.google.com.au
Frame #1    Diffserv Field: 136    DSCP: 34
192.168.0.7 -> 74.125.19.103 ICMP Echo (ping) request

Frame #2    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  ICMP Echo (ping) reply

Frame #3    Diffserv Field: 136    DSCP: 34
192.168.0.7 -> 74.125.19.103 ICMP Echo (ping) request

Frame #4    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  ICMP Echo (ping) reply

Frame #5    Diffserv Field: 0    DSCP: 0
192.168.0.7 -> 74.125.19.103 TCP linx > http [SYN] Seq=0 Win=16384 Len=0 MSS=1260

Frame #6    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP http > linx [SYN, ACK] Seq=0 Ack=1 Win=5720 Len=0 MSS=1430

Frame #7    Diffserv Field: 0    DSCP: 0
192.168.0.7 -> 74.125.19.103 TCP linx > http [ACK] Seq=1 Ack=1 Win=17640 Len=0

Frame #8    Diffserv Field: 136    DSCP: 34
192.168.0.7 -> 74.125.19.103 HTTP GET / HTTP/1.0

Frame #9    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP http > linx [ACK] Seq=1 Ack=41 Win=5720 Len=0

Frame #10    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP [TCP segment of a reassembled PDU]

Frame #11    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP [TCP segment of a reassembled PDU]

Frame #12    Diffserv Field: 136    DSCP: 34
192.168.0.7 -> 74.125.19.103 TCP linx > http [ACK] Seq=41 Ack=2521 Win=17640 Len=0

Frame #13    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP [TCP segment of a reassembled PDU]

Frame #14    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP [TCP segment of a reassembled PDU]

Frame #15    Diffserv Field: 136    DSCP: 34
192.168.0.7 -> 74.125.19.103 TCP linx > http [ACK] Seq=41 Ack=5041 Win=17640 Len=0

Frame #16    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP [TCP segment of a reassembled PDU]

Frame #17    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  HTTP HTTP/1.0 200 OK  (text/html)

Frame #18    Diffserv Field: 136    DSCP: 34
192.168.0.7 -> 74.125.19.103 TCP linx > http [ACK] Seq=41 Ack=6611 Win=17640 Len=0

Frame #19    Diffserv Field: 136    DSCP: 34
192.168.0.7 -> 74.125.19.103 TCP linx > http [FIN, ACK] Seq=41 Ack=6611 Win=17640 Len=0

Frame #20    Diffserv Field: 0    DSCP: 0
74.125.19.103 -> 192.168.0.7  TCP http > linx [ACK] Seq=6611 Ack=42 Win=5720 Len=0
Listing  1

using System;
using System.Text;
using System.Net.Sockets;

namespace tcptos
{
	class Program
	{
		public static void Main(string[] args)
		{
			Console.WriteLine("Testing DSCP packet marking.Wireshark should already be running!\n");

			TcpClient cli = new TcpClient();
			cli.Client.SetSocketOption(SocketOptionLevel.IP,
			                           SocketOptionName.TypeOfService, 136);
			cli.Connect("www.google.com.au",80);
			byte[] buf = Encoding.ASCII.GetBytes("GET / HTTP/1.0\nHost: www.google.com.au\n\n");
			byte[] readbuf = new byte[4096];
			int bytesRead;
			StringBuilder response = new StringBuilder();
			NetworkStream mystream = cli.GetStream();
			mystream.Write(buf,0,buf.Length);
			do{
				bytesRead = mystream.Read(readbuf, 0, readbuf.Length);
				response.AppendFormat("{0}", Encoding.ASCII.GetString(readbuf, 0, bytesRead));
			}
			while(bytesRead > 0);
			Console.Write(response.ToString());
			Console.Write("\nPress any key to continue . . . ");
			Console.ReadKey(true);
			cli.Close();
		}
	}
}

Listing 2

local dsfield = Field.new("ip.dsfield")
local dscp = Field.new("ip.dsfield.dscp")
local fnum = Field.new("frame.number")
do
    packets = 0;
    local function init_listener()
        local tap = Listener.new("frame","ip.version == 4")

        function tap.reset()
        end
        function tap.packet(pinfo,tvb,ip)
            local fnumber = tostring(fnum())
            local diffserv = tostring(dsfield())
            local codepoint = tostring(dscp())
            local stroutput = "\nFrame #" .. fnumber .. "\tDiffserv Field: " ..
				diffserv .. "\tDSCP: " ..codepoint
            print(stroutput)
        end
        function tap.draw()

        end
    end
    init_listener()
end
Advertisements

1 Comment »

  1. […] themselves wishing for the ability the add some packet detail to the summary information. In the previous post I was looking at DSCP  and TOS information and wanted to add that to the summary rather than […]

    Pingback by Combine Wireshark Summary and Detail Information with XML Joins « The Moose and Squirrel Files — February 28, 2009 @ 8:45 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: