Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse lookups and PTR packages #13

Open
yan-foto opened this issue Jul 30, 2015 · 6 comments
Open

Reverse lookups and PTR packages #13

yan-foto opened this issue Jul 30, 2015 · 6 comments

Comments

@yan-foto
Copy link

Lets say I know the ip of brunhilde.local and want to know its host name (i.e. brunhilde.local!). So I build up my query like this:

mdns.query({questions:[{name:'26.178.168.192.in-addr.arpa.',type:'PTR'}]});

What I can see when I monitor the network using Wireshark is that the mDNS query is malformed and type and class are missing:

26.178.168.192.in-addr.arpa: type Unused, class Unknown (3072), "QM" question

A valid query (e.g. generated using dig -p 5353 @224.0.0.251 -x 192.168.178.26) would be as the following:

26.178.168.192.in-addr.arpa: type PTR, class IN, "QM" question

unfortunately I didn't have enough time to get deep into the code to see if I'm doing something wrong (or undesired) or is it a valid bug. Any help is appreciated.

@thenewwazoo
Copy link

thenewwazoo commented Dec 21, 2020

Hi! I hit this today, and did a bit more digging, but have also hit a wall. The mdns.query method passes the first argument unchanged into the dns-packet library, which expects something like this (note that questions is a member of the object). The code looks like:

        let resolver = mdns({
            ttl: 1,
        });
        resolver.query({
            flags: 1 << 8 | 1 << 5,
            id: getRandomInt(1, 65534),
            questions: [
                {
                    name: reversed,
                    type: 'PTR',
                    class: 'IN'
                }
            ]
        });

Unfortunately, that still doesn't work. I've included relevant captures below. The first (from dig) gets a response, but the second doesn't appear to (that is, sudo tcpdump -w mdns.pcap -n -l -i en0 -v udp and port 5353 and host 192.168.1.140 doesn't capture anything coming back).

From dig:

No.     Time           Source                Destination           Protocol Length Info
      2 0.080721       192.168.1.140         224.0.0.251           MDNS     97     Standard query 0x144e PTR 151.1.168.192.in-addr.arpa, "QM" question OPT

Frame 2: 97 bytes on wire (776 bits), 97 bytes captured (776 bits)
Ethernet II, Src: Apple_ae:41:66 (38:f9:d3:ae:41:66), Dst: IPv4mcast_fb (01:00:5e:00:00:fb)
Internet Protocol Version 4, Src: 192.168.1.140, Dst: 224.0.0.251
User Datagram Protocol, Src Port: 54962, Dst Port: 5353
    Source Port: 54962
    Destination Port: 5353
    Length: 63
    Checksum: 0x6f78 [unverified]
    [Checksum Status: Unverified]
    [Stream index: 0]
    [Timestamps]
    UDP payload (55 bytes)
Multicast Domain Name System (query)
    Transaction ID: 0x144e
    Flags: 0x0120 Standard query
        0... .... .... .... = Response: Message is a query
        .000 0... .... .... = Opcode: Standard query (0)
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...1 .... .... = Recursion desired: Do query recursively
        .... .... .0.. .... = Z: reserved (0)
        .... .... ..1. .... = AD bit: Set
        .... .... ...0 .... = Non-authenticated data: Unacceptable
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 1
    Queries
        151.1.168.192.in-addr.arpa: type PTR, class IN, "QM" question
            Name: 151.1.168.192.in-addr.arpa
            [Name Length: 26]
            [Label Count: 6]
            Type: PTR (domain name PoinTeR) (12)
            .000 0000 0000 0001 = Class: IN (0x0001)
            0... .... .... .... = "QU" question: False
    Additional records
        <Root>: type OPT
            Name: <Root>
            Type: OPT (41)
            .001 0000 0000 0000 = UDP payload size: 0x1000
            0... .... .... .... = Cache flush: False
            Higher bits in extended RCODE: 0x00
            EDNS0 version: 0
            Z: 0x0000
                0... .... .... .... = DO bit: Cannot handle DNSSEC security RRs
                .000 0000 0000 0000 = Reserved: 0x0000
            Data length: 0

And from multicast-dns:

No.     Time           Source                Destination           Protocol Length Info
      3 1.753128       192.168.1.140         224.0.0.251           MDNS     87     Standard query 0x5a9c PTR 151.1.168.192.in-addr.arpa, "QM" question

Frame 3: 87 bytes on wire (696 bits), 87 bytes captured (696 bits)
Ethernet II, Src: Apple_ae:41:66 (38:f9:d3:ae:41:66), Dst: IPv4mcast_fb (01:00:5e:00:00:fb)
Internet Protocol Version 4, Src: 192.168.1.140, Dst: 224.0.0.251
User Datagram Protocol, Src Port: 5353, Dst Port: 5353
    Source Port: 5353
    Destination Port: 5353
    Length: 53
    Checksum: 0x1319 [unverified]
    [Checksum Status: Unverified]
    [Stream index: 1]
    [Timestamps]
    UDP payload (45 bytes)
Multicast Domain Name System (query)
    Transaction ID: 0x5a9c
    Flags: 0x0120 Standard query
        0... .... .... .... = Response: Message is a query
        .000 0... .... .... = Opcode: Standard query (0)
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...1 .... .... = Recursion desired: Do query recursively
        .... .... .0.. .... = Z: reserved (0)
        .... .... ..1. .... = AD bit: Set
        .... .... ...0 .... = Non-authenticated data: Unacceptable
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 0
    Queries
        151.1.168.192.in-addr.arpa: type PTR, class IN, "QM" question
            Name: 151.1.168.192.in-addr.arpa
            [Name Length: 26]
            [Label Count: 6]
            Type: PTR (domain name PoinTeR) (12)
            .000 0000 0000 0001 = Class: IN (0x0001)
            0... .... .... .... = "QU" question: False

@thenewwazoo
Copy link

I did some more looking, and adding the following code:

        resolver.query({
            flags: 1 << 8 | 1 << 5,
            id: getRandomInt(1, 65534),
            questions: [
                {
                    name: reversed,
                    type: 'PTR',
                    class: 'IN'
                },
            ],
            additionals: [
                {
                    name: '.',
                    type: 'OPT',
                    udpPayloadSize: 0x1000,
                },
            ],
        });

causes the packet to include the OPT additional. The weird thing is that doing so with multicast-dns results in a packet that's one byte longer than it should be. The request packet from multicast-dns:

No.     Time           Source                Destination           Protocol Length Info
      4 3.552637       192.168.1.140         224.0.0.251           MDNS     98     Standard query 0xe88c PTR 151.1.168.192.in-addr.arpa, "QM" question OPT

Frame 4: 98 bytes on wire (784 bits), 98 bytes captured (784 bits)
Ethernet II, Src: Apple_ae:41:66 (38:f9:d3:ae:41:66), Dst: IPv4mcast_fb (01:00:5e:00:00:fb)
Internet Protocol Version 4, Src: 192.168.1.140, Dst: 224.0.0.251
User Datagram Protocol, Src Port: 5353, Dst Port: 5353
Multicast Domain Name System (query)
    Transaction ID: 0xe88c
    Flags: 0x0120 Standard query
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 1
    Queries
        151.1.168.192.in-addr.arpa: type PTR, class IN, "QM" question
            Name: 151.1.168.192.in-addr.arpa
            [Name Length: 26]
            [Label Count: 6]
            Type: PTR (domain name PoinTeR) (12)
            .000 0000 0000 0001 = Class: IN (0x0001)
            0... .... .... .... = "QU" question: False
    Additional records
        <Root>: type OPT
            Name: <Root>
            Type: OPT (41)
            .001 0000 0000 0000 = UDP payload size: 0x1000
            0... .... .... .... = Cache flush: False
            Higher bits in extended RCODE: 0x00
            EDNS0 version: 0
            Z: 0x0000
                0... .... .... .... = DO bit: Cannot handle DNSSEC security RRs
                .000 0000 0000 0000 = Reserved: 0x0000
            Data length: 0

The diff between the above packet (from node) and the one from dig in my previous comment:

$ diff dig.txt node.txt
2c2
<       1 0.000000       192.168.1.140         224.0.0.251           MDNS     97     Standard query 0x2f6a PTR 151.1.168.192.in-addr.arpa, "QM" question OPT
---
>       4 3.552637       192.168.1.140         224.0.0.251           MDNS     98     Standard query 0xe88c PTR 151.1.168.192.in-addr.arpa, "QM" question OPT
4c4
< Frame 1: 97 bytes on wire (776 bits), 97 bytes captured (776 bits)
---
> Frame 4: 98 bytes on wire (784 bits), 98 bytes captured (784 bits)
7c7
< User Datagram Protocol, Src Port: 65385, Dst Port: 5353
---
> User Datagram Protocol, Src Port: 5353, Dst Port: 5353
9c9
<     Transaction ID: 0x2f6a
---
>     Transaction ID: 0xe88c

The implications here are that the node-produced packet is one byte longer but no fields are different.

The raw packet bytes are:

From dig:

00000000: 0100 5e00 00fb 38f9 d3ae 4166 0800 4500  ..^...8...Af..E.
00000010: 0053 a0c0 0000 0111 75aa c0a8 018c e000  .S......u.......
00000020: 00fb c67b 14e9 003f 9776 fc86 0120 0001  ...{...?.v... ..
00000030: 0000 0000 0001 0331 3531 0131 0331 3638  .......151.1.168
00000040: 0331 3932 0769 6e2d 6164 6472 0461 7270  .192.in-addr.arp
00000050: 6100 000c 0001 0000 2910 0000 0000 0000  a.......).......
00000060: 00

From node:

00000000: 0100 5e00 00fb 38f9 d3ae 4166 0800 4500  ..^...8...Af..E.
00000010: 0054 3f8b 0000 0111 d6de c0a8 018c e000  .T?.............
00000020: 00fb 14e9 14e9 0040 490b fc82 0120 0001  .......@I.... ..
00000030: 0000 0000 0001 0331 3531 0131 0331 3638  .......151.1.168
00000040: 0331 3932 0769 6e2d 6164 6472 0461 7270  .192.in-addr.arp
00000050: 6100 000c 0001 0000 2910 0000 0000 0000  a.......).......
00000060: 0000                                     ..

Note the extra 0x00 byte at the end.

@thenewwazoo
Copy link

This smells like an off-by-one error in the encoder resulting in malformed packets that are getting ignored, but I am not an expert.

@thenewwazoo
Copy link

@mafintosh I know this issue is years and years old, but I'd love it if you could take another look, especially since you're more familiar with the encoder. I am emphatically not a JS programmer.

@yan-foto
Copy link
Author

@thenewwazoo it seems that @mafintosh is most probably like the rest of use have limited time for maintenance :)

@thenewwazoo
Copy link

thenewwazoo commented Dec 28, 2020

Progress! If I specify rinfo in my query, I see a response back on the network. The code now looks like


        let resolver = mdns({
            multicast: true,
            ttl: 1,
            port: 0,
        });

        resolver.query({
            flags: 1 << 8 | 1 << 5,
            id: getRandomInt(1, 65534),
            questions: [
                {
                    name: reversed,
                    type: 'PTR',
                    class: 'IN'
                },
            ],
            additionals: [
                {
                    name: '.',
                    type: 'OPT',
                    udpPayloadSize: 0x1000,
                },
            ],
        }, {
                      port: 5353,
                      address: "224.0.0.251",
        });

The problem I'm having now is that nodejs never seems to receive the response datagram that I can see in packet capture. Looks like I had a bug in my response handler code, and I am now successfully doing reverse lookups.

namtx pushed a commit to namtx/multicast-dns that referenced this issue May 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants