]> git.saurik.com Git - apple/mdnsresponder.git/blob - Clients/dnssdutil/DNSMessage.h
mDNSResponder-1310.40.42.tar.gz
[apple/mdnsresponder.git] / Clients / dnssdutil / DNSMessage.h
1 /*
2 Copyright (c) 2016-2020 Apple Inc. All rights reserved.
3 */
4
5 #ifndef __DNSMessage_h
6 #define __DNSMessage_h
7
8 #include <CoreUtils/CommonServices.h>
9
10 CU_ASSUME_NONNULL_BEGIN
11
12 __BEGIN_DECLS
13
14 //---------------------------------------------------------------------------------------------------------------------------
15 /*! @group DNS domain name size limits
16
17 @discussion See <https://tools.ietf.org/html/rfc1035#section-2.3.4>.
18 */
19 #define kDomainLabelLengthMax 63
20 #define kDomainNameLengthMax 256 // For compatibility with mDNS. See <https://tools.ietf.org/html/rfc6762#appendix-C>.
21
22 //---------------------------------------------------------------------------------------------------------------------------
23 /*! @group DNS message header
24 */
25 typedef struct
26 {
27 uint8_t id[ 2 ];
28 uint8_t flags[ 2 ];
29 uint8_t questionCount[ 2 ];
30 uint8_t answerCount[ 2 ];
31 uint8_t authorityCount[ 2 ];
32 uint8_t additionalCount[ 2 ];
33
34 } DNSHeader;
35
36 #define kDNSHeaderLength 12
37 check_compile_time( sizeof( DNSHeader ) == kDNSHeaderLength );
38
39 #define DNSHeaderGetID( HDR ) ReadBig16( ( HDR )->id )
40 #define DNSHeaderGetFlags( HDR ) ReadBig16( ( HDR )->flags )
41 #define DNSHeaderGetQuestionCount( HDR ) ReadBig16( ( HDR )->questionCount )
42 #define DNSHeaderGetAnswerCount( HDR ) ReadBig16( ( HDR )->answerCount )
43 #define DNSHeaderGetAuthorityCount( HDR ) ReadBig16( ( HDR )->authorityCount )
44 #define DNSHeaderGetAdditionalCount( HDR ) ReadBig16( ( HDR )->additionalCount )
45
46 #define DNSHeaderSetID( HDR, X ) WriteBig16( ( HDR )->id, (X) )
47 #define DNSHeaderSetFlags( HDR, X ) WriteBig16( ( HDR )->flags, (X) )
48 #define DNSHeaderSetQuestionCount( HDR, X ) WriteBig16( ( HDR )->questionCount, (X) )
49 #define DNSHeaderSetAnswerCount( HDR, X ) WriteBig16( ( HDR )->answerCount, (X) )
50 #define DNSHeaderSetAuthorityCount( HDR, X ) WriteBig16( ( HDR )->authorityCount, (X) )
51 #define DNSHeaderSetAdditionalCount( HDR, X ) WriteBig16( ( HDR )->additionalCount, (X) )
52
53 // Single-bit DNS header fields
54
55 #define kDNSHeaderFlag_Response ( 1U << 15 ) // QR (bit 15), Query (0)/Response (1)
56 #define kDNSHeaderFlag_AuthAnswer ( 1U << 10 ) // AA (bit 10), Authoritative Answer
57 #define kDNSHeaderFlag_Truncation ( 1U << 9 ) // TC (bit 9), TrunCation
58 #define kDNSHeaderFlag_RecursionDesired ( 1U << 8 ) // RD (bit 8), Recursion Desired
59 #define kDNSHeaderFlag_RecursionAvailable ( 1U << 7 ) // RA (bit 7), Recursion Available
60 #define kDNSHeaderFlag_Z ( 1U << 6 ) // Z (bit 6), Reserved (must be zero)
61 #define kDNSHeaderFlag_AuthenticData ( 1U << 5 ) // AD (bit 5), Authentic Data (RFC 2535, Section 6)
62 #define kDNSHeaderFlag_CheckingDisabled ( 1U << 4 ) // CD (bit 4), Checking Disabled (RFC 2535, Section 6)
63
64 // OPCODE (bits 14-11), Operation Code
65
66 #define DNSFlagsGetOpCode( FLAGS ) ( ( (FLAGS) >> 11 ) & 0x0FU )
67 #define DNSFlagsSetOpCode( FLAGS, OPCODE ) \
68 do { (FLAGS) = ( (FLAGS) & ~0x7800U ) | ( ( (OPCODE) & 0x0FU ) << 11 ); } while( 0 )
69
70 #define kDNSOpCode_Query 0 // QUERY (standard query)
71 #define kDNSOpCode_InverseQuery 1 // IQUERY (inverse query)
72 #define kDNSOpCode_Status 2 // STATUS
73 #define kDNSOpCode_Notify 4 // NOTIFY
74 #define kDNSOpCode_Update 5 // UPDATE
75
76 // RCODE (bits 3-0), Response Code
77
78 #define DNSFlagsGetRCode( FLAGS ) ( (FLAGS) & 0x0FU )
79 #define DNSFlagsSetRCode( FLAGS, RCODE ) \
80 do { (FLAGS) = ( (FLAGS) & ~0x000FU ) | ( ( (unsigned int)(RCODE) ) & 0x0FU ); } while( 0 )
81
82 //---------------------------------------------------------------------------------------------------------------------------
83 /*! @group Multicast DNS Constants
84 */
85
86 #define kMDNSClassUnicastResponseBit ( 1U << 15 ) // See <https://tools.ietf.org/html/rfc6762#section-18.12>.
87 #define kMDNSClassCacheFlushBit ( 1U << 15 ) // See <https://tools.ietf.org/html/rfc6762#section-18.13>.
88
89 //---------------------------------------------------------------------------------------------------------------------------
90 /*! @group Misc. DNS message data structures
91 */
92
93 #define _DNSMessageGet8( PTR ) Read8( PTR )
94 #define _DNSMessageGet16( PTR ) ReadBig16( PTR )
95 #define _DNSMessageGet32( PTR ) ReadBig32( PTR )
96 #define _DNSMessageSet8( PTR, X ) Write8( PTR, X )
97 #define _DNSMessageSet16( PTR, X ) WriteBig16( PTR, X )
98 #define _DNSMessageSet32( PTR, X ) WriteBig32( PTR, X )
99
100 #define dns_fields_define_accessors( PREFIX, TYPE, FIELD, BIT_SIZE ) \
101 STATIC_INLINE uint ## BIT_SIZE ## _t \
102 dns_ ## PREFIX ## _ ## TYPE ## _get_ ## FIELD ( \
103 const dns_ ## PREFIX ## _ ## TYPE * inFields ) \
104 { \
105 return _DNSMessageGet ## BIT_SIZE ( inFields->FIELD ); \
106 } \
107 \
108 STATIC_INLINE void \
109 dns_ ## PREFIX ## _ ## TYPE ## _set_ ## FIELD ( \
110 dns_ ## PREFIX ## _ ## TYPE * inFields, \
111 uint ## BIT_SIZE ## _t inValue ) \
112 { \
113 _DNSMessageSet ## BIT_SIZE ( inFields->FIELD, inValue ); \
114 } \
115 check_compile_time( ( sizeof_field( dns_ ## PREFIX ## _ ## TYPE, FIELD ) * 8 ) == (BIT_SIZE) )
116
117 #define dns_fixed_fields_define_accessors( TYPE, FIELD, BIT_SIZE ) \
118 dns_fields_define_accessors( fixed_fields, TYPE, FIELD, BIT_SIZE )
119
120 #define dns_dnskey_fields_define_accessors( TYPE, FIELD, BIT_SIZE ) \
121 dns_fields_define_accessors( dnskey, TYPE, FIELD, BIT_SIZE )
122
123 #define dns_ds_fields_define_accessors( TYPE, FIELD, BIT_SIZE ) \
124 dns_fields_define_accessors( ds, TYPE, FIELD, BIT_SIZE )
125
126 // DNS question fixed-length fields
127 // See <https://tools.ietf.org/html/rfc1035#section-4.1.2>
128
129 typedef struct
130 {
131 uint8_t type[ 2 ];
132 uint8_t class[ 2 ];
133
134 } dns_fixed_fields_question;
135
136 check_compile_time( sizeof( dns_fixed_fields_question ) == 4 );
137
138 dns_fixed_fields_define_accessors( question, type, 16 );
139 dns_fixed_fields_define_accessors( question, class, 16 );
140
141 STATIC_INLINE void
142 dns_fixed_fields_question_init(
143 dns_fixed_fields_question * inFields,
144 uint16_t inQType,
145 uint16_t inQClass )
146 {
147 dns_fixed_fields_question_set_type( inFields, inQType );
148 dns_fixed_fields_question_set_class( inFields, inQClass );
149 }
150
151 // DNS resource record fixed-length fields
152 // See <https://tools.ietf.org/html/rfc1035#section-4.1.3>
153
154 typedef struct
155 {
156 uint8_t type[ 2 ];
157 uint8_t class[ 2 ];
158 uint8_t ttl[ 4 ];
159 uint8_t rdlength[ 2 ];
160
161 } dns_fixed_fields_record;
162
163 check_compile_time( sizeof( dns_fixed_fields_record ) == 10 );
164
165 dns_fixed_fields_define_accessors( record, type, 16 );
166 dns_fixed_fields_define_accessors( record, class, 16 );
167 dns_fixed_fields_define_accessors( record, ttl, 32 );
168 dns_fixed_fields_define_accessors( record, rdlength, 16 );
169
170 STATIC_INLINE void
171 dns_fixed_fields_record_init(
172 dns_fixed_fields_record * inFields,
173 uint16_t inType,
174 uint16_t inClass,
175 uint32_t inTTL,
176 uint16_t inRDLength )
177 {
178 dns_fixed_fields_record_set_type( inFields, inType );
179 dns_fixed_fields_record_set_class( inFields, inClass );
180 dns_fixed_fields_record_set_ttl( inFields, inTTL );
181 dns_fixed_fields_record_set_rdlength( inFields, inRDLength );
182 }
183
184 // DNS SRV record data fixed-length fields
185 // See <https://tools.ietf.org/html/rfc2782>
186
187 typedef struct
188 {
189 uint8_t priority[ 2 ];
190 uint8_t weight[ 2 ];
191 uint8_t port[ 2 ];
192
193 } dns_fixed_fields_srv;
194
195 check_compile_time( sizeof( dns_fixed_fields_srv ) == 6 );
196
197 dns_fixed_fields_define_accessors( srv, priority, 16 );
198 dns_fixed_fields_define_accessors( srv, weight, 16 );
199 dns_fixed_fields_define_accessors( srv, port, 16 );
200
201 STATIC_INLINE void
202 dns_fixed_fields_srv_init(
203 dns_fixed_fields_srv * inFields,
204 uint16_t inPriority,
205 uint16_t inWeight,
206 uint16_t inPort )
207 {
208 dns_fixed_fields_srv_set_priority( inFields, inPriority );
209 dns_fixed_fields_srv_set_weight( inFields, inWeight );
210 dns_fixed_fields_srv_set_port( inFields, inPort );
211 }
212
213 // DNS SOA record data fixed-length fields
214 // See <https://tools.ietf.org/html/rfc1035#section-3.3.13>
215
216 typedef struct
217 {
218 uint8_t serial[ 4 ];
219 uint8_t refresh[ 4 ];
220 uint8_t retry[ 4 ];
221 uint8_t expire[ 4 ];
222 uint8_t minimum[ 4 ];
223
224 } dns_fixed_fields_soa;
225
226 check_compile_time( sizeof( dns_fixed_fields_soa ) == 20 );
227
228 dns_fixed_fields_define_accessors( soa, serial, 32 );
229 dns_fixed_fields_define_accessors( soa, refresh, 32 );
230 dns_fixed_fields_define_accessors( soa, retry, 32 );
231 dns_fixed_fields_define_accessors( soa, expire, 32 );
232 dns_fixed_fields_define_accessors( soa, minimum, 32 );
233
234 STATIC_INLINE void
235 dns_fixed_fields_soa_init(
236 dns_fixed_fields_soa * inFields,
237 uint32_t inSerial,
238 uint32_t inRefresh,
239 uint32_t inRetry,
240 uint32_t inExpire,
241 uint32_t inMinimum )
242 {
243 dns_fixed_fields_soa_set_serial( inFields, inSerial );
244 dns_fixed_fields_soa_set_refresh( inFields, inRefresh );
245 dns_fixed_fields_soa_set_retry( inFields, inRetry );
246 dns_fixed_fields_soa_set_expire( inFields, inExpire );
247 dns_fixed_fields_soa_set_minimum( inFields, inMinimum );
248 }
249
250 // OPT pseudo-resource record fixed-length fields without RDATA
251 // See <https://tools.ietf.org/html/rfc6891#section-6.1.2>
252
253 typedef struct
254 {
255 uint8_t name[ 1 ];
256 uint8_t type[ 2 ];
257 uint8_t udp_payload_size[ 2 ];
258 uint8_t extended_rcode[ 1 ];
259 uint8_t version[ 1 ];
260 uint8_t extended_flags[ 2 ];
261 uint8_t rdlen[ 2 ];
262
263 } dns_fixed_fields_opt;
264
265 check_compile_time( sizeof( dns_fixed_fields_opt ) == 11 );
266
267 #define kDNSExtendedFlag_DNSSECOK ( 1U << 15 ) // <https://tools.ietf.org/html/rfc3225#section-3>
268
269 dns_fixed_fields_define_accessors( opt, name, 8 );
270 dns_fixed_fields_define_accessors( opt, type, 16 );
271 dns_fixed_fields_define_accessors( opt, udp_payload_size, 16 );
272 dns_fixed_fields_define_accessors( opt, extended_rcode, 8 );
273 dns_fixed_fields_define_accessors( opt, version, 8 );
274 dns_fixed_fields_define_accessors( opt, extended_flags, 16 );
275 dns_fixed_fields_define_accessors( opt, rdlen, 16 );
276
277 // OPT pseudo-resource record fixed-length fields with OPTION-CODE and OPTION-LENGTH
278 // See <https://tools.ietf.org/html/rfc6891#section-6.1.2>
279
280 typedef struct
281 {
282 uint8_t name[ 1 ];
283 uint8_t type[ 2 ];
284 uint8_t udp_payload_size[ 2 ];
285 uint8_t extended_rcode[ 1 ];
286 uint8_t version[ 1 ];
287 uint8_t extended_flags[ 2 ];
288 uint8_t rdlen[ 2 ];
289 uint8_t option_code[ 2 ];
290 uint8_t option_length[ 2 ];
291
292 } dns_fixed_fields_opt1;
293
294 check_compile_time( sizeof( dns_fixed_fields_opt1 ) == 15 );
295
296 dns_fixed_fields_define_accessors( opt1, name, 8 );
297 dns_fixed_fields_define_accessors( opt1, type, 16 );
298 dns_fixed_fields_define_accessors( opt1, udp_payload_size, 16 );
299 dns_fixed_fields_define_accessors( opt1, extended_rcode, 8 );
300 dns_fixed_fields_define_accessors( opt1, version, 8 );
301 dns_fixed_fields_define_accessors( opt1, extended_flags, 16 );
302 dns_fixed_fields_define_accessors( opt1, rdlen, 16 );
303 dns_fixed_fields_define_accessors( opt1, option_code, 16 );
304 dns_fixed_fields_define_accessors( opt1, option_length, 16 );
305
306 // OPT pseudo-resource record RDATA option fixed-length fields
307 // See <https://tools.ietf.org/html/rfc6891#section-6.1.2>
308
309 typedef struct
310 {
311 uint8_t code[ 2 ];
312 uint8_t length[ 2 ];
313
314 } dns_fixed_fields_option;
315
316 check_compile_time( sizeof( dns_fixed_fields_option ) == 4 );
317
318 dns_fixed_fields_define_accessors( option, code, 16 );
319 dns_fixed_fields_define_accessors( option, length, 16 );
320
321 // DNS DNSKEY record data fixed-length fields
322 // See <https://tools.ietf.org/html/rfc4034#section-2.1>
323
324 typedef struct
325 {
326 uint8_t flags[ 2 ];
327 uint8_t protocol[ 1 ];
328 uint8_t algorithm[ 1 ];
329
330 } dns_fixed_fields_dnskey;
331
332 check_compile_time( sizeof( dns_fixed_fields_dnskey ) == 4 );
333
334 dns_fixed_fields_define_accessors( dnskey, flags, 16 );
335 dns_fixed_fields_define_accessors( dnskey, protocol, 8 );
336 dns_fixed_fields_define_accessors( dnskey, algorithm, 8 );
337
338 #define kDNSKeyFlag_ZoneKey ( 1U << ( 15 - 7 ) ) // MSB bit 7 <https://tools.ietf.org/html/rfc4034#section-2.1.1>
339 #define kDNSKeyFlag_SEP ( 1U << ( 15 - 15 ) ) // MSB bit 15 <https://tools.ietf.org/html/rfc4034#section-2.1.1>
340
341 #define kDNSKeyProtocol_DNSSEC 3 // Protocol value must be 3. <https://tools.ietf.org/html/rfc4034#section-2.1.2>
342
343 // DNSSEC Algoritm Numbers
344 // See <https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml#dns-sec-alg-numbers-1>
345
346 #define kDNSSECAlgorithm_RSASHA1 5 // RSA/SHA-1
347 #define kDNSSECAlgorithm_RSASHA256 8 // RSA/SHA-256
348 #define kDNSSECAlgorithm_RSASHA512 10 // RSA/SHA-512
349 #define kDNSSECAlgorithm_ECDSAP256SHA256 13 // ECDSA P-256 curve/SHA-256
350 #define kDNSSECAlgorithm_ECDSAP384SHA384 14 // ECDSA P-384 curve/SHA-384
351 #define kDNSSECAlgorithm_Ed25519 15 // Ed25519
352
353 // DNS RRSIG record data fixed-length fields
354 // See <https://tools.ietf.org/html/rfc4034#section-3.1>
355
356 typedef struct
357 {
358 uint8_t type_covered[ 2 ];
359 uint8_t algorithm[ 1 ];
360 uint8_t labels[ 1 ];
361 uint8_t original_ttl[ 4 ];
362 uint8_t signature_expiration[ 4 ];
363 uint8_t signature_inception[ 4 ];
364 uint8_t key_tag[ 2 ];
365
366 } dns_fixed_fields_rrsig;
367
368 check_compile_time( sizeof( dns_fixed_fields_rrsig ) == 18 );
369
370 dns_fixed_fields_define_accessors( rrsig, type_covered, 16 );
371 dns_fixed_fields_define_accessors( rrsig, algorithm, 8 );
372 dns_fixed_fields_define_accessors( rrsig, labels, 8 );
373 dns_fixed_fields_define_accessors( rrsig, original_ttl, 32 );
374 dns_fixed_fields_define_accessors( rrsig, signature_expiration, 32 );
375 dns_fixed_fields_define_accessors( rrsig, signature_inception, 32 );
376 dns_fixed_fields_define_accessors( rrsig, key_tag, 16 );
377
378 // DNS DS record data fixed-length fields
379 // See <https://tools.ietf.org/html/rfc4034#section-5.1>
380
381 typedef struct
382 {
383 uint8_t key_tag[ 2 ];
384 uint8_t algorithm[ 1 ];
385 uint8_t digest_type[ 1 ];
386
387 } dns_fixed_fields_ds;
388
389 check_compile_time( sizeof( dns_fixed_fields_ds ) == 4 );
390
391 dns_fixed_fields_define_accessors( ds, key_tag, 16 );
392 dns_fixed_fields_define_accessors( ds, algorithm, 8 );
393 dns_fixed_fields_define_accessors( ds, digest_type, 8 );
394
395 #define kDSDigestType_SHA1 1 // SHA-1 <https://tools.ietf.org/html/rfc4034#appendix-A.2>
396 #define kDSDigestType_SHA256 2 // SHA-256 <https://tools.ietf.org/html/rfc4509#section-5>
397
398 // DNS DS record data
399 // See <https://tools.ietf.org/html/rfc4509#section-2.2>
400
401 typedef struct
402 {
403 uint8_t key_tag[ 2 ];
404 uint8_t algorithm[ 1 ];
405 uint8_t digest_type[ 1 ];
406 uint8_t digest[ 32 ];
407
408 } dns_ds_sha256;
409
410 check_compile_time( sizeof( dns_ds_sha256 ) == 36 );
411
412 dns_ds_fields_define_accessors( sha256, key_tag, 16 );
413 dns_ds_fields_define_accessors( sha256, algorithm, 8 );
414 dns_ds_fields_define_accessors( sha256, digest_type, 8 );
415
416 // DNS NSEC3 record data fixed-length fields
417 // See <https://tools.ietf.org/html/rfc5155#section-3.2>
418
419 typedef struct
420 {
421 uint8_t hash_alg[ 1 ];
422 uint8_t flags[ 1 ];
423 uint8_t iterations[ 2 ];
424
425 } dns_fixed_fields_nsec3;
426
427 check_compile_time( sizeof( dns_fixed_fields_nsec3 ) == 4 );
428
429 dns_fixed_fields_define_accessors( nsec3, hash_alg, 8 );
430 dns_fixed_fields_define_accessors( nsec3, flags, 8 );
431 dns_fixed_fields_define_accessors( nsec3, iterations, 16 );
432
433 // DNS SVCB record data fixed-length fields
434 // See <https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-00#section-2.2>
435
436 typedef struct
437 {
438 uint8_t priority[ 2 ];
439
440 } dns_fixed_fields_svcb;
441
442 check_compile_time( sizeof( dns_fixed_fields_svcb ) == 2 );
443
444 dns_fixed_fields_define_accessors( svcb, priority, 16 );
445
446 typedef struct
447 {
448 uint8_t key[ 2 ];
449 uint8_t value_length[ 2 ];
450
451 } dns_fixed_fields_svcb_param;
452
453 check_compile_time( sizeof( dns_fixed_fields_svcb_param ) == 4 );
454
455 dns_fixed_fields_define_accessors( svcb_param, key, 16 );
456 dns_fixed_fields_define_accessors( svcb_param, value_length, 16 );
457
458 //---------------------------------------------------------------------------------------------------------------------------
459 /*! @group DNS record types
460 */
461 // This code was autogenerated on 2020-06-30 by dns-rr-func-autogen version 1.3
462 // Data source URL: https://www.iana.org/assignments/dns-parameters/dns-parameters-4.csv
463 // Overrides: none
464
465 typedef enum
466 {
467 kDNSRecordType_A = 1,
468 kDNSRecordType_NS = 2,
469 kDNSRecordType_MD = 3,
470 kDNSRecordType_MF = 4,
471 kDNSRecordType_CNAME = 5,
472 kDNSRecordType_SOA = 6,
473 kDNSRecordType_MB = 7,
474 kDNSRecordType_MG = 8,
475 kDNSRecordType_MR = 9,
476 kDNSRecordType_NULL = 10,
477 kDNSRecordType_WKS = 11,
478 kDNSRecordType_PTR = 12,
479 kDNSRecordType_HINFO = 13,
480 kDNSRecordType_MINFO = 14,
481 kDNSRecordType_MX = 15,
482 kDNSRecordType_TXT = 16,
483 kDNSRecordType_RP = 17,
484 kDNSRecordType_AFSDB = 18,
485 kDNSRecordType_X25 = 19,
486 kDNSRecordType_ISDN = 20,
487 kDNSRecordType_RT = 21,
488 kDNSRecordType_NSAP = 22,
489 kDNSRecordType_NSAP_PTR = 23,
490 kDNSRecordType_SIG = 24,
491 kDNSRecordType_KEY = 25,
492 kDNSRecordType_PX = 26,
493 kDNSRecordType_GPOS = 27,
494 kDNSRecordType_AAAA = 28,
495 kDNSRecordType_LOC = 29,
496 kDNSRecordType_NXT = 30,
497 kDNSRecordType_EID = 31,
498 kDNSRecordType_NIMLOC = 32,
499 kDNSRecordType_SRV = 33,
500 kDNSRecordType_ATMA = 34,
501 kDNSRecordType_NAPTR = 35,
502 kDNSRecordType_KX = 36,
503 kDNSRecordType_CERT = 37,
504 kDNSRecordType_A6 = 38,
505 kDNSRecordType_DNAME = 39,
506 kDNSRecordType_SINK = 40,
507 kDNSRecordType_OPT = 41,
508 kDNSRecordType_APL = 42,
509 kDNSRecordType_DS = 43,
510 kDNSRecordType_SSHFP = 44,
511 kDNSRecordType_IPSECKEY = 45,
512 kDNSRecordType_RRSIG = 46,
513 kDNSRecordType_NSEC = 47,
514 kDNSRecordType_DNSKEY = 48,
515 kDNSRecordType_DHCID = 49,
516 kDNSRecordType_NSEC3 = 50,
517 kDNSRecordType_NSEC3PARAM = 51,
518 kDNSRecordType_TLSA = 52,
519 kDNSRecordType_SMIMEA = 53,
520 kDNSRecordType_HIP = 55,
521 kDNSRecordType_NINFO = 56,
522 kDNSRecordType_RKEY = 57,
523 kDNSRecordType_TALINK = 58,
524 kDNSRecordType_CDS = 59,
525 kDNSRecordType_CDNSKEY = 60,
526 kDNSRecordType_OPENPGPKEY = 61,
527 kDNSRecordType_CSYNC = 62,
528 kDNSRecordType_ZONEMD = 63,
529 kDNSRecordType_SVCB = 64,
530 kDNSRecordType_HTTPS = 65,
531 kDNSRecordType_SPF = 99,
532 kDNSRecordType_UINFO = 100,
533 kDNSRecordType_UID = 101,
534 kDNSRecordType_GID = 102,
535 kDNSRecordType_UNSPEC = 103,
536 kDNSRecordType_NID = 104,
537 kDNSRecordType_L32 = 105,
538 kDNSRecordType_L64 = 106,
539 kDNSRecordType_LP = 107,
540 kDNSRecordType_EUI48 = 108,
541 kDNSRecordType_EUI64 = 109,
542 kDNSRecordType_TKEY = 249,
543 kDNSRecordType_TSIG = 250,
544 kDNSRecordType_IXFR = 251,
545 kDNSRecordType_AXFR = 252,
546 kDNSRecordType_MAILB = 253,
547 kDNSRecordType_MAILA = 254,
548 kDNSRecordType_ANY = 255,
549 kDNSRecordType_URI = 256,
550 kDNSRecordType_CAA = 257,
551 kDNSRecordType_AVC = 258,
552 kDNSRecordType_DOA = 259,
553 kDNSRecordType_AMTRELAY = 260,
554 kDNSRecordType_TA = 32768,
555 kDNSRecordType_DLV = 32769,
556 kDNSRecordType_Reserved = 65535,
557
558 } DNSRecordType;
559
560 //---------------------------------------------------------------------------------------------------------------------------
561 /*! @group DNS RCODEs
562 */
563 // This code was autogenerated on 2020-06-15 by dns-rcode-func-autogen version 1.0
564 // Data source URL: https://www.iana.org/assignments/dns-parameters/dns-parameters-6.csv
565
566 typedef enum
567 {
568 kDNSRCode_NoError = 0,
569 kDNSRCode_FormErr = 1,
570 kDNSRCode_ServFail = 2,
571 kDNSRCode_NXDomain = 3,
572 kDNSRCode_NotImp = 4,
573 kDNSRCode_Refused = 5,
574 kDNSRCode_YXDomain = 6,
575 kDNSRCode_YXRRSet = 7,
576 kDNSRCode_NXRRSet = 8,
577 kDNSRCode_NotAuth = 9,
578 kDNSRCode_NotZone = 10,
579 kDNSRCode_DSOTYPENI = 11
580
581 } DNSRCode;
582
583 //---------------------------------------------------------------------------------------------------------------------------
584 /*! @group DNS classes
585 */
586
587 typedef enum
588 {
589 kDNSClassType_IN = 1 // See <https://tools.ietf.org/html/rfc1035#section-3.2.4>.
590
591 } DNSClassType;
592
593 //---------------------------------------------------------------------------------------------------------------------------
594 /*! @group DNS EDNS0 Option Codes
595 */
596 typedef enum
597 {
598 kDNSEDNS0OptionCode_Padding = 12 // <https://tools.ietf.org/html/rfc7830#section-3>
599
600 } DNSEDNS0OptionCode;
601
602 //---------------------------------------------------------------------------------------------------------------------------
603 /*! @group DNS EDNS0 Option Codes
604 @discussion See <https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-00#section-12.1.2>.
605 */
606 typedef enum
607 {
608 kDNSSVCParamKey_Mandatory = 0,
609 kDNSSVCParamKey_ALPN = 1,
610 kDNSSVCParamKey_NoDefaultALPN = 2,
611 kDNSSVCParamKey_Port = 3,
612 kDNSSVCParamKey_IPv4Hint = 4,
613 kDNSSVCParamKey_ECHConfig = 5,
614 kDNSSVCParamKey_IPv6Hint = 6,
615 kDNSSVCParamKey_DOHURI = 32768 // XXX: Apple Internal
616
617 } DNSSVCParamKey;
618
619 //---------------------------------------------------------------------------------------------------------------------------
620 /*! @brief Extracts a domain name from a DNS message.
621
622 @param inMsgPtr Pointer to the beginning of the DNS message containing the domain name.
623 @param inMsgLen Length of the DNS message containing the domain name.
624 @param inPtr Pointer to the domain name field.
625 @param outName Buffer to write extracted domain name. (Optional)
626 @param outPtr Gets set to point to the end of the domain name field. (Optional)
627 */
628 OSStatus
629 DNSMessageExtractDomainName(
630 const uint8_t * inMsgPtr,
631 size_t inMsgLen,
632 const uint8_t * inPtr,
633 uint8_t outName[ _Nullable kDomainNameLengthMax ],
634 const uint8_t * _Nullable * _Nullable outPtr );
635
636 //---------------------------------------------------------------------------------------------------------------------------
637 /*! @brief Extracts a domain name from a DNS message as a C string.
638
639 @param inMsgPtr Pointer to the beginning of the DNS message containing the domain name.
640 @param inMsgLen Length of the DNS message containing the domain name.
641 @param inPtr Pointer to the domain name field.
642 @param outName Buffer to write extracted domain name. (Optional)
643 @param outPtr Gets set to point to the end of the domain name field. (Optional)
644 */
645 OSStatus
646 DNSMessageExtractDomainNameString(
647 const void * inMsgPtr,
648 size_t inMsgLen,
649 const void * inPtr,
650 char outName[ _Nullable kDNSServiceMaxDomainName ],
651 const uint8_t * _Nullable * _Nullable outPtr );
652
653 //---------------------------------------------------------------------------------------------------------------------------
654 /*! @brief Extracts a question from a DNS message.
655
656 @param inMsgPtr Pointer to the beginning of the DNS message containing a question.
657 @param inMsgLen Length of the DNS message containing the question.
658 @param inPtr Pointer to the question.
659 @param outName Buffer to write the question's QNAME. (Optional)
660 @param outType Gets set to question's QTYPE value. (Optional)
661 @param outClass Gets set to question's QCLASS value. (Optional)
662 @param outPtr Gets set to point to the end of the question. (Optional)
663 */
664 OSStatus
665 DNSMessageExtractQuestion(
666 const uint8_t * inMsgPtr,
667 size_t inMsgLen,
668 const uint8_t * inPtr,
669 uint8_t outName[ _Nullable kDomainNameLengthMax ],
670 uint16_t * _Nullable outType,
671 uint16_t * _Nullable outClass,
672 const uint8_t * _Nullable * _Nullable outPtr );
673
674 //---------------------------------------------------------------------------------------------------------------------------
675 /*! @brief Extracts a resource record from a DNS message.
676
677 @param inMsgPtr Pointer to the beginning of the DNS message containing the resource record.
678 @param inMsgLen Length of the DNS message containing the resource record.
679 @param inPtr Pointer to the resource record.
680 @param outName Buffer to write the resource record's NAME. (Optional)
681 @param outType Gets set to resource record's TYPE value. (Optional)
682 @param outClass Gets set to resource record's CLASS value. (Optional)
683 @param outTTL Gets set to resource record's TTL value. (Optional)
684 @param outRDataPtr Gets set to point to the resource record's RDATA. (Optional)
685 @param outRDataLen Gets set to the resource record's RDLENGTH. (Optional)
686 @param outPtr Gets set to point to the end of the resource record. (Optional)
687 */
688 OSStatus
689 DNSMessageExtractRecord(
690 const uint8_t * inMsgPtr,
691 size_t inMsgLen,
692 const uint8_t * inPtr,
693 uint8_t outName[ _Nullable kDomainNameLengthMax ],
694 uint16_t * _Nullable outType,
695 uint16_t * _Nullable outClass,
696 uint32_t * _Nullable outTTL,
697 const uint8_t * _Nullable * _Nullable outRDataPtr,
698 size_t * _Nullable outRDataLen,
699 const uint8_t * _Nullable * _Nullable outPtr );
700
701 //---------------------------------------------------------------------------------------------------------------------------
702 /*! @brief Gets a DNS message's answer section, i.e., the end of the message's question section.
703
704 @param inMsgPtr Pointer to the beginning of the DNS message.
705 @param inMsgLen Length of the DNS message.
706 @param outPtr Gets set to point to the start of the answer section. (Optional)
707 */
708 OSStatus
709 DNSMessageGetAnswerSection(
710 const uint8_t * inMsgPtr,
711 size_t inMsgLen,
712 const uint8_t * _Nullable * _Nullable outPtr );
713
714 //---------------------------------------------------------------------------------------------------------------------------
715 /*! @brief Gets a DNS message's OPT record if it exists.
716
717 @param inMsgPtr Pointer to the beginning of the DNS message.
718 @param inMsgLen Length of the DNS message.
719 @param outOptPtr Gets set to point to the start of the OPT record. (Optional)
720 @param outOptLen Gets set to point to the length of the OPT record. (Optional)
721 */
722 OSStatus
723 DNSMessageGetOptRecord(
724 const uint8_t * inMsgPtr,
725 size_t inMsgLen,
726 const uint8_t * _Nullable * _Nullable outOptPtr,
727 size_t * _Nullable outOptLen );
728
729 //---------------------------------------------------------------------------------------------------------------------------
730 /*! @brief Writes a DNS message compression label pointer.
731
732 @param inLabelPtr Pointer to the two bytes to which to write the label pointer.
733 @param inOffset The label pointer's offset value. This offset is relative to the start of the DNS message.
734
735 @discussion See <https://tools.ietf.org/html/rfc1035#section-4.1.4>.
736 */
737 STATIC_INLINE void DNSMessageWriteLabelPointer( uint8_t inLabelPtr[ STATIC_PARAM 2 ], size_t inOffset )
738 {
739 inLabelPtr[ 0 ] = (uint8_t)( ( ( inOffset >> 8 ) & 0x3F ) | 0xC0 );
740 inLabelPtr[ 1 ] = (uint8_t)( inOffset & 0xFF );
741 }
742
743 #define kDNSCompressionOffsetMax 0x3FFF
744 #define kDNSCompressionPointerLength 2
745
746 //---------------------------------------------------------------------------------------------------------------------------
747 #define kDNSQueryMessageMaxLen ( kDNSHeaderLength + kDomainNameLengthMax + sizeof( dns_fixed_fields_question ) )
748
749 /*! @brief Writes a single-question DNS query message.
750
751 @param inMsgID The query message's ID.
752 @param inFlags The query message's flags.
753 @param inQName The question's QNAME in label format.
754 @param inQType The question's QTYPE.
755 @param inQClass The question's QCLASS.
756 @param outMsg Buffer to write DNS query message.
757 @param outLen Gets set to the length of the DNS query message.
758 */
759 OSStatus
760 DNSMessageWriteQuery(
761 uint16_t inMsgID,
762 uint16_t inFlags,
763 const uint8_t * inQName,
764 uint16_t inQType,
765 uint16_t inQClass,
766 uint8_t outMsg[ STATIC_PARAM kDNSQueryMessageMaxLen ],
767 size_t * outLen );
768
769 //---------------------------------------------------------------------------------------------------------------------------
770 /*! @brief Creates a collapsed version of a DNS message.
771
772 @param inMsgPtr Pointer to the start of the DNS message.
773 @param inMsgLen Length of the DNS message.
774 @param outMsgLen Pointer of variable to set to the length of the collapsed DNS message.
775 @param outError Pointer of variable to set to the error encountered by this function, if any.
776
777 @result A dynamically allocated collapsed version of the DNS message.
778
779 @discussion This function creates a copy of a DNS message, except that
780
781 1. All records not in the Authority and Additional sections are removed.
782 2. The CNAME chain, if any, from the QNAME to the non-CNAME records is collapsed, i.e., all CNAME records are removed.
783 3. All records that are not direct or indirect answers to the question are also removed.
784
785 Note: Collapsing a DNS message is a non-standard operation and should be used with caution.
786 */
787 uint8_t * _Nullable
788 DNSMessageCollapse(
789 const uint8_t * inMsgPtr,
790 size_t inMsgLen,
791 size_t * _Nullable outMsgLen,
792 OSStatus * _Nullable outError );
793
794 //---------------------------------------------------------------------------------------------------------------------------
795 /*! @brief Appends one domain name to another.
796
797 @param inName Pointer to the target domain name.
798 @param inOtherName Pointer to the domain name to append to the target domain name.
799 @param outEnd Gets set to point to the new end of the domain name if the append succeeded. (Optional)
800 */
801 OSStatus
802 DomainNameAppendDomainName(
803 uint8_t inName[ STATIC_PARAM kDomainNameLengthMax ],
804 const uint8_t * inOtherName,
805 uint8_t * _Nullable * _Nullable outEnd );
806
807 //---------------------------------------------------------------------------------------------------------------------------
808 /*! @brief Appends a C string representing a textual sequence of labels to a domain name.
809
810 @param inName Pointer to the domain name.
811 @param inString Pointer to textual sequence of labels as a C string.
812 @param outEnd Gets set to point to the new end of the domain name if the append succeeded. (Optional)
813 */
814 OSStatus
815 DomainNameAppendString(
816 uint8_t inName[ STATIC_PARAM kDomainNameLengthMax ],
817 const char * inString,
818 uint8_t * _Nullable * _Nullable outEnd );
819
820 //---------------------------------------------------------------------------------------------------------------------------
821 /*! @brief Creates a duplicate domain name.
822
823 @param inName The domain name to duplicate.
824 @param inLower If true, uppercase letters in the duplicate are converted to lowercase.
825 @param outNamePtr Gets set to point to a dynamically allocated duplicate.
826 @param outNameLen Gets set to the length of the duplicate. (Optional)
827
828 @discussion The duplicate domain name must be freed with free() when no longer needed.
829 */
830 OSStatus
831 DomainNameDupEx(
832 const uint8_t * inName,
833 Boolean inLower,
834 uint8_t * _Nullable * _Nonnull outNamePtr,
835 size_t * _Nullable outNameLen );
836
837 #define DomainNameDup( IN_NAME, OUT_NAME, OUT_LEN ) DomainNameDupEx( IN_NAME, false, OUT_NAME, OUT_LEN )
838 #define DomainNameDupLower( IN_NAME, OUT_NAME, OUT_LEN ) DomainNameDupEx( IN_NAME, true, OUT_NAME, OUT_LEN )
839
840 //---------------------------------------------------------------------------------------------------------------------------
841 /*! @brief Compares two domain names in label format for case-insensitive equality.
842
843 @param inName1 Pointer to the first domain name.
844 @param inName2 Pointer to the second domain name.
845
846 @result If the domain names are equal, returns true, otherwise, returns false.
847 */
848 Boolean DomainNameEqual( const uint8_t *inName1, const uint8_t *inName2 );
849
850 //---------------------------------------------------------------------------------------------------------------------------
851 /*! @brief Converts a domain name's textual representation to a domain name in label format.
852
853 @param outName Buffer to write the domain name in label format.
854 @param inString Textual representation of a domain name as a C string.
855 @param outEnd Gets set to point to the new end of the domain name if the append succeeded. (Optional)
856 */
857 OSStatus
858 DomainNameFromString(
859 uint8_t outName[ STATIC_PARAM kDomainNameLengthMax ],
860 const char * inString,
861 uint8_t * _Nullable * _Nullable outEnd );
862
863 //---------------------------------------------------------------------------------------------------------------------------
864 /*! @brief Gets the next label in a domain name label sequence.
865
866 @param inLabel Pointer to the current label.
867
868 @result If the current label is a root label, returns NULL. Otherwise, returns the next label.
869 */
870 STATIC_INLINE const uint8_t * DomainNameGetNextLabel( const uint8_t *inLabel )
871 {
872 const int len = *inLabel;
873 return ( ( len == 0 ) ? NULL : &inLabel[ 1 + len ] );
874 }
875
876 //---------------------------------------------------------------------------------------------------------------------------
877 /*! @brief Returns the length of a domain name.
878
879 @param inName The domain name in label format.
880 */
881 size_t DomainNameLength( const uint8_t *inName );
882
883 //---------------------------------------------------------------------------------------------------------------------------
884 /*! @brief Returns the number of labels that make up a domain name.
885
886 @param inName The uncompressed domain name in label format.
887
888 @result Returns -1 if the domain name is malformed. Otherwise, returns the number of labels, not counting the root.
889 */
890 int DomainNameLabelCount( const uint8_t *inName );
891
892 //---------------------------------------------------------------------------------------------------------------------------
893 /*! @brief Converts a domain name in label format to its textual representation as a C string.
894
895 @param inName Pointer to the domain name.
896 @param inLimit Pointer to not exceed while parsing a potentially truncated domain name. (Optional)
897 @param outString Buffer to write the C string.
898 @param outPtr Gets set to point to the end of the domain name. (Optional)
899 */
900 OSStatus
901 DomainNameToString(
902 const uint8_t * inName,
903 const uint8_t * _Nullable inLimit,
904 char outString[ STATIC_PARAM kDNSServiceMaxDomainName ],
905 const uint8_t * _Nullable * _Nullable outPtr );
906
907 //---------------------------------------------------------------------------------------------------------------------------
908 /*! @brief Compares two domain name labels for case-insensitive equality.
909
910 @param inLabel1 Pointer to the first label.
911 @param inLabel2 Pointer to the second label.
912
913 @result If the label are equal, returns true. Otherwise, returns false.
914 */
915 Boolean DomainLabelEqual( const uint8_t *inLabel1, const uint8_t *inLabel2 );
916
917 //---------------------------------------------------------------------------------------------------------------------------
918 /*! @brief For a resource record type's numeric value, returns the resource record type's mnemonic as a C string.
919
920 @param inValue A resource record type's numeric value.
921
922 @result The resource record type's mnemonic as a C string if the numeric value is recognized, otherwise, NULL.
923 */
924 const char * _Nullable DNSRecordTypeValueToString( int inValue );
925
926 //---------------------------------------------------------------------------------------------------------------------------
927 /*! @brief For a resource record type's mnemonic, returns the resource record type's numeric value.
928
929 @param inString A resource record type's mnemonic as a C string.
930
931 @result The resource record type's numeric value if the mnemonic is recognized, otherwise, 0.
932 */
933 uint16_t DNSRecordTypeStringToValue( const char *inString );
934
935 //---------------------------------------------------------------------------------------------------------------------------
936 /*! @brief For an RCODE value, returns the corresponding RCODE mnemonic as a C string.
937
938 @param inValue An RCODE value.
939
940 @result The mnemonic as a C string if the RCODE value is recognized. Otherwise, NULL.
941 */
942 const char * _Nullable DNSRCodeToString( int inValue );
943
944 //---------------------------------------------------------------------------------------------------------------------------
945 /*! @brief For an RCODE mnemonic, returns the corresponding RCODE value.
946
947 @param inString An RCODE mnemonic as a C string.
948
949 @result If the mnemonic is recognized, the corresponding RCODE value (between 0 and 15, inclusive). Otherwise, -1.
950 */
951 int DNSRCodeFromString( const char * const inString );
952
953 //---------------------------------------------------------------------------------------------------------------------------
954 /*! @typedef DNSMessageToStringFlags
955
956 @brief Formatting options for DNSMessageToString().
957 */
958 typedef uint32_t DNSMessageToStringFlags;
959
960 #define kDNSMessageToStringFlag_Null 0
961 #define kDNSMessageToStringFlag_MDNS ( 1U << 0 ) // Treat the message as an mDNS message as opposed to DNS.
962 #define kDNSMessageToStringFlag_RawRData ( 1U << 1 ) // Print record data as a hex string, i.e., no formatting.
963 #define kDNSMessageToStringFlag_OneLine ( 1U << 2 ) // Format the string as a single line.
964 #define kDNSMessageToStringFlag_Privacy ( 1U << 3 ) // Obfuscate or redact items such as domain names and IP addresses.
965 #define kDNSMessageToStringFlag_HeaderOnly ( 1U << 4 ) // Limit printing to just the message header.
966 #define kDNSMessageToStringFlag_BodyOnly ( 1U << 5 ) // Limit printing to just the message body.
967
968 #define kDNSMessageToStringFlags_None kDNSMessageToStringFlag_Null
969
970 //---------------------------------------------------------------------------------------------------------------------------
971 /*! @brief Creates a textual representation of a DNS message as a C string.
972
973 @param inMsgPtr Pointer to the beginning of the DNS message.
974 @param inMsgLen Length of the DNS message.
975 @param inFlags Flags that specify formatting options.
976 @param outString Gets set to point to the dynamically allocated C string.
977
978 @discussion The created string must be freed with free() when no longer needed.
979 */
980 OSStatus
981 DNSMessageToString(
982 const uint8_t * inMsgPtr,
983 size_t inMsgLen,
984 DNSMessageToStringFlags inFlags,
985 char * _Nullable * _Nonnull outString );
986
987 //---------------------------------------------------------------------------------------------------------------------------
988 /*! @brief Creates a textual representation of a DNS resource record's data as a C string.
989
990 @param inRDataPtr Pointer to the beginning of record data.
991 @param inRDataLen Length of the record data.
992 @param inRecordType The record's numeric type.
993 @param inMsgPtr Pointer to the beginning of the DNS message containing the resource record. (Optional)
994 @param inMsgLen Length of the DNS message containing the resource record.
995 @param inPrivacy If true, sensitive items, such as domain names and IP addresses, are obfuscated or redacted.
996 @param outString Gets set to point to the dynamically allocated C string.
997
998 @discussion The created string must be freed with free() when no longer needed.
999 */
1000 OSStatus
1001 DNSRecordDataToStringEx(
1002 const void * inRDataPtr,
1003 size_t inRDataLen,
1004 int inRecordType,
1005 const void * _Nullable inMsgPtr,
1006 size_t inMsgLen,
1007 Boolean inPrivacy,
1008 char * _Nullable * _Nonnull outString );
1009
1010 #define DNSRecordDataToString(IN_RDATA_PTR, IN_RDATA_LEN, IN_RECORD_TYPE, OUT_STRING) \
1011 DNSRecordDataToStringEx(IN_RDATA_PTR, IN_RDATA_LEN, IN_RECORD_TYPE, NULL, 0, false, OUT_STRING)
1012
1013 //---------------------------------------------------------------------------------------------------------------------------
1014 /*! @brief Computes a DNSKEY record data's DNSSEC key tag.
1015
1016 @param inRDataPtr Pointer to the beginning of the DNSKEY record data.
1017 @param inRDataLen Length of the DNSKEY record data.
1018
1019 @discussion Uses calculation described by <https://tools.ietf.org/html/rfc4034#appendix-B>.
1020 */
1021 uint16_t DNSComputeDNSKeyTag( const void *inRDataPtr, size_t inRDataLen );
1022
1023 //---------------------------------------------------------------------------------------------------------------------------
1024 /*! @brief Writes an obfuscated version of a C string to a buffer as a C string.
1025
1026 @param inBufPtr Pointer to the beginning of the buffer to write the obfuscated version of the string.
1027 @param inBufLen Length of the buffer.
1028 @param inString The string to obfuscate.
1029
1030 @result
1031 If the value returned is non-negative, then the value is the number of non-NUL characters that would have been
1032 written if the size of the buffer were unlimited. If the value returned is negative, then the function failed.
1033 In this case, the value returned is an error code.
1034
1035 @discussion
1036 This function is useful for obfuscating domain name strings using the same type of obfuscation used by
1037 DNSMessageToString().
1038
1039 If the returned value is non-negative, then, unless inBufLen is 0, the output string will be NUL-terminated.
1040 If inBufLen is too small, then the end of the output string will be truncated. If inBufLen is not greater than
1041 a non-negative return value, then the output string was truncated.
1042 */
1043 int DNSMessagePrintObfuscatedString( char *inBufPtr, size_t inBufLen, const char *inString );
1044
1045 //---------------------------------------------------------------------------------------------------------------------------
1046 /*! @brief Writes an obfuscated version of an IPv4 address to a buffer as a C string.
1047
1048 @param inBufPtr Pointer to the beginning of the buffer to write the obfuscated version of the string.
1049 @param inBufLen Length of the buffer.
1050 @param inAddr IPv4 address in host byte order.
1051
1052 @result
1053 If the value returned is non-negative, then the value is the number of non-NUL characters that would have been
1054 written if the size of the buffer were unlimited. If the value returned is negative, then the function failed.
1055 In this case, the value returned is an error code.
1056
1057 @discussion
1058 This function is useful for obfuscating an IPv4 addresses using the same type of obfuscation used by
1059 DNSMessageToString().
1060
1061 If the returned value is non-negative, then, unless inBufLen is 0, the output string will be NUL-terminated.
1062 If inBufLen is too small, then the end of the output string will be truncated. If inBufLen is not greater than
1063 a non-negative return value, then the output string was truncated.
1064 */
1065 int DNSMessagePrintObfuscatedIPv4Address( char *inBufPtr, size_t inBufLen, const uint32_t inAddr );
1066
1067 //---------------------------------------------------------------------------------------------------------------------------
1068 /*! @brief Writes an obfuscated version of an IPv6 address to a buffer as a C string.
1069
1070 @param inBufPtr Pointer to the beginning of the buffer to write the obfuscated version of the string.
1071 @param inBufLen Length of the buffer.
1072 @param inAddr IPv6 address as an array of 16 bytes.
1073
1074 @result
1075 If the value returned is non-negative, then the value is the number of non-NUL characters that would have been
1076 written if the size of the buffer were unlimited. If the value returned is negative, then the function failed.
1077 In this case, the value returned is an error code.
1078
1079 @discussion
1080 This function is useful for obfuscating an IPv6 address using the same type of obfuscation used by
1081 DNSMessageToString().
1082
1083 If the returned value is non-negative, then, unless inBufLen is 0, the output string will be NUL-terminated.
1084 If inBufLen is too small, then the end of the output string will be truncated. If inBufLen is not greater than
1085 a non-negative return value, then the output string was truncated.
1086 */
1087 int DNSMessagePrintObfuscatedIPv6Address( char *inBufPtr, size_t inBufLen, const uint8_t inAddr[ STATIC_PARAM 16 ] );
1088
1089 __END_DECLS
1090
1091 CU_ASSUME_NONNULL_END
1092
1093 #endif // __DNSMessage_h