]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSCore/DNSCommon.h
mDNSResponder-107.6.tar.gz
[apple/mdnsresponder.git] / mDNSCore / DNSCommon.h
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16
17 Change History (most recent first):
18
19 $Log: DNSCommon.h,v $
20 Revision 1.34.2.1 2006/08/29 06:24:22 cheshire
21 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
22
23 Revision 1.34 2006/03/18 21:47:56 cheshire
24 <rdar://problem/4073825> Improve logic for delaying packets after repeated interface transitions
25
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
29
30 Revision 1.32 2005/03/21 00:33:51 shersche
31 <rdar://problem/4021486> Fix build warnings on Win32 platform
32
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
35
36 Revision 1.30 2005/01/19 03:12:44 cheshire
37 Move LocalRecordReady() macro from mDNS.c to DNSCommon.h
38
39 Revision 1.29 2004/12/15 02:11:22 ksekar
40 <rdar://problem/3917317> Don't check for Dynamic DNS hostname uniqueness
41
42 Revision 1.28 2004/12/06 21:15:22 ksekar
43 <rdar://problem/3884386> mDNSResponder crashed in CheckServiceRegistrations
44
45 Revision 1.27 2004/12/03 07:20:50 ksekar
46 <rdar://problem/3674208> Wide-Area: Registration of large TXT record fails
47
48 Revision 1.26 2004/12/03 05:18:33 ksekar
49 <rdar://problem/3810596> mDNSResponder needs to return more specific TSIG errors
50
51 Revision 1.25 2004/10/26 03:52:02 cheshire
52 Update checkin comments
53
54 Revision 1.24 2004/10/23 01:16:00 cheshire
55 <rdar://problem/3851677> uDNS operations not always reliable on multi-homed hosts
56
57 Revision 1.23 2004/10/03 23:18:58 cheshire
58 Move address comparison macros from DNSCommon.h to mDNSEmbeddedAPI.h
59
60 Revision 1.22 2004/09/30 00:24:56 ksekar
61 <rdar://problem/3695802> Dynamically update default registration domains on config change
62
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.
68
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
72
73 Revision 1.19 2004/09/16 21:59:15 cheshire
74 For consistency with zerov6Addr, rename zeroIPAddr to zerov4Addr
75
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
79
80 Revision 1.17 2004/09/14 23:27:46 cheshire
81 Fix compile errors
82
83 Revision 1.16 2004/08/13 23:46:58 cheshire
84 "asyncronous" -> "asynchronous"
85
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
89
90 Revision 1.14 2004/05/28 23:42:36 ksekar
91 <rdar://problem/3258021>: Feature: DNS server->client notification on record changes (#7805)
92
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
95
96 Revision 1.12 2004/04/22 04:03:59 cheshire
97 Headers should use "extern" declarations, not "mDNSexport"
98
99 Revision 1.11 2004/04/14 23:09:28 ksekar
100 Support for TSIG signed dynamic updates.
101
102 Revision 1.10 2004/03/13 01:57:33 ksekar
103 <rdar://problem/3192546>: DynDNS: Dynamic update of service records
104
105 Revision 1.9 2004/02/21 08:56:58 bradley
106 Wrap prototypes with extern "C" for C++ builds.
107
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)
111
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.
117
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
120
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
123
124 Revision 1.4 2004/01/24 03:38:27 cheshire
125 Fix minor syntactic error: Headers should use "extern" declarations, not "mDNSexport"
126
127 Revision 1.3 2004/01/23 23:23:14 ksekar
128 Added TCP support for truncated unicast messages.
129
130 Revision 1.2 2004/01/21 21:12:23 cheshire
131 Add missing newline at end of file to make Unix tools happier
132
133 Revision 1.1 2003/12/13 03:05:27 ksekar
134 <rdar://problem/3192548>: DynDNS: Unicast query of service records
135
136
137 */
138
139 #ifndef __DNSCOMMON_H_
140 #define __DNSCOMMON_H_
141
142 #include "mDNSEmbeddedAPI.h"
143
144 #ifdef __cplusplus
145 extern "C" {
146 #endif
147
148
149 // ***************************************************************************
150 #if COMPILER_LIKES_PRAGMA_MARK
151 #pragma mark - DNS Protocol Constants
152 #endif
153
154 typedef enum
155 {
156 kDNSFlag0_QR_Mask = 0x80, // Query or response?
157 kDNSFlag0_QR_Query = 0x00,
158 kDNSFlag0_QR_Response = 0x80,
159
160 kDNSFlag0_OP_Mask = 0x78, // Operation type
161 kDNSFlag0_OP_StdQuery = 0x00,
162 kDNSFlag0_OP_Iquery = 0x08,
163 kDNSFlag0_OP_Status = 0x10,
164 kDNSFlag0_OP_Unused3 = 0x18,
165 kDNSFlag0_OP_Notify = 0x20,
166 kDNSFlag0_OP_Update = 0x28,
167
168 kDNSFlag0_QROP_Mask = kDNSFlag0_QR_Mask | kDNSFlag0_OP_Mask,
169
170 kDNSFlag0_AA = 0x04, // Authoritative Answer?
171 kDNSFlag0_TC = 0x02, // Truncated?
172 kDNSFlag0_RD = 0x01, // Recursion Desired?
173 kDNSFlag1_RA = 0x80, // Recursion Available?
174
175 kDNSFlag1_Zero = 0x40, // Reserved; must be zero
176 kDNSFlag1_AD = 0x20, // Authentic Data [RFC 2535]
177 kDNSFlag1_CD = 0x10, // Checking Disabled [RFC 2535]
178
179 kDNSFlag1_RC = 0x0F, // Response code
180 kDNSFlag1_RC_NoErr = 0x00,
181 kDNSFlag1_RC_FmtErr = 0x01,
182 kDNSFlag1_RC_SrvErr = 0x02,
183 kDNSFlag1_RC_NXDomain = 0x03,
184 kDNSFlag1_RC_NotImpl = 0x04,
185 kDNSFlag1_RC_Refused = 0x05,
186 kDNSFlag1_RC_YXDomain = 0x06,
187 kDNSFlag1_RC_YXRRSet = 0x07,
188 kDNSFlag1_RC_NXRRSet = 0x08,
189 kDNSFlag1_RC_NotAuth = 0x09,
190 kDNSFlag1_RC_NotZone = 0x0A
191 } DNS_Flags;
192
193 typedef enum
194 {
195 TSIG_ErrBadSig = 16,
196 TSIG_ErrBadKey = 17,
197 TSIG_ErrBadTime = 18
198 } TSIG_ErrorCode;
199
200
201 // ***************************************************************************
202 #if COMPILER_LIKES_PRAGMA_MARK
203 #pragma mark -
204 #pragma mark - General Utility Functions
205 #endif
206
207 extern const NetworkInterfaceInfo *GetFirstActiveInterface(const NetworkInterfaceInfo *intf);
208 extern mDNSInterfaceID GetNextActiveInterfaceID(const NetworkInterfaceInfo *intf);
209
210 extern mDNSu32 mDNSRandom(mDNSu32 max);
211 extern mDNSu32 mDNSRandomFromFixedSeed(mDNSu32 seed, mDNSu32 max);
212
213
214 // ***************************************************************************
215 #if COMPILER_LIKES_PRAGMA_MARK
216 #pragma mark -
217 #pragma mark - Domain Name Utility Functions
218 #endif
219
220 #define mdnsIsDigit(X) ((X) >= '0' && (X) <= '9')
221 #define mDNSIsUpperCase(X) ((X) >= 'A' && (X) <= 'Z')
222 #define mDNSIsLowerCase(X) ((X) >= 'a' && (X) <= 'z')
223 #define mdnsIsLetter(X) (mDNSIsUpperCase(X) || mDNSIsLowerCase(X))
224
225 #define mdnsValidHostChar(X, notfirst, notlast) (mdnsIsLetter(X) || mdnsIsDigit(X) || ((notfirst) && (notlast) && (X) == '-') )
226
227 extern mDNSu16 CompressedDomainNameLength(const domainname *const name, const domainname *parent);
228
229 extern mDNSu32 TruncateUTF8ToLength(mDNSu8 *string, mDNSu32 length, mDNSu32 max);
230 extern mDNSBool LabelContainsSuffix(const domainlabel *const name, const mDNSBool RichText);
231 extern mDNSu32 RemoveLabelSuffix(domainlabel *name, mDNSBool RichText);
232 extern void AppendLabelSuffix(domainlabel *name, mDNSu32 val, mDNSBool RichText);
233 extern void mDNS_HostNameCallback(mDNS *const m, AuthRecord *const rr, mStatus result);
234 #define ValidateDomainName(N) (DomainNameLength(N) <= MAX_DOMAIN_NAME)
235
236
237 // ***************************************************************************
238 #if COMPILER_LIKES_PRAGMA_MARK
239 #pragma mark -
240 #pragma mark - Resource Record Utility Functions
241 #endif
242
243 extern mDNSu32 RDataHashValue(mDNSu16 const rdlength, const RDataBody *const rdb);
244
245 extern mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *const r2);
246 extern mDNSBool SameRData(const ResourceRecord *const r1, const ResourceRecord *const r2);
247
248 extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
249
250 extern mDNSBool SameResourceRecord(ResourceRecord *r1, ResourceRecord *r2);
251
252 extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
253
254 #define GetRRDomainNameTarget(RR) ( \
255 ((RR)->rrtype == kDNSType_CNAME || (RR)->rrtype == kDNSType_PTR || (RR)->rrtype == kDNSType_NS) \
256 ? &(RR)->rdata->u.name : \
257 ((RR)->rrtype == kDNSType_SRV ) ? &(RR)->rdata->u.srv.target : mDNSNULL )
258
259 extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
260 #define LocalRecordReady(X) ((X)->resrec.RecordType != kDNSRecordTypeUnique && (X)->resrec.RecordType != kDNSRecordTypeDeregistering)
261
262
263 // ***************************************************************************
264 #if COMPILER_LIKES_PRAGMA_MARK
265 #pragma mark -
266 #pragma mark -
267 #pragma mark - DNS Message Creation Functions
268 #endif
269
270 extern void InitializeDNSMessage(DNSMessageHeader *h, mDNSOpaque16 id, mDNSOpaque16 flags);
271 extern const mDNSu8 *FindCompressionPointer(const mDNSu8 *const base, const mDNSu8 *const end, const mDNSu8 *const domname);
272
273 extern mDNSu8 *putDomainNameAsLabels(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name);
274
275 extern mDNSu8 *putRData(const DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, ResourceRecord *rr);
276
277 // If we have a single large record to put in the packet, then we allow the packet to be up to 9K bytes,
278 // but in the normal case we try to keep the packets below 1500 to avoid IP fragmentation on standard Ethernet
279
280 extern mDNSu8 *PutResourceRecordTTLWithLimit(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 ttl, const mDNSu8 *limit);
281
282 #define PutResourceRecordTTL(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
283 ((msg)->h.numAnswers || (msg)->h.numAuthorities || (msg)->h.numAdditionals) ? (msg)->data + NormalMaxDNSMessageData : (msg)->data + AbsoluteMaxDNSMessageData)
284
285 #define PutResourceRecordTTLJumbo(msg, ptr, count, rr, ttl) PutResourceRecordTTLWithLimit((msg), (ptr), (count), (rr), (ttl), \
286 (msg)->data + AbsoluteMaxDNSMessageData)
287
288 extern mDNSu8 *PutResourceRecordCappedTTL(DNSMessage *const msg, mDNSu8 *ptr, mDNSu16 *count, ResourceRecord *rr, mDNSu32 maxttl);
289
290 extern mDNSu8 *putEmptyResourceRecord(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, mDNSu16 *count, const AuthRecord *rr);
291
292 extern mDNSu8 *putQuestion(DNSMessage *const msg, mDNSu8 *ptr, const mDNSu8 *const limit, const domainname *const name, mDNSu16 rrtype, mDNSu16 rrclass);
293
294 extern mDNSu8 *putZone(DNSMessage *const msg, mDNSu8 *ptr, mDNSu8 *limit, const domainname *zone, mDNSOpaque16 zoneClass);
295
296 extern mDNSu8 *putPrereqNameNotInUse(domainname *name, DNSMessage *msg, mDNSu8 *ptr, mDNSu8 *end);
297
298 extern mDNSu8 *putDeletionRecord(DNSMessage *msg, mDNSu8 *ptr, ResourceRecord *rr);
299
300 extern mDNSu8 *putDeleteRRSet(DNSMessage *msg, mDNSu8 *ptr, const domainname *name, mDNSu16 rrtype);
301
302 extern mDNSu8 *putDeleteAllRRSets(DNSMessage *msg, mDNSu8 *ptr, const domainname *name);
303
304 extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
305
306 #define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
307
308
309 // ***************************************************************************
310 #if COMPILER_LIKES_PRAGMA_MARK
311 #pragma mark -
312 #pragma mark - DNS Message Parsing Functions
313 #endif
314
315 extern mDNSu32 DomainNameHashValue(const domainname *const name);
316
317 extern void SetNewRData(ResourceRecord *const rr, RData *NewRData, mDNSu16 rdlength);
318
319
320 extern const mDNSu8 *skipDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end);
321
322 extern const mDNSu8 *getDomainName(const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end,
323 domainname *const name);
324
325 extern const mDNSu8 *skipResourceRecord(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
326
327 extern const mDNSu8 *GetLargeResourceRecord(mDNS *const m, const DNSMessage * const msg, const mDNSu8 *ptr,
328 const mDNSu8 * end, const mDNSInterfaceID InterfaceID, mDNSu8 RecordType, LargeCacheRecord *largecr);
329
330 extern const mDNSu8 *skipQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end);
331
332 extern const mDNSu8 *getQuestion(const DNSMessage *msg, const mDNSu8 *ptr, const mDNSu8 *end, const mDNSInterfaceID InterfaceID,
333 DNSQuestion *question);
334
335 extern const mDNSu8 *LocateAnswers(const DNSMessage *const msg, const mDNSu8 *const end);
336
337 extern const mDNSu8 *LocateAuthorities(const DNSMessage *const msg, const mDNSu8 *const end);
338
339 extern const mDNSu8 *LocateAdditionals(const DNSMessage *const msg, const mDNSu8 *const end);
340
341
342 // ***************************************************************************
343 #if COMPILER_LIKES_PRAGMA_MARK
344 #pragma mark -
345 #pragma mark -
346 #pragma mark - Packet Sending Functions
347 #endif
348
349 extern mStatus mDNSSendDNSMessage(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end,
350 mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstport, int sd, uDNS_AuthInfo *authInfo);
351
352
353 // ***************************************************************************
354 #if COMPILER_LIKES_PRAGMA_MARK
355 #pragma mark -
356 #pragma mark - RR List Management & Task Management
357 #endif
358
359 extern void mDNS_Lock(mDNS *const m);
360 extern void mDNS_Unlock(mDNS *const m);
361
362 #ifdef __cplusplus
363 }
364 #endif
365
366 #endif // __DNSCOMMON_H_