def create_response( request: bytes, services: Dict[str, FakeDnsService], ip_filter: Optional[str] = None, sleep_proxy: bool = False, ): msg = dns.DnsMessage().unpack(request) resp = dns.DnsMessage() resp.flags = 0x0840 resp.questions = msg.questions for question in resp.questions: service, full_name = _lookup_service(question, services) if service is None or (ip_filter and ip_filter not in service.addresses): continue # For typing purposes, because service is not None, then full_name is not None # either. full_name = cast(str, full_name) # Add answer if full_name: resp.answers.append(dns_utils.answer(question.qname, full_name)) # If acting as sleep proxy, just return a PTR if sleep_proxy and question.qname.startswith("_"): continue # Add service (SRV) resource if service.port: local_name = dns.qname_encode(service.name + ".local") rd = struct.pack(">3H", 0, 0, service.port) + local_name resp.resources.append( dns_utils.resource(full_name, dns.QueryType.SRV, rd)) # Add IP address(es) for address in service.addresses: ipaddr = IPv4Address(address).packed resp.resources.append( dns_utils.resource(service.name + ".local", dns.QueryType.A, ipaddr)) # Add properties if service.properties: rd = dns_utils.properties(service.properties) resp.resources.append( dns_utils.resource(full_name, dns.QueryType.TXT, rd)) # Add model if present if service.model: rd = dns_utils.properties({"model": service.model.encode("utf-8")}) resp.resources.append( dns_utils.resource(service.name + "._device-info._tcp.local", dns.QueryType.TXT, rd)) return resp
def test_authority(): msg = dns.DnsMessage() msg.authorities.append( dns_utils.resource("test.local", dns.QueryType.A, b"\x01\x02\x03\x04")) unpacked = dns.DnsMessage().unpack(msg.pack()) assert len(unpacked.authorities) == 1 record = unpacked.authorities[0] assert record.qname == "test.local" assert record.qtype == dns.QueryType.A assert record.qclass == dns_utils.DEFAULT_QCLASS assert record.ttl == dns_utils.DEFAULT_TTL assert record.rd == "1.2.3.4"