9 // ***************************************************************************
10 // Function scope indicators
12 // If you see "mDNSlocal" before a function name, it means the function is not callable outside this file
13 #define mDNSlocal static
14 // If you see "mDNSexport" before a symbol, it means the symbol is exported for use by clients
17 // ***************************************************************************
19 #pragma mark - DNS Resource Record class and type constants
22 typedef enum // From RFC 1035
24 kDNSClass_IN
= 1, // Internet
25 kDNSClass_CS
= 2, // CSNET
26 kDNSClass_CH
= 3, // CHAOS
27 kDNSClass_HS
= 4, // Hesiod
28 kDNSClass_NONE
= 254, // Used in DNS UPDATE [RFC 2136]
29 kDNSQClass_ANY
= 255, // Not a DNS class, but a DNS query class, meaning "all classes"
30 kDNSQClass_Mask
= 0x7FFF, // Multicast DNS uses the bottom 15 bits to identify the record class...
31 kDNSClass_UniqueRRSet
= 0x8000 // ... and the top bit indicates that all other cached records are now invalid
34 typedef enum // From RFC 1035
36 kDNSType_A
= 1, // 1 Address
37 kDNSType_NS
, // 2 Name Server
38 kDNSType_MD
, // 3 Mail Destination
39 kDNSType_MF
, // 4 Mail Forwarder
40 kDNSType_CNAME
, // 5 Canonical Name
41 kDNSType_SOA
, // 6 Start of Authority
42 kDNSType_MB
, // 7 Mailbox
43 kDNSType_MG
, // 8 Mail Group
44 kDNSType_MR
, // 9 Mail Rename
45 kDNSType_NULL
, // 10 NULL RR
46 kDNSType_WKS
, // 11 Well-known-service
47 kDNSType_PTR
, // 12 Domain name pointer
48 kDNSType_HINFO
, // 13 Host information
49 kDNSType_MINFO
, // 14 Mailbox information
50 kDNSType_MX
, // 15 Mail Exchanger
51 kDNSType_TXT
, // 16 Arbitrary text string
53 kDNSType_SRV
= 33, // 33 Service record
55 kDNSQType_ANY
= 255 // Not a DNS type, but a DNS query type, meaning "all types"
58 // ***************************************************************************
60 #pragma mark - Simple types
63 // mDNS defines its own names for these common types to simplify portability across
64 // multiple platforms that may each have their own (different) names for these types.
65 typedef unsigned char mDNSBool
;
66 typedef signed char mDNSs8
;
67 typedef unsigned char mDNSu8
;
68 typedef signed short mDNSs16
;
69 typedef unsigned short mDNSu16
;
70 typedef signed long mDNSs32
;
71 typedef unsigned long mDNSu32
;
73 // These types are for opaque two- and four-byte identifiers.
74 // The "NotAnInteger" fields of the unions allow the value to be conveniently passed around in a register
75 // for the sake of efficiency, but don't forget -- just because it is in a register doesn't mean it is an
76 // integer. Operations like add, multiply, increment, decrement, etc., are undefined for opaque identifiers.
77 typedef union { mDNSu8 b
[2]; mDNSu16 NotAnInteger
; } mDNSOpaque16
;
78 typedef union { mDNSu8 b
[4]; mDNSu32 NotAnInteger
; } mDNSOpaque32
;
80 typedef mDNSOpaque16 mDNSIPPort
; // An IP port is a two-byte opaque identifier (not an integer)
81 typedef mDNSOpaque32 mDNSIPAddr
; // An IP address is a four-byte opaque identifier (not an integer)
83 enum { mDNSfalse
= 0, mDNStrue
= 1 };
92 // mDNS Error codes are in the range FFFE FF00 (-65792) to FFFE FFFF (-65537)
93 mStatus_UnknownErr
= -65537, // 0xFFFE FFFF
94 mStatus_NoSuchNameErr
= -65538,
95 mStatus_NoMemoryErr
= -65539,
96 mStatus_BadParamErr
= -65540,
97 mStatus_BadReferenceErr
= -65541,
98 mStatus_BadStateErr
= -65542,
99 mStatus_BadFlagsErr
= -65543,
100 mStatus_UnsupportedErr
= -65544,
101 mStatus_NotInitializedErr
= -65545,
102 mStatus_NoCache
= -65546,
103 mStatus_AlreadyRegistered
= -65547,
104 mStatus_NameConflict
= -65548,
105 mStatus_Invalid
= -65549,
107 mStatus_MemFree
= -65792 // 0xFFFE FF00
110 typedef mDNSs32 mStatus
;
112 #define MAX_DOMAIN_LABEL 63
113 typedef struct { mDNSu8 c
[ 64]; } domainlabel
; // One label: length byte and up to 63 characters
114 #define MAX_DOMAIN_NAME 255
115 typedef struct { mDNSu8 c
[256]; } domainname
; // Up to 255 bytes of length-prefixed domainlabels
116 typedef struct { mDNSu8 c
[256]; } UTF8str255
; // Null-terminated C string
118 // ***************************************************************************
120 #pragma mark - Resource Record structures
123 // Shared Resource Records do not have to be unique
124 // -- Shared Resource Records are used for NIAS service PTRs
125 // -- It is okay for several hosts to have RRs with the same name but different RDATA
126 // -- We use a random delay on replies to reduce collisions when all the hosts reply to the same query
127 // -- These RRs typically have moderately high TTLs (e.g. one hour)
128 // -- These records are announced on startup and topology changes for the benefit of passive listeners
130 // Unique Resource Records should be unique among hosts within any given mDNS scope
131 // -- The majority of Resource Records are of this type
132 // -- If two entities on the network have RRs with the same name but different RDATA, this is a conflict
133 // -- Replies may be sent immediately, because only one host should be replying to any particular query
134 // -- These RRs typically have low TTLs (e.g. ten seconds)
135 // -- On startup and after topology changes, a host issues queries to verify uniqueness
137 // Known Unique Resource Records are treated like Unique Resource Records, except that mDNS does
138 // not have to verify their uniqueness because this is already known by other means (e.g. the RR name
139 // is derived from the host's IP or Ethernet address, which is already known to be a unique identifier).
143 kDNSRecordTypeUnregistered
= 0x00, // Not currently in any list
144 kDNSRecordTypeDeregistering
= 0x01, // Shared record about to announce its departure and leave the list
146 kDNSRecordTypeUnique
= 0x08, // Will become a kDNSRecordTypeVerified when probing is complete
148 kDNSRecordTypePacketAnswer
= 0x10, // Received in the Answer Section of a DNS Response
149 kDNSRecordTypePacketAdditional
= 0x11, // Received in the Additional Section of a DNS Response
150 kDNSRecordTypePacketUniqueAns
= 0x18, // Received in the Answer Section of a DNS Response with kDNSQClass_CacheFlushBit set
151 kDNSRecordTypePacketUniqueAdd
= 0x19, // Received in the Additional Section of a DNS Response with kDNSQClass_CacheFlushBit set
153 kDNSRecordTypeShared
= 0x20, // Shared means record name does not have to be unique -- so use random delay on replies
154 kDNSRecordTypeVerified
= 0x28, // Unique means mDNS should check that name is unique (and then send immediate replies)
155 kDNSRecordTypeKnownUnique
= 0x29, // Known Unique means mDNS can assume name is unique without checking
157 kDNSRecordTypeUniqueMask
= 0x08, // Test for records that are supposed to not be shared with other hosts
158 kDNSRecordTypeRegisteredMask
= 0xF8, // Test for records that have not had mDNS_Deregister called on them yet
159 kDNSRecordTypeActiveMask
= 0xF0 // Test for all records that have finished their probing and are now active
164 kDNSSendPriorityNone
= 0, // Don't need to send this record right now
165 kDNSSendPriorityAdditional
= 1, // Send this record as an additional, if we have space in the packet
166 kDNSSendPriorityAnswer
= 2 // Need to send this record as an answer
169 typedef struct { mDNSu16 priority
; mDNSu16 weight
; mDNSIPPort port
; domainname target
; } rdataSRV
;
173 mDNSu8 data
[512]; // Generic untyped data (temporarily set 512 for the benefit of iChat)
174 mDNSIPAddr ip
; // For 'A' record
175 domainname name
; // For PTR and CNAME records
176 UTF8str255 txt
; // For TXT record
177 rdataSRV srv
; // For SRV record
182 mDNSu16 MaxRDLength
; // Amount of storage allocated for rdata (usually sizeof(RDataBody))
183 mDNSu16 RDLength
; // Size of the rdata currently stored here
187 typedef struct ResourceRecord_struct ResourceRecord
;
188 typedef struct ResourceRecord_struct
*ResourceRecordPtr
;
190 typedef struct mDNS_struct mDNS
;
191 typedef struct mDNS_PlatformSupport_struct mDNS_PlatformSupport
;
193 typedef void mDNSRecordCallback(mDNS
*const m
, ResourceRecord
*const rr
, mStatus result
);
194 typedef void mDNSRecordUpdateCallback(mDNS
*const m
, ResourceRecord
*const rr
, RData
*OldRData
);
196 // Fields labelled "AR:" apply to our authoritative records
197 // Fields labelled "CR:" apply to cache records
198 // Fields labelled "--:" apply to both
199 // (May want to make this a union later, but not now, because using the
200 // same storage for two different purposes always makes debugging harder.)
201 struct ResourceRecord_struct
203 ResourceRecord
*next
; // --: Next in list
205 // Field Group 1: Persistent metadata for Authoritative Records
206 ResourceRecord
*Additional1
; // AR: Recommended additional record to include in response
207 ResourceRecord
*Additional2
; // AR: Another additional
208 ResourceRecord
*DependentOn
; // AR: This record depends on another for its uniqueness checking
209 ResourceRecord
*RRSet
; // AR: This unique record is part of an RRSet
210 mDNSRecordCallback
*Callback
; // AR: Callback function to call for state changes
211 void *Context
; // AR: Context parameter for the callback function
212 mDNSu8 RecordType
; // --: See enum above
213 mDNSu8 HostTarget
; // AR: Set if the target of this record (PTR, CNAME, SRV, etc.) is our host name
215 // Field Group 2: Transient state for Authoritative Records
216 mDNSu8 Acknowledged
; // AR: Set if we've given the success callback to the client
217 mDNSu8 ProbeCount
; // AR: Number of probes remaining before this record is valid (kDNSRecordTypeUnique)
218 mDNSu8 AnnounceCount
; // AR: Number of announcements remaining (kDNSRecordTypeShared)
219 mDNSu8 IncludeInProbe
; // AR: Set if this RR is being put into a probe right now
220 mDNSu8 SendPriority
; // AR: See enum above
221 mDNSIPAddr Requester
; // AR: Used for inter-packet duplicate suppression
222 // If set, give the IP address of the last host that sent a truncated query for this record
223 // If set to all-ones, more than one host sent such a request in the last few milliseconds
224 ResourceRecord
*NextResponse
; // AR: Link to the next element in the chain of responses to generate
225 const mDNSu8
*NR_AnswerTo
; // AR: Set if this record was selected by virtue of being a direct answer to a question
226 ResourceRecord
*NR_AdditionalTo
; // AR: Set if this record was selected by virtue of being additional to another
227 mDNSs32 LastSendTime
; // AR: In platform time units
228 mDNSs32 NextSendTime
; // AR: In platform time units
229 mDNSs32 NextSendInterval
; // AR: In platform time units
230 RData
*NewRData
; // AR: Set if we are updating this record with new rdata
231 mDNSRecordUpdateCallback
*UpdateCallback
;
233 // Field Group 3: Transient state for Cache Records
234 ResourceRecord
*NextDupSuppress
; // CR: Link to the next element in the chain of duplicate suppression answers to send
235 mDNSs32 TimeRcvd
; // CR: In platform time units
236 mDNSs32 LastUsed
; // CR: In platform time units
237 mDNSu32 UseCount
; // CR: Number of times this RR has been used to answer a question
238 mDNSu32 UnansweredQueries
; // CR: Number of times we've issued a query for this record without getting an answer
239 mDNSBool Active
; // CR: Set if there is currently a question referencing this answer
240 mDNSBool NewData
; // CR: Set if this is a record we just received
242 // Field Group 4: The actual information pertaining to this resource record
243 mDNSIPAddr InterfaceAddr
; // --: Set if this RR is specific to one interface (e.g. a linklocal address)
244 // For records received off the wire, InterfaceAddr is *always* set to the receiving interface
245 // For our authoritative records, InterfaceAddr is usually zero,
246 // except those few records that are interface-specific (e.g. linklocal address records)
247 domainname name
; // --: All the rest are used both in our authoritative records and in cache records
250 mDNSu32 rroriginalttl
; // In seconds.
251 mDNSu32 rrremainingttl
; // In seconds. Always set to correct value before calling question callback.
252 mDNSu16 rdestimate
; // Upper bound on size of rdata after name compression
253 RData
*rdata
; // Pointer to storage for this rdata
254 RData rdatastorage
; // Normally the storage is right here, except for oversized records
257 typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo
;
259 struct NetworkInterfaceInfo_struct
261 NetworkInterfaceInfo
*next
;
263 mDNSBool Advertise
; // Set Advertise to false if you are only searching on this interface
264 // Standard ResourceRecords that every Responder host should have (one per active IP address)
265 ResourceRecord RR_A1
; // 'A' (address) record for our ".local" name
266 ResourceRecord RR_A2
; // 'A' record for our ".local.arpa" name
267 ResourceRecord RR_PTR
; // PTR (reverse lookup) record
270 typedef struct ExtraResourceRecord_struct ExtraResourceRecord
;
271 struct ExtraResourceRecord_struct
273 ExtraResourceRecord
*next
;
275 // Note: Add any additional fields *before* the ResourceRecord in this structure, not at the end.
276 // In some cases clients can allocate larger chunks of memory and set r->rdata->MaxRDLength to indicate
277 // that this extra memory is available, which would result in any fields after the ResourceRecord getting smashed
280 typedef struct ServiceRecordSet_struct ServiceRecordSet
;
281 typedef void mDNSServiceCallback(mDNS
*const m
, ServiceRecordSet
*const sr
, mStatus result
);
282 struct ServiceRecordSet_struct
284 mDNSServiceCallback
*Callback
;
286 ExtraResourceRecord
*Extras
; // Optional list of extra ResourceRecords attached to this service registration
287 mDNSBool Conflict
; // Set if this record set was forcibly deregistered because of a conflict
288 domainname Host
; // Set if this service record does not use the standard target host name
289 ResourceRecord RR_PTR
; // e.g. _printer._tcp.local. PTR Name._printer._tcp.local.
290 ResourceRecord RR_SRV
; // e.g. Name._printer._tcp.local. SRV 0 0 port target
291 ResourceRecord RR_TXT
; // e.g. Name._printer._tcp.local. TXT PrintQueueName
292 // Don't add any fields after ResourceRecord RR_TXT.
293 // This is where the implicit extra space goes if we allocate a ServiceRecordSet containing an oversized RR_TXT record
296 // ***************************************************************************
298 #pragma mark - Question structures
301 typedef struct DNSQuestion_struct DNSQuestion
;
302 typedef void mDNSQuestionCallback(mDNS
*const m
, DNSQuestion
*question
, const ResourceRecord
*const answer
);
303 struct DNSQuestion_struct
306 mDNSs32 NextQTime
; // In platform time units
307 mDNSs32 ThisQInterval
; // In platform time units (zero for questions not in list)
308 // ThisQInterval will be non-zero for an active question;
309 // Zero for a cancelled or inactive question
310 mDNSs32 NextQInterval
;
311 DNSQuestion
*DuplicateOf
;
312 mDNSIPAddr InterfaceAddr
; // Non-zero if you want to issue link-local queries only on a single specific IP interface
316 mDNSQuestionCallback
*Callback
;
323 mDNSIPAddr InterfaceAddr
; // Local (source) IP Interface (needed for scoped addresses such as link-local)
324 mDNSIPAddr ip
; // Remote (destination) IP address where this service can be accessed
325 mDNSIPPort port
; // Port where this service can be accessed
327 mDNSu8 TXTinfo
[2048]; // Additional demultiplexing information (e.g. LPR queue name)
330 typedef struct ServiceInfoQuery_struct ServiceInfoQuery
;
331 typedef void ServiceInfoQueryCallback(mDNS
*const m
, ServiceInfoQuery
*query
);
332 struct ServiceInfoQuery_struct
341 ServiceInfoQueryCallback
*Callback
;
345 // ***************************************************************************
347 #pragma mark - Main mDNS object, used to hold all the mDNS state
350 typedef void mDNSCallback(mDNS
*const m
, mStatus result
);
354 mDNS_PlatformSupport
*p
; // Pointer to platform-specific data of indeterminite size
355 mStatus mDNSPlatformStatus
;
356 mDNSCallback
*Callback
;
359 mDNSu32 mDNS_busy
; // For debugging: To catch and report locking failures
361 mDNSu8 lock_rrcache
; // For debugging: Set at times when these lists may not be modified
362 mDNSu8 lock_Questions
;
366 // These fields only required for mDNS Searcher...
367 DNSQuestion
*ActiveQuestions
; // List of all active questions
368 DNSQuestion
*NewQuestions
; // Fresh questions not yet answered from cache
369 DNSQuestion
*CurrentQuestion
; // Next question about to be examined in AnswerLocalQuestions()
370 mDNSu32 rrcache_size
;
371 mDNSu32 rrcache_used
;
372 mDNSu32 rrcache_report
;
373 ResourceRecord
*rrcache_free
;
374 ResourceRecord
*rrcache
;
376 // Fields below only required for mDNS Responder...
377 domainlabel nicelabel
; // Rich text label encoded using canonically precomposed UTF-8
378 domainlabel hostlabel
; // Conforms to RFC 1034 "letter-digit-hyphen" ARPANET host name rules
379 domainname hostname1
; // Primary Host Name "Foo.local."
380 domainname hostname2
; // Secondary Host Name "Foo.local.arpa."
381 ResourceRecord
*ResourceRecords
;
382 ResourceRecord
*CurrentRecord
; // Next ResourceRecord about to be examined
383 NetworkInterfaceInfo
*HostInterfaces
;
384 mDNSs32 SuppressSending
;
385 mDNSs32 SuppressProbes
;
390 // ***************************************************************************
392 #pragma mark - Useful Static Constants
395 extern const ResourceRecord zeroRR
;
396 extern const mDNSIPPort zeroIPPort
;
397 extern const mDNSIPAddr zeroIPAddr
;
398 extern const mDNSIPAddr onesIPAddr
;
400 extern const mDNSIPPort UnicastDNSPort
;
401 extern const mDNSIPPort MulticastDNSPort
;
402 extern const mDNSIPAddr AllDNSLinkGroup
;
403 extern const mDNSIPAddr AllDNSAdminGroup
;
405 // ***************************************************************************
407 #pragma mark - Main Client Functions
410 // Every client should call mDNS_Init, passing in storage for the mDNS object, mDNS_PlatformSupport object, and rrcache.
411 // The rrcachesize parameter is the size of (i.e. number of entries in) the rrcache array passed in.
412 // When mDNS has finished setting up the initComplete callback is called
413 // A client can also spin and poll the mDNSPlatformStatus field to see when it changes from mStatus_Waiting to mStatus_NoError
415 // Call mDNS_Close to tidy up before exiting
417 // Call mDNS_Register with a completed ResourceRecord object to register a resource record
418 // If the resource record type is kDNSRecordTypeUnique (or kDNSknownunique) then if a conflicting resource record is discovered,
419 // the resource record's mDNSRecordCallback will be called with error code mStatus_NameConflict. The callback should deregister
420 // the record, and may then try registering the record again after picking a new name (e.g. by automatically appending a number).
422 // Call mDNS_StartQuery to initiate a query. mDNS will proceed to issue Multicast DNS query packets, and any time a reply
423 // is received containing a record which matches the question, the DNSQuestion's mDNSAnswerCallback function will be called
424 // Call mDNS_StopQuery when no more answers are required
426 // The mDNS routines are intentionally not thread-safe -- adding locking operations would add overhead that may not
427 // be necessary or appropriate on every platform. Instead, code in a pre-emptive environment calling any mDNS routine
428 // (except mDNS_Init and mDNS_Close) is responsible for doing the necessary synchronization to ensure that mDNS code is
429 // not re-entered. This includes both client software above mDNS, and the platform support code below. For example, if
430 // the support code on a particular platform implements timer callbacks at interrupt time, then clients on that platform
431 // need to disable interrupts or do similar concurrency control to ensure that the mDNS code is not entered by an
432 // interrupt-time timer callback while in the middle of processing a client call.
434 extern mStatus
mDNS_Init (mDNS
*const m
, mDNS_PlatformSupport
*const p
,
435 ResourceRecord
*rrcachestorage
, mDNSu32 rrcachesize
, mDNSCallback
*Callback
, void *Context
);
436 extern void mDNS_Close (mDNS
*const m
);
437 extern mStatus
mDNS_Register (mDNS
*const m
, ResourceRecord
*const rr
);
438 extern mStatus
mDNS_Update (mDNS
*const m
, ResourceRecord
*const rr
, mDNSu32 newttl
,
439 RData
*const newrdata
, mDNSRecordUpdateCallback
*Callback
);
440 extern void mDNS_Deregister(mDNS
*const m
, ResourceRecord
*const rr
);
441 extern mStatus
mDNS_StartQuery(mDNS
*const m
, DNSQuestion
*const question
);
442 extern void mDNS_StopQuery (mDNS
*const m
, DNSQuestion
*const question
);
444 // ***************************************************************************
446 #pragma mark - General utility and helper functions
449 // mDNS_RegisterHostSet is a single call to register the standard resource records associated with every host.
450 // mDNS_RegisterService is a single call to register the set of resource records associated with a given named service.
452 // mDNS_StartResolveService is single call which is equivalent to multiple calls to mDNS_StartQuery,
453 // to find the IP address, port number, and demultiplexing information for a given named service.
454 // As with mDNS_StartQuery, it executes asynchronously, and calls the ServiceInfoQueryCallback when the answer is
455 // found. After the service is resolved, the client should call mDNS_StopResolveService to complete the transaction.
456 // The client can also call mDNS_StopResolveService at any time to abort the transaction.
458 // mDNS_GetBrowseDomains is a special case of the mDNS_StartQuery call, where the resulting answers
459 // are a list of PTR records indicating (in the rdata) domains that are recommended for browsing.
460 // After getting the list of domains to browse, call mDNS_StopQuery to end the search.
461 // mDNS_GetDefaultBrowseDomain returns the name of the domain that should be highlighted by default.
463 // mDNS_GetRegistrationDomains and mDNS_GetDefaultRegistrationDomain are the equivalent calls to get the list
464 // of one or more domains that should be offered to the user as choices for where they may register their service,
465 // and the default domain in which to register in the case where the user has made no selection.
467 extern void mDNS_SetupResourceRecord(ResourceRecord
*rr
, RData
*RDataStorage
, mDNSIPAddr InterfaceAddr
,
468 mDNSu16 rrtype
, mDNSu32 ttl
, mDNSu8 RecordType
, mDNSRecordCallback Callback
, void *Context
);
470 extern void mDNS_GenerateFQDN(mDNS
*const m
);
471 extern mStatus
mDNS_RegisterInterface (mDNS
*const m
, NetworkInterfaceInfo
*set
);
472 extern void mDNS_DeregisterInterface(mDNS
*const m
, NetworkInterfaceInfo
*set
);
474 extern mStatus
mDNS_RegisterService (mDNS
*const m
, ServiceRecordSet
*sr
,
475 const domainlabel
*const name
, const domainname
*const type
, const domainname
*const domain
,
476 const domainname
*const host
, mDNSIPPort port
, const mDNSu8 txtinfo
[], mDNSu16 txtlen
,
477 mDNSServiceCallback Callback
, void *Context
);
478 extern mStatus
mDNS_AddRecordToService(mDNS
*const m
, ServiceRecordSet
*sr
, ExtraResourceRecord
*extra
, RData
*rdata
, mDNSu32 ttl
);
479 extern mStatus
mDNS_RemoveRecordFromService(mDNS
*const m
, ServiceRecordSet
*sr
, ExtraResourceRecord
*extra
);
480 extern mStatus
mDNS_RenameAndReregisterService(mDNS
*const m
, ServiceRecordSet
*const sr
);
481 extern void mDNS_DeregisterService(mDNS
*const m
, ServiceRecordSet
*sr
);
483 extern mStatus
mDNS_StartBrowse(mDNS
*const m
, DNSQuestion
*const question
,
484 const domainname
*const srv
, const domainname
*const domain
,
485 const mDNSIPAddr InterfaceAddr
, mDNSQuestionCallback
*Callback
, void *Context
);
486 #define mDNS_StopBrowse mDNS_StopQuery
488 extern mStatus
mDNS_StartResolveService(mDNS
*const m
, ServiceInfoQuery
*query
, ServiceInfo
*info
, ServiceInfoQueryCallback
*Callback
, void *Context
);
489 extern void mDNS_StopResolveService (mDNS
*const m
, ServiceInfoQuery
*query
);
493 mDNS_DomainTypeBrowse
= 0,
494 mDNS_DomainTypeBrowseDefault
= 1,
495 mDNS_DomainTypeRegistration
= 2,
496 mDNS_DomainTypeRegistrationDefault
= 3
499 extern mStatus
mDNS_GetDomains(mDNS
*const m
, DNSQuestion
*const question
, mDNSu8 DomainType
, const mDNSIPAddr InterfaceAddr
, mDNSQuestionCallback
*Callback
, void *Context
);
500 #define mDNS_StopGetDomains mDNS_StopQuery
501 extern mStatus
mDNS_AdvertiseDomains(mDNS
*const m
, ResourceRecord
*rr
, mDNSu8 DomainType
, const mDNSIPAddr InterfaceAddr
, char *domname
);
502 #define mDNS_StopAdvertiseDomains mDNS_Deregister
504 // ***************************************************************************
506 #pragma mark - DNS name utility functions
509 // In order to expose the full capabilities of the DNS protocol (which allows any arbitrary eight-bit values
510 // in domain name labels, including unlikely characters like ascii nulls and even dots) all the mDNS APIs
511 // work with DNS's native length-prefixed strings. For convenience in C, the following utility functions
512 // are provided for converting between C's null-terminated strings and DNS's length-prefixed strings.
514 extern mDNSBool
SameDomainName(const domainname
*const d1
, const domainname
*const d2
);
516 extern mDNSu32
DomainNameLength(const domainname
*const name
);
517 extern void AppendDomainLabelToName(domainname
*const name
, const domainlabel
*const label
);
518 extern void AppendStringLabelToName(domainname
*const name
, const char *cstr
);
519 extern void AppendDomainNameToName(domainname
*const name
, const domainname
*const append
);
520 extern void AppendStringNameToName(domainname
*const name
, const char *cstr
);
522 extern void ConvertCStringToDomainLabel(const char *src
, domainlabel
*label
);
523 extern mDNSu8
*ConvertCStringToDomainName(const char *const cstr
, domainname
*name
);
525 extern char *ConvertDomainLabelToCString_withescape(const domainlabel
*const name
, char *cstr
, char esc
);
526 #define ConvertDomainLabelToCString_unescaped(D,C) ConvertDomainLabelToCString_withescape((D), (C), 0)
527 #define ConvertDomainLabelToCString(D,C) ConvertDomainLabelToCString_withescape((D), (C), '\\')
529 extern char *ConvertDomainNameToCString_withescape(const domainname
*const name
, char *cstr
, char esc
);
530 #define ConvertDomainNameToCString_unescaped(D,C) ConvertDomainNameToCString_withescape((D), (C), 0)
531 #define ConvertDomainNameToCString(D,C) ConvertDomainNameToCString_withescape((D), (C), '\\')
532 extern void ConvertUTF8PstringToRFC1034HostLabel(const mDNSu8 UTF8Name
[], domainlabel
*const hostlabel
);
534 extern mDNSu8
*ConstructServiceName(domainname
*const fqdn
, const domainlabel
*const name
, const domainname
*const type
, const domainname
*const domain
);
535 extern mDNSBool
DeconstructServiceName(const domainname
*const fqdn
, domainlabel
*const name
, domainname
*const type
, domainname
*const domain
);