lost and found ( for me ? )

python scapy : add DSCP value in an IP header

Here is how to add DSCP value in an IP header with scapy.

reference
http://packetlife.net/blog/2011/aug/1/qos-marking-scapy/

$ dpkg -l python-scapy | tail -1
ii  python-scapy                                2.2.0-1                                             all          Packet generator/sniffer and network scanner/discovery

  • DSCP 10

add 10 in DSCP value
$ cat scapy_dns01.py
from scapy.all import *

answer = sr1(IP(dst="8.8.8.8",tos=40)/UDP(sport=RandShort(),dport=53)/DNS(rd=1,qd=DNSQR(qname="www.google.com")),verbose=0)
print answer[DNS].summary()

When adding DSCP value with scapy, you need to specify DSCP value by using tos=.
TOS field is 8 bits, DSCP field, on the other hands,  is first 6 bits of TOS field, so you need to do some conversion when specifying DSCP value.

Here is how to convert DSCP 10 to tos=40.
convert int 10 to binary

>>> bin(10)
'0b1010'


add two trailing zeros

101000

then convert that to int

>>> int('101000',2)
40

tos=40

run the script
$ sudo python scapy_dns01.py
WARNING: No route found for IPv6 destination :: (no default route?)
DNS Ans "216.58.220.164"

Here is a snippet of capture data.
Internet Protocol Version 4, Src: 192.168.11.6 (192.168.11.6), Dst: 8.8.8.8 (8.8.8.8)
   Version: 4
   Header length: 20 bytes
   Differentiated Services Field: 0x28 (DSCP 0x0a: Assured Forwarding 11; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
       0010 10.. = Differentiated Services Codepoint: Assured Forwarding 11 (0x0a)
       .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
   Total Length: 60
   Identification: 0x0001 (1)
   Flags: 0x00
       0... .... = Reserved bit: Not set
       .0.. .... = Don't fragment: Not set
       ..0. .... = More fragments: Not set
   Fragment offset: 0
   Time to live: 64

  • DSCP 63

>>> bin(63)
'0b111111'

>>> int('11111100',2)
252

$ cat scapy_dns01_dscp63.py
from scapy.all import *

answer = sr1(IP(dst="8.8.8.8",tos=252)/UDP(sport=RandShort(),dport=53)/DNS(rd=1,qd=DNSQR(qname="www.google.com")),verbose=0)
print answer[DNS].summary()

capture data
Internet Protocol Version 4, Src: 192.168.11.6 (192.168.11.6), Dst: 8.8.8.8 (8.8.8.8)
   Version: 4
   Header length: 20 bytes
   Differentiated Services Field: 0xfc (DSCP 0x3f: Unknown DSCP; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
       1111 11.. = Differentiated Services Codepoint: Unknown (0x3f)
       .... ..00 = Explicit Congestion Notification: Not-ECT (Not ECN-Capable Transport) (0x00)
   Total Length: 60
   Identification: 0x0001 (1)
   Flags: 0x00