2 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
26 Revision 1.33 2006/03/10 21:51:41 cheshire
27 <rdar://problem/4111464> After record update, old record sometimes remains in cache
28 Split out SameRDataBody() into a separate routine so it can be called from other code
30 Revision 1.32 2005/03/21 00:33:51 shersche
31 <rdar://problem/4021486> Fix build warnings on Win32 platform
33 Revision 1.31 2005/02/18 00:43:11 cheshire
34 <rdar://problem/4010245> mDNSResponder should auto-truncate service names that are too long
36 Revision 1.30 2005/01/19 03:12:44 cheshire
37 Move LocalRecordReady() macro from mDNS.c to DNSCommon.h
39 Revision 1.29 2004/12/15 02:11:22 ksekar
40 <rdar://problem/3917317> Don't check for Dynamic DNS hostname uniqueness
42 Revision 1.28 2004/12/06 21:15:22 ksekar
43 <rdar://problem/3884386> mDNSResponder crashed in CheckServiceRegistrations
45 Revision 1.27 2004/12/03 07:20:50 ksekar
46 <rdar://problem/3674208> Wide-Area: Registration of large TXT record fails
48 Revision 1.26 2004/12/03 05:18:33 ksekar
49 <rdar://problem/3810596> mDNSResponder needs to return more specific TSIG errors
51 Revision 1.25 2004/10/26 03:52:02 cheshire
52 Update checkin comments
54 Revision 1.24 2004/10/23 01:16:00 cheshire
55 <rdar://problem/3851677> uDNS operations not always reliable on multi-homed hosts
57 Revision 1.23 2004/10/03 23:18:58 cheshire
58 Move address comparison macros from DNSCommon.h to mDNSEmbeddedAPI.h
60 Revision 1.22 2004/09/30 00:24:56 ksekar
61 <rdar://problem/3695802> Dynamically update default registration domains on config change
63 Revision 1.21 2004/09/17 01:08:48 cheshire
64 Renamed mDNSClientAPI.h to mDNSEmbeddedAPI.h
65 The name "mDNSClientAPI.h" is misleading to new developers looking at this code. The interfaces
66 declared in that file are ONLY appropriate to single-address-space embedded applications.
67 For clients on general-purpose computers, the interfaces defined in dns_sd.h should be used.
69 Revision 1.20 2004/09/17 00:49:51 cheshire
70 Get rid of now-unused GetResourceRecord -- the correct (safe) routine to use
71 is GetLargeResourceRecord
73 Revision 1.19 2004/09/16 21:59:15 cheshire
74 For consistency with zerov6Addr, rename zeroIPAddr to zerov4Addr
76 Revision 1.18 2004/09/16 02:29:39 cheshire
77 Moved mDNS_Lock/mDNS_Unlock to DNSCommon.c; Added necessary locking around
78 uDNS_ReceiveMsg, uDNS_StartQuery, uDNS_UpdateRecord, uDNS_RegisterService
80 Revision 1.17 2004/09/14 23:27:46 cheshire
83 Revision 1.16 2004/08/13 23:46:58 cheshire
84 "asyncronous" -> "asynchronous"
86 Revision 1.15 2004/08/10 23:19:14 ksekar
87 <rdar://problem/3722542>: DNS Extension daemon for Wide Area Service Discovery
88 Moved routines/constants to allow extern access for garbage collection daemon
90 Revision 1.14 2004/05/28 23:42:36 ksekar
91 <rdar://problem/3258021>: Feature: DNS server->client notification on record changes (#7805)
93 Revision 1.13 2004/05/18 23:51:25 cheshire
94 Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
96 Revision 1.12 2004/04/22 04:03:59 cheshire
97 Headers should use "extern" declarations, not "mDNSexport"
99 Revision 1.11 2004/04/14 23:09:28 ksekar
100 Support for TSIG signed dynamic updates.
102 Revision 1.10 2004/03/13 01:57:33 ksekar
103 <rdar://problem/3192546>: DynDNS: Dynamic update of service records
105 Revision 1.9 2004/02/21 08:56:58 bradley
106 Wrap prototypes with extern "C" for C++ builds.
108 Revision 1.8 2004/02/06 23:04:18 ksekar
109 Basic Dynamic Update support via mDNS_Register (dissabled via
110 UNICAST_REGISTRATION #define)
112 Revision 1.7 2004/02/03 19:47:36 ksekar
113 Added an asynchronous state machine mechanism to uDNS.c, including
114 calls to find the parent zone for a domain name. Changes include code
115 in repository previously dissabled via "#if 0 incomplete". Codepath
116 is currently unused, and will be called to create update records, etc.
118 Revision 1.6 2004/01/27 20:15:22 cheshire
119 <rdar://problem/3541288>: Time to prune obsolete code for listening on port 53
121 Revision 1.5 2004/01/24 03:40:56 cheshire
122 Move mDNSAddrIsDNSMulticast() from DNSCommon.h to mDNSEmbeddedAPI.h so embedded clients can use it
124 Revision 1.4 2004/01/24 03:38:27 cheshire
125 Fix minor syntactic error: Headers should use "extern" declarations, not "mDNSexport"
127 Revision 1.3 2004/01/23 23:23:14 ksekar
128 Added TCP support for truncated unicast messages.
130 Revision 1.2 2004/01/21 21:12:23 cheshire
131 Add missing newline at end of file to make Unix tools happier
133 Revision 1.1 2003/12/13 03:05:27 ksekar
134 <rdar://problem/3192548>: DynDNS: Unicast query of service records
139 #ifndef __DNSCOMMON_H_
140 #define __DNSCOMMON_H_
142 #include "mDNSEmbeddedAPI.h"
148 // ***************************************************************************
149 #if COMPILER_LIKES_PRAGMA_MARK
150 #pragma mark - DNS Protocol Constants
155 kDNSFlag0_QR_Mask
= 0x80, // Query or response?
156 kDNSFlag0_QR_Query
= 0x00,
157 kDNSFlag0_QR_Response
= 0x80,
159 kDNSFlag0_OP_Mask
= 0x78, // Operation type
160 kDNSFlag0_OP_StdQuery
= 0x00,
161 kDNSFlag0_OP_Iquery
= 0x08,
162 kDNSFlag0_OP_Status
= 0x10,
163 kDNSFlag0_OP_Unused3
= 0x18,
164 kDNSFlag0_OP_Notify
= 0x20,
165 kDNSFlag0_OP_Update
= 0x28,
167 kDNSFlag0_QROP_Mask
= kDNSFlag0_QR_Mask
| kDNSFlag0_OP_Mask
,
169 kDNSFlag0_AA
= 0x04, // Authoritative Answer?
170 kDNSFlag0_TC
= 0x02, // Truncated?
171 kDNSFlag0_RD
= 0x01, // Recursion Desired?
172 kDNSFlag1_RA
= 0x80, // Recursion Available?
174 kDNSFlag1_Zero
= 0x40, // Reserved; must be zero
175 kDNSFlag1_AD
= 0x20, // Authentic Data [RFC 2535]
176 kDNSFlag1_CD
= 0x10, // Checking Disabled [RFC 2535]
178 kDNSFlag1_RC
= 0x0F, // Response code
179 kDNSFlag1_RC_NoErr
= 0x00,
180 kDNSFlag1_RC_FmtErr
= 0x01,
181 kDNSFlag1_RC_SrvErr
= 0x02,
182 kDNSFlag1_RC_NXDomain
= 0x03,
183 kDNSFlag1_RC_NotImpl
= 0x04,
184 kDNSFlag1_RC_Refused
= 0x05,
185 kDNSFlag1_RC_YXDomain
= 0x06,
186 kDNSFlag1_RC_YXRRSet
= 0x07,
187 kDNSFlag1_RC_NXRRSet
= 0x08,
188 kDNSFlag1_RC_NotAuth
= 0x09,
189 kDNSFlag1_RC_NotZone
= 0x0A
199 // ***************************************************************************
200 #if COMPILER_LIKES_PRAGMA_MARK
202 #pragma mark - General Utility Functions
205 extern const NetworkInterfaceInfo
*GetFirstActiveInterface(const NetworkInterfaceInfo
*intf
);
206 extern mDNSInterfaceID
GetNextActiveInterfaceID(const NetworkInterfaceInfo
*intf
);
208 extern mDNSu32
mDNSRandom(mDNSu32 max
);
211 // ***************************************************************************
212 #if COMPILER_LIKES_PRAGMA_MARK
214 #pragma mark - Domain Name Utility Functions
217 #define mdnsIsDigit(X) ((X) >= '0' && (X) <= '9')
218 #define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
219 #define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
220 #define mdnsIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
222 #define mdnsValidHostChar(X, notfirst, notlast) (mdnsIsLetter(X) || mdnsIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
224 extern mDNSu16
CompressedDomainNameLength(const domainname
*const name
, const domainname
*parent
);
226 extern mDNSu32
TruncateUTF8ToLength(mDNSu8
*string
, mDNSu32 length
, mDNSu32 max
);
227 extern mDNSBool
LabelContainsSuffix(const domainlabel
*const name
, const mDNSBool RichText
);
228 extern mDNSu32
RemoveLabelSuffix(domainlabel
*name
, mDNSBool RichText
);
229 extern void AppendLabelSuffix(domainlabel
*name
, mDNSu32 val
, mDNSBool RichText
);
230 extern void mDNS_HostNameCallback(mDNS
*const m
, AuthRecord
*const rr
, mStatus result
);
231 #define ValidateDomainName(N) (DomainNameLength(N) <= MAX_DOMAIN_NAME)
234 // ***************************************************************************
235 #if COMPILER_LIKES_PRAGMA_MARK
237 #pragma mark - Resource Record Utility Functions
240 extern mDNSu32
RDataHashValue(mDNSu16
const rdlength
, const RDataBody
*const rdb
);
242 extern mDNSBool
SameRDataBody(const ResourceRecord
*const r1
, const RDataBody
*const r2
);
243 extern mDNSBool
SameRData(const ResourceRecord
*const r1
, const ResourceRecord
*const r2
);
245 extern mDNSBool
ResourceRecordAnswersQuestion(const ResourceRecord
*const rr
, const DNSQuestion
*const q
);
247 extern mDNSBool
SameResourceRecord(ResourceRecord
*r1
, ResourceRecord
*r2
);
249 extern mDNSu16
GetRDLength(const ResourceRecord
*const rr
, mDNSBool estimate
);
251 #define GetRRDomainNameTarget(RR) ( \
252 ((RR)->rrtype == kDNSType_CNAME || (RR)->rrtype == kDNSType_PTR || (RR)->rrtype == kDNSType_NS) \
253 ? &(RR)->rdata->u.name : \
254 ((RR)->rrtype == kDNSType_SRV ) ? &(RR)->rdata->u.srv.target : mDNSNULL )
256 extern mDNSBool
ValidateRData(const mDNSu16 rrtype
, const mDNSu16 rdlength
, const RData
*const rd
);
257 #define LocalRecordReady(X) ((X)->resrec.RecordType != kDNSRecordTypeUnique && (X)->resrec.RecordType != kDNSRecordTypeDeregistering)
260 // ***************************************************************************
261 #if COMPILER_LIKES_PRAGMA_MARK
264 #pragma mark - DNS Message Creation Functions
267 extern void InitializeDNSMessage(DNSMessageHeader
*h
, mDNSOpaque16 id
, mDNSOpaque16 flags
);
268 extern const mDNSu8
*FindCompressionPointer(const mDNSu8
*const base
, const mDNSu8
*const end
, const mDNSu8
*const domname
);
270 extern mDNSu8
*putDomainNameAsLabels(const DNSMessage
*const msg
, mDNSu8
*ptr
, const mDNSu8
*const limit
, const domainname
*const name
);
272 extern mDNSu8
*putRData(const DNSMessage
*const msg
, mDNSu8
*ptr
, const mDNSu8
*const limit
, ResourceRecord
*rr
);
274 // If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
275 // but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
277 extern mDNSu8
*PutResourceRecordTTLWithLimit(DNSMessage
*const msg
, mDNSu8
*ptr
, mDNSu16
*count
, ResourceRecord
*rr
, mDNSu32 ttl
, const mDNSu8
*limit
);
279 #define PutResourceRecordTTL(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
280 ((msg)->h.numAnswers || (msg)->h.numAuthorities || (msg)->h.numAdditionals) ? (msg)->data + NormalMaxDNSMessageData : (msg)->data + AbsoluteMaxDNSMessageData)
282 #define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
283 (msg)->data + AbsoluteMaxDNSMessageData)
285 extern mDNSu8
*PutResourceRecordCappedTTL(DNSMessage
*const msg
, mDNSu8
*ptr
, mDNSu16
*count
, ResourceRecord
*rr
, mDNSu32 maxttl
);
287 extern mDNSu8
*putEmptyResourceRecord(DNSMessage
*const msg
, mDNSu8
*ptr
, const mDNSu8
*const limit
, mDNSu16
*count
, const AuthRecord
*rr
);
289 extern mDNSu8
*putQuestion(DNSMessage
*const msg
, mDNSu8
*ptr
, const mDNSu8
*const limit
, const domainname
*const name
, mDNSu16 rrtype
, mDNSu16 rrclass
);
291 extern mDNSu8
*putZone(DNSMessage
*const msg
, mDNSu8
*ptr
, mDNSu8
*limit
, const domainname
*zone
, mDNSOpaque16 zoneClass
);
293 extern mDNSu8
*putPrereqNameNotInUse(domainname
*name
, DNSMessage
*msg
, mDNSu8
*ptr
, mDNSu8
*end
);
295 extern mDNSu8
*putDeletionRecord(DNSMessage
*msg
, mDNSu8
*ptr
, ResourceRecord
*rr
);
297 extern mDNSu8
*putDeleteRRSet(DNSMessage
*msg
, mDNSu8
*ptr
, const domainname
*name
, mDNSu16 rrtype
);
299 extern mDNSu8
*putDeleteAllRRSets(DNSMessage
*msg
, mDNSu8
*ptr
, const domainname
*name
);
301 extern mDNSu8
*putUpdateLease(DNSMessage
*msg
, mDNSu8
*end
, mDNSu32 lease
);
303 #define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
306 // ***************************************************************************
307 #if COMPILER_LIKES_PRAGMA_MARK
309 #pragma mark - DNS Message Parsing Functions
312 extern mDNSu32
DomainNameHashValue(const domainname
*const name
);
314 extern void SetNewRData(ResourceRecord
*const rr
, RData
*NewRData
, mDNSu16 rdlength
);
317 extern const mDNSu8
*skipDomainName(const DNSMessage
*const msg
, const mDNSu8
*ptr
, const mDNSu8
*const end
);
319 extern const mDNSu8
*getDomainName(const DNSMessage
*const msg
, const mDNSu8
*ptr
, const mDNSu8
*const end
,
320 domainname
*const name
);
322 extern const mDNSu8
*skipResourceRecord(const DNSMessage
*msg
, const mDNSu8
*ptr
, const mDNSu8
*end
);
324 extern const mDNSu8
*GetLargeResourceRecord(mDNS
*const m
, const DNSMessage
* const msg
, const mDNSu8
*ptr
,
325 const mDNSu8
* end
, const mDNSInterfaceID InterfaceID
, mDNSu8 RecordType
, LargeCacheRecord
*largecr
);
327 extern const mDNSu8
*skipQuestion(const DNSMessage
*msg
, const mDNSu8
*ptr
, const mDNSu8
*end
);
329 extern const mDNSu8
*getQuestion(const DNSMessage
*msg
, const mDNSu8
*ptr
, const mDNSu8
*end
, const mDNSInterfaceID InterfaceID
,
330 DNSQuestion
*question
);
332 extern const mDNSu8
*LocateAnswers(const DNSMessage
*const msg
, const mDNSu8
*const end
);
334 extern const mDNSu8
*LocateAuthorities(const DNSMessage
*const msg
, const mDNSu8
*const end
);
336 extern const mDNSu8
*LocateAdditionals(const DNSMessage
*const msg
, const mDNSu8
*const end
);
338 // ***************************************************************************
339 #if COMPILER_LIKES_PRAGMA_MARK
342 #pragma mark - Packet Sending Functions
345 extern mStatus
mDNSSendDNSMessage(const mDNS
*const m
, DNSMessage
*const msg
, mDNSu8
*end
,
346 mDNSInterfaceID InterfaceID
, const mDNSAddr
*dst
, mDNSIPPort dstport
, int sd
, uDNS_AuthInfo
*authInfo
);
348 // ***************************************************************************
349 #if COMPILER_LIKES_PRAGMA_MARK
351 #pragma mark - RR List Management & Task Management
354 extern void mDNS_Lock(mDNS
*const m
);
355 extern void mDNS_Unlock(mDNS
*const m
);
361 #endif // __DNSCOMMON_H_