Multicast DNS Quickstart

Obtain the code, either through perforce or grab the latest snapshot. The code should compile fine on both current and 6-STABLE.

Note that this is NOT production ready yet

If anything crashes or misbehaves, please try to obtain a backtrace from gdb


> cd mdnsd
> make

If you want it to announce and claim records for your hostname you need to supply a configuration file, the default should do fine.

./mdnsd -f mdnsd.conf.sample

It's quite noisy as most debugging is still enabled, you can change the output by manipulating the DEBUG_MASK in mdnsd/Makefile. Debugging masks are defined in mdnsd/debug.h

If your hostname is foobar, the name foobar.local. will be claimed as yours and you should be able to use this name from another mDNS enabled machine (example Mac OS X client) to contact your machine.

Note that you need to start mdnsd as root if you want to be able to use libmdns, this is because the pipe is created in /var/run/mdnsd.pipe. It's possible to drop privileges with the -u and -g flags.

./mdnsd -f mdnsd.conf.sample -u nobody -g nobody


This needs to be compiled before you can use mdns or nss_mdns.

> cd libmdns
> make

You do not need to install it, if you do and want to remove it later it installs the following files


Once mdnsd and libmdns is up and running you can play with the administrative and debugging utility mdns

cd mdns

> ./mdns 
./mdns query [-v] [-i ifnam] [-f family] [-w sec] [-c class] [-t type] name
./mdns db [-i ifnam] name `ident' [-s] add|del `host'
./mdns db [-i ifnam] res `ident' [-p] [-t ttl] add|del `class' `type' `res'
./mdns db -i ifnam list [ident]
./mdns cache [-i ifnam] view|flush

The query subcommand allows you do do a multicast dns query. The class (-c) and type (-t) arguments take case insensitive ascii representations of classes and types. Default class is IN and the default type is ANY. The -i argument allows you to specify a specific interface to query on, the default is all interfaces. The -f argument controls on which family to query (INET4/INET6), the default is both. -w controls how many seconds to wait for a response, there is no NXDOMAIN in mDNS, the absence of a response is interpreted as an implicit NXDOMAIN.


fli@nexus> ./mdns query shiva.local
shiva.local. has address fe80::211:24ff:fe76:da00
shiva.local. has address
fli@nexus> ./mdns query domain name pointer shiva.local.
fli@nexus> ./mdns query fe80::211:24ff:fe76:da00 domain name pointer shiva.local.

The db sub-command allows you to manipulate the state of the record database (you need to be root to use this). A resource set (rrset) is identified by an arbitrary unique identifier, a rrset can have one or many names assigned to it, but only one of them are in use at any given moment. Other names are used as fallback names in case name collisions. In addition to the names a rrset of course has resources, a resource is identified by (class, type, resource data). Both names and resource data are abstract and allows the use of variables in the names, the are then auto encoded into the correct format. A variable might expand to more than one data line, hence creating multiple records.


root@nexus> ./mdns db -i em0 list
Names on identifier 'hostname'
        $(hostname).local. (nexus.local.)
Resources on identifier 'hostname'
        120 IN A $(ifaddrs4)
        120 IN AAAA $(ifaddrs6)
Names on identifier 'ip4-ptr'
        $(ifaddrs4) (
Resources on identifier 'ip4-ptr'
        120 IN PTR $(hostname).local. (pointer to 'hostname')
Names on identifier 'ip6-ptr'
        $(ifaddrs6) (fe80:1::219:d1ff:fedd:7914)
Resources on identifier 'ip6-ptr'
        120 IN PTR $(hostname).local. (pointer to 'hostname')

This is the names and resources created by mdnsd.conf.sample, together they form a real set of records.

For example the identifier 'hostname', it has two names assigned to it "$(hostname).local" which has been expanded to "nexus.local." and is the name currently in use, there is also a fallback name "$(hostname)-$(ifname).local" in case "nexus.local." would have been in use by some other host on the network. It has two resources, one (IN,A) resource with TTL 120 and data "$(ifaddrs4)" and one (IN,AAAA), TTL 120 and data "$(ifaddrs6)". Both "$(ifaddrs4)" and "$(ifaddrs6)" are expanded to the current ip-addresses of the interface "em0" (although not shown in this output).

The command db name and db res allows you to add and remove existing names and resources (root only).

Sub-command cache allows you to view/flush the cache on a specific interface (root only). Example

root@nexus> ./mdns cache -i em0 view
shiva [00:11:24:76:da:00]._workstation._tcp.local.       120 116 IN SRV 0 0 9 shiva.local.
shiva._sftp-ssh._tcp.local.      120 116 IN SRV 0 0 22 shiva.local.
shiva._ssh._tcp.local.   120 116 IN SRV 0 0 22 shiva.local.
shiva.local.     120 116 IN AAAA fe80::211:24ff:fe76:da00        120 116 IN PTR shiva.local.
shiva.local.     120 116 IN A       120 116 IN PTR shiva.local.
shiva [00:11:24:76:da:00]._workstation._tcp.local.       4500 4496 IN TXT  
_services._dns-sd._udp.local.    4500 4496 IN PTR _workstation._tcp.local.
_workstation._tcp.local.         4500 4496 IN PTR shiva [00:11:24:76:da:00]._workstation._tcp.local.
shiva._sftp-ssh._tcp.local.      4500 4496 IN TXT  
_services._dns-sd._udp.local.    4500 4496 IN PTR _sftp-ssh._tcp.local.
_sftp-ssh._tcp.local.    4500 4496 IN PTR shiva._sftp-ssh._tcp.local.
shiva._ssh._tcp.local.   4500 4496 IN TXT  
_services._dns-sd._udp.local.    4500 4496 IN PTR _ssh._tcp.local.
_ssh._tcp.local.         4500 4496 IN PTR shiva._ssh._tcp.local.


To use this you need to really install libmdns first.

cd nss_mdns
make install

It installs the following files

Now you need to modify you /etc/nsswitch.conf file Change the hosts line to something like this

hosts: files dns mdns

You should now be able to resolv mDNS names from any application.


fli@nexus> ping6 shiva.local
PING6(56=40+8+8 bytes) fe80::219:d1ff:fedd:7914%em0 --> ?
16 bytes from fe80::211:24ff:fe76:da00%em0, icmp_seq=0 hlim=64 time=8.527 ms
16 bytes from fe80::211:24ff:fe76:da00%em0, icmp_seq=1 hlim=64 time=0.575 ms
16 bytes from fe80::211:24ff:fe76:da00%em0, icmp_seq=2 hlim=64 time=1.418 ms
--- shiva.local. ping6 statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.575/3.507/8.527/3.567 ms

If you want you can play with the mdns.conf.sample file, place it in /etc/mdns.conf and nss_mdns should pick it up.

The default looks like this (also hard coded in nss_mdns)

# nss_mdns sample configuration file
# These configuration values represent the default values that
# are used when no configuration file is present.

search local.
allow local.
allow fe80::/10

The search keyword makes nss_mdns auto-append .local. to names that fails to resolve, which means that you even can leave out the .local-part when using mdns names (eg ping6 shiva instead of ping6 shiva.local). The allow keyword controls what types of names that can be resolved, ip-addresses represents PTR-records.

MulticastDNS/Quickstart (last edited 2008-06-17T21:37:27+0000 by anonymous)