diff --git a/scapy/layers/dns.py b/scapy/layers/dns.py
index 4e6bacbf5eb1d1bfcd73aa6b23d02bdd9e4f037b..5b2417e3219d7c714e13e593c167c84c71f4b8d3 100644
--- a/scapy/layers/dns.py
+++ b/scapy/layers/dns.py
@@ -59,7 +59,7 @@ class DNSRRCountField(ShortField):
     def _countRR(self, pkt):
         x = getattr(pkt,self.rr)
         i = 0
-        while isinstance(x, DNSRR) or isinstance(x, DNSQR):
+        while isinstance(x, DNSRR) or isinstance(x, DNSQR) or isdnssecRR(x):
             x = x.payload
             i += 1
         return i
@@ -121,9 +121,13 @@ class DNSRRField(StrField):
         type,cls,ttl,rdlen = struct.unpack("!HHIH", ret)
         p += 10
         rr = DNSRR("\x00"+ret+s[p:p+rdlen])
-        if rr.type in [2, 3, 4, 5]:
+        if type in [2, 3, 4, 5]:
             rr.rdata = DNSgetstr(s,p)[0]
-        del(rr.rdlen)
+            del(rr.rdlen)
+        elif type in dnsRRdispatcher.keys():
+            rr = dnsRRdispatcher[type]("\x00"+ret+s[p:p+rdlen])
+	else:
+          del(rr.rdlen)
         
         p += rdlen
         
@@ -206,14 +210,17 @@ class RDLenField(Field):
 
 class DNS(Packet):
     name = "DNS"
-    fields_desc = [ ShortField("id",0),
-                    BitField("qr",0, 1),
+    fields_desc = [ ShortField("id", 0),
+                    BitField("qr", 0, 1),
                     BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}),
                     BitField("aa", 0, 1),
                     BitField("tc", 0, 1),
                     BitField("rd", 0, 1),
-                    BitField("ra", 0 ,1),
-                    BitField("z", 0, 3),
+                    BitField("ra", 0, 1),
+                    BitField("z", 0, 1),
+                    # AD and CD bits are defined in RFC 2535
+                    BitField("ad", 0, 1), # Authentic Data
+                    BitField("cd", 0, 1), # Checking Disabled
                     BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}),
                     DNSRRCountField("qdcount", None, "qd"),
                     DNSRRCountField("ancount", None, "an"),
@@ -245,7 +252,9 @@ class DNS(Packet):
 dnstypes = { 0:"ANY", 255:"ALL",
              1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG",
              9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",
-             17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
+             17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME",
+             41:"OPT", 43:"DS", 46:"RRSIG", 47:"NSEC", 48:"DNSKEY",
+	     50: "NSEC3", 51: "NSEC3PARAM", 32769:"DLV" }
 
 dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"}
 dnsqtypes.update(dnstypes)
@@ -261,6 +270,320 @@ class DNSQR(Packet):
                     
                     
 
+# RFC 2671 - Extension Mechanisms for DNS (EDNS0)
+
+class EDNS0TLV(Packet):
+    name = "DNS EDNS0 TLV"
+    fields_desc = [ ShortEnumField("optcode", 0, { 0: "Reserved", 1: "LLQ", 2: "UL", 3: "NSID", 4: "Reserved", 5: "PING" }),
+                    FieldLenField("optlen", None, "optdata", fmt="H"),
+                    StrLenField("optdata", "", length_from=lambda pkt: pkt.optlen) ]
+
+    def extract_padding(self, p):
+	return "", p
+
+class DNSRROPT(Packet):
+    name = "DNS OPT Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 41, dnstypes),
+                    ShortField("rclass", 4096),
+                    ByteField("extrcode", 0),
+                    ByteField("version", 0),
+                    # version 0 means EDNS0
+                    BitEnumField("z", 32768, 16, { 32768: "D0" }),
+                    # D0 means DNSSEC OK from RFC 3225
+                    FieldLenField("rdlen", None, length_of="rdata", fmt="H"),
+                    PacketListField("rdata", [], EDNS0TLV, length_from=lambda pkt: pkt.rdlen) ]
+
+# RFC 4034 - Resource Records for the DNS Security Extensions
+
+# 09/2013 from http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
+dnssecalgotypes = { 0:"Reserved", 1:"RSA/MD5", 2:"Diffie-Hellman", 3:"DSA/SHA-1", 
+                    4:"Reserved", 5:"RSA/SHA-1", 6:"DSA-NSEC3-SHA1",
+                    7:"RSASHA1-NSEC3-SHA1", 8:"RSA/SHA-256", 9:"Reserved",
+                   10:"RSA/SHA-512", 11:"Reserved", 12:"GOST R 34.10-2001",
+                   13:"ECDSA Curve P-256 with SHA-256", 14: "ECDSA Curve P-384 with SHA-384",
+                  252:"Reserved for Indirect Keys", 253:"Private algorithms - domain name",
+                  254:"Private algorithms - OID", 255:"Reserved" }
+
+# 09/2013 from http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml
+dnssecdigesttypes = { 0:"Reserved", 1:"SHA-1", 2:"SHA-256", 3:"GOST R 34.11-94",  4:"SHA-384" }
+
+
+class TimeField(IntField):
+
+    def any2i(self, pkt, x):
+        if type(x) == str:
+	    import time, calendar
+	    t = time.strptime(x, "%Y%m%d%H%M%S")
+            return int(calendar.timegm(t))
+        return x
+
+    def i2repr(self, pkt, x):
+	import time
+	x = self.i2h(pkt, x)
+	t = time.strftime("%Y%m%d%H%M%S", time.gmtime(x))
+	return "%s (%d)" % (t ,x) 
+
+
+def bitmap2RRlist(bitmap):
+    """
+    Decode the 'Type Bit Maps' field of the NSEC Resource Record into an 
+    integer list.
+    """
+    # RFC 4034, 4.1.2. The Type Bit Maps Field
+
+    RRlist = []
+
+    while bitmap:
+
+	if len(bitmap) < 2:
+	    warning("bitmap too short (%i)" % len(bitmap))
+	    return
+   
+	window_block = ord(bitmap[0]) # window number
+	offset = 256*window_block # offset of the Ressource Record
+	bitmap_len = ord(bitmap[1]) # length of the bitmap in bytes
+
+	if bitmap_len <= 0 or bitmap_len > 32:
+	    warning("bitmap length is no valid (%i)" % bitmap_len)
+	    return
+
+	tmp_bitmap = bitmap[2:2+bitmap_len]
+
+	# Let's compare each bit of tmp_bitmap and compute the real RR value
+	for b in xrange(len(tmp_bitmap)):
+	    v = 128
+	    for i in xrange(8):
+		if ord(tmp_bitmap[b]) & v:
+		    # each of the RR is encoded as a bit
+		    RRlist += [ offset + b*8 + i ] 
+		v = v >> 1
+	
+	# Next block if any
+	bitmap = bitmap[2+bitmap_len:]
+
+    return RRlist
+
+
+def RRlist2bitmap(lst):
+    """
+    Encode a list of integers representing Resource Records to a bitmap field 
+    used in the NSEC Resource Record.
+    """
+    # RFC 4034, 4.1.2. The Type Bit Maps Field
+
+    import math
+
+    bitmap = ""
+    lst = list(set(lst))
+    lst.sort()
+    
+    lst = filter(lambda x: x <= 65535, lst)
+    lst = map(lambda x: abs(x), lst)
+
+    # number of window blocks
+    max_window_blocks = int(math.ceil(lst[-1] / 256.))
+    min_window_blocks = int(math.floor(lst[0] / 256.))
+    if min_window_blocks == max_window_blocks:
+	max_window_blocks += 1
+
+    for wb in xrange(min_window_blocks, max_window_blocks+1):
+        # First, filter out RR not encoded in the current window block
+        # i.e. keep everything between 256*wb <= 256*(wb+1)
+        rrlist = filter(lambda x: 256*wb <= x and x < 256*(wb+1), lst)
+        rrlist.sort()
+        if rrlist == []:
+            continue
+     
+        # Compute the number of bytes used to store the bitmap
+        if rrlist[-1] == 0: # only one element in the list
+	    bytes = 1
+        else:
+	    max = rrlist[-1] - 256*wb
+	    bytes = int(math.ceil(max / 8)) + 1  # use at least 1 byte
+        if bytes > 32: # Don't encode more than 256 bits / values
+	    bytes = 32
+
+        bitmap += struct.pack("B", wb)
+        bitmap += struct.pack("B", bytes)
+
+        # Generate the bitmap
+        for tmp in xrange(bytes):
+            v = 0
+            # Remove out of range Ressource Records
+            tmp_rrlist = filter(lambda x: 256*wb+8*tmp <= x and x < 256*wb+8*tmp+8, rrlist)
+            if not tmp_rrlist == []:
+                # 1. rescale to fit into 8 bits
+                tmp_rrlist = map(lambda x: (x-256*wb)-(tmp*8), tmp_rrlist)
+                # 2. x gives the bit position ; compute the corresponding value
+                tmp_rrlist = map(lambda x: 2**(7-x) , tmp_rrlist)
+                # 3. sum everything
+                v = reduce(lambda x,y: x+y, tmp_rrlist)
+            bitmap += struct.pack("B", v)
+   
+    return bitmap
+
+
+class RRlistField(StrField):
+    def h2i(self, pkt, x):
+	if type(x) == list:
+	    return RRlist2bitmap(x)
+	return x
+
+    def i2repr(self, pkt, x):
+	x = self.i2h(pkt, x)
+	rrlist = bitmap2RRlist(x)
+	return [ dnstypes.get(rr, rr) for rr in rrlist ]
+
+
+class _DNSRRdummy(Packet):
+    name = "Dummy class that implements post_build() for Ressource Records"
+    def post_build(self, pkt, pay):
+        if not self.rdlen == None:
+            return pkt
+
+        lrrname = len(self.fields_desc[0].i2m("", self.getfieldval("rrname")))
+        l = len(pkt) - lrrname - 10
+        pkt = pkt[:lrrname+8] + struct.pack("!H", l) + pkt[lrrname+8+2:]
+        
+        return pkt
+
+class DNSRRSOA(_DNSRRdummy):
+    name = "DNS SOA Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 6, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    ShortField("rdlen", None),
+                    DNSStrField("mname", ""),
+                    DNSStrField("rname", ""),
+                    IntField("serial", 0),
+                    IntField("refresh", 0),
+                    IntField("retry", 0),
+                    IntField("expire", 0),
+                    IntField("minimum", 0)
+                  ]
+
+class DNSRRRSIG(_DNSRRdummy):
+    name = "DNS RRSIG Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 46, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    ShortField("rdlen", None),
+                    ShortEnumField("typecovered", 1, dnstypes),
+                    ByteEnumField("algorithm", 5, dnssecalgotypes),
+                    ByteField("labels", 0),
+                    IntField("originalttl", 0),
+                    TimeField("expiration", 0),
+                    TimeField("inception", 0),
+                    ShortField("keytag", 0),
+                    DNSStrField("signersname", ""),
+                    StrField("signature", "")
+                  ]
+
+
+class DNSRRNSEC(_DNSRRdummy):
+    name = "DNS NSEC Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 47, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    ShortField("rdlen", None),
+                    DNSStrField("nextname", ""),
+                    RRlistField("typebitmaps", "")
+                  ]
+
+
+class DNSRRDNSKEY(_DNSRRdummy):
+    name = "DNS DNSKEY Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 48, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    ShortField("rdlen", None),
+                    FlagsField("flags", 256, 16, "S???????Z???????"),
+                    # S: Secure Entry Point
+                    # Z: Zone Key
+                    ByteField("protocol", 3),
+                    ByteEnumField("algorithm", 5, dnssecalgotypes),
+                    StrField("publickey", "")
+                  ]
+
+
+class DNSRRDS(_DNSRRdummy):
+    name = "DNS DS Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 43, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    ShortField("rdlen", None),
+                    ShortField("keytag", 0),
+                    ByteEnumField("algorithm", 5, dnssecalgotypes),
+                    ByteEnumField("digesttype", 5, dnssecdigesttypes),
+                    StrField("digest", "")
+                  ]
+
+
+# RFC 5074 - DNSSEC Lookaside Validation (DLV)
+class DNSRRDLV(DNSRRDS):
+    name = "DNS DLV Resource Record"
+    def __init__(self, *args, **kargs):
+       DNSRRDS.__init__(self, *args, **kargs)
+       if not kargs.get('type', 0):
+           self.type = 32769
+
+# RFC 5155 - DNS Security (DNSSEC) Hashed Authenticated Denial of Existence
+class DNSRRNSEC3(_DNSRRdummy):
+    name = "DNS NSEC3 Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 50, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    ShortField("rdlen", None),
+		    ByteField("hashalg", 0), 
+                    BitEnumField("flags", 0, 8, {1:"Opt-Out"}),
+		    ShortField("iterations", 0), 
+		    FieldLenField("saltlength", 0, fmt="!B", length_of="salt"),
+		    StrLenField("salt", "", length_from=lambda x: x.saltlength),
+		    FieldLenField("hashlength", 0, fmt="!B", length_of="nexthashedownername"),
+		    StrLenField("nexthashedownername", "", length_from=lambda x: x.hashlength),
+                    RRlistField("typebitmaps", "")
+		  ]
+
+
+class DNSRRNSEC3PARAM(_DNSRRdummy):
+    name = "DNS NSEC3PARAM Resource Record"
+    fields_desc = [ DNSStrField("rrname",""),
+                    ShortEnumField("type", 51, dnstypes),
+                    ShortEnumField("rclass", 1, dnsclasses),
+                    IntField("ttl", 0),
+                    ShortField("rdlen", None),
+		    ByteField("hashalg", 0), 
+		    ByteField("flags", 0), 
+		    ShortField("iterations", 0), 
+		    FieldLenField("saltlength", 0, fmt="!B", length_of="salt"),
+		    StrLenField("salt", "", length_from=lambda pkt: pkt.saltlength)
+		  ]
+
+
+dnssecclasses = [ DNSRROPT, DNSRRRSIG, DNSRRDLV, DNSRRDNSKEY, DNSRRNSEC, DNSRRDS, DNSRRNSEC3, DNSRRNSEC3PARAM ]
+
+def isdnssecRR(obj):
+    list = [ isinstance (obj, cls) for cls in dnssecclasses ]
+    return reduce(lambda x,y: x or y, list)
+
+dnsRRdispatcher = {     #6: DNSRRSOA,
+                       41: DNSRROPT,        # RFC 1671
+                       43: DNSRRDS,         # RFC 4034
+                       46: DNSRRRSIG,       # RFC 4034
+                       47: DNSRRNSEC,       # RFC 4034
+                       48: DNSRRDNSKEY,     # RFC 4034
+                       50: DNSRRNSEC3,      # RFC 5155
+                       51: DNSRRNSEC3PARAM, # RFC 5155
+                    32769: DNSRRDLV         # RFC 4431
+                   }
+
 class DNSRR(Packet):
     name = "DNS Resource Record"
     show_indent=0
diff --git a/test/dnssecRR.uts b/test/dnssecRR.uts
new file mode 100644
index 0000000000000000000000000000000000000000..90dcf84403a56d0436eafb9d939f7b0786f4a7da
--- /dev/null
+++ b/test/dnssecRR.uts
@@ -0,0 +1,113 @@
+# DNSSEC Ressource Record unit tests
+#
+# Type the following command to launch start the tests:
+# $ sudo bash test/run_tests -t test/dnssecRR.uts -F
+
++ bitmap2RRlist()
+
+= example from RFC 4034
+RRlist2bitmap([1, 15, 46, 47, 1234]) == '\x00\x06@\x01\x00\x00\x00\x03\x04\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20'
+
+= [0]
+RRlist2bitmap([0]) == '\x00\x01\x80'
+
+= [0,1,2,3,4,5,6,7]
+RRlist2bitmap([0,1,2,3,4,5,6,7]) == '\x00\x01\xff'
+
+= [256,512,4096,36864]
+RRlist2bitmap([256,512,4096,36864]) == '\x01\x01\x80\x02\x01\x80\x10\x01\x80\x90\x01\x80'
+
+= [65535]
+RRlist2bitmap([65535]) == '\xff\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
+
++ From RRlist2bitmap() to bitmap2RRlist()
+
+= example from RFC 4034
+b = '\x00\x06@\x01\x00\x00\x00\x03\x04\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20'
+RRlist2bitmap(bitmap2RRlist(b)) == b
+
+= [0]
+b= '\x00\x01\x80'
+RRlist2bitmap(bitmap2RRlist(b)) == b
+
+= [0,1,2,3,4,5,6,7]
+b = '\x00\x01\xff'
+RRlist2bitmap(bitmap2RRlist(b)) == b
+
+= [256,512,4096,36864]
+b = '\x01\x01\x80\x02\x01\x80\x10\x01\x80\x90\x01\x80'
+RRlist2bitmap(bitmap2RRlist(b)) == b
+
+= [65535]
+b = '\xff\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
+RRlist2bitmap(bitmap2RRlist(b)) == b
+
++ Test NSEC RR
+
+= DNSRRNSEC(), basic instanciation
+t = DNSRRNSEC()
+str(t) == '\x00\x00/\x00\x01\x00\x00\x00\x00\x00\x01\x00'
+
+= DNSRRRNSEC(), check parameters
+t = DNSRRNSEC(rrname="scapy.secdev.org.", rclass=42, ttl=28, nextname="www.secdev.org.", typebitmaps=RRlist2bitmap([1,2,3,4,1234]))
+str(t) == '\x05scapy\x06secdev\x03org\x00\x00/\x00*\x00\x00\x00\x1c\x000\x03www\x06secdev\x03org\x00\x00\x01x\x04\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 '
+
++ Test NSEC3 RR
+
+= DNSRRNSEC3(), basic instanciation
+t = DNSRRNSEC3()
+str(t) == '\x00\x002\x00\x01\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00'
+
+= DNSRRRNSEC3(), check parameters
+t = DNSRRNSEC3(rrname="scapy.secdev.org.", rclass=42, ttl=28, hashalg=7, iterations=80, saltlength=28, salt="\x28\x07", hashlength=31, nexthashedownername="XXX.scapy.secdev.org", typebitmaps=RRlist2bitmap([1,2,3,4,1234]))
+str(t) == '\x05scapy\x06secdev\x03org\x00\x002\x00*\x00\x00\x00\x1c\x00<\x07\x00\x00P\x1c(\x07\x1fXXX.scapy.secdev.org\x00\x01x\x04\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 '
+
++ Test NSEC3PARAM RR
+
+= DNSRRNSEC3PARAM(), basic instanciation
+t = DNSRRNSEC3PARAM()
+str(t) == '\x00\x003\x00\x01\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00'
+
+= DNSRRRNSEC3PARAM(), check parameters
+t = DNSRRNSEC3(rrname="scapy.secdev.org.", rclass=42, ttl=28, hashalg=7, flags=80, iterations=80, saltlength=28, salt="\x28\x07")
+str(t) == '\x05scapy\x06secdev\x03org\x00\x002\x00*\x00\x00\x00\x1c\x00\x08\x07P\x00P\x1c(\x07\x00'
+
++ Test RRSIG RR
+
+= DNSRRRSIG(), basic instanciation
+t = DNSRRRSIG()
+str(t) == '\x00\x00.\x00\x01\x00\x00\x00\x00\x00\x13\x00\x01\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+
+= DNSRRRSIG(), check parameters
+t = DNSRRRSIG(rrname="test.example.com.", type=46, rclass=12, ttl=64, originalttl=2807, keytag=42, signersname="test.rsig", signature="test RSIG")
+str(t) == '\x04test\x07example\x03com\x00\x00.\x00\x0c\x00\x00\x00@\x00&\x00\x01\x05\x00\x00\x00\n\xf7\x00\x00\x00\x00\x00\x00\x00\x00\x00*\x04test\x04rsig\x00test RSIG'
+
+= DNSRRRSIG(), dissection
+rrsig = '\x03isc\x03org\x00\x00.\x00\x01\x00\x00\x96O\x00\x9b\x00\x02\x05\x02\x00\x00\xa8\xc0K-3\xd9K\x05\xa6\xd9\xed6\x03isc\x03org\x00\xac\xb2_I\x9e\xdcU\xca/3\x1c\xdf{\xba\xd5\x80\xb0 \xa4~\x98\x95\xab~\x84\xb2\x1f9\x17#\x7f\xfeP\xb9\xfb\x8d\x13\x19\xd7\x7f\x9e/\x1c\xd7rv<\xc6\xd3\xf1\xae8\rh\xba\x1e\xaa\xe6\xf1\x1e\x1d\xdaS\xd4\\\xfd\xa3`P\xa1\xe0\xa2\x860\xd4?\xb4}j\x81O\x03\xdc&v\x13\xd4(k\xa07\x8f-\x08e\x06\xff\xb8h\x8f\x16j\xe4\xd92\xd2\x99\xc2\xb4'
+t = DNSRRRSIG(rrsig)
+t.rrname == 'isc.org.' and t.labels == 2 and t.keytag == 60726 and t.signature[-4:] == '\xd2\x99\xc2\xb4'
+
++ Test DNSKEY RR
+
+= DNSRRDNSKEY(), basic instanciation
+t = DNSRRDNSKEY()
+str(t) == '\x00\x000\x00\x01\x00\x00\x00\x00\x00\x04\x01\x00\x03\x05' and t.sprintf("%flags%") == 'Z'
+
+= DNSRRDNSKEY(), check parameters
+t = DNSRRDNSKEY(rrname="www.secdev.org.", type=42, rclass=12, ttl=1234, rdlen=567, flags=2807, protocol=195, algorithm=66, publickey="strong public key")
+str(t) == '\x03www\x06secdev\x03org\x00\x00*\x00\x0c\x00\x00\x04\xd2\x027\n\xf7\xc3Bstrong public key'
+
+= DNSRRDNSKEY(), dissection
+t = DNSRRDNSKEY('\x03dlv\x03isc\x03org\x00\x000\x00\x01\x00\x00\x1bq\x01\t\x01\x01\x03\x05\x04@\x00\x00\x03\xc72\xef\xf9\xa2|\xeb\x10N\xf3\xd5\xe8&\x86\x0f\xd6<\xed>\x8e\xea\x19\xadm\xde\xb9a\'\xe0\xccC\x08M~\x94\xbc\xb6n\xb8P\xbf\x9a\xcd\xdfdJ\xb4\xcc\xd7\xe8\xc8\xfb\xd27sx\xd0\xf8^I\xd6\xe7\xc7g$\xd3\xc2\xc6\x7f>\x8c\x01\xa5\xd8VK+\xcb~\xd6\xea\xb8[\xe9\xe7\x03z\x8e\xdb\xe0\xcb\xfaN\x81\x0f\x89\x9e\xc0\xc2\xdb!\x81p{C\xc6\xeft\xde\xf5\xf6v\x90\x96\xf9\xe9\xd8`1\xd7\xb9\xcae\xf8\x04\x8f\xe8C\xe7\x00+\x9d?\xc6\xf2o\xd3Ak\x7f\xc90\xea\xe7\x0cO\x01e\x80\xf7\xbe\x8eq\xb1<\xf1&\x1c\x0b^\xfdDdc\xad\x99~B\xe8\x04\x00\x03,t="\xb4\xb6\xb6\xbc\x80{\xb9\x9b\x05\x95\\;\x02\x1eS\xf4p\xfedq\xfe\xfc00$\xe05\xba\x0c@\xabTv\xf3W\x0e\xb6\t\r!\xd9\xc2\xcd\xf1\x89\x15\xc5\xd5\x17\xfej_T\x99\x97\xd2j\xff\xf85b\xca\x8c|\xe9O\x9fd\xfdT\xadL3taK\x96\xac\x13a')
+t.rrname == "dlv.isc.org." and t.rdlen == 265 and t.sprintf("%flags%") == 'SZ' and t.publickey == '\x04@\x00\x00\x03\xc72\xef\xf9\xa2|\xeb\x10N\xf3\xd5\xe8&\x86\x0f\xd6<\xed>\x8e\xea\x19\xadm\xde\xb9a\'\xe0\xccC\x08M~\x94\xbc\xb6n\xb8P\xbf\x9a\xcd\xdfdJ\xb4\xcc\xd7\xe8\xc8\xfb\xd27sx\xd0\xf8^I\xd6\xe7\xc7g$\xd3\xc2\xc6\x7f>\x8c\x01\xa5\xd8VK+\xcb~\xd6\xea\xb8[\xe9\xe7\x03z\x8e\xdb\xe0\xcb\xfaN\x81\x0f\x89\x9e\xc0\xc2\xdb!\x81p{C\xc6\xeft\xde\xf5\xf6v\x90\x96\xf9\xe9\xd8`1\xd7\xb9\xcae\xf8\x04\x8f\xe8C\xe7\x00+\x9d?\xc6\xf2o\xd3Ak\x7f\xc90\xea\xe7\x0cO\x01e\x80\xf7\xbe\x8eq\xb1<\xf1&\x1c\x0b^\xfdDdc\xad\x99~B\xe8\x04\x00\x03,t="\xb4\xb6\xb6\xbc\x80{\xb9\x9b\x05\x95\\;\x02\x1eS\xf4p\xfedq\xfe\xfc00$\xe05\xba\x0c@\xabTv\xf3W\x0e\xb6\t\r!\xd9\xc2\xcd\xf1\x89\x15\xc5\xd5\x17\xfej_T\x99\x97\xd2j\xff\xf85b\xca\x8c|\xe9O\x9fd\xfdT\xadL3taK\x96\xac\x13a'
+
++ Test DS and DLV RR
+
+= DNSRRDS() and DNSRRDLV(), basic instancaition
+ds = DNSRRDS()
+dlv = DNSRRDLV(type=43)
+str(ds) == str(dlv)
+
+= DNSRRDS(), check parameters
+t = DNSRRDS('\x03isc\x03org\x00\x00+\x00\x01\x00\x01Q(\x00\x182\\\x05\x01\x98!\x13\xd0\x8bLj\x1d\x9fj\xee\x1e"7\xae\xf6\x9f?\x97Y')
+t.rrname == 'isc.org.' and t.keytag == 12892 and t.algorithm == 5 and t.digesttype == 1 and t.digest == '\x98!\x13\xd0\x8bLj\x1d\x9fj\xee\x1e"7\xae\xf6\x9f?\x97Y'
diff --git a/test/edns0.uts b/test/edns0.uts
new file mode 100644
index 0000000000000000000000000000000000000000..717db5fcc92a4138c2cc04acdc0a94dea1841102
--- /dev/null
+++ b/test/edns0.uts
@@ -0,0 +1,60 @@
+# DNS OPT Ressource Record unit tests
+#
+# Type the following command to launch start the tests:
+# $ sudo bash test/run_tests -t test/edns0.uts -F
+
++ Test EDNS0 rdata
+
+= EDNS0TLV(), basic instanciation
+tlv = EDNS0TLV()
+str(tlv) == '\x00\x00\x00\x00'
+
+= EDNS0TLV(), check parameters
+tlv = EDNS0TLV(optcode=42, optlen=12, optdata="edns0tlv")
+str(tlv) == '\x00*\x00\x0cedns0tlv'
+
+= EDNS0TLV(), check computed optlen
+tlv = EDNS0TLV(optdata="edns0tlv")
+str(tlv) == '\x00\x00\x00\x08edns0tlv'
+
+= EDNS0TLV(), dissection
+tlv = EDNS0TLV('\x00*\x00\x08edns0tlv')
+tlv.optcode == 42 and tlv.optlen == 8 and tlv.optdata == "edns0tlv"
+
++ Test OPT RR
+
+= DNSRROPT(), basic instanciation
+opt = DNSRROPT()
+str(opt) == '\x00\x00)\x10\x00\x00\x00\x80\x00\x00\x00'
+
+= DNSRROPT(), check parameters
+opt = DNSRROPT(rrname="rropt", type=42, rclass=123, extrcode=1, version=2, z=3, rdlen=4, rdata=[EDNS0TLV()])
+str(opt) == '\x05rropt\x00\x00*\x00{\x01\x02\x00\x03\x00\x04\x00\x00\x00\x00'
+
+= DNSRROPT() & EDN0TLV(), check parameters
+opt = DNSRROPT(rrname="rropt", type=42, rclass=123, extrcode=1, version=2, z=3, rdlen=4, rdata=[EDNS0TLV(optcode=42, optlen=12, optdata="edns0tlv")])
+str(opt) == '\x05rropt\x00\x00*\x00{\x01\x02\x00\x03\x00\x04\x00*\x00\x0cedns0tlv'
+
+= DNSRROP(), dissection
+opt = DNSRROPT('\x05rropt\x00\x00*\x00{\x01\x02\x00\x03\x00\x0c\x00*\x00\x0cedns0tlv')
+opt.rrname == "rropt." and opt.rdlen == 12 and opt.rdata[0].optcode == 42 and opt.rdata[0].optdata == "edns0tlv"
+
++ Test EDNS-PING
+
+= EDNS-PING - basic instanciation
+tlv = EDNS0TLV(optcode=5, optdata="\x00\x11\x22\x33")
+str(tlv) == '\x00\x05\x00\x04\x00\x11"3'
+
+= EDNS-PING - Live test
+r = sr1(IP(dst="85.17.219.217")/UDP()/DNS(qd=[DNSQR(qtype="A", qname="www.edns-ping.org.")], ar=[DNSRROPT(z=0, rdata=[EDNS0TLV(optcode="PING", optdata="\x00\x11\x22\x33")])]))
+len(r.ar) and r.ar.rdata[0].optcode == 4  # XXX: should be 5
+
++ Test DNS Name Server Identifier (NSID) Option
+
+= NSID- basic instanciation
+tlv = EDNS0TLV(optcode=2, optdata="")
+str(tlv) == '\x00\x02\x00\x00'
+
+= NSID - Live test
+r = sr1(IP(dst="85.17.219.217")/UDP()/DNS(qd=[DNSQR(qtype="A", qname="www.edns-ping.org.")], ar=[DNSRROPT(z=0, rdata=[EDNS0TLV(optcode="NSID")])]))
+r.ar.rdata[0].optcode == 3 and r.ar.rdata[0].optdata == "dns01"