For most of this year I’ve been working on a new product called Cisco OnPlus, a network management service for small business. In order to do its job effectively, OnPlus needs to know what devices are present on the network, and one of the key tools we use to accomplish this is DNS Service Discovery. In this article I will show you a little bit about how we use DNS-SD, and show you how you can put it to work effectively in your networks.


Cisco OnPlus is a cloud-based network management tool that helps resellers support their customers. The figure below shows you a typical view of a customer network from an OnPlus browser screen. (The customer in this case being my Dad.) OnPlus not only identifies the devices on the customer’s network, it also performs configuration backups, firmware updates, and monitors network performance.

This graphic shows the OnPlus topology view, which is a nice rendering of a network and the devices that have been discovered on it.
The OnPlus Topology View

In order to get this information about the customer’s network, OnPlus relies on the OnPlus Network Agent - an ARM-based Linux PC about the size of a paperback book. This computer is a close relative of the Sheeva Plug, and despite its small size it runs a fairly complete distribution of Linux.

A picture of the OnPlus Network Agent. It is a small computer with a few LEDs on the front.
The OnPlus Network Agent

The agent regularly runs a complete inventory of the network, attempting to learn as much as possible about all of the devices it can find. The inventory process uses a huge list of protocols when scanning the network, including:

  • DNS Service Discovery
  • DHCP Packet Inspection
  • DNS Packet Inspection
  • Windows Management Instrumentation
  • Cisco Discovery Protocol, or CDP
  • UPnP
  • SLP
  • Traceroute
  • ARP

When it comes to locating devices made by my business unit at Cisco, the most useful protocols are DNS Service Discovery and Cisco Discovery Protocol. DNS Service Discovery provides all the information the inventory process needs to fully identify a device: its specific Product ID (more or less a model number), the version number of both the hardware and the firmware, its MAC address, and its IP address. (CDP provides a nearly, but not identical bundle of data.) This information is readily available because devices made by Cisco’s Small Business Technology Group use DNS-SD to broadcast information using our proprietary service type: csco-sb.

A Quick Overview of DNS Service Discovery

So what exactly is DNS Service Discovery? If you’re like me, you became aware of DNS-SD because Apple uses it as part of Bonjour. Bonjour is a proprietary implementation of Zeroconf, a set of technologies marked by by three key network components:

  • Address assignment
  • Service discovery
  • Name resolution

The history of Zeroconf is a somewhat quixotic story, based around the shared idea that setting up small networks ought to be a painless and simple process. The components of Zeroconf provide a nice, vendor-agnostic way to set up networks in such a way that no consumer would ever have to manually assign an IP address, set up a DHCP server, or manually enter the address of a printer.

Apple has embraced this idea, with their implementation of Zeroconf called Bonjour, an Apple trademark. If you run iTunes on your Apple or Windows PC, you may well see that there are other users out there running iTunes who would be happy to share their collections with you. This happens more or less with no work on your part, and can be a really nice feature in a big office:

This graphic shows a portion of the iTunes music screen - under the label 'SHARED' is a list of home sharing libraries.
Sharing iTunes Libraries

iTunes accomplishes this sharing using DNS-SD, which is built into OS X and is configured on Windows machines as part of the iTunes installation. Every instance of iTunes that is configured to share its library uses Bonjour to advertise an instance of the daap service. If we look in the official roster of registered DNS Service types, we find this record:

daap Digital Audio Access Protocol (iTunes)
     Amandeep Jawa <daap at>
     Defined TXT keys: txtvers, Version, iTSh Version, Machine ID, 
                       Database ID, Machine Name, Password

This is a pretty simple definition - let’s see what it looks like on the network.

On my desktop Linux sytem, I have the avahi utilities installed. Avahi provides a nice suite of tools used to implement DNS-SD. I’ll use the avahi-browse command to see what these daap services actually look like:

mark@ubuntu:~$ avahi-browse _daap._tcp -t
+   eth0 IPv4 Itunes NAS Server on nas                      iTunes Audio Access  local
+   eth0 IPv4 Denise___s Library                            iTunes Audio Access  local
+   eth0 IPv4 Mark___s Library                              iTunes Audio Access  local

If I ask avahi-browse to resolve the services, it will query the service provider for the details in the advertisement. A partial output is shown below:

mark@ubuntu:~$ avahi-browse _daap._tcp -r -t
+   eth0 IPv4 Itunes NAS Server on nas                      iTunes Audio Access  local
+   eth0 IPv4 Denise___s Library                            iTunes Audio Access  local
+   eth0 IPv4 Mark___s Library                              iTunes Audio Access  local
=   eth0 IPv4 Itunes NAS Server on nas                      iTunes Audio Access  local
   hostname = [nas.local]
   address = []
   port = [3689]
   txt = ["ffid=075abcc4" "Password=false" "Version=196610" "iTSh Version=131073" 
          "mtd-version=svn-1676" "Machine Name=Itunes NAS Server" "Machine ID=BE8926F6" 
          "Database ID=BE8926F6" "txtvers=1"]

From this information, I know have everything I need in order to connect to to a server and start playing music. I have a hostname, IP address, and a port, all of which can be used to access the service. Finally I have a txt record that contains an aribtrary set of name/value pairs, as defined in the service definition. The use of these fields is up to the creator of the service, and in this case most of them are self-evident.

Browsing the Network

We use the avahi toolkit in OnPlus to browse the network for devices. It is worth doing a little exploring on my home network to see what kind of information we get out of this process.

To get a high-level view, I can ask avahi-browse to query for a special service: _services._dns-sd._udp. When this browse request goes out on the network, all the active nodes using DNS-SD issue records detailing the types of services they support. The result on my home network looks like this:

mark@ubuntu:~$ avahi-browse _services._dns-sd._udp -t
+   eth0 IPv4 _udisks-ssh                                   _tcp                 local
+   eth0 IPv4 _workstation                                  _tcp                 local
+   eth0 IPv4 _ir-hvac-021                                  _tcp                 local
+   eth0 IPv4 _ir-hvac-020                                  _tcp                 local
+   eth0 IPv4 _ir-hvac-000                                  _tcp                 local
+   eth0 IPv4 _pdl-datastream                               _tcp                 local
+   eth0 IPv4 _printer                                      _tcp                 local
+   eth0 IPv4 _tivo-videos                                  _tcp                 local
+   eth0 IPv4 _readynas                                     _tcp                 local
+   eth0 IPv4 _smb                                          _tcp                 local
+   eth0 IPv4 _afpovertcp                                   _tcp                 local
+   eth0 IPv4 _rsp                                          _tcp                 local
+   eth0 IPv4 _daap                                         _tcp                 local
+   eth0 IPv4 _http                                         _tcp                 local
+   eth0 IPv4 _csco-sb                                      _tcp                 local

As you can see, there are a surprising number of DNS-SD services present. On my network, an explanation for each of the services is:

_udisks-ssh: A remote disk management tool being advertised by my Ubuntu systems
_workstation: Some sort of workgroup management interface support by various Linux systems.
_ir-hvac-0xx: Management interfaces on a Trane thermostat that happens to have wireless access to my network
_pdl-datastream: Printer page description language interface. This is a service that is used in Bonjour printing. Both of my networked printers support it.
_printer Both of my printers use this advertisement to offer TCP port 515 up for LPR print spooling
_tivo-videos My Tivo sends out this advertisement which provides a complete URL I can use to get an XML-formatted version of the Now Playing section of the Tivo UI.
_readynas My Netgear ReadyNAS uses this unregistered service type to advertise something that can be reached on port 9. Exactly what, I don't know, but I think it might be just a way for PC users to find the NAS with RAIDar.
_smb My Netgear ReadyNAS advertises its Windows shares with this service type
_afpovertcp My Netgear ReadyNAS uses this registered service type to advertise its Apple File Sharing volumes
_rsp I have a Firefly iTunes server running on my NAS. In addition to serving music via DAAP, it uses the Roku Server Protocol as well, presumably working with software that doesn't support iTunes protocols.
_http Most of the devices on my network that are running web servers issue an HTTP advertisement, which points to that interface.
_csco-sb My two Cisco SB devices advertise their presence using this service

This special command to show me the services available is not actually used in OnPlus. Instead, we call avahi-browse with the -r and -p commands, asking it to do a full resolution on all discovered services.

Cisco Devices

The place where we get the most interesting results from avahi-browse is when we tell it to look specifically for instances of the cisco-sb service. That command produces output like this:

mark@ubuntu:~$ avahi-browse -r -t _csco-sb._tcp
+   eth0 IPv4 switch32026a                                  _csco-sb._tcp        local
+   eth0 IPv4 onplus005229                                  _csco-sb._tcp        local
=   eth0 IPv4 switch32026a                                  _csco-sb._tcp        local
   hostname = [sg200-26p.local]
   address = []
   port = [80]
   txt = ["hostname=sg200-26p" "serialNo=DNI1515005U" "MACAddress=44E4D932026A" 
          "PIDVID=SLM2024PT V01" "fmVersion=" 
          "deviceDescr=26-port Gigabit PoE Smart Switch" "deviceType=Switch" 
          "model=SG 200-26P"]
=   eth0 IPv4 onplus005229                                  _csco-sb._tcp        local
   hostname = [PLG1000F0AD4E005229.local]
   address = []
   port = [80]
   txt = ["accessType=http" "MDFID=Unassigned" "hostname=onplus005229" 
          "serialNo=PLGF0AD4E005229" "MACAddress=F0:AD:4E:00:52:29" 
          "PIDVID=Unassigned" "fmVersion=" "deviceDescr=Cisco OnPlus Network Agent" 
          "deviceType=Service Appliance" "model=PLG1000" "version=1.0"]

If you look at the first ‘=’ records that is issued by avahi-browse, you can see that when it comes to discovery, I have really hit the jackpot. I’ve identified a device on my system that I can reach with a specific IP address. I have a MAC address that I can now use as a globally unique identifier. And I have the Cisco Product ID, the hardware version, and the firmware version, as well as the user-assigned host name and a friendly model name.

When I have information like this, it allows me to fill in the details in the topology map quite accurately. Better yet, since this is a Cisco device, the OnPlus appliance can now send it some queries to find out more network information. As an example, the switch’s CAM table provides me with a list of devices and the ports they are attached to, which helps me fill in some of the details of the topology picture.

Processing This Data

If you are a programmer, the natural question you might be asking is how you access these service advertisements from inside your program. In the case of Cisco OnPlus, most of the code running the inventory task consists of PHP scripts. As far as I know, there are no bindings in PHP to DNS-SD services, and we elected not to try to invent that wheel.

Instead, we use PHP’s popen() function to run instances of avahi-browse, collecting the output from the program and parsing it accordingly. We actually have three instances of the browser running at any time. Two are dedicated to Cisco-specific services, while the third looks at all other services. Even though other services might not give us as much information as csco-sb, they still supply host names, MAC addresses, IP addresses, descriptions, and more, and we use whatever we can find.

These instances of avahi-browse run as independent discovery processes, collecting and storing data as it is seen on the network. The records that they collect are then used by the inventory process when it is periodically launched.

The DNS-SD discovery processes actually take an active role in the inventory scheme. When one of the avahi-based processes discovers a significant new device on the network, such as one advertising cisco-sb, it stores the data record and then triggers an early start to the inventory process. This allows OnPlus to respond to new devices on the network in something close to real-time.


So let’s say you decide you want to use DNS-SD for some form of network discovery. I’ve shown you how you can you discover network nodes that are advertising a service, but how do you actually perform that advertisment?

In the OnPlus Network we use the avahi package to advertise services as well as to find them. The avahi-publish command does the job, typically started as a daemon to run for the lifetime of the system. When executing avahi-publish, you will normally want to specify:

  • A service type
  • The name of the service instance
  • A port to access the service
  • Text records containing whatever name/value pairs you want to publish

One thing to note is that you can use DNS-SD to advertise things that don’t necessarily map directly to a port. For example, if you just want to let everyone know of your existence, the port parameter might be irrelevant, but the name/value pairs could still be valuable.

As an example, I might create a photo sharing service that I advertise on the network using a service I’ll call PhotoMark. To let everyone know about this, I execute the following command when my system starts up:

avahi-publish -s mark _PhotoMark._tcp 9999 "payload=.gif" "folder=/pictures"

Anyone on the network using DNS-SD could then see that I was advertising photo sharing with photos of type GIF accessible on my pictures folder. Of course, the details of the protocol are not included in the advertisement - that’s outside the scope of DNS-SD.

Often a good choice for the service instance is to simply use the computer name:

avahi-publish -s `uname -n` _PhotoMark._tcp 9999 "payload=.gif" "folder=/pictures"

What's Next

In this article I showed you how we use DNS-SD on the Cisco OnPlus Network Agent. Mostly it involves calling the avahi command line tools and parsing their output with PHP scripts.

In my next post, I’ll show you how to do the same thing on a Windows PC using the Apple Bonjour SDK. Unfortunately, Windows has not included DNS-SD support in the O/S, so instead of using the Win32 API to do service discovery, you will have to rely on some slightly less elegant methods. But when it comes to network discovery, functionality and interoperability trump elegance every day of the week.