Ejemplo n.º 1
0
def create_response(
    request: bytes,
    services: Dict[str, FakeDnsService],
    ip_filter: Optional[str] = None,
    sleep_proxy: bool = False,
):
    msg = mdns.DnsMessage().unpack(request)

    resp = mdns.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 service.address != ip_filter):
            continue

        # 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 = mdns.qname_encode(service.name + ".local")
            rd = struct.pack(">3H", 0, 0, service.port) + local_name
            resp.resources.append(
                dns_utils.resource(full_name, mdns.QTYPE_SRV, rd))

        # Add IP address
        if service.address:
            ipaddr = IPv4Address(service.address).packed
            resp.resources.append(
                dns_utils.resource(service.name + ".local", mdns.QTYPE_A,
                                   ipaddr))

        # Add properties
        if service.properties:
            rd = dns_utils.properties(service.properties)
            resp.resources.append(
                dns_utils.resource(full_name, mdns.QTYPE_TXT, rd))

        # Add model if present
        if service.model:
            rd = dns_utils.properties(
                {b"model": service.model.encode("utf-8")})
            resp.resources.append(
                dns_utils.resource(service.name + "._device-info._tcp.local",
                                   mdns.QTYPE_TXT, rd))

    return resp
Ejemplo n.º 2
0
def test_authority():
    msg = mdns.DnsMessage()
    msg.authorities.append(
        dns_utils.resource("test.local", mdns.QTYPE_A, b"\x01\x02\x03\x04")
    )

    unpacked = mdns.DnsMessage().unpack(msg.pack())
    assert len(unpacked.authorities) == 1

    record = unpacked.authorities[0]
    assert record.qname == "test.local"
    assert record.qtype == mdns.QTYPE_A
    assert record.qclass == dns_utils.DEFAULT_QCLASS
    assert record.ttl == dns_utils.DEFAULT_TTL
    assert record.rd == "1.2.3.4"
Ejemplo n.º 3
0
def test_parse_with_port_and_address():
    service_params = ("_abc._tcp.local", "service", "10.0.0.1", 123, {})
    message = dns_utils.add_service(mdns.DnsMessage(), *service_params)

    parsed = mdns.parse_services(message)
    assert len(parsed) == 1
    dns_utils.assert_service(parsed[0], *service_params)
Ejemplo n.º 4
0
def test_parse_with_name_and_type():
    service_params = ("_abc._tcp.local", "service", None, 0, {})
    message = dns_utils.add_service(mdns.DnsMessage(), *service_params)

    parsed = mdns.parse_services(message)
    assert len(parsed) == 1
    dns_utils.assert_service(parsed[0], *service_params)
Ejemplo n.º 5
0
def test_parse_single_service():
    service_params = ("_abc._tcp.local", "service", "10.0.10.1", 123, {"foo": "bar"})
    message = dns_utils.add_service(mdns.DnsMessage(), *service_params)

    parsed = mdns.parse_services(message)
    assert len(parsed) == 1
    dns_utils.assert_service(parsed[0], *service_params)
Ejemplo n.º 6
0
    def datagram_received(self, data: bytes, addr):
        msg = mdns.DnsMessage().unpack(data)
        _LOGGER.debug("Received DNS request %s: %s", addr, msg)

        if self.skip_count > 0:
            _LOGGER.debug("Not sending DNS response (%d)", self.skip_count)
            self.skip_count -= 1
            return

        resp = create_response(data, self.services, self.ip_filter, self.sleep_proxy)
        self.transport.sendto(resp.pack(), addr)
        self.request_count += 1
Ejemplo n.º 7
0
def test_parse_double_service():
    service1_params = ("_abc._tcp.local", "service1", "10.0.10.1", 123, {"foo": "bar"})
    service2_params = (
        "_def._tcp.local",
        "service2",
        "10.0.10.2",
        456,
        {"fizz": "buzz"},
    )
    message = dns_utils.add_service(mdns.DnsMessage(), *service1_params)
    message = dns_utils.add_service(message, *service2_params)

    parsed = mdns.parse_services(message)
    assert len(parsed) == 2
    dns_utils.assert_service(parsed[0], *service1_params)
    dns_utils.assert_service(parsed[1], *service2_params)
Ejemplo n.º 8
0
def get_response_for_service(
    service: str, ) -> Tuple[mdns.DnsMessage, fake_udns.FakeDnsService]:
    req = mdns.create_request([service])
    resp = fake_udns.create_response(req, TEST_SERVICES)
    return mdns.DnsMessage().unpack(resp.pack()), TEST_SERVICES.get(service)
Ejemplo n.º 9
0
def test_parse_no_service_name():
    service_params = ("_abc._tcp.local", None, None, 0, {})
    message = dns_utils.add_service(mdns.DnsMessage(), *service_params)

    parsed = mdns.parse_services(message)
    assert len(parsed) == 0
Ejemplo n.º 10
0
def test_parse_no_service_type():
    service_params = (None, "service", None, 0, {})
    message = dns_utils.add_service(mdns.DnsMessage(), *service_params)

    parsed = mdns.parse_services(message)
    assert len(parsed) == 0
Ejemplo n.º 11
0
def test_parse_empty_service():
    assert mdns.parse_services(mdns.DnsMessage()) == []