mDNSResponder, mDNS and dns-sd

The process that makes Bonjour work is mDNSResponder, located in /usr/sbin. /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist invokes mDNSResponder on boot. One of the easiest ways to troubleshoot issues you think are related to Bonjour is to temporarily disable the mDNSResponder:

launchctl unload -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist

To enable it:

launchctl load -w /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist

In addition to basic starting and stopping of the mDNSResponder, when troubleshooting any service, one should always look at logs. Log events are logged to the standard syslog facility and so are available via Console. These are locate at /var/log/system.log. Searching for mDNSResponder errors in system.log can also be done from the command line using:

cat /var/log/system.log | grep mDNSResponder

Or interactively so you can watch errors as they appear:

tail -f /var/log/system.log | grep mDNSResponder

To see more information in system.log, send a SIGUSR1 to mDNSResponder using killall:

sudo killall -USR1 mDNSResponder

To then see packet-level information in system.log, send a SIGUSR2 to mDNSResponder:

sudo killall -USR2 mDNSResponder

To dump the state into system.log:

sudo killall -INFO mDNSResponder

mDNSResponder uses Mach port 5123. Each service that is Bonjour-enabled will register itself with mDNSResponder at that port and can be queried. These are similar to DNS records where they have a prefix for the service and a suffix of the TCP/IP type. For example, IPP Printing is _ipp._tcp, Remote Apple Events is _eppc._tcp., Remote Frame Buffer is _rfb._tcp., SSH is _ssh._tcp., SFTP is _sftp-ssh._tcp., Apple’s Home Sharing is called _home-sharing._tcp, iTunes Music Sharing is _afpovertcp._tcp. and AFP is _afpovertcp._tcp. As an example of UDP traffic, ARD is known as _net-assistant._udp.

To see which services are registered (and register services if you build a network service that needs one), use the mDNS command. The -B option for mDNS can be used to query a given namespace. For example, the _afpovertcp._tcp namespace can be queried using the following command:

mDNS -B _afpovertcp._tcp

This would result in the following output, showing all live instances that the system sees:

Timestamp     A/R Flags Domain                   Service Type             Instance Name

18:29:40.771  Add     0 local.                   _afpovertcp._tcp.        Krypted MacBook Air

To register services with Bonjour, use the -R operator and to lookup information about a given service instance, use the -L operator. The -L operator allows you to get a lot of information about a given object. Once you have found the object using the -B option you’ll have the Domain and Instance Name. These can be supplied to mDNS to get IPv4, IPv6, port number, and TXT records, which provide a bevy of options, such as information about printers and other services or objects. For example, Mac OS X automatically generates information about printers based on built-in OS information about those printers, such as staple support (Staple=F), collate support (Collate=T) and CUPS admin url’s (adminurl:http://<computer name>:631/printers/<printername>. Other services such as Home Sharing might make heavy use of Machine Name’s or iTunes Database IDs.

To use mDNS to obtain this extended output, use the mDNS command, along with the -L option, followed by the Instance Name (the instance name is defined by the service registering the instance and can be a printer name, a computer name, a GUID or whatever the vendor chooses to use. After the Instance Name, provide the address space (Service Type) and then the domain from the -B output. For example, to look at an HP 8565 shared from Krypted MacBook Air called “HP 8565 Krypted MacBook Air”, I would use:

mDNS -L "HP 8565 Krypted MacBook Air" _ipp._tcp local.

Other operators not in the man page, but available, include -E for finding recommended registration domains, -F for finding information about browsing domains, -A to test updates to records, -U to test updates to TXT records, -N to test updates to NULL records, -T to test adding big records, -M for multiple records and -I for immediately updating records rather than running through cache. Also available for querying is dns-sd, using identical syntax as mDNS and with the same output. Data regarding systems doesn’t always change dynamically. To reload information following changes, use the -flushcache option of dscacheutil:

dscacheutil -flushcache

When I have a chance I’ll try and look at multiple domain name spaces and registering text records as a part 2 of this article, but for now there’s a 2 year old who just woke up and is wanting a little attention (and deservedly so).

  • http://www.radiotope.com Edward Marczak

    As of 10.6, unloading mDNSResponder is generally a bad idea as that will break proper DNS for Cocoa apps. (Unload mDNSResponder and then try to load a page in Safari.)

    Also, rather than using mDNS, wouldn’t it be better to register a service via launchd?

    • http://www.krypted.com Charles

      This was meant for temporary testing. Not long-term leave it disabled kinda’ stuff. I’ll add that in there though. Maybe I’ll save registering services with Bonjour via launchd for a later article. I was really just trying to focus on those 3 binaries here.

  • Pingback: mDNSResponder, mDNS et dns-sd | Le blog de NausicaMedia()