Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion tests/test_dns.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing import Dict, cast # noqa # used in type hints

import zeroconf as r
from zeroconf import const, current_time_millis
from zeroconf import DNSIncoming, const, current_time_millis
from zeroconf import (
DNSHinfo,
DNSText,
Expand Down Expand Up @@ -747,3 +747,23 @@ def test_tc_bit_not_set_in_answer_packet():
third_packet = r.DNSIncoming(packets[2])
assert third_packet.flags & const._FLAGS_TC == 0
assert third_packet.valid is True


# 4003 15.973052 192.168.107.68 224.0.0.251 MDNS 76 Standard query 0xffc4 PTR _raop._tcp.local, "QM" question
def test_qm_packet_parser():
"""Test we can parse a query packet with the QM bit."""
qm_packet = (
b'\xff\xc4\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x05_raop\x04_tcp\x05local\x00\x00\x0c\x00\x01'
)
parsed = DNSIncoming(qm_packet)
assert parsed.questions[0].unicast is False
assert ",QM," in str(parsed.questions[0])


# 389951 1450.577370 192.168.107.111 224.0.0.251 MDNS 115 Standard query 0x0000 PTR _companion-link._tcp.local, "QU" question OPT
def test_qu_packet_parser():
"""Test we can parse a query packet with the QU bit."""
qu_packet = b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x01\x0f_companion-link\x04_tcp\x05local\x00\x00\x0c\x80\x01\x00\x00)\x05\xa0\x00\x00\x11\x94\x00\x12\x00\x04\x00\x0e\x00dz{\x8a6\x9czF\x84,\xcaQ\xff'
parsed = DNSIncoming(qu_packet)
assert parsed.questions[0].unicast is True
assert ",QU," in str(parsed.questions[0])
35 changes: 23 additions & 12 deletions zeroconf/_dns.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,14 @@ def get_type(t: int) -> str:

def entry_to_string(self, hdr: str, other: Optional[Union[bytes, str]]) -> str:
"""String representation with additional information"""
result = "%s[%s,%s" % (hdr, self.get_type(self.type), self.get_class_(self.class_))
if self.unique:
result += "-unique,"
else:
result += ","
result += self.name
if other is not None:
result += "]=%s" % cast(Any, other)
else:
result += "]"
return result
return "%s[%s,%s%s,%s]%s" % (
hdr,
self.get_type(self.type),
self.get_class_(self.class_),
"-unique" if self.unique else "",
self.name,
"=%s" % cast(Any, other) if other is not None else "",
)


class DNSQuestion(DNSEntry):
Expand All @@ -119,9 +116,23 @@ def answered_by(self, rec: 'DNSRecord') -> bool:
and self.name == rec.name
)

@property
def unicast(self) -> bool:
"""Returns true if the QU (not QM) is set.

unique shares the same mask as the one
used for unicast.
"""
return self.unique

def __repr__(self) -> str:
"""String representation"""
return DNSEntry.entry_to_string(self, "question", None)
return "%s[question,%s,%s,%s]" % (
self.get_type(self.type),
"QU" if self.unicast else "QM",
self.get_class_(self.class_),
self.name,
)


class DNSRecord(DNSEntry):
Expand Down