Advertising a Bonjour service on a specific set of networking interfaces.

Q: I want to use Bonjour to advertise my services but I only want to do so on a specific set of networking interfaces. Is this possible?

A: Yes. However, you will NOT be able to use the NSNetServices and CFNetServices APIs to do this. You will need to use the DNSServiceDiscovery socket-based API.

You can register your service by issuing a call to DNSServiceRegister(), paying close attention to the third parameter specifying an interface index. Determining which interface index maps to a specific interface name can be done by calling if_nametoindex(). See below for an example:

Listing 1: Example function that registers a service on a single interface.

static int doBonjourRegisterOnSingleInterface(
    char * interface_name,          // e.g., "en0", "en1", etc.
    DNSServiceRef * ssr,
    DNSServiceRegisterReply callBack
)
{
    int err = 0;

    DNSServiceFlags flags   = kDNSServiceFlagsDefault;
    uint32_t int_index      = 0;
    const char *name        = "Clarus";
    const char *regtype     = "_http._tcp";
    const char *domain      = NULL;     // default domain
    const char *host        = NULL;     // default host
    uint16_t port           = 9999;
    uint16_t txtLen         = 5;
    const char txtRecord[]  = "\x04Moof";

    // Resolve the index of the specified interface.
    int_index = if_nametoindex(interface_name);

    if(int_index != 0) {

          err = DNSServiceRegister(
                            ssr,
                            flags,
                            int_index,
                            name,       /* may be NULL */
                            regType,
                            domain,     /* may be NULL */
                            host,       /* may be NULL */
                            htons(port),
                            txtLen,
                            txtRecord,
                            callback,   /* may be NULL */
                            NULL        /* may be NULL */
          );

     } else {
          // Desired interface name could not be resolved.
          err = -1;
     }

    return err;
}

Note: Be mindful of the formats and types for the data parameters passed into DNSServiceRegister(), e.g., "the TXT record string must be in DNS TXT record format of [length byte] [data] [length byte] [data] ...", otherwise you will receive an invalid parameter (-65540) error. See Q&A 1306.

Document Revision History

DateNotes
2007-02-12First Version

Posted: 2007-02-12


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.