scapy
scapy copied to clipboard
RFE: mDNS unicast-response and cache-flush bits
Brief description
Currently the unicast-response and cache-flush bits aren't supported.
(It's mostly cosmetic because it's possible to get/set those bits manually. It's just something I noticed when I started playing with https://github.com/secdev/scapy/pull/4385)
Scapy version
f17e8da65d9299d6dbc84b427aaf7761aff31355
Python version
3.12.3
Operating system
6.8.9-300.fc40.x86_64
Additional environment information
No response
How to reproduce
with_unicast_response_bit = DNS(b'\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x01Q\x05_qotd\x04_tcp\x05local\x00\x00\xff\x80\x01\x06host-5\x05local\x00\x00\xff\x80\x01\x01Q\x05_qotd\x04_tcp\x05local\x00\x00!\x00\x01\x00\x00\x00x\x00\x14\x00\x00\x00\x00\x00{\x06host-5\x05local\x00\x06host-5\x05local\x00\x00\x01\x00\x01\x00\x00\x00x\x00\x04\xc0\xa88\x03\x06host-5\x05local\x00\x00\x1c\x00\x01\x00\x00\x00x\x00\x10\xfe\x80\x00\x00\x00\x00\x00\x00\x1c\x12+\xc1\xf3]\x97\x94')
with_cache_flush_bit = DNS(b'\x00\x00\x84\x00\x00\x00\x00\x06\x00\x00\x00\x02\x01Q\x05_qotd\x04_tcp\x05local\x00\x00\x10\x80\x01\x00\x00\x11\x94\x00\x01\x00\t_services\x07_dns-sd\x04_udp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x12\x05_qotd\x04_tcp\x05local\x00\x05_qotd\x04_tcp\x05local\x00\x00\x0c\x00\x01\x00\x00\x11\x94\x00\x14\x01Q\x05_qotd\x04_tcp\x05local\x00\x01Q\x05_qotd\x04_tcp\x05local\x00\x00!\x80\x01\x00\x00\x00x\x00\x14\x00\x00\x00\x00\x00{\x06host-5\x05local\x00\x06host-5\x05local\x00\x00\x01\x80\x01\x00\x00\x00x\x00\x04\xc0\xa88\x03\x06host-5\x05local\x00\x00\x1c\x80\x01\x00\x00\x00x\x00\x10\xfe\x80\x00\x00\x00\x00\x00\x00\x1c\x12+\xc1\xf3]\x97\x94\x01Q\x05_qotd\x04_tcp\x05local\x00\x00/\x80\x01\x00\x00\x11\x94\x00\x1b\x01Q\x05_qotd\x04_tcp\x05local\x00\x00\x05\x00\x00\x80\x00@\x06host-5\x05local\x00\x00/\x80\x01\x00\x00\x00x\x00\x14\x06host-5\x05local\x00\x00\x04@\x00\x00\x08')
Actual result
>>> with_unicast_response_bit.qd[0].show()
###[ DNS Question Record ]###
qname = b'Q._qotd._tcp.local.'
qtype = ALL
qclass = 32769
>>> with_cache_flush_bit.an[0].show()
###[ DNS Resource Record ]###
rrname = b'Q._qotd._tcp.local.'
type = TXT
rclass = 32769
ttl = 4500
rdlen = None
rdata = [b'']
Expected result
tshark
shows
Q._qotd._tcp.local: type ANY, class IN, "QU" question
Name: Q._qotd._tcp.local
[Name Length: 18]
[Label Count: 4]
Type: ANY (255) (A request for all records the server/cache has available)
.000 0000 0000 0001 = Class: IN (0x0001)
1... .... .... .... = "QU" question: True
and
Q._qotd._tcp.local: type TXT, class IN, cache flush
Name: Q._qotd._tcp.local
Type: TXT (16) (Text strings)
.000 0000 0000 0001 = Class: IN (0x0001)
1... .... .... .... = Cache flush: True
Time to live: 4500 (1 hour, 15 minutes)
Data length: 1
TXT Length: 0
TXT:
respectively.
Related resources
https://datatracker.ietf.org/doc/html/rfc6762#section-19
Multicast DNS... ...
- defines a unicast-response bit in the rrclass of query questions
- defines a cache-flush bit in the rrclass of response records
https://datatracker.ietf.org/doc/html/rfc6762#section-5.4
Multicast DNS defines the top bit in the class field of a DNS question as the unicast-response bit. When this bit is set in a question, it indicates that the querier is willing to accept unicast replies in response to this specific query, as well as the usual multicast responses. These questions requesting unicast responses are referred to as "QU" questions, to distinguish them from the more usual questions requesting multicast responses ("QM" questions).
https://datatracker.ietf.org/doc/html/rfc6762#section-10.2
the host MUST then send a series of unsolicited announcements to update cache entries in its neighbor hosts. In these unsolicited announcements, if the record is one that has been verified unique, the host sets the most significant bit of the rrclass field of the resource record. This bit, the cache-flush bit, tells neighboring hosts that this is not a shared record type.
That's a good point. It's pretty similar to LLMNR.
I'll add it to #4385 when I get the time. Edit: I ended up merging it but I'll make it into a future PR.
You can checkout https://github.com/secdev/scapy/pull/4390
I just added the bits everywhere. It might be an annoyance for classes > 32k for classic DNS.. but I'm unsure those are frequent so it'll do for now.