Multicast DNS
In computer networking, the multicast Domain Name System (mDNS) resolves host names to IP addresses within small networks that do not include a local name server. It is a zero-configuration service, using essentially the same programming interfaces, packet formats and operating semantics as the unicast Domain Name System (DNS). Although Stuart Cheshire designed mDNS to be stand-alone capable, it can work in concert with unicast DNS servers.[1]
The mDNS protocol is published as RFC 6762, uses IP multicast User Datagram Protocol (UDP) packets, and is implemented by the Apple Bonjour and Linux nss-mdns services.
mDNS can work in conjunction with DNS Service Discovery (DNS-SD), a companion zero-configuration technique specified separately in RFC 6763.[2]
Protocol overview
When an mDNS client needs to resolve a host name, it sends an IP multicast query message that asks the host having that name to identify itself. That target machine then multicasts a message that includes its IP address. All machines in that subnet can then use that information to update their mDNS caches.
Any host can relinquish its claim to a domain name by sending a response packet with a time to live (TTL) equal to zero.
By default, mDNS only and exclusively resolves host names ending with the .local
top-level domain (TLD). This can cause problems if that domain includes hosts which do not implement mDNS but which can be found via a conventional unicast DNS server. Resolving such conflicts requires network-configuration changes that violate the zero-configuration goal.
Packet structure
The mDNS Ethernet frame is a multicast UDP packet to:
- MAC address
01:00:5E:00:00:FB
(for IPv4) or33:33:00:00:00:FB
(for IPv6) - IPv4 address
224.0.0.251
or IPv6 addressFF02::FB
- UDP port
5353
Its payload is based on the DNS packet format.[3] It consists of two parts—the header and the data.[4]
offset (bytes) | 0 | 1 |
---|---|---|
0 | ID = 0x0000 | |
2 | Flags | |
4 | QDCOUNT | |
6 | ANCOUNT | |
8 | NSCOUNT | |
10 | ARCOUNT | |
12 | Data |
The Flags word will generally be 00 00
for a query and 84 00
for a response.
Each packet's data begins with the fully qualified domain name (FQDN) to be resolved, and ends with two 2-byte flags indicating the QTYPE
(00 01 for a host address query) and QCLASS
(00 01 for Internet):
- A query packet's data includes no other information.
- In a response packet's data, the FQDN is followed by the target host's IPv4 address, IPv6 address and name section records.
The FQDN is specified by a list of component strings, beginning with the host name and ending with the top-level domain (TLD). Each such string consists of a length byte followed by that many UTF-8 bytes. The TLD is followed by a null string (hex 00) that terminates the FQDN.
The target host's IPv4 address record consists of:
- a 2-byte type field (hex 00 00 for an A record),
- a 2-byte class field (hex 80 01 for class IN with cache-flush bit set),
- a 32-bit signed integer Time To Live (TTL) field (in seconds),
- a 2-byte length field (hex 00 04 for a 4-byte IPv4 address), and
- the 4 IPv4 address bytes.
Its IPv6 address record consists of:
- a 2-byte link indicating the offset of the host name (hex C0 0C),
- a 2-byte type field (hex 00 1C for an AAAA record),
- a 2-byte class field (hex 80 01 for class IN with cache-flush bit set),
- a 32-bit signed integer Time To Live (TTL) field,
- a 2-byte length field (hex 00 10 for a 16-byte IPv6 address), and
- the 16 IPv6 address bytes.
The name section record consists of:
- a 2-byte link indicating the offset of the host name (hex C0 0C),
- a 2-byte type field (hex 00 2f for an NSEC record),
- a 2-byte class field (hex 80 01 for class IN with cache-flush bit set),
- a 32-bit signed integer Time To Live (TTL) field,
- a 2-byte length field (hex 00 08 for an 8-byte NSEC record), and
- the 8 block and bitmap bytes.
In a standard DNS message the upper byte of any class field is always 0x00, in mDNS the upper bit of this byte may be set, resulting in a value of 0x80. This is the cache-flush bit and should not be interpreted as part of the class value - see section 10.2 of RFC 6762.
Example
Trying to ping
the appletv.local
host would cause an mDNS client computer to multicast the following UDP packet:
00 00 00 00 00 01 00 00 00 00 00 00 07 61 70 70 6c 65 74 76 05 6c 6f 63 61 6c 00 00 01 00 01
All six header fields equal zero (00 00) except the QDCOUNT
, which equals one (00 01). The data begin with the seven character appletv
host name (hex 07 61 70 70 6c 65 74 76) followed by the five character local
domain string (hex 05 6c 6f 63 61 6c) and the requisite null string (00). That entire FQDN is followed by the host address QTYPE flag (hex 00 01) and the internet QCLASS flag (00 01).
The appletv.local host would respond by multicasting its mDNS response packet. For example:
00 00 84 00 00 00 00 01 00 00 00 02 07 61 70 70 6c 65 74 76 05 6c 6f 63 61 6c 00 00 01 80 01 00 00 78 00 00 04 99 6d 07 5a c0 0c 00 1c 80 01 00 00 78 00 00 10 fe 80 00 00 00 00 00 00 02 23 32 ff fe b1 21 52 c0 0c 00 2f 80 01 00 00 78 00 00 08 c0 0c 00 04 40 00 00 08
In its header, the non-zero fields are the Flags
word (84 00), the ANCOUNT
word (00 01), and the ARCOUNT
word (00 02). The data again begin with the FQDN (hex 07 61 70 70 6c 65 74 76 05 6c 6f 63 61 6c 00 for appletv.local), followed by that host's DNS information:
- the A/IPv4 address type code (hex 00 01),
- the IPv4 class code (hex 80 01),
- the IPv4 TTL (hex 00 00 78 00 for 30720 seconds),
- the IPv4 length (hex 00 04),
- the four IPv4 address bytes (hex 99 6D 07 5A, or 153.109.7.90 in dotted-decimal notation),
- the FQDN offset (hex C0 0C for byte 12),
- the AAAA/IPv6 address type code (hex 00 1C),
- the IPv6 class code (hex 80 01),
- the IPv6 TTL (again hex 00 00 78 00),
- the IPv6 length (hex 00 10),
- the 16 IPv6 address bytes (hex FE 80 00 00 00 00 00 00 02 23 32 FF FE B1 21 52),
- the FQDN offset (hex C0 0C for byte 12),
- the NSEC type code (hex 00 2F),
- the NSEC class code (hex 80 01),
- the NSEC TTL (again hex 00 00 78 00),
- the NSEC length (hex 00 08, for an 8-byte name section record), and
- the 8 NSEC block and bitmap bytes (hex C0 0C 00 04 40 00 00 08)