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