]> git.saurik.com Git - apple/configd.git/blob - dnsinfo/dnsinfo_internal.h
configd-888.51.2.tar.gz
[apple/configd.git] / dnsinfo / dnsinfo_internal.h
1 /*
2 * Copyright (c) 2013, 2015, 2016 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #ifndef _S_DNSINFO_INTERNAL_H
25 #define _S_DNSINFO_INTERNAL_H
26
27 #include <Availability.h>
28 #include <TargetConditionals.h>
29 #include <sys/cdefs.h>
30 #include <SystemConfiguration/SystemConfiguration.h>
31 #include <SystemConfiguration/SCPrivate.h>
32 #include "SCNetworkReachabilityInternal.h"
33 #include <arpa/inet.h>
34
35 #include <dnsinfo.h>
36 #include "dnsinfo_private.h"
37
38
39 __BEGIN_DECLS
40
41
42 #ifndef my_log
43 #define MY_LOG_DEFINED_LOCALLY
44 #define my_log(__level, __format, ...) SC_log(__level, __format, ## __VA_ARGS__)
45 #endif // !my_log
46
47
48 #define DNS_CONFIG_BUF_MAX 1024*1024
49
50
51 /*
52 * claim space for a list [of pointers] from the expanded DNS configuration padding
53 */
54 static __inline__ boolean_t
55 __dns_configuration_expand_add_list(void **padding, uint32_t *n_padding, int32_t count, int32_t size, void **list)
56 {
57 int32_t need;
58
59 need = count * size;
60 if (need > *n_padding) {
61 return FALSE;
62 }
63
64 *list = (need == 0) ? NULL : *padding;
65 *padding += need;
66 *n_padding -= need;
67 return TRUE;
68 }
69
70
71 /*
72 * expand a DNS "resolver" from the provided buffer
73 */
74 static __inline__ dns_resolver_t *
75 _dns_configuration_expand_resolver(_dns_resolver_buf_t *buf, uint32_t n_buf, void **padding, uint32_t *n_padding)
76 {
77 dns_attribute_t *attribute;
78 uint32_t n_attribute;
79 int32_t n_nameserver = 0;
80 int32_t n_search = 0;
81 int32_t n_sortaddr = 0;
82 dns_resolver_t *resolver = (dns_resolver_t *)&buf->resolver;
83
84 if (n_buf < sizeof(_dns_resolver_buf_t)) {
85 goto error;
86 }
87
88 // initialize domain
89
90 resolver->domain = NULL;
91
92 // initialize nameserver list
93
94 resolver->n_nameserver = ntohl(resolver->n_nameserver);
95 if (!__dns_configuration_expand_add_list(padding,
96 n_padding,
97 resolver->n_nameserver,
98 sizeof(DNS_PTR(struct sockaddr *, x)),
99 (void **)&resolver->nameserver)) {
100 goto error;
101 }
102
103 // initialize port
104
105 resolver->port = ntohs(resolver->port);
106
107 // initialize search list
108
109 resolver->n_search = ntohl(resolver->n_search);
110 if (!__dns_configuration_expand_add_list(padding,
111 n_padding,
112 resolver->n_search,
113 sizeof(DNS_PTR(char *, x)),
114 (void **)&resolver->search)) {
115 goto error;
116 }
117
118 // initialize sortaddr list
119
120 resolver->n_sortaddr = ntohl(resolver->n_sortaddr);
121 if (!__dns_configuration_expand_add_list(padding,
122 n_padding,
123 resolver->n_sortaddr,
124 sizeof(DNS_PTR(dns_sortaddr_t *, x)),
125 (void **)&resolver->sortaddr)) {
126 goto error;
127 }
128
129 // initialize options
130
131 resolver->options = NULL;
132
133 // initialize timeout
134
135 resolver->timeout = ntohl(resolver->timeout);
136
137 // initialize search_order
138
139 resolver->search_order = ntohl(resolver->search_order);
140
141 // initialize if_index
142
143 resolver->if_index = ntohl(resolver->if_index);
144
145 // initialize service_identifier
146
147 resolver->service_identifier = ntohl(resolver->service_identifier);
148
149 // initialize flags
150
151 resolver->flags = ntohl(resolver->flags);
152
153 // initialize SCNetworkReachability flags
154
155 resolver->reach_flags = ntohl(resolver->reach_flags);
156
157 // process resolver buffer "attribute" data
158
159 n_attribute = n_buf - sizeof(_dns_resolver_buf_t);
160 /* ALIGN: alignment not assumed, using accessors */
161 attribute = (dns_attribute_t *)(void *)&buf->attribute[0];
162 if (n_attribute != ntohl(buf->n_attribute)) {
163 goto error;
164 }
165
166 while (n_attribute >= sizeof(dns_attribute_t)) {
167 uint32_t attribute_length = ntohl(attribute->length);
168
169 switch (ntohl(attribute->type)) {
170 case RESOLVER_ATTRIBUTE_DOMAIN :
171 resolver->domain = (char *)&attribute->attribute[0];
172 break;
173
174 case RESOLVER_ATTRIBUTE_ADDRESS :
175 if (resolver->nameserver == NULL) {
176 goto error;
177 }
178 resolver->nameserver[n_nameserver++] = (struct sockaddr *)&attribute->attribute[0];
179 break;
180
181 case RESOLVER_ATTRIBUTE_SEARCH :
182 if (resolver->search == NULL) {
183 goto error;
184 }
185 resolver->search[n_search++] = (char *)&attribute->attribute[0];
186 break;
187
188 case RESOLVER_ATTRIBUTE_SORTADDR :
189 if (resolver->sortaddr == NULL) {
190 goto error;
191 }
192 resolver->sortaddr[n_sortaddr++] = (dns_sortaddr_t *)(void *)&attribute->attribute[0];
193 break;
194
195 case RESOLVER_ATTRIBUTE_OPTIONS :
196 resolver->options = (char *)&attribute->attribute[0];
197 break;
198
199 case RESOLVER_ATTRIBUTE_CONFIGURATION_ID :
200 resolver->cid = (char *)&attribute->attribute[0];
201 break;
202
203 default :
204 break;
205 }
206
207 attribute = (dns_attribute_t *)((void *)attribute + attribute_length);
208 n_attribute -= attribute_length;
209 }
210
211 if ((n_nameserver != resolver->n_nameserver) ||
212 (n_search != resolver->n_search ) ||
213 (n_sortaddr != resolver->n_sortaddr )) {
214 goto error;
215 }
216
217 return resolver;
218
219 error :
220
221 return NULL;
222 }
223
224
225 /*
226 * expand a DNS "configuration" from the provided buffer
227 */
228 static __inline__ dns_config_t *
229 _dns_configuration_expand_config(_dns_config_buf_t *buf)
230 {
231 dns_attribute_t *attribute;
232 dns_config_t *config = (dns_config_t *)buf;
233 uint32_t n_attribute;
234 uint32_t n_padding;
235 int32_t n_resolver = 0;
236 int32_t n_scoped_resolver = 0;
237 int32_t n_service_specific_resolver = 0;
238 void *padding;
239
240 n_attribute = ntohl(buf->n_attribute); // pre-validated (or known OK) at entry
241 n_padding = ntohl(buf->n_padding); // pre-validated (or known OK) at entry
242
243 // establish the start of padding to be after the last attribute
244
245 padding = &buf->attribute[n_attribute];
246
247 // initialize resolver lists
248
249 config->n_resolver = ntohl(config->n_resolver);
250 if (!__dns_configuration_expand_add_list(&padding,
251 &n_padding,
252 config->n_resolver,
253 sizeof(DNS_PTR(dns_resolver_t *, x)),
254 (void **)&config->resolver)) {
255 goto error;
256 }
257
258 config->n_scoped_resolver = ntohl(config->n_scoped_resolver);
259 if (!__dns_configuration_expand_add_list(&padding,
260 &n_padding,
261 config->n_scoped_resolver,
262 sizeof(DNS_PTR(dns_resolver_t *, x)),
263 (void **)&config->scoped_resolver)) {
264 goto error;
265 }
266
267 config->n_service_specific_resolver = ntohl(config->n_service_specific_resolver);
268 if (!__dns_configuration_expand_add_list(&padding,
269 &n_padding,
270 config->n_service_specific_resolver,
271 sizeof(DNS_PTR(dns_resolver_t *, x)),
272 (void **)&config->service_specific_resolver)) {
273 goto error;
274 }
275
276 // process configuration buffer "attribute" data
277
278 attribute = (dns_attribute_t *)(void *)&buf->attribute[0];
279
280 while (n_attribute >= sizeof(dns_attribute_t)) {
281 uint32_t attribute_length = ntohl(attribute->length);
282 uint32_t attribute_type = ntohl(attribute->type);
283
284 switch (attribute_type) {
285 case CONFIG_ATTRIBUTE_RESOLVER :
286 case CONFIG_ATTRIBUTE_SCOPED_RESOLVER :
287 case CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER : {
288 dns_resolver_t *resolver;
289
290 // expand resolver buffer
291
292 resolver = _dns_configuration_expand_resolver((_dns_resolver_buf_t *)(void *)&attribute->attribute[0],
293 attribute_length - sizeof(dns_attribute_t),
294 &padding,
295 &n_padding);
296 if (resolver == NULL) {
297 goto error;
298 }
299
300 // add resolver to config list
301
302 if (attribute_type == CONFIG_ATTRIBUTE_RESOLVER) {
303 if (config->resolver == NULL) {
304 goto error;
305 }
306 config->resolver[n_resolver++] = resolver;
307 } else if (attribute_type == CONFIG_ATTRIBUTE_SCOPED_RESOLVER) {
308 if (config->scoped_resolver == NULL) {
309 goto error;
310 }
311 config->scoped_resolver[n_scoped_resolver++] = resolver;
312 } else if (attribute_type == CONFIG_ATTRIBUTE_SERVICE_SPECIFIC_RESOLVER) {
313 if (config->service_specific_resolver == NULL) {
314 goto error;
315 }
316 config->service_specific_resolver[n_service_specific_resolver++] = resolver;
317 }
318
319 break;
320 }
321
322 default :
323 break;
324 }
325
326 attribute = (dns_attribute_t *)((void *)attribute + attribute_length);
327 n_attribute -= attribute_length;
328 }
329
330 if (n_resolver != config->n_resolver) {
331 goto error;
332 }
333
334 if (n_scoped_resolver != config->n_scoped_resolver) {
335 goto error;
336 }
337
338 if (n_service_specific_resolver != config->n_service_specific_resolver) {
339 goto error;
340 }
341
342 return config;
343
344 error :
345
346 return NULL;
347 }
348
349
350 static __inline__ void
351 _dns_resolver_log(dns_resolver_t *resolver, int index, Boolean debug)
352 {
353 int i;
354 uint32_t flags;
355 CFMutableStringRef str;
356
357 my_log(LOG_INFO, " ");
358 my_log(LOG_INFO, "resolver #%d", index);
359
360 if (resolver->domain != NULL) {
361 my_log(LOG_INFO, " domain : %s", resolver->domain);
362 }
363
364 for (i = 0; i < resolver->n_search; i++) {
365 my_log(LOG_INFO, " search domain[%d] : %s", i, resolver->search[i]);
366 }
367
368 for (i = 0; i < resolver->n_nameserver; i++) {
369 char buf[128];
370
371 _SC_sockaddr_to_string(resolver->nameserver[i], buf, sizeof(buf));
372 my_log(LOG_INFO, " nameserver[%d] : %s", i, buf);
373 }
374
375 for (i = 0; i < resolver->n_sortaddr; i++) {
376 char abuf[32];
377 char mbuf[32];
378
379 (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->address, abuf, sizeof(abuf));
380 (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->mask, mbuf, sizeof(mbuf));
381 my_log(LOG_INFO, " sortaddr[%d] : %s/%s", i, abuf, mbuf);
382 }
383
384 if (resolver->options != NULL) {
385 my_log(LOG_INFO, " options : %s", resolver->options);
386 }
387
388 if (resolver->port != 0) {
389 my_log(LOG_INFO, " port : %hd", resolver->port);
390 }
391
392 if (resolver->timeout != 0) {
393 my_log(LOG_INFO, " timeout : %d", resolver->timeout);
394 }
395
396 if (resolver->if_index != 0) {
397 char buf[IFNAMSIZ];
398 char *if_name;
399
400 if_name = if_indextoname(resolver->if_index, buf);
401 my_log(LOG_INFO, " if_index : %d (%s)",
402 resolver->if_index,
403 (if_name != NULL) ? if_name : "?");
404 }
405
406 if (resolver->service_identifier != 0) {
407 my_log(LOG_INFO, " service_identifier : %d",
408 resolver->service_identifier);
409 }
410
411 flags = resolver->flags;
412 str = CFStringCreateMutable(NULL, 0);
413 CFStringAppend(str, CFSTR(" flags : "));
414 if (debug) {
415 CFStringAppendFormat(str, NULL, CFSTR("0x%08x ("), flags);
416 }
417 if (flags & DNS_RESOLVER_FLAGS_SCOPED) {
418 flags &= ~DNS_RESOLVER_FLAGS_SCOPED;
419 CFStringAppendFormat(str, NULL, CFSTR("Scoped%s"), flags != 0 ? ", " : "");
420 }
421 if (flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC) {
422 flags &= ~DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC;
423 CFStringAppendFormat(str, NULL, CFSTR("Service-specific%s"), flags != 0 ? ", " : "");
424 }
425 if (flags & DNS_RESOLVER_FLAGS_SUPPLEMENTAL) {
426 flags &= ~DNS_RESOLVER_FLAGS_SUPPLEMENTAL;
427 CFStringAppendFormat(str, NULL, CFSTR("Supplemental%s"), flags != 0 ? ", " : "");
428 }
429 if (flags & DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS) {
430 flags &= ~DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS;
431 CFStringAppendFormat(str, NULL, CFSTR("Request A records%s"), flags != 0 ? ", " : "");
432 }
433 if (flags & DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS) {
434 flags &= ~DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS;
435 CFStringAppendFormat(str, NULL, CFSTR("Request AAAA records%s"), flags != 0 ? ", " : "");
436 }
437 if (flags != 0) {
438 CFStringAppendFormat(str, NULL, CFSTR("0x%08x"), flags);
439 }
440 if (debug) {
441 CFStringAppend(str, CFSTR(")"));
442 }
443 my_log(LOG_INFO, "%@", str);
444 CFRelease(str);
445
446 str = (CFMutableStringRef)__SCNetworkReachabilityCopyFlags(resolver->reach_flags,
447 CFSTR(" reach : "),
448 debug);
449 my_log(LOG_INFO, "%@", str);
450 CFRelease(str);
451
452 if (resolver->search_order != 0) {
453 my_log(LOG_INFO, " order : %d", resolver->search_order);
454 }
455
456 if (debug && (resolver->cid != NULL)) {
457 my_log(LOG_INFO, " config id: %s", resolver->cid);
458 }
459
460 return;
461 }
462
463
464 static __inline__ void
465 _dns_configuration_log(dns_config_t *dns_config, Boolean debug)
466 {
467 int i;
468
469 my_log(LOG_INFO, "DNS configuration");
470
471 for (i = 0; i < dns_config->n_resolver; i++) {
472 dns_resolver_t *resolver = dns_config->resolver[i];
473
474 _dns_resolver_log(resolver, i + 1, debug);
475 }
476
477 if ((dns_config->n_scoped_resolver > 0) && (dns_config->scoped_resolver != NULL)) {
478 my_log(LOG_INFO, " ");
479 my_log(LOG_INFO, "DNS configuration (for scoped queries)");
480
481 for (i = 0; i < dns_config->n_scoped_resolver; i++) {
482 dns_resolver_t *resolver = dns_config->scoped_resolver[i];
483
484 _dns_resolver_log(resolver, i + 1, debug);
485 }
486 }
487
488 if ((dns_config->n_service_specific_resolver > 0) && (dns_config->service_specific_resolver != NULL)) {
489 my_log(LOG_INFO, " ");
490 my_log(LOG_INFO, "DNS configuration (for service-specific queries)");
491
492 for (i = 0; i < dns_config->n_service_specific_resolver; i++) {
493 dns_resolver_t *resolver = dns_config->service_specific_resolver[i];
494
495 _dns_resolver_log(resolver, i + 1, debug);
496 }
497 }
498
499 return;
500 }
501
502
503 #ifdef MY_LOG_DEFINED_LOCALLY
504 #undef my_log
505 #undef MY_LOG_DEFINED_LOCALLY
506 #endif // MY_LOG_DEFINED_LOCALLY
507
508
509 __END_DECLS
510
511 #endif /* !_S_DNSINFO_INTERNAL_H */