Technical Q&A QA1513

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: 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?

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;
}


Document Revision History


DateNotes
2007-02-12

New document that explains how to register a Bonjour service only on a specific set of networking interfaces.