1 /*
2  * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1.  Redistributions of source code must retain the above copyright notice,
8  *     this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright notice,
10  *     this list of conditions and the following disclaimer in the documentation
11  *     and/or other materials provided with the distribution.
12  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
13  *     contributors may be used to endorse or promote products derived from this
14  *     software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef OW_DNSSD_H
29 #define OW_DNSSD_H
30 
31 #define ORIGINAL_DNSSD_INCLUDE 0
32 
33 #ifdef  __cplusplus
34 extern "C" {
35 
36 #endif							/*
37  */
38 
39 int OW_Load_dnssd_library(void);
40 
41 void OW_Free_dnssd_library(void);
42 
43 
44 /* standard calling convention under Win32 is __stdcall */
45 /* Note: When compiling Intel EFI (Extensible Firmware Interface) under MS Visual Studio, the */
46 /* _WIN32 symbol is defined by the compiler even though it's NOT compiling code for Windows32 */
47 #if defined(_WIN32) && !defined(EFI32) && !defined(EFI64)
48 #define DNSSD_API __stdcall
49 #else							/*
50  */
51 #define DNSSD_API
52 #endif							/*
53  */
54 
55 /* stdint.h does not exist on FreeBSD 4.x; its types are defined in sys/types.h instead */
56 #if defined(__FreeBSD_version) && (__FreeBSD_version < 500000)
57 #include <sys/types.h>
58 
59 /* Likewise, on Sun, standard integer types are in sys/types.h */
60 #elif defined(__sun__)
61 #include <sys/types.h>
62 
63 /* EFI does not have stdint.h, or anything else equivalent */
64 #elif defined(EFI32) || defined(EFI64)
65 	typedef UINT8 uint8_t;
66 
67 typedef INT8 int8_t;
68 
69 typedef UINT16 uint16_t;
70 
71 typedef INT16 int16_t;
72 
73 typedef UINT32 uint32_t;
74 
75 typedef INT32 int32_t;
76 
77 
78 /* Windows has its own differences */
79 #elif defined(_WIN32)
80 #include <windows.h>
81 #define _UNUSED
82 #define bzero(a, b) memset(a, 0, b)
83 #ifndef _MSL_STDINT_H
84 	typedef UINT8 uint8_t;
85 
86 typedef INT8 int8_t;
87 
88 typedef UINT16 uint16_t;
89 
90 typedef INT16 int16_t;
91 
92 typedef UINT32 uint32_t;
93 
94 typedef INT32 int32_t;
95 
96 #endif							/*
97  */
98 
99 /* All other Posix platforms use stdint.h */
100 #else							/*
101  */
102 #include <stdint.h>
103 #endif							/*
104  */
105 
106 /* DNSServiceRef, DNSRecordRef
107  *
108  * Opaque internal data types.
109  * Note: client is responsible for serializing access to these structures if
110  * they are shared between concurrent threads.
111  */
112 
113 typedef struct _DNSServiceRef_t *DNSServiceRef;
114 
115 typedef struct _DNSRecordRef_t *DNSRecordRef;
116 
117 
118 /* General flags used in functions defined below */
119 	enum
120  {
121 kDNSServiceFlagsMoreComing = 0x1,
122 			/* MoreComing indicates to a callback that at least one more result is
123 			 * queued and will be delivered following immediately after this one.
124 			 * Applications should not update their UI to display browse
125 			 * results when the MoreComing flag is set, because this would
126 			 * result in a great deal of ugly flickering on the screen.
127 			 * Applications should instead wait until until MoreComing is not set,
128 			 * and then update their UI.
129 			 * When MoreComing is not set, that doesn't mean there will be no more
130 			 * answers EVER, just that there are no more answers immediately
131 			 * available right now at this instant. If more answers become available
132 			 * in the future they will be delivered as usual.
133 			 */
134 
135 kDNSServiceFlagsAdd = 0x2,
136 kDNSServiceFlagsDefault = 0x4,
137 			/* Flags for domain enumeration and browse/query reply callbacks.
138 			 * "Default" applies only to enumeration and is only valid in
139 			 * conjuction with "Add".  An enumeration callback with the "Add"
140 			 * flag NOT set indicates a "Remove", i.e. the domain is no longer
141 			 * valid.
142 			 */
143 
144 kDNSServiceFlagsNoAutoRename = 0x8,
145 			/* Flag for specifying renaming behavior on name conflict when registering
146 			 * non-shared records. By default, name conflicts are automatically handled
147 			 * by renaming the service.  NoAutoRename overrides this behavior - with this
148 			 * flag set, name conflicts will result in a callback.  The NoAutorename flag
149 			 * is only valid if a name is explicitly specified when registering a service
150 			 * (i.e. the default name is not used.)
151 			 */
152 
153 kDNSServiceFlagsShared = 0x10,
154 kDNSServiceFlagsUnique = 0x20,
155 			/* Flag for registering individual records on a connected
156 			 * DNSServiceRef.  Shared indicates that there may be multiple records
157 			 * with this name on the network (e.g. PTR records).  Unique indicates that the
158 			 * record's name is to be unique on the network (e.g. SRV records).
159 			 */
160 
161 kDNSServiceFlagsBrowseDomains = 0x40,
162 kDNSServiceFlagsRegistrationDomains = 0x80,
163 			/* Flags for specifying domain enumeration type in DNSServiceEnumerateDomains.
164 			 * BrowseDomains enumerates domains recommended for browsing, RegistrationDomains
165 			 * enumerates domains recommended for registration.
166 			 */
167 
168 kDNSServiceFlagsLongLivedQuery = 0x100,
169 			/* Flag for creating a long-lived unicast query for the DNSServiceQueryRecord call. */
170 
171 kDNSServiceFlagsAllowRemoteQuery = 0x200,
172 			/* Flag for creating a record for which we will answer remote queries
173 			 * (queries from hosts more than one hop away; hosts not directly connected to the local link).
174 			 */
175 
176 kDNSServiceFlagsForceMulticast = 0x400
177 			/* Flag for signifying that a query or registration should be performed exclusively via multicast DNS,
178 			 * even for a name in a domain (e.g. foo.apple.com.) that would normally imply unicast DNS.
179 			 */
180 	};
181 
182 
183 /*
184  * The values for DNS Classes and Types are listed in RFC 1035, and are available
185  * on every OS in its DNS header file. Unfortunately every OS does not have the
186  * same header file containing DNS Class and Type constants, and the names of
187  * the constants are not consistent. For example, BIND 8 uses "T_A",
188  * BIND 9 uses "ns_t_a", Windows uses "DNS_TYPE_A", etc.
189  * For this reason, these constants are also listed here, so that code using
190  * the DNS-SD programming APIs can use these constants, so that the same code
191  * can compile on all our supported platforms.
192  */
193 
194 enum
195  {
196 kDNSServiceClass_IN = 1 /* Internet */
197 	};
198 
199 
200 enum
201 {
202 	kDNSServiceType_A = 1, /* Host address. */
203 	kDNSServiceType_NS = 2, /* Authoritative server. */
204 	kDNSServiceType_MD = 3, /* Mail destination. */
205 	kDNSServiceType_MF = 4, /* Mail forwarder. */
206 	kDNSServiceType_CNAME = 5, /* Canonical name. */
207 	kDNSServiceType_SOA = 6, /* Start of authority zone. */
208 	kDNSServiceType_MB = 7, /* Mailbox domain name. */
209 	kDNSServiceType_MG = 8, /* Mail group member. */
210 	kDNSServiceType_MR = 9, /* Mail rename name. */
211 	kDNSServiceType_NULL = 10, /* Null resource record. */
212 	kDNSServiceType_WKS = 11, /* Well known service. */
213 	kDNSServiceType_PTR = 12, /* Domain name pointer. */
214 	kDNSServiceType_HINFO = 13, /* Host information. */
215 	kDNSServiceType_MINFO = 14, /* Mailbox information. */
216 	kDNSServiceType_MX = 15, /* Mail routing information. */
217 	kDNSServiceType_TXT = 16, /* One or more text strings. */
218 	kDNSServiceType_RP = 17, /* Responsible person. */
219 	kDNSServiceType_AFSDB = 18, /* AFS cell database. */
220 	kDNSServiceType_X25 = 19, /* X_25 calling address. */
221 	kDNSServiceType_ISDN = 20, /* ISDN calling address. */
222 	kDNSServiceType_RT = 21, /* Router. */
223 	kDNSServiceType_NSAP = 22, /* NSAP address. */
224 	kDNSServiceType_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */
225 	kDNSServiceType_SIG = 24, /* Security signature. */
226 	kDNSServiceType_KEY = 25, /* Security key. */
227 	kDNSServiceType_PX = 26, /* X.400 mail mapping. */
228 	kDNSServiceType_GPOS = 27, /* Geographical position (withdrawn). */
229 	kDNSServiceType_AAAA = 28, /* Ip6 Address. */
230 	kDNSServiceType_LOC = 29, /* Location Information. */
231 	kDNSServiceType_NXT = 30, /* Next domain (security). */
232 	kDNSServiceType_EID = 31, /* Endpoint identifier. */
233 	kDNSServiceType_NIMLOC = 32, /* Nimrod Locator. */
234 	kDNSServiceType_SRV = 33, /* Server Selection. */
235 	kDNSServiceType_ATMA = 34, /* ATM Address */
236 	kDNSServiceType_NAPTR = 35, /* Naming Authority PoinTeR */
237 	kDNSServiceType_KX = 36, /* Key Exchange */
238 	kDNSServiceType_CERT = 37, /* Certification record */
239 	kDNSServiceType_A6 = 38, /* IPv6 address (deprecates AAAA) */
240 	kDNSServiceType_DNAME = 39, /* Non-terminal DNAME (for IPv6) */
241 	kDNSServiceType_SINK = 40, /* Kitchen sink (experimentatl) */
242 	kDNSServiceType_OPT = 41, /* EDNS0 option (meta-RR) */
243 	kDNSServiceType_TKEY = 249, /* Transaction key */
244 	kDNSServiceType_TSIG = 250, /* Transaction signature. */
245 	kDNSServiceType_IXFR = 251, /* Incremental zone transfer. */
246 	kDNSServiceType_AXFR = 252, /* Transfer zone of authority. */
247 	kDNSServiceType_MAILB = 253, /* Transfer mailbox records. */
248 	kDNSServiceType_MAILA = 254, /* Transfer mail agent records. */
249 	kDNSServiceType_ANY = 255 /* Wildcard match. */
250 };
251 
252 
253 
254 /* possible error code values */
255 enum
256 {
257 	kDNSServiceErr_NoError = 		0,
258 	kDNSServiceErr_Unknown = 		-65537, /* 0xFFFE FFFF */
259 	kDNSServiceErr_NoSuchName = 	-65538,
260 	kDNSServiceErr_NoMemory =		-65539,
261 	kDNSServiceErr_BadParam =		-65540,
262 	kDNSServiceErr_BadReference =	-65541,
263 	kDNSServiceErr_BadState =		-65542,
264 	kDNSServiceErr_BadFlags =		-65543,
265 	kDNSServiceErr_Unsupported =	-65544,
266 	kDNSServiceErr_NotInitialized =	-65545,
267 	kDNSServiceErr_AlreadyRegistered =-65547,
268 	kDNSServiceErr_NameConflict =	-65548,
269 	kDNSServiceErr_Invalid =		-65549,
270 	kDNSServiceErr_Firewall =		-65550,
271 	kDNSServiceErr_Incompatible = 	-65551, /* client library incompatible with daemon */
272 	kDNSServiceErr_BadInterfaceIndex =-65552,
273 	kDNSServiceErr_Refused =		-65553,
274 	kDNSServiceErr_NoSuchRecord =	-65554,
275 	kDNSServiceErr_NoAuth =			-65555,
276 	kDNSServiceErr_NoSuchKey =		-65556,
277 	kDNSServiceErr_NATTraversal =	-65557,
278 	kDNSServiceErr_DoubleNAT =		-65558,
279 	kDNSServiceErr_BadTime =		-65559
280 	/* mDNS Error codes are in the range
281 	* FFFE FF00 (-65792) to FFFE FFFF (-65537) */
282 	};
283 
284 
285 
286 /* Maximum length, in bytes, of a service name represented as a */
287 /* literal C-String, including the terminating NULL at the end. */
288 
289 #define kDNSServiceMaxServiceName 64
290 
291 /* Maximum length, in bytes, of a domain name represented as an *escaped* C-String */
292 /* including the final trailing dot, and the C-String terminating NULL at the end. */
293 
294 #define kDNSServiceMaxDomainName 1005
295 
296 /*
297  * Notes on DNS Name Escaping
298  *   -- or --
299  * "Why is kDNSServiceMaxDomainName 1005, when the maximum legal domain name is 255 bytes?"
300  *
301  * All strings used in DNS-SD are UTF-8 strings.
302  * With few exceptions, most are also escaped using standard DNS escaping rules:
303  *
304  *   '\\' represents a single literal '\' in the name
305  *   '\.' represents a single literal '.' in the name
306  *   '\ddd', where ddd is a three-digit decimal value from 000 to 255,
307  *        represents a single literal byte with that value.
308  *   A bare unescaped '.' is a label separator, marking a boundary between domain and subdomain.
309  *
310  * The exceptions, that do not use escaping, are the routines where the full
311  * DNS name of a resource is broken, for convenience, into servicename/regtype/domain.
312  * In these routines, the "servicename" is NOT escaped. It does not need to be, since
313  * it is, by definition, just a single literal string. Any characters in that string
314  * represent exactly what they are. The "regtype" portion is, technically speaking,
315  * escaped, but since legal regtypes are only allowed to contain letters, digits,
316  * and hyphens, there is nothing to escape, so the issue is moot. The "domain"
317  * portion is also escaped, though most domains in use on the public Internet
318  * today, like regtypes, don't contain any characters that need to be escaped.
319  * As DNS-SD becomes more popular, rich-text domains for service discovery will
320  * become common, so software should be written to cope with domains with escaping.
321  *
322  * The servicename may be up to 63 bytes of UTF-8 text (not counting the C-String
323  * terminating NULL at the end). The regtype is of the form _service._tcp or
324  * _service._udp, where the "service" part is 1-14 characters, which may be
325  * letters, digits, or hyphens. The domain part of the three-part name may be
326  * any legal domain, providing that the resulting servicename+regtype+domain
327  * name does not exceed 255 bytes.
328  *
329  * For most software, these issues are transparent. When browsing, the discovered
330  * servicenames should simply be displayed as-is. When resolving, the discovered
331  * servicename/regtype/domain are simply passed unchanged to DNSServiceResolve().
332  * When a DNSServiceResolve() succeeds, the returned fullname is already in
333  * the correct format to pass to standard system DNS APIs such as res_query().
334  * For converting from servicename/regtype/domain to a single properly-escaped
335  * full DNS name, the helper function DNSServiceConstructFullName() is provided.
336  *
337  * The following (highly contrived) example illustrates the escaping process.
338  * Suppose you have an service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
339  * in subdomain "4th. Floor" of subdomain "Building 2" of domain "apple.com."
340  * The full (escaped) DNS name of this service's SRV record would be:
341  * Dr\.\032Smith\\Dr\.\032Johnson._ftp._tcp.4th\.\032Floor.Building\0322.apple.com.
342  */
343 
344 
345 /*
346  * Constants for specifying an interface index
347  *
348  * Specific interface indexes are identified via a 32-bit unsigned integer returned
349  * by the if_nametoindex() family of calls.
350  *
351  * If the client passes 0 for interface index, that means "do the right thing",
352  * which (at present) means, "if the name is in an mDNS local multicast domain
353  * (e.g. 'local.', '254.169.in-addr.arpa.', '0.8.E.F.ip6.arpa.') then multicast
354  * on all applicable interfaces, otherwise send via unicast to the appropriate
355  * DNS server." Normally, most clients will use 0 for interface index to
356  * automatically get the default sensible behaviour.
357  *
358  * If the client passes a positive interface index, then for multicast names that
359  * indicates to do the operation only on that one interface. For unicast names the
360  * interface index is ignored unless kDNSServiceFlagsForceMulticast is also set.
361  *
362  * If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
363  * a service, then that service will be found *only* by other local clients
364  * on the same machine that are browsing using kDNSServiceInterfaceIndexLocalOnly
365  * or kDNSServiceInterfaceIndexAny.
366  * If a client has a 'private' service, accessible only to other processes
367  * running on the same machine, this allows the client to advertise that service
368  * in a way such that it does not inadvertently appear in service lists on
369  * all the other machines on the network.
370  *
371  * If the client passes kDNSServiceInterfaceIndexLocalOnly when browsing
372  * then it will find *all* records registered on that same local machine.
373  * Clients explicitly wishing to discover *only* LocalOnly services can
374  * accomplish this by inspecting the interfaceIndex of each service reported
375  * to their DNSServiceBrowseReply() callback function, and discarding those
376  * where the interface index is not kDNSServiceInterfaceIndexLocalOnly.
377  */
378 
379 #define kDNSServiceInterfaceIndexAny 0
380 #define kDNSServiceInterfaceIndexLocalOnly ( (uint32_t) -1 )
381 
382 
383 typedef uint32_t DNSServiceFlags;
384 
385 typedef int32_t DNSServiceErrorType;
386 
387 
388 
389 /*********************************************************************************************
390  *
391  * Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
392  *
393  *********************************************************************************************/
394 
395 
396 /* DNSServiceRefSockFD()
397  *
398  * Access underlying Unix domain socket for an initialized DNSServiceRef.
399  * The DNS Service Discovery implmementation uses this socket to communicate between
400  * the client and the mDNSResponder daemon.  The application MUST NOT directly read from
401  * or write to this socket.  Access to the socket is provided so that it can be used as a
402  * run loop source, or in a select() loop: when data is available for reading on the socket,
403  * DNSServiceProcessResult() should be called, which will extract the daemon's reply from
404  * the socket, and pass it to the appropriate application callback.  By using a run loop or
405  * select(), results from the daemon can be processed asynchronously.  Without using these
406  * constructs, DNSServiceProcessResult() will block until the response from the daemon arrives.
407  * The client is responsible for ensuring that the data on the socket is processed in a timely
408  * fashion - the daemon may terminate its connection with a client that does not clear its
409  * socket buffer.
410  *
411  * sdRef:            A DNSServiceRef initialized by any of the DNSService calls.
412  *
413  * return value:    The DNSServiceRef's underlying socket descriptor, or -1 on
414  *                  error.
415  */
416 
417 #if ORIGINAL_DNSSD_INCLUDE
418 	int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
419 
420 #else							/*
421  */
422 	typedef int DNSSD_API(*_DNSServiceRefSockFD) (DNSServiceRef sdRef);
423 
424 extern _DNSServiceRefSockFD DNSServiceRefSockFD;
425 
426 #endif							/*
427  */
428 
429 /* DNSServiceProcessResult()
430  *
431  * Read a reply from the daemon, calling the appropriate application callback.  This call will
432  * block until the daemon's response is received.  Use DNSServiceRefSockFD() in
433  * conjunction with a run loop or select() to determine the presence of a response from the
434  * server before calling this function to process the reply without blocking.  Call this function
435  * at any point if it is acceptable to block until the daemon's response arrives.  Note that the
436  * client is responsible for ensuring that DNSServiceProcessResult() is called whenever there is
437  * a reply from the daemon - the daemon may terminate its connection with a client that does not
438  * process the daemon's responses.
439  *
440  * sdRef:           A DNSServiceRef initialized by any of the DNSService calls
441  *                  that take a callback parameter.
442  *
443  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns
444  *                  an error code indicating the specific failure that occurred.
445  */
446 
447 #if ORIGINAL_DNSSD_INCLUDE
448 	 DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
449 
450 #else							/*
451  */
452 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceProcessResult) (DNSServiceRef sdRef);
453 
454 extern _DNSServiceProcessResult DNSServiceProcessResult;
455 
456 #endif							/*
457  */
458 
459 /* DNSServiceRefDeallocate()
460  *
461  * Terminate a connection with the daemon and free memory associated with the DNSServiceRef.
462  * Any services or records registered with this DNSServiceRef will be deregistered. Any
463  * Browse, Resolve, or Query operations called with this reference will be terminated.
464  *
465  * Note: If the reference's underlying socket is used in a run loop or select() call, it should
466  * be removed BEFORE DNSServiceRefDeallocate() is called, as this function closes the reference's
467  * socket.
468  *
469  * Note: If the reference was initialized with DNSServiceCreateConnection(), any DNSRecordRefs
470  * created via this reference will be invalidated by this call - the resource records are
471  * deregistered, and their DNSRecordRefs may not be used in subsequent functions.  Similarly,
472  * if the reference was initialized with DNSServiceRegister, and an extra resource record was
473  * added to the service via DNSServiceAddRecord(), the DNSRecordRef created by the Add() call
474  * is invalidated when this function is called - the DNSRecordRef may not be used in subsequent
475  * functions.
476  *
477  * Note: This call is to be used only with the DNSServiceRef defined by this API.  It is
478  * not compatible with dns_service_discovery_ref objects defined in the legacy Mach-based
479  * DNSServiceDiscovery.h API.
480  *
481  * sdRef:           A DNSServiceRef initialized by any of the DNSService calls.
482  *
483  */
484 
485 #if ORIGINAL_DNSSD_INCLUDE
486 	void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef);
487 
488 #else							/*
489  */
490 	typedef void DNSSD_API(*_DNSServiceRefDeallocate) (DNSServiceRef sdRef);
491 
492 extern _DNSServiceRefDeallocate DNSServiceRefDeallocate;
493 
494 #endif							/*
495  */
496 
497 
498 /*********************************************************************************************
499  *
500  * Domain Enumeration
501  *
502  *********************************************************************************************/
503 
504 /* DNSServiceEnumerateDomains()
505  *
506  * Asynchronously enumerate domains available for browsing and registration.
507  *
508  * The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
509  * are to be found.
510  *
511  * Note that the names returned are (like all of DNS-SD) UTF-8 strings,
512  * and are escaped using standard DNS escaping rules.
513  * (See "Notes on DNS Name Escaping" earlier in this file for more details.)
514  * A graphical browser displaying a hierarchical tree-structured view should cut
515  * the names at the bare dots to yield individual labels, then de-escape each
516  * label according to the escaping rules, and then display the resulting UTF-8 text.
517  *
518  * DNSServiceDomainEnumReply Callback Parameters:
519  *
520  * sdRef:           The DNSServiceRef initialized by DNSServiceEnumerateDomains().
521  *
522  * flags:           Possible values are:
523  *                  kDNSServiceFlagsMoreComing
524  *                  kDNSServiceFlagsAdd
525  *                  kDNSServiceFlagsDefault
526  *
527  * interfaceIndex:  Specifies the interface on which the domain exists.  (The index for a given
528  *                  interface is determined via the if_nametoindex() family of calls.)
529  *
530  * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
531  *                  the failure that occurred (other parameters are undefined if errorCode is nonzero).
532  *
533  * replyDomain:     The name of the domain.
534  *
535  * context:         The context pointer passed to DNSServiceEnumerateDomains.
536  *
537  */
538 
539 typedef void (DNSSD_API * DNSServiceDomainEnumReply)
540 		(
541 		DNSServiceRef sdRef,
542 		DNSServiceFlags flags,
543 		uint32_t interfaceIndex,
544 		DNSServiceErrorType errorCode,
545 		const char *replyDomain,
546 		void *context
547 		);
548 
549 
550 
551 /* DNSServiceEnumerateDomains() Parameters:
552  *
553  *
554  * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds
555  *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
556  *                  and the enumeration operation will run indefinitely until the client
557  *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
558  *
559  * flags:           Possible values are:
560  *                  kDNSServiceFlagsBrowseDomains to enumerate domains recommended for browsing.
561  *                  kDNSServiceFlagsRegistrationDomains to enumerate domains recommended
562  *                  for registration.
563  *
564  * interfaceIndex:  If non-zero, specifies the interface on which to look for domains.
565  *                  (the index for a given interface is determined via the if_nametoindex()
566  *                  family of calls.)  Most applications will pass 0 to enumerate domains on
567  *                  all interfaces. See "Constants for specifying an interface index" for more details.
568  *
569  * callBack:        The function to be called when a domain is found or the call asynchronously
570  *                  fails.
571  *
572  * context:         An application context pointer which is passed to the callback function
573  *                  (may be NULL).
574  *
575  * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
576  *                  errors are delivered to the callback), otherwise returns an error code indicating
577  *                  the error that occurred (the callback is not invoked and the DNSServiceRef
578  *                  is not initialized.)
579  */
580 
581 #if ORIGINAL_DNSSD_INCLUDE
582 	DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
583 		(
584 		DNSServiceRef * sdRef,
585 		DNSServiceFlags flags,
586 
587 		uint32_t interfaceIndex,
588 		DNSServiceDomainEnumReply callBack,
589 		void *context /* may be NULL */
590 		);
591 
592 #else							/*
593  */
594 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceEnumerateDomains)
595 		(
596 		DNSServiceRef * sdRef,
597 		DNSServiceFlags flags,
598 		uint32_t interfaceIndex,
599 		DNSServiceDomainEnumReply callBack,
600 		void *context /* may be NULL */
601 		);
602 
603 extern _DNSServiceEnumerateDomains DNSServiceEnumerateDomains;
604 
605 #endif							/*
606  */
607 
608 /*********************************************************************************************
609  *
610  *  Service Registration
611  *
612  *********************************************************************************************/
613 
614 /* Register a service that is discovered via Browse() and Resolve() calls.
615  *
616  *
617  * DNSServiceRegisterReply() Callback Parameters:
618  *
619  * sdRef:           The DNSServiceRef initialized by DNSServiceRegister().
620  *
621  * flags:           Currently unused, reserved for future use.
622  *
623  * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
624  *                  indicate the failure that occurred (including name conflicts,
625  *                  if the kDNSServiceFlagsNoAutoRename flag was used when registering.)
626  *                  Other parameters are undefined if errorCode is nonzero.
627  *
628  * name:            The service name registered (if the application did not specify a name in
629  *                  DNSServiceRegister(), this indicates what name was automatically chosen).
630  *
631  * regtype:         The type of service registered, as it was passed to the callout.
632  *
633  * domain:          The domain on which the service was registered (if the application did not
634  *                  specify a domain in DNSServiceRegister(), this indicates the default domain
635  *                  on which the service was registered).
636  *
637  * context:         The context pointer that was passed to the callout.
638  *
639  */
640 
641 typedef void (DNSSD_API * DNSServiceRegisterReply)
642 		(
643 		DNSServiceRef sdRef,
644 		DNSServiceFlags flags,
645 		DNSServiceErrorType errorCode,
646 		const char *name,
647 		const char *regtype,
648 		const char *domain,
649 		void *context
650 		);
651 
652 
653 
654 /* DNSServiceRegister()  Parameters:
655  *
656  * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds
657  *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
658  *                  and the registration will remain active indefinitely until the client
659  *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
660  *
661  * interfaceIndex:  If non-zero, specifies the interface on which to register the service
662  *                  (the index for a given interface is determined via the if_nametoindex()
663  *                  family of calls.)  Most applications will pass 0 to register on all
664  *                  available interfaces. See "Constants for specifying an interface index" for more details.
665  *
666  * flags:           Indicates the renaming behavior on name conflict (most applications
667  *                  will pass 0).  See flag definitions above for details.
668  *
669  * name:            If non-NULL, specifies the service name to be registered.
670  *                  Most applications will not specify a name, in which case the computer
671  *                  name is used (this name is communicated to the client via the callback).
672  *                  If a name is specified, it must be 1-63 bytes of UTF-8 text.
673  *                  If the name is longer than 63 bytes it will be automatically truncated
674  *                  to a legal length, unless the NoAutoRename flag is set,
675  *                  in which case kDNSServiceErr_BadParam will be returned.
676  *
677  * regtype:         The service type followed by the protocol, separated by a dot
678  *                  (e.g. "_ftp._tcp"). The service type must be an underscore, followed
679  *                  by 1-14 characters, which may be letters, digits, or hyphens.
680  *                  The transport protocol must be "_tcp" or "_udp". New service types
681  *                  should be registered at <http://www.dns-sd.org/ServiceTypes.html>.
682  *
683  * domain:          If non-NULL, specifies the domain on which to advertise the service.
684  *                  Most applications will not specify a domain, instead automatically
685  *                  registering in the default domain(s).
686  *
687  * host:            If non-NULL, specifies the SRV target host name.  Most applications
688  *                  will not specify a host, instead automatically using the machine's
689  *                  default host name(s).  Note that specifying a non-NULL host does NOT
690  *                  create an address record for that host - the application is responsible
691  *                  for ensuring that the appropriate address record exists, or creating it
692  *                  via DNSServiceRegisterRecord().
693  *
694  * port:            The port, in network byte order, on which the service accepts connections.
695  *                  Pass 0 for a "placeholder" service (i.e. a service that will not be discovered
696  *                  by browsing, but will cause a name conflict if another client tries to
697  *                  register that same name).  Most clients will not use placeholder services.
698  *
699  * txtLen:          The length of the txtRecord, in bytes.  Must be zero if the txtRecord is NULL.
700  *
701  * txtRecord:       The TXT record rdata. A non-NULL txtRecord MUST be a properly formatted DNS
702  *                  TXT record, i.e. <length byte> <data> <length byte> <data> ...
703  *                  Passing NULL for the txtRecord is allowed as a synonym for txtLen=1, txtRecord="",
704  *                  i.e. it creates a TXT record of length one containing a single empty string.
705  *                  RFC 1035 doesn't allow a TXT record to contain *zero* strings, so a single empty
706  *                  string is the smallest legal DNS TXT record.
707  *
708  * callBack:        The function to be called when the registration completes or asynchronously
709  *                  fails.  The client MAY pass NULL for the callback -  The client will NOT be notified
710  *                  of the default values picked on its behalf, and the client will NOT be notified of any
711  *                  asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
712  *                  of the service.  The client may NOT pass the NoAutoRename flag if the callback is NULL.
713  *                  The client may still deregister the service at any time via DNSServiceRefDeallocate().
714  *
715  * context:         An application context pointer which is passed to the callback function
716  *                  (may be NULL).
717  *
718  * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
719  *                  errors are delivered to the callback), otherwise returns an error code indicating
720  *                  the error that occurred (the callback is never invoked and the DNSServiceRef
721  *                  is not initialized.)
722  *
723  */
724 
725 #if ORIGINAL_DNSSD_INCLUDE
726 	DNSServiceErrorType DNSSD_API DNSServiceRegister
727 		(
728 		DNSServiceRef * sdRef,
729 		DNSServiceFlags flags,
730 		uint32_t interfaceIndex,
731 		const char *name, /* may be NULL */
732 		const char *regtype,
733 		const char *domain, /* may be NULL */
734 		const char *host, /* may be NULL */
735 		uint16_t port,
736 		uint16_t txtLen,
737 		const void *txtRecord, /* may be NULL */
738 		DNSServiceRegisterReply callBack, /* may be NULL */
739 		void *context /* may be NULL */
740 		);
741 
742 #else							/*
743  */
744 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceRegister)
745 		(
746 		DNSServiceRef * sdRef,
747 		DNSServiceFlags flags,
748 		uint32_t interfaceIndex,
749 		const char *name, /* may be NULL */
750 		const char *regtype,
751 		const char *domain, /* may be NULL */
752 		const char *host, /* may be NULL */
753 		uint16_t port,
754 		uint16_t txtLen,
755 		const void *txtRecord, /* may be NULL */
756 		DNSServiceRegisterReply callBack, /* may be NULL */
757 		void *context /* may be NULL */
758 		);
759 
760 extern _DNSServiceRegister DNSServiceRegister;
761 
762 #endif							/*
763  */
764 
765 /* DNSServiceAddRecord()
766  *
767  * Add a record to a registered service.  The name of the record will be the same as the
768  * registered service's name.
769  * The record can later be updated or deregistered by passing the RecordRef initialized
770  * by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
771  *
772  *
773  * Parameters;
774  *
775  * sdRef:           A DNSServiceRef initialized by DNSServiceRegister().
776  *
777  * RecordRef:       A pointer to an uninitialized DNSRecordRef.  Upon succesfull completion of this
778  *                  call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
779  *                  If the above DNSServiceRef is passed to DNSServiceRefDeallocate(), RecordRef is also
780  *                  invalidated and may not be used further.
781  *
782  * flags:           Currently ignored, reserved for future use.
783  *
784  * rrtype:          The type of the record (e.g. kDNSServiceType_TXT, kDNSServiceType_SRV, etc)
785  *
786  * rdlen:           The length, in bytes, of the rdata.
787  *
788  * rdata:           The raw rdata to be contained in the added resource record.
789  *
790  * ttl:             The time to live of the resource record, in seconds.  Pass 0 to use a default value.
791  *
792  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
793  *                  error code indicating the error that occurred (the RecordRef is not initialized).
794  */
795 
796 #if ORIGINAL_DNSSD_INCLUDE
797 	 DNSServiceErrorType DNSSD_API DNSServiceAddRecord
798 		(
799 		DNSServiceRef sdRef,
800 		DNSRecordRef * RecordRef,
801 		DNSServiceFlags flags,
802 		uint16_t rrtype,
803 		uint16_t rdlen,
804 		const void *rdata,
805 		uint32_t ttl
806 		);
807 
808 #else							/*
809  */
810 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceAddRecord)
811 		(
812 		DNSServiceRef sdRef,
813 		DNSRecordRef * RecordRef,
814 		DNSServiceFlags flags,
815 		uint16_t rrtype,
816 		uint16_t rdlen,
817 		const void *rdata,
818 		uint32_t ttl
819 		);
820 
821 extern _DNSServiceAddRecord DNSServiceAddRecord;
822 
823 #endif							/*
824  */
825 
826 /* DNSServiceUpdateRecord
827  *
828  * Update a registered resource record.  The record must either be:
829  *   - The primary txt record of a service registered via DNSServiceRegister()
830  *   - A record added to a registered service via DNSServiceAddRecord()
831  *   - An individual record registered by DNSServiceRegisterRecord()
832  *
833  *
834  * Parameters:
835  *
836  * sdRef:           A DNSServiceRef that was initialized by DNSServiceRegister()
837  *                  or DNSServiceCreateConnection().
838  *
839  * RecordRef:       A DNSRecordRef initialized by DNSServiceAddRecord, or NULL to update the
840  *                  service's primary txt record.
841  *
842  * flags:           Currently ignored, reserved for future use.
843  *
844  * rdlen:           The length, in bytes, of the new rdata.
845  *
846  * rdata:           The new rdata to be contained in the updated resource record.
847  *
848  * ttl:             The time to live of the updated resource record, in seconds.
849  *
850  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
851  *                  error code indicating the error that occurred.
852  */
853 
854 #if ORIGINAL_DNSSD_INCLUDE
855 	 DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
856 		(
857 		DNSServiceRef sdRef,
858 		DNSRecordRef RecordRef, /* may be NULL */
859 		DNSServiceFlags flags,
860 		uint16_t rdlen,
861 		const void *rdata,
862 		uint32_t ttl
863 		);
864 
865 #else							/*
866  */
867 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceUpdateRecord)
868 		(
869 		DNSServiceRef sdRef,
870 		DNSRecordRef RecordRef, /* may be NULL */
871 		DNSServiceFlags flags,
872 		uint16_t rdlen,
873 		const void *rdata,
874 		uint32_t ttl
875 		);
876 
877 extern _DNSServiceUpdateRecord DNSServiceUpdateRecord;
878 
879 #endif							/*
880  */
881 
882 /* DNSServiceRemoveRecord
883  *
884  * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
885  * an record registered individually via DNSServiceRegisterRecord().
886  *
887  * Parameters:
888  *
889  * sdRef:           A DNSServiceRef initialized by DNSServiceRegister() (if the
890  *                  record being removed was registered via DNSServiceAddRecord()) or by
891  *                  DNSServiceCreateConnection() (if the record being removed was registered via
892  *                  DNSServiceRegisterRecord()).
893  *
894  * recordRef:       A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
895  *                  or DNSServiceRegisterRecord().
896  *
897  * flags:           Currently ignored, reserved for future use.
898  *
899  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
900  *                  error code indicating the error that occurred.
901  */
902 
903 #if ORIGINAL_DNSSD_INCLUDE
904 	 DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
905 		(
906 		DNSServiceRef sdRef,
907 		DNSRecordRef RecordRef,
908 		DNSServiceFlags flags
909 		);
910 
911 #else							/*
912  */
913 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceRemoveRecord)
914 		(
915 		DNSServiceRef sdRef,
916 		DNSRecordRef RecordRef,
917 		DNSServiceFlags flags
918 		);
919 
920 extern _DNSServiceRemoveRecord DNSServiceRemoveRecord;
921 
922 #endif							/*
923  */
924 
925 
926 /*********************************************************************************************
927  *
928  *  Service Discovery
929  *
930  *********************************************************************************************/
931 
932 /* Browse for instances of a service.
933  *
934  *
935  * DNSServiceBrowseReply() Parameters:
936  *
937  * sdRef:           The DNSServiceRef initialized by DNSServiceBrowse().
938  *
939  * flags:           Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd.
940  *                  See flag definitions for details.
941  *
942  * interfaceIndex:  The interface on which the service is advertised.  This index should
943  *                  be passed to DNSServiceResolve() when resolving the service.
944  *
945  * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise will
946  *                  indicate the failure that occurred.  Other parameters are undefined if
947  *                  the errorCode is nonzero.
948  *
949  * serviceName:     The discovered service name. This name should be displayed to the user,
950  *                  and stored for subsequent use in the DNSServiceResolve() call.
951  *
952  * regtype:         The service type, which is usually (but not always) the same as was passed
953  *                  to DNSServiceBrowse(). One case where the discovered service type may
954  *                  not be the same as the requested service type is when using subtypes:
955  *                  The client may want to browse for only those ftp servers that allow
956  *                  anonymous connections. The client will pass the string "_ftp._tcp,_anon"
957  *                  to DNSServiceBrowse(), but the type of the service that's discovered
958  *                  is simply "_ftp._tcp". The regtype for each discovered service instance
959  *                  should be stored along with the name, so that it can be passed to
960  *                  DNSServiceResolve() when the service is later resolved.
961  *
962  * domain:          The domain of the discovered service instance. This may or may not be the
963  *                  same as the domain that was passed to DNSServiceBrowse(). The domain for each
964  *                  discovered service instance should be stored along with the name, so that
965  *                  it can be passed to DNSServiceResolve() when the service is later resolved.
966  *
967  * context:         The context pointer that was passed to the callout.
968  *
969  */
970 
971 typedef void (DNSSD_API * DNSServiceBrowseReply)
972 		(
973 		DNSServiceRef sdRef,
974 		DNSServiceFlags flags,
975 		uint32_t interfaceIndex,
976 		DNSServiceErrorType errorCode,
977 		const char *serviceName,
978 		const char *regtype,
979 		const char *replyDomain,
980 		void *context
981 		);
982 
983 
984 
985 /* DNSServiceBrowse() Parameters:
986  *
987  * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds
988  *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
989  *                  and the browse operation will run indefinitely until the client
990  *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
991  *
992  * flags:           Currently ignored, reserved for future use.
993  *
994  * interfaceIndex:  If non-zero, specifies the interface on which to browse for services
995  *                  (the index for a given interface is determined via the if_nametoindex()
996  *                  family of calls.)  Most applications will pass 0 to browse on all available
997  *                  interfaces. See "Constants for specifying an interface index" for more details.
998  *
999  * regtype:         The service type being browsed for followed by the protocol, separated by a
1000  *                  dot (e.g. "_ftp._tcp").  The transport protocol must be "_tcp" or "_udp".
1001  *
1002  * domain:          If non-NULL, specifies the domain on which to browse for services.
1003  *                  Most applications will not specify a domain, instead browsing on the
1004  *                  default domain(s).
1005  *
1006  * callBack:        The function to be called when an instance of the service being browsed for
1007  *                  is found, or if the call asynchronously fails.
1008  *
1009  * context:         An application context pointer which is passed to the callback function
1010  *                  (may be NULL).
1011  *
1012  * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
1013  *                  errors are delivered to the callback), otherwise returns an error code indicating
1014  *                  the error that occurred (the callback is not invoked and the DNSServiceRef
1015  *                  is not initialized.)
1016  */
1017 
1018 #if ORIGINAL_DNSSD_INCLUDE
1019 	 DNSServiceErrorType DNSSD_API DNSServiceBrowse
1020 		(
1021 		DNSServiceRef * sdRef,
1022 		DNSServiceFlags flags,
1023 		uint32_t interfaceIndex,
1024 		const char *regtype,
1025 		const char *domain, /* may be NULL */
1026 		DNSServiceBrowseReply callBack,
1027 		void *context /* may be NULL */
1028 		);
1029 
1030 #else							/*
1031  */
1032 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceBrowse)
1033 		(
1034 		DNSServiceRef * sdRef,
1035 		DNSServiceFlags flags,
1036 		uint32_t interfaceIndex,
1037 		const char *regtype,
1038 		const char *domain, /* may be NULL */
1039 		DNSServiceBrowseReply callBack,
1040 		void *context /* may be NULL */
1041 		);
1042 
1043 extern _DNSServiceBrowse DNSServiceBrowse;
1044 
1045 #endif							/*
1046  */
1047 
1048 /* DNSServiceResolve()
1049  *
1050  * Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and
1051  * txt record.
1052  *
1053  * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
1054  * DNSServiceQueryRecord() instead, as it is more efficient for this task.
1055  *
1056  * Note: When the desired results have been returned, the client MUST terminate the resolve by calling
1057  * DNSServiceRefDeallocate().
1058  *
1059  * Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record
1060  * and a single TXT record. To resolve non-standard services with multiple SRV or TXT records,
1061  * DNSServiceQueryRecord() should be used.
1062  *
1063  * DNSServiceResolveReply Callback Parameters:
1064  *
1065  * sdRef:           The DNSServiceRef initialized by DNSServiceResolve().
1066  *
1067  * flags:           Currently unused, reserved for future use.
1068  *
1069  * interfaceIndex:  The interface on which the service was resolved.
1070  *
1071  * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise will
1072  *                  indicate the failure that occurred.  Other parameters are undefined if
1073  *                  the errorCode is nonzero.
1074  *
1075  * fullname:        The full service domain name, in the form <servicename>.<protocol>.<domain>.
1076  *                  (This name is escaped following standard DNS rules, making it suitable for
1077  *                  passing to standard system DNS APIs such as res_query(), or to the
1078  *                  special-purpose functions included in this API that take fullname parameters.
1079  *                  See "Notes on DNS Name Escaping" earlier in this file for more details.)
1080  *
1081  * hosttarget:      The target hostname of the machine providing the service.  This name can
1082  *                  be passed to functions like gethostbyname() to identify the host's IP address.
1083  *
1084  * port:            The port, in network byte order, on which connections are accepted for this service.
1085  *
1086  * txtLen:          The length of the txt record, in bytes.
1087  *
1088  * txtRecord:       The service's primary txt record, in standard txt record format.
1089  *
1090 
1091  * context:         The context pointer that was passed to the callout.
1092  *
1093  */
1094 
1095 typedef void (DNSSD_API * DNSServiceResolveReply)
1096 		(
1097 		DNSServiceRef sdRef,
1098 		DNSServiceFlags flags,
1099 		uint32_t interfaceIndex,
1100 		DNSServiceErrorType errorCode,
1101 		const char *fullname,
1102 		const char *hosttarget,
1103 		uint16_t port,
1104 		uint16_t txtLen,
1105 		const unsigned char *txtRecord,
1106 		void *context
1107 		);
1108 
1109 
1110 
1111 /* DNSServiceResolve() Parameters
1112  *
1113  * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds
1114  *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
1115  *                  and the resolve operation will run indefinitely until the client
1116  *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
1117  *
1118  * flags:           Currently ignored, reserved for future use.
1119  *
1120  * interfaceIndex:  The interface on which to resolve the service. If this resolve call is
1121  *                  as a result of a currently active DNSServiceBrowse() operation, then the
1122  *                  interfaceIndex should be the index reported in the DNSServiceBrowseReply
1123  *                  callback. If this resolve call is using information previously saved
1124  *                  (e.g. in a preference file) for later use, then use interfaceIndex 0, because
1125  *                  the desired service may now be reachable via a different physical interface.
1126  *                  See "Constants for specifying an interface index" for more details.
1127  *
1128  * name:            The name of the service instance to be resolved, as reported to the
1129  *                  DNSServiceBrowseReply() callback.
1130  *
1131  * regtype:         The type of the service instance to be resolved, as reported to the
1132  *                  DNSServiceBrowseReply() callback.
1133  *
1134  * domain:          The domain of the service instance to be resolved, as reported to the
1135  *                  DNSServiceBrowseReply() callback.
1136  *
1137  * callBack:        The function to be called when a result is found, or if the call
1138  *                  asynchronously fails.
1139  *
1140  * context:         An application context pointer which is passed to the callback function
1141  *                  (may be NULL).
1142  *
1143  * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
1144  *                  errors are delivered to the callback), otherwise returns an error code indicating
1145  *                  the error that occurred (the callback is never invoked and the DNSServiceRef
1146  *                  is not initialized.)
1147  */
1148 
1149 #if ORIGINAL_DNSSD_INCLUDE
1150 	 DNSServiceErrorType DNSSD_API DNSServiceResolve
1151 		(
1152 		DNSServiceRef * sdRef,
1153 		DNSServiceFlags flags,
1154 
1155 		uint32_t interfaceIndex,
1156 		const char *name,
1157 		const char *regtype,
1158 
1159 		const char *domain,
1160 		DNSServiceResolveReply callBack,
1161 		void *context /* may be NULL */
1162 		);
1163 
1164 #else							/*
1165  */
1166 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceResolve)
1167 		(
1168 		DNSServiceRef * sdRef,
1169 		DNSServiceFlags flags,
1170 		uint32_t interfaceIndex,
1171 		const char *name,
1172 		const char *regtype,
1173 		const char *domain,
1174 		DNSServiceResolveReply callBack,
1175 		void *context /* may be NULL */
1176 		);
1177 
1178 extern _DNSServiceResolve DNSServiceResolve;
1179 
1180 #endif							/*
1181  */
1182 
1183 
1184 /*********************************************************************************************
1185  *
1186  *  Special Purpose Calls (most applications will not use these)
1187  *
1188  *********************************************************************************************/
1189 
1190 /* DNSServiceCreateConnection()
1191  *
1192  * Create a connection to the daemon allowing efficient registration of
1193  * multiple individual records.
1194  *
1195  *
1196  * Parameters:
1197  *
1198  * sdRef:           A pointer to an uninitialized DNSServiceRef.  Deallocating
1199  *                  the reference (via DNSServiceRefDeallocate()) severs the
1200  *                  connection and deregisters all records registered on this connection.
1201  *
1202  * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns
1203  *                  an error code indicating the specific failure that occurred (in which
1204  *                  case the DNSServiceRef is not initialized).
1205  */
1206 
1207 #if ORIGINAL_DNSSD_INCLUDE
1208 	 DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef * sdRef);
1209 
1210 #else							/*
1211  */
1212 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceCreateConnection) (DNSServiceRef * sdRef);
1213 
1214 extern _DNSServiceCreateConnection DNSServiceCreateConnection;
1215 
1216 #endif							/*
1217  */
1218 
1219 
1220 /* DNSServiceRegisterRecord
1221  *
1222  * Register an individual resource record on a connected DNSServiceRef.
1223  *
1224  * Note that name conflicts occurring for records registered via this call must be handled
1225  * by the client in the callback.
1226  *
1227  *
1228  * DNSServiceRegisterRecordReply() parameters:
1229  *
1230  * sdRef:           The connected DNSServiceRef initialized by
1231  *                  DNSServiceDiscoveryConnect().
1232  *
1233  * RecordRef:       The DNSRecordRef initialized by DNSServiceRegisterRecord().  If the above
1234  *                  DNSServiceRef is passed to DNSServiceRefDeallocate(), this DNSRecordRef is
1235  *                  invalidated, and may not be used further.
1236  *
1237  * flags:           Currently unused, reserved for future use.
1238  *
1239  * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
1240  *                  indicate the failure that occurred (including name conflicts.)
1241  *                  Other parameters are undefined if errorCode is nonzero.
1242  *
1243  * context:         The context pointer that was passed to the callout.
1244  *
1245  */
1246 
1247 typedef void (DNSSD_API * DNSServiceRegisterRecordReply)
1248 		(
1249 		DNSServiceRef sdRef,
1250 		DNSRecordRef RecordRef,
1251 		DNSServiceFlags flags,
1252 		DNSServiceErrorType errorCode,
1253 		void *context
1254 		);
1255 
1256 
1257 
1258 /* DNSServiceRegisterRecord() Parameters:
1259  *
1260  * sdRef:           A DNSServiceRef initialized by DNSServiceCreateConnection().
1261  *
1262  * RecordRef:       A pointer to an uninitialized DNSRecordRef.  Upon succesfull completion of this
1263  *                  call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
1264  *                  (To deregister ALL records registered on a single connected DNSServiceRef
1265  *                  and deallocate each of their corresponding DNSServiceRecordRefs, call
1266  *                  DNSServiceRefDealloocate()).
1267  *
1268  * flags:           Possible values are kDNSServiceFlagsShared or kDNSServiceFlagsUnique
1269  *                  (see flag type definitions for details).
1270  *
1271  * interfaceIndex:  If non-zero, specifies the interface on which to register the record
1272  *                  (the index for a given interface is determined via the if_nametoindex()
1273  *                  family of calls.)  Passing 0 causes the record to be registered on all interfaces.
1274  *                  See "Constants for specifying an interface index" for more details.
1275  *
1276  * fullname:        The full domain name of the resource record.
1277  *
1278  * rrtype:          The numerical type of the resource record (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
1279  *
1280  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN)
1281  *
1282  * rdlen:           Length, in bytes, of the rdata.
1283  *
1284  * rdata:           A pointer to the raw rdata, as it is to appear in the DNS record.
1285  *
1286  * ttl:             The time to live of the resource record, in seconds.  Pass 0 to use a default value.
1287  *
1288  * callBack:        The function to be called when a result is found, or if the call
1289  *                  asynchronously fails (e.g. because of a name conflict.)
1290  *
1291  * context:         An application context pointer which is passed to the callback function
1292  *                  (may be NULL).
1293  *
1294  * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
1295  *                  errors are delivered to the callback), otherwise returns an error code indicating
1296  *                  the error that occurred (the callback is never invoked and the DNSRecordRef is
1297  *                  not initialized.)
1298  */
1299 
1300 #if ORIGINAL_DNSSD_INCLUDE
1301 	 DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
1302 		(
1303 		DNSServiceRef sdRef,
1304 		DNSRecordRef * RecordRef,
1305 
1306 		DNSServiceFlags flags,
1307 		uint32_t interfaceIndex,
1308 
1309 		const char *fullname,
1310 		uint16_t rrtype,
1311 		uint16_t rrclass,
1312 
1313 		uint16_t rdlen,
1314 		const void *rdata,
1315 		uint32_t ttl,
1316 		DNSServiceRegisterRecordReply callBack,
1317 		void *context /* may be NULL */
1318 		);
1319 
1320 #else							/*
1321  */
1322 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceRegisterRecord)
1323 		(
1324 		DNSServiceRef sdRef,
1325 		DNSRecordRef * RecordRef,
1326 		DNSServiceFlags flags,
1327 		uint32_t interfaceIndex,
1328 		const char *fullname,
1329 		uint16_t rrtype,
1330 		uint16_t rrclass,
1331 
1332 		uint16_t rdlen,
1333 		const void *rdata,
1334 		uint32_t ttl,
1335 		DNSServiceRegisterRecordReply callBack,
1336 		void *context /* may be NULL */
1337 		);
1338 
1339 extern _DNSServiceRegisterRecord DNSServiceRegisterRecord;
1340 
1341 #endif							/*
1342  */
1343 
1344 
1345 /* DNSServiceQueryRecord
1346  *
1347  * Query for an arbitrary DNS record.
1348  *
1349  *
1350  * DNSServiceQueryRecordReply() Callback Parameters:
1351  *
1352  * sdRef:           The DNSServiceRef initialized by DNSServiceQueryRecord().
1353  *
1354  * flags:           Possible values are kDNSServiceFlagsMoreComing and
1355  *                  kDNSServiceFlagsAdd.  The Add flag is NOT set for PTR records
1356  *                  with a ttl of 0, i.e. "Remove" events.
1357  *
1358  * interfaceIndex:  The interface on which the query was resolved (the index for a given
1359  *                  interface is determined via the if_nametoindex() family of calls).
1360  *                  See "Constants for specifying an interface index" for more details.
1361  *
1362  * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
1363  *                  indicate the failure that occurred.  Other parameters are undefined if
1364  *                  errorCode is nonzero.
1365  *
1366  * fullname:        The resource record's full domain name.
1367  *
1368  * rrtype:          The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
1369  *
1370  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
1371  *
1372  * rdlen:           The length, in bytes, of the resource record rdata.
1373  *
1374  * rdata:           The raw rdata of the resource record.
1375  *
1376  * ttl:             The resource record's time to live, in seconds.
1377  *
1378  * context:         The context pointer that was passed to the callout.
1379  *
1380  */
1381 
1382 typedef void (DNSSD_API * DNSServiceQueryRecordReply)
1383 		(
1384 		DNSServiceRef DNSServiceRef_,
1385 		DNSServiceFlags flags,
1386 		uint32_t interfaceIndex,
1387 		DNSServiceErrorType errorCode,
1388 		const char *fullname,
1389 		uint16_t rrtype,
1390 		uint16_t rrclass,
1391 		uint16_t rdlen,
1392 		const void *rdata,
1393 		uint32_t ttl,
1394 		void *context
1395 		);
1396 
1397 
1398 
1399 /* DNSServiceQueryRecord() Parameters:
1400  *
1401  * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds
1402  *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
1403  *                  and the query operation will run indefinitely until the client
1404  *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
1405  *
1406  * flags:           Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast
1407  *                  query in a non-local domain.  Without setting this flag, unicast queries
1408  *                  will be one-shot - that is, only answers available at the time of the call
1409  *                  will be returned.  By setting this flag, answers (including Add and Remove
1410  *                  events) that become available after the initial call is made will generate
1411  *                  callbacks.  This flag has no effect on link-local multicast queries.
1412  *
1413  * interfaceIndex:  If non-zero, specifies the interface on which to issue the query
1414  *                  (the index for a given interface is determined via the if_nametoindex()
1415  *                  family of calls.)  Passing 0 causes the name to be queried for on all
1416  *                  interfaces. See "Constants for specifying an interface index" for more details.
1417  *
1418  * fullname:        The full domain name of the resource record to be queried for.
1419  *
1420  * rrtype:          The numerical type of the resource record to be queried for
1421  *                  (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
1422  *
1423  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
1424  *
1425  * callBack:        The function to be called when a result is found, or if the call
1426  *                  asynchronously fails.
1427  *
1428  * context:         An application context pointer which is passed to the callback function
1429  *                  (may be NULL).
1430  *
1431  * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
1432  *                  errors are delivered to the callback), otherwise returns an error code indicating
1433  *                  the error that occurred (the callback is never invoked and the DNSServiceRef
1434  *                  is not initialized.)
1435  */
1436 
1437 #if ORIGINAL_DNSSD_INCLUDE
1438 	 DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
1439 		(
1440 		DNSServiceRef * sdRef,
1441 		DNSServiceFlags flags,
1442 
1443 		uint32_t interfaceIndex,
1444 		const char *fullname,
1445 		uint16_t rrtype,
1446 
1447 		uint16_t rrclass,
1448 		DNSServiceQueryRecordReply callBack,
1449 		void *context /* may be NULL */
1450 		);
1451 
1452 #else							/*
1453  */
1454 	typedef DNSServiceErrorType DNSSD_API(*_DNSServiceQueryRecord)
1455 		(
1456 		DNSServiceRef * sdRef,
1457 		DNSServiceFlags flags,
1458 		uint32_t interfaceIndex,
1459 		const char *fullname,
1460 		uint16_t rrtype,
1461 		uint16_t rrclass,
1462 		DNSServiceQueryRecordReply callBack,
1463 		void *context /* may be NULL */
1464 		);
1465 
1466 extern _DNSServiceQueryRecord DNSServiceQueryRecord;
1467 
1468 #endif							/*
1469  */
1470 
1471 
1472 /* DNSServiceReconfirmRecord
1473  *
1474  * Instruct the daemon to verify the validity of a resource record that appears to
1475  * be out of date (e.g. because tcp connection to a service's target failed.)
1476  * Causes the record to be flushed from the daemon's cache (as well as all other
1477  * daemons' caches on the network) if the record is determined to be invalid.
1478  *
1479  * Parameters:
1480  *
1481  * flags:           Currently unused, reserved for future use.
1482  *
1483  * interfaceIndex:  If non-zero, specifies the interface of the record in question.
1484  *                  Passing 0 causes all instances of this record to be reconfirmed.
1485  *
1486  * fullname:        The resource record's full domain name.
1487  *
1488  * rrtype:          The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
1489  *
1490  * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
1491  *
1492  * rdlen:           The length, in bytes, of the resource record rdata.
1493  *
1494  * rdata:           The raw rdata of the resource record.
1495  *
1496  */
1497 
1498 #if ORIGINAL_DNSSD_INCLUDE
1499 	void DNSSD_API DNSServiceReconfirmRecord
1500 		(
1501 		DNSServiceFlags flags,
1502 		uint32_t interfaceIndex,
1503 		const char *fullname,
1504 		uint16_t rrtype,
1505 		uint16_t rrclass,
1506 		uint16_t rdlen,
1507 		const void *rdata
1508 		);
1509 
1510 #else							/*
1511  */
1512 	typedef void DNSSD_API(*_DNSServiceReconfirmRecord)
1513 		(
1514 		DNSServiceFlags flags,
1515 		uint32_t interfaceIndex,
1516 		const char *fullname,
1517 		uint16_t rrtype,
1518 		uint16_t rrclass,
1519 		uint16_t rdlen,
1520 		const void *rdata
1521 		);
1522 
1523 extern _DNSServiceReconfirmRecord DNSServiceReconfirmRecord;
1524 
1525 #endif							/*
1526  */
1527 
1528 
1529 /*********************************************************************************************
1530  *
1531  *  General Utility Functions
1532  *
1533  *********************************************************************************************/
1534 
1535 /* DNSServiceConstructFullName()
1536  *
1537  * Concatenate a three-part domain name (as returned by the above callbacks) into a
1538  * properly-escaped full domain name. Note that callbacks in the above functions ALREADY ESCAPE
1539  * strings where necessary.
1540  *
1541  * Parameters:
1542  *
1543  * fullName:        A pointer to a buffer that where the resulting full domain name is to be written.
1544  *                  The buffer must be kDNSServiceMaxDomainName (1005) bytes in length to
1545  *                  accommodate the longest legal domain name without buffer overrun.
1546  *
1547  * service:         The service name - any dots or backslashes must NOT be escaped.
1548  *                  May be NULL (to construct a PTR record name, e.g.
1549  *                  "_ftp._tcp.apple.com.").
1550  *
1551  * regtype:         The service type followed by the protocol, separated by a dot
1552  *                  (e.g. "_ftp._tcp").
1553  *
1554  * domain:          The domain name, e.g. "apple.com.".  Literal dots or backslashes,
1555  *                  if any, must be escaped, e.g. "1st\. Floor.apple.com."
1556  *
1557  * return value:    Returns 0 on success, -1 on error.
1558  *
1559  */
1560 
1561 #if ORIGINAL_DNSSD_INCLUDE
1562 	int DNSSD_API DNSServiceConstructFullName
1563 		(
1564 		char *fullName,
1565 		const char *service, /* may be NULL */
1566 		const char *regtype,
1567 		const char *domain
1568 		);
1569 
1570 #else							/*
1571  */
1572 	typedef int DNSSD_API(*_DNSServiceConstructFullName)
1573 		(
1574 		char *fullName,
1575 		const char *service, /* may be NULL */
1576 		const char *regtype,
1577 		const char *domain
1578 		);
1579 
1580 extern _DNSServiceConstructFullName DNSServiceConstructFullName;
1581 
1582 #endif							/*
1583  */
1584 
1585 
1586 /*********************************************************************************************
1587  *
1588  *   TXT Record Construction Functions
1589  *
1590  *********************************************************************************************/
1591 
1592 /*
1593  * A typical calling sequence for TXT record construction is something like:
1594  *
1595  * Client allocates storage for TXTRecord data (e.g. declare buffer on the stack)
1596  * TXTRecordCreate();
1597  * TXTRecordSetValue();
1598  * TXTRecordSetValue();
1599  * TXTRecordSetValue();
1600  * ...
1601  * DNSServiceRegister( ... TXTRecordGetLength(), TXTRecordGetBytesPtr() ... );
1602  * TXTRecordDeallocate();
1603  * Explicitly deallocate storage for TXTRecord data (if not allocated on the stack)
1604  */
1605 
1606 
1607 /* TXTRecordRef
1608  *
1609  * Opaque internal data type.
1610  * Note: Represents a DNS-SD TXT record.
1611  */
1612 
1613 typedef union _TXTRecordRef_t {
1614 	char PrivateData[16];
1615 	char *ForceNaturalAlignment;
1616 } TXTRecordRef;
1617 
1618 
1619 
1620 /* TXTRecordCreate()
1621  *
1622  * Creates a new empty TXTRecordRef referencing the specified storage.
1623  *
1624  * If the buffer parameter is NULL, or the specified storage size is not
1625  * large enough to hold a key subsequently added using TXTRecordSetValue(),
1626  * then additional memory will be added as needed using malloc().
1627  *
1628  * On some platforms, when memory is low, malloc() may fail. In this
1629  * case, TXTRecordSetValue() will return kDNSServiceErr_NoMemory, and this
1630  * error condition will need to be handled as appropriate by the caller.
1631  *
1632  * You can avoid the need to handle this error condition if you ensure
1633  * that the storage you initially provide is large enough to hold all
1634  * the key/value pairs that are to be added to the record.
1635  * The caller can precompute the exact length required for all of the
1636  * key/value pairs to be added, or simply provide a fixed-sized buffer
1637  * known in advance to be large enough.
1638  * A no-value (key-only) key requires  (1 + key length) bytes.
1639  * A key with empty value requires     (1 + key length + 1) bytes.
1640  * A key with non-empty value requires (1 + key length + 1 + value length).
1641  * For most applications, DNS-SD TXT records are generally
1642  * less than 100 bytes, so in most cases a simple fixed-sized
1643  * 256-byte buffer will be more than sufficient.
1644  * Recommended size limits for DNS-SD TXT Records are discussed in
1645  * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
1646  *
1647  * Note: When passing parameters to and from these TXT record APIs,
1648  * the key name does not include the '=' character. The '=' character
1649  * is the separator between the key and value in the on-the-wire
1650  * packet format; it is not part of either the key or the value.
1651  *
1652  * txtRecord:       A pointer to an uninitialized TXTRecordRef.
1653  *
1654  * bufferLen:       The size of the storage provided in the "buffer" parameter.
1655  *
1656  * buffer:          Optional caller-supplied storage used to hold the TXTRecord data.
1657  *                  This storage must remain valid for as long as
1658  *                  the TXTRecordRef.
1659  */
1660 
1661 void DNSSD_API TXTRecordCreate
1662 		(
1663 		TXTRecordRef * txtRecord,
1664 		uint16_t bufferLen,
1665 		void *buffer
1666 		);
1667 
1668 
1669 
1670 /* TXTRecordDeallocate()
1671  *
1672  * Releases any resources allocated in the course of preparing a TXT Record
1673  * using TXTRecordCreate()/TXTRecordSetValue()/TXTRecordRemoveValue().
1674  * Ownership of the buffer provided in TXTRecordCreate() returns to the client.
1675  *
1676  * txtRecord:           A TXTRecordRef initialized by calling TXTRecordCreate().
1677  *
1678  */
1679 
1680 void DNSSD_API TXTRecordDeallocate
1681 		(
1682 		TXTRecordRef * txtRecord
1683 		);
1684 
1685 
1686 
1687 /* TXTRecordSetValue()
1688  *
1689  * Adds a key (optionally with value) to a TXTRecordRef. If the "key" already
1690  * exists in the TXTRecordRef, then the current value will be replaced with
1691  * the new value.
1692  * Keys may exist in four states with respect to a given TXT record:
1693  *  - Absent (key does not appear at all)
1694  *  - Present with no value ("key" appears alone)
1695  *  - Present with empty value ("key=" appears in TXT record)
1696  *  - Present with non-empty value ("key=value" appears in TXT record)
1697  * For more details refer to "Data Syntax for DNS-SD TXT Records" in
1698  * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
1699  *
1700  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
1701  *
1702  * key:             A null-terminated string which only contains printable ASCII
1703  *                  values (0x20-0x7E), excluding '=' (0x3D). Keys should be
1704  *                  8 characters or less (not counting the terminating null).
1705  *
1706  * valueSize:       The size of the value.
1707  *
1708  * value:           Any binary value. For values that represent
1709  *                  textual data, UTF-8 is STRONGLY recommended.
1710  *                  For values that represent textual data, valueSize
1711  *                  should NOT include the terminating null (if any)
1712  *                  at the end of the string.
1713  *                  If NULL, then "key" will be added with no value.
1714  *                  If non-NULL but valueSize is zero, then "key=" will be
1715  *                  added with empty value.
1716  *
1717  * return value:    Returns kDNSServiceErr_NoError on success.
1718  *                  Returns kDNSServiceErr_Invalid if the "key" string contains
1719  *                  illegal characters.
1720  *                  Returns kDNSServiceErr_NoMemory if adding this key would
1721  *                  exceed the available storage.
1722  */
1723 
1724 DNSServiceErrorType DNSSD_API TXTRecordSetValue
1725 		(
1726 		TXTRecordRef * txtRecord,
1727 		const char *key,
1728 		uint8_t valueSize, /* may be zero */
1729 		const void *value /* may be NULL */
1730 		);
1731 
1732 
1733 
1734 /* TXTRecordRemoveValue()
1735  *
1736  * Removes a key from a TXTRecordRef.  The "key" must be an
1737  * ASCII string which exists in the TXTRecordRef.
1738  *
1739  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
1740  *
1741  * key:             A key name which exists in the TXTRecordRef.
1742  *
1743  * return value:    Returns kDNSServiceErr_NoError on success.
1744  *                  Returns kDNSServiceErr_NoSuchKey if the "key" does not
1745  *                  exist in the TXTRecordRef.
1746  *
1747  */
1748 
1749 DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
1750 		(
1751 		TXTRecordRef * txtRecord,
1752 		const char *key
1753 		);
1754 
1755 
1756 
1757 /* TXTRecordGetLength()
1758  *
1759  * Allows you to determine the length of the raw bytes within a TXTRecordRef.
1760  *
1761  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
1762  *
1763  * return value:    Returns the size of the raw bytes inside a TXTRecordRef
1764  *                  which you can pass directly to DNSServiceRegister() or
1765  *                  to DNSServiceUpdateRecord().
1766  *                  Returns 0 if the TXTRecordRef is empty.
1767  *
1768  */
1769 
1770 uint16_t DNSSD_API TXTRecordGetLength
1771 		(
1772 		const TXTRecordRef * txtRecord
1773 		);
1774 
1775 
1776 
1777 /* TXTRecordGetBytesPtr()
1778  *
1779  * Allows you to retrieve a pointer to the raw bytes within a TXTRecordRef.
1780  *
1781  * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
1782  *
1783  * return value:    Returns a pointer to the raw bytes inside the TXTRecordRef
1784  *                  which you can pass directly to DNSServiceRegister() or
1785  *                  to DNSServiceUpdateRecord().
1786  *
1787  */
1788 
1789 const void *DNSSD_API TXTRecordGetBytesPtr
1790 		(
1791 		const TXTRecordRef * txtRecord
1792 		);
1793 
1794 
1795 
1796 /*********************************************************************************************
1797  *
1798  *   TXT Record Parsing Functions
1799  *
1800  *********************************************************************************************/
1801 
1802 /*
1803  * A typical calling sequence for TXT record parsing is something like:
1804  *
1805  * Receive TXT record data in DNSServiceResolve() callback
1806  * if (TXTRecordContainsKey(txtLen, txtRecord, "key")) then do something
1807  * val1ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key1", &len1);
1808  * val2ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key2", &len2);
1809  * ...
1810  * bcopy(val1ptr, myval1, len1);
1811  * bcopy(val2ptr, myval2, len2);
1812  * ...
1813  * return;
1814  *
1815  * If you wish to retain the values after return from the DNSServiceResolve()
1816  * callback, then you need to copy the data to your own storage using bcopy()
1817  * or similar, as shown in the example above.
1818  *
1819  * If for some reason you need to parse a TXT record you built yourself
1820  * using the TXT record construction functions above, then you can do
1821  * that using TXTRecordGetLength and TXTRecordGetBytesPtr calls:
1822  * TXTRecordGetValue(TXTRecordGetLength(x), TXTRecordGetBytesPtr(x), key, &len);
1823  *
1824  * Most applications only fetch keys they know about from a TXT record and
1825  * ignore the rest.
1826  * However, some debugging tools wish to fetch and display all keys.
1827  * To do that, use the TXTRecordGetCount() and TXTRecordGetItemAtIndex() calls.
1828  */
1829 
1830 /* TXTRecordContainsKey()
1831  *
1832  * Allows you to determine if a given TXT Record contains a specified key.
1833  *
1834  * txtLen:          The size of the received TXT Record.
1835  *
1836  * txtRecord:       Pointer to the received TXT Record bytes.
1837  *
1838  * key:             A null-terminated ASCII string containing the key name.
1839  *
1840  * return value:    Returns 1 if the TXT Record contains the specified key.
1841  *                  Otherwise, it returns 0.
1842  *
1843  */
1844 
1845 int DNSSD_API TXTRecordContainsKey
1846 		(
1847 		uint16_t txtLen,
1848 		const void *txtRecord,
1849 		const char *key
1850 		);
1851 
1852 
1853 
1854 /* TXTRecordGetValuePtr()
1855  *
1856  * Allows you to retrieve the value for a given key from a TXT Record.
1857  *
1858  * txtLen:          The size of the received TXT Record
1859  *
1860  * txtRecord:       Pointer to the received TXT Record bytes.
1861  *
1862  * key:             A null-terminated ASCII string containing the key name.
1863  *
1864  * valueLen:        On output, will be set to the size of the "value" data.
1865  *
1866  * return value:    Returns NULL if the key does not exist in this TXT record,
1867  *                  or exists with no value (to differentiate between
1868  *                  these two cases use TXTRecordContainsKey()).
1869  *                  Returns pointer to location within TXT Record bytes
1870  *                  if the key exists with empty or non-empty value.
1871  *                  For empty value, valueLen will be zero.
1872  *                  For non-empty value, valueLen will be length of value data.
1873  */
1874 
1875 const void *DNSSD_API TXTRecordGetValuePtr
1876 		(
1877 		uint16_t txtLen,
1878 		const void *txtRecord,
1879 		const char *key,
1880 		uint8_t * valueLen
1881 		);
1882 
1883 
1884 
1885 /* TXTRecordGetCount()
1886  *
1887  * Returns the number of keys stored in the TXT Record.  The count
1888  * can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
1889  *
1890  * txtLen:          The size of the received TXT Record.
1891  *
1892  * txtRecord:       Pointer to the received TXT Record bytes.
1893  *
1894  * return value:    Returns the total number of keys in the TXT Record.
1895  *
1896  */
1897 
1898 uint16_t DNSSD_API TXTRecordGetCount
1899 		(
1900 		uint16_t txtLen,
1901 		const void *txtRecord
1902 		);
1903 
1904 
1905 
1906 /* TXTRecordGetItemAtIndex()
1907  *
1908  * Allows you to retrieve a key name and value pointer, given an index into
1909  * a TXT Record.  Legal index values range from zero to TXTRecordGetCount()-1.
1910  * It's also possible to iterate through keys in a TXT record by simply
1911  * calling TXTRecordGetItemAtIndex() repeatedly, beginning with index zero
1912  * and increasing until TXTRecordGetItemAtIndex() returns kDNSServiceErr_Invalid.
1913  *
1914  * On return:
1915  * For keys with no value, *value is set to NULL and *valueLen is zero.
1916  * For keys with empty value, *value is non-NULL and *valueLen is zero.
1917  * For keys with non-empty value, *value is non-NULL and *valueLen is non-zero.
1918  *
1919  * txtLen:          The size of the received TXT Record.
1920  *
1921  * txtRecord:       Pointer to the received TXT Record bytes.
1922  *
1923  * index:           An index into the TXT Record.
1924  *
1925  * keyBufLen:       The size of the string buffer being supplied.
1926  *
1927  * key:             A string buffer used to store the key name.
1928  *                  On return, the buffer contains a null-terminated C string
1929  *                  giving the key name. DNS-SD TXT keys are usually
1930  *                  8 characters or less. To hold the maximum possible
1931  *                  key name, the buffer should be 256 bytes long.
1932  *
1933  * valueLen:        On output, will be set to the size of the "value" data.
1934  *
1935  * value:           On output, *value is set to point to location within TXT
1936  *                  Record bytes that holds the value data.
1937  *
1938  * return value:    Returns kDNSServiceErr_NoError on success.
1939  *                  Returns kDNSServiceErr_NoMemory if keyBufLen is too short.
1940  *                  Returns kDNSServiceErr_Invalid if index is greater than
1941  *                  TXTRecordGetCount()-1.
1942  */
1943 
1944 DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
1945 		(
1946 		uint16_t txtLen,
1947 		const void *txtRecord,
1948 		uint16_t index_,
1949 		uint16_t keyBufLen,
1950 		char *key,
1951 		uint8_t * valueLen,
1952 		const void **value
1953 		);
1954 
1955 
1956 #ifdef __APPLE_API_PRIVATE
1957 
1958 /*
1959  * Mac OS X specific functionality
1960  * 3rd party clients of this API should not depend on future support or availability of this routine
1961  */
1962 
1963 /* DNSServiceSetDefaultDomainForUser()
1964  *
1965  * Set the default domain for the caller's UID.  Future browse and registration
1966  * calls by this user that do not specify an explicit domain will browse and
1967  * register in this wide-area domain in addition to .local.  In addition, this
1968  * domain will be returned as a Browse domain via domain enumeration calls.
1969  *
1970  *
1971  * Parameters:
1972  *
1973  * flags:           Pass kDNSServiceFlagsAdd to add a domain for a user.  Call without
1974  *                  this flag set to clear a previously added domain.
1975  *
1976  * domain:          The domain to be used for the caller's UID.
1977  *
1978  * return value:    Returns kDNSServiceErr_NoError on succeses, otherwise returns
1979  *                  an error code indicating the error that occurred
1980  */
1981 
1982 DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser
1983 (
1984 	DNSServiceFlags flags,
1985 	const char *domain
1986 );
1987 
1988 
1989 #endif							//__APPLE_API_PRIVATE
1990 
1991 // Some C compiler cleverness. We can make the compiler check certain things for us,
1992 // and report errors at compile-time if anything is wrong. The usual way to do this would
1993 // be to use a run-time "if" statement or the conventional run-time "assert" mechanism, but
1994 // then you don't find out what's wrong until you run the software. This way, if the assertion
1995 // condition is false, the array size is negative, and the complier complains immediately.
1996 
1997 struct DNS_SD_CompileTimeAssertionChecks
1998 {
1999 	char assert0[(sizeof(union _TXTRecordRef_t) == 16) ? 1 : -1];
2000 };
2001 
2002 
2003 #ifdef  __cplusplus
2004 }
2005 #endif							/*
2006  */
2007 
2008 #endif	/* _DNS_SD_H */
2009