2 * Copyright (c) 2004, 2006 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@
25 * Modification History
27 * March 9, 2004 Allan Nathanson <ajn@apple.com>
32 #include <mach/mach.h>
33 #include <mach/mach_error.h>
36 #include "dnsinfo_private.h"
37 #include "shared_dns_info.h"
41 add_list(void **padding
, uint32_t *n_padding
, int32_t count
, int32_t size
, void **list
)
46 if (need
> *n_padding
) {
50 *list
= (need
== 0) ? NULL
: *padding
;
57 static _dns_config_buf_t
*
61 dnsDataOut_t dataRef
= NULL
;
62 mach_msg_type_number_t dataLen
= 0;
66 server
= _dns_configuration_server_port();
67 if (server
== MACH_PORT_NULL
) {
71 status
= shared_dns_infoGet(server
, &dataRef
, &dataLen
);
72 (void)mach_port_deallocate(mach_task_self(), server
);
73 if (status
!= KERN_SUCCESS
) {
74 mach_error("shared_dns_infoGet():", status
);
78 if (dataRef
!= NULL
) {
79 if (dataLen
>= sizeof(_dns_config_buf_t
)) {
80 _dns_config_buf_t
*config
= (_dns_config_buf_t
*)dataRef
;
82 uint32_t n_padding
= ntohl(config
->n_padding
);
84 len
= dataLen
+ n_padding
;
86 bcopy((void *)dataRef
, buf
, dataLen
);
87 bzero(&buf
[dataLen
], n_padding
);
90 status
= vm_deallocate(mach_task_self(), (vm_address_t
)dataRef
, dataLen
);
91 if (status
!= KERN_SUCCESS
) {
92 mach_error("vm_deallocate():", status
);
98 return (_dns_config_buf_t
*)buf
;
102 static dns_resolver_t
*
103 expand_resolver(_dns_resolver_buf_t
*buf
, uint32_t n_buf
, void **padding
, uint32_t *n_padding
)
105 dns_attribute_t
*attribute
;
106 uint32_t n_attribute
;
107 int32_t n_nameserver
= 0;
108 int32_t n_search
= 0;
109 int32_t n_sortaddr
= 0;
110 dns_resolver_t
*resolver
= (dns_resolver_t
*)&buf
->resolver
;
112 if (n_buf
< sizeof(_dns_resolver_buf_t
)) {
118 resolver
->domain
= NULL
;
120 // initialize nameserver list
122 resolver
->n_nameserver
= ntohl(resolver
->n_nameserver
);
123 if (!add_list(padding
,
125 resolver
->n_nameserver
,
126 sizeof(DNS_PTR(struct sockaddr
*, x
)),
127 (void **)&resolver
->nameserver
)) {
133 resolver
->port
= ntohs(resolver
->port
);
135 // initialize search list
137 resolver
->n_search
= ntohl(resolver
->n_search
);
138 if (!add_list(padding
,
141 sizeof(DNS_PTR(char *, x
)),
142 (void **)&resolver
->search
)) {
146 // initialize sortaddr list
148 resolver
->n_sortaddr
= ntohl(resolver
->n_sortaddr
);
149 if (!add_list(padding
,
151 resolver
->n_sortaddr
,
152 sizeof(DNS_PTR(dns_sortaddr_t
*, x
)),
153 (void **)&resolver
->sortaddr
)) {
157 // initialize options
159 resolver
->options
= NULL
;
161 // initialize timeout
163 resolver
->timeout
= ntohl(resolver
->timeout
);
165 // initialize search_order
167 resolver
->search_order
= ntohl(resolver
->search_order
);
169 // process resolver buffer "attribute" data
171 n_attribute
= n_buf
- sizeof(_dns_resolver_buf_t
);
172 attribute
= (dns_attribute_t
*)&buf
->attribute
[0];
173 if (n_attribute
!= ntohl(buf
->n_attribute
)) {
177 while (n_attribute
>= sizeof(dns_attribute_t
)) {
178 int32_t attribute_length
= ntohl(attribute
->length
);
180 switch (ntohl(attribute
->type
)) {
181 case RESOLVER_ATTRIBUTE_DOMAIN
:
182 resolver
->domain
= (char *)&attribute
->attribute
[0];
185 case RESOLVER_ATTRIBUTE_ADDRESS
:
186 resolver
->nameserver
[n_nameserver
++] = (struct sockaddr
*)&attribute
->attribute
[0];
189 case RESOLVER_ATTRIBUTE_SEARCH
:
190 resolver
->search
[n_search
++] = (char *)&attribute
->attribute
[0];
193 case RESOLVER_ATTRIBUTE_SORTADDR
:
194 resolver
->sortaddr
[n_sortaddr
++] = (dns_sortaddr_t
*)&attribute
->attribute
[0];
197 case RESOLVER_ATTRIBUTE_OPTIONS
:
198 resolver
->options
= (char *)&attribute
->attribute
[0];
205 attribute
= (dns_attribute_t
*)((void *)attribute
+ attribute_length
);
206 n_attribute
-= attribute_length
;
209 if ((n_nameserver
!= resolver
->n_nameserver
) ||
210 (n_search
!= resolver
->n_search
) ||
211 (n_sortaddr
!= resolver
->n_sortaddr
)) {
223 static dns_config_t
*
224 expand_config(_dns_config_buf_t
*buf
)
226 dns_attribute_t
*attribute
;
227 dns_config_t
*config
= (dns_config_t
*)buf
;
228 uint32_t n_attribute
;
230 int32_t n_resolver
= 0;
235 padding
= &buf
->attribute
[ntohl(buf
->n_attribute
)];
236 n_padding
= ntohl(buf
->n_padding
);
238 // initialize resolver list
240 config
->n_resolver
= ntohl(config
->n_resolver
);
241 if (!add_list(&padding
,
244 sizeof(DNS_PTR(dns_resolver_t
*, x
)),
245 (void **)&config
->resolver
)) {
249 // process configuration buffer "attribute" data
251 n_attribute
= ntohl(buf
->n_attribute
);
252 attribute
= (dns_attribute_t
*)&buf
->attribute
[0];
254 while (n_attribute
>= sizeof(dns_attribute_t
)) {
255 int32_t attribute_length
= ntohl(attribute
->length
);
257 switch (ntohl(attribute
->type
)) {
258 case CONFIG_ATTRIBUTE_RESOLVER
: {
259 dns_resolver_t
*resolver
;
261 // expand resolver buffer
263 resolver
= expand_resolver((_dns_resolver_buf_t
*)&attribute
->attribute
[0],
264 attribute_length
- sizeof(dns_attribute_t
),
267 if (resolver
== NULL
) {
271 // add resolver to config list
273 config
->resolver
[n_resolver
++] = resolver
;
282 attribute
= (dns_attribute_t
*)((void *)attribute
+ attribute_length
);
283 n_attribute
-= attribute_length
;
286 if (n_resolver
!= config
->n_resolver
) {
300 dns_configuration_notify_key()
302 return _dns_configuration_notify_key();
308 dns_configuration_copy()
310 _dns_config_buf_t
*buf
;
311 dns_config_t
*config
;
313 buf
= copy_dns_info();
318 config
= expand_config(buf
);
319 if (config
== NULL
) {
330 dns_configuration_free(dns_config_t
*config
)
332 if (config
== NULL
) {
336 free((void *)config
);