]> git.saurik.com Git - apple/configd.git/blob - dnsinfo/dnsinfo_internal.h
configd-802.20.7.tar.gz
[apple/configd.git] / dnsinfo / dnsinfo_internal.h
1 /*
2 * Copyright (c) 2013, 2015 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, fmt, ...) SC_log(__level, fmt, ## __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, "\nresolver #%d", index);
358
359 if (resolver->domain != NULL) {
360 my_log(LOG_INFO, " domain : %s", resolver->domain);
361 }
362
363 for (i = 0; i < resolver->n_search; i++) {
364 my_log(LOG_INFO, " search domain[%d] : %s", i, resolver->search[i]);
365 }
366
367 for (i = 0; i < resolver->n_nameserver; i++) {
368 char buf[128];
369
370 _SC_sockaddr_to_string(resolver->nameserver[i], buf, sizeof(buf));
371 my_log(LOG_INFO, " nameserver[%d] : %s", i, buf);
372 }
373
374 for (i = 0; i < resolver->n_sortaddr; i++) {
375 char abuf[32];
376 char mbuf[32];
377
378 (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->address, abuf, sizeof(abuf));
379 (void)inet_ntop(AF_INET, &resolver->sortaddr[i]->mask, mbuf, sizeof(mbuf));
380 my_log(LOG_INFO, " sortaddr[%d] : %s/%s", i, abuf, mbuf);
381 }
382
383 if (resolver->options != NULL) {
384 my_log(LOG_INFO, " options : %s", resolver->options);
385 }
386
387 if (resolver->port != 0) {
388 my_log(LOG_INFO, " port : %hd", resolver->port);
389 }
390
391 if (resolver->timeout != 0) {
392 my_log(LOG_INFO, " timeout : %d", resolver->timeout);
393 }
394
395 if (resolver->if_index != 0) {
396 char buf[IFNAMSIZ];
397 char *if_name;
398
399 if_name = if_indextoname(resolver->if_index, buf);
400 my_log(LOG_INFO, " if_index : %d (%s)",
401 resolver->if_index,
402 (if_name != NULL) ? if_name : "?");
403 }
404
405 if (resolver->service_identifier != 0) {
406 my_log(LOG_INFO, " service_identifier : %d",
407 resolver->service_identifier);
408 }
409
410 flags = resolver->flags;
411 str = CFStringCreateMutable(NULL, 0);
412 CFStringAppend(str, CFSTR(" flags : "));
413 if (debug) {
414 CFStringAppendFormat(str, NULL, CFSTR("0x%08x ("), flags);
415 }
416 if (flags & DNS_RESOLVER_FLAGS_SCOPED) {
417 flags &= ~DNS_RESOLVER_FLAGS_SCOPED;
418 CFStringAppendFormat(str, NULL, CFSTR("Scoped%s"), flags != 0 ? ", " : "");
419 }
420 if (flags & DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC) {
421 flags &= ~DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC;
422 CFStringAppendFormat(str, NULL, CFSTR("Service-specific%s"), flags != 0 ? ", " : "");
423 }
424 if (flags & DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS) {
425 flags &= ~DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS;
426 CFStringAppendFormat(str, NULL, CFSTR("Request A records%s"), flags != 0 ? ", " : "");
427 }
428 if (flags & DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS) {
429 flags &= ~DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS;
430 CFStringAppendFormat(str, NULL, CFSTR("Request AAAA records%s"), flags != 0 ? ", " : "");
431 }
432 if (flags != 0) {
433 CFStringAppendFormat(str, NULL, CFSTR("0x%08x"), flags);
434 }
435 if (debug) {
436 CFStringAppend(str, CFSTR(")"));
437 }
438 my_log(LOG_INFO, "%@", str);
439 CFRelease(str);
440
441 str = (CFMutableStringRef)__SCNetworkReachabilityCopyFlags(resolver->reach_flags,
442 CFSTR(" reach : "),
443 debug);
444 my_log(LOG_INFO, "%@", str);
445 CFRelease(str);
446
447 if (resolver->search_order != 0) {
448 my_log(LOG_INFO, " order : %d", resolver->search_order);
449 }
450
451 if (debug && (resolver->cid != NULL)) {
452 my_log(LOG_INFO, " config id: %s", resolver->cid);
453 }
454
455 return;
456 }
457
458
459 static __inline__ void
460 _dns_configuration_log(dns_config_t *dns_config, Boolean debug)
461 {
462 int i;
463
464 my_log(LOG_INFO, "DNS configuration");
465
466 for (i = 0; i < dns_config->n_resolver; i++) {
467 dns_resolver_t *resolver = dns_config->resolver[i];
468
469 _dns_resolver_log(resolver, i + 1, debug);
470 }
471
472 if ((dns_config->n_scoped_resolver > 0) && (dns_config->scoped_resolver != NULL)) {
473 my_log(LOG_INFO, "\nDNS configuration (for scoped queries)");
474
475 for (i = 0; i < dns_config->n_scoped_resolver; i++) {
476 dns_resolver_t *resolver = dns_config->scoped_resolver[i];
477
478 _dns_resolver_log(resolver, i + 1, debug);
479 }
480 }
481
482 if ((dns_config->n_service_specific_resolver > 0) && (dns_config->service_specific_resolver != NULL)) {
483 my_log(LOG_INFO, "\nDNS configuration (for service-specific queries)");
484
485 for (i = 0; i < dns_config->n_service_specific_resolver; i++) {
486 dns_resolver_t *resolver = dns_config->service_specific_resolver[i];
487
488 _dns_resolver_log(resolver, i + 1, debug);
489 }
490 }
491
492 return;
493 }
494
495
496 #ifdef MY_LOG_DEFINED_LOCALLY
497 #undef my_log
498 #undef MY_LOG_DEFINED_LOCALLY
499 #endif // MY_LOG_DEFINED_LOCALLY
500
501
502 __END_DECLS
503
504 #endif /* !_S_DNSINFO_INTERNAL_H */