]> git.saurik.com Git - apple/libinfo.git/blame - dns.subproj/res_query.c
Libinfo-459.40.1.tar.gz
[apple/libinfo.git] / dns.subproj / res_query.c
CommitLineData
03fb6eb0 1/*
0eb52ff2 2 * Copyright (c) 1999, 2012 Apple Inc. All rights reserved.
03fb6eb0
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ad21edcc
A
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
03fb6eb0
A
13 *
14 * The Original Code and all software distributed under the License are
ad21edcc 15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
03fb6eb0
A
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ad21edcc
A
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
0eb52ff2 21 *
03fb6eb0
A
22 * @APPLE_LICENSE_HEADER_END@
23 */
03fb6eb0 24
0eb52ff2 25#include <dns_sd.h>
03fb6eb0 26#include <errno.h>
d49d4c81 27
0eb52ff2
A
28#include <arpa/nameser_compat.h>
29#include <nameser.h>
d49d4c81 30
0eb52ff2 31#include "si_module.h"
03fb6eb0 32
0eb52ff2 33extern int h_errno;
03fb6eb0 34
0eb52ff2
A
35// Storage for the global struct __res_9_state.
36// The BIND9 libresolv.dylib shares the same storage for this structure as the
37// legacy BIND8 libsystem_info.dylib. This implementation does not require the
38// _res structure but libresolv.dylib does and many 3rd-party applications
39// access this global symbol directly so we preserve it here.
40#ifdef __LP64__
41#define RES_9_STATE_SIZE 552
03fb6eb0 42#else
0eb52ff2 43#define RES_9_STATE_SIZE 512
03fb6eb0 44#endif
0eb52ff2 45char _res[RES_9_STATE_SIZE] = {0};
03fb6eb0 46
03fb6eb0 47int
0eb52ff2 48res_init(void)
03fb6eb0 49{
0eb52ff2
A
50 // For compatibility only.
51 return 0;
03fb6eb0
A
52}
53
0eb52ff2
A
54// Perform a DNS query. Returned DNS response is placed in the answer buffer.
55// A preliminary check of the answer is performed and success is returned only
56// if no error is indicated in the answer and the answer count is nonzero.
57// Returns the size of the response on success, or -1 with h_errno set.
58static int
59_mdns_query(int call, const char *name, int class, int type, u_char *answer, int anslen)
03fb6eb0 60{
0eb52ff2
A
61 int res = -1;
62 si_item_t *item;
63 uint32_t err;
64
65 si_mod_t *dns = si_module_with_name("mdns");
66 if (dns == NULL) {
67 h_errno = NO_RECOVERY;
68 return -1;
03fb6eb0 69 }
0eb52ff2
A
70
71 item = dns->vtable->sim_item_call(dns, call, name, NULL, NULL, class, type, &err);
72
73 if (item != NULL) {
74 si_dnspacket_t *p;
75
76 p = (si_dnspacket_t *)((uintptr_t)item + sizeof(si_item_t));
77
78 res = p->dns_packet_len;
79
80 // Truncate to destination buffer size.
81 memcpy(answer, p->dns_packet, MIN(res, anslen));
82
83 si_item_release(item);
84 } else {
85 h_errno = HOST_NOT_FOUND;
86 res = -1;
03fb6eb0
A
87 }
88
0eb52ff2
A
89 if (MIN(res, anslen) >= sizeof(HEADER)) {
90 HEADER *hp = (HEADER *)answer;
91 switch (hp->rcode) {
92 case NXDOMAIN:
93 h_errno = HOST_NOT_FOUND;
94 res = -1;
95 break;
96 case SERVFAIL:
03fb6eb0 97 h_errno = TRY_AGAIN;
0eb52ff2 98 res = -1;
03fb6eb0 99 break;
0eb52ff2
A
100 case NOERROR:
101 if (ntohs(hp->ancount) == 0) {
102 h_errno = NO_DATA;
103 res = -1;
03fb6eb0 104 }
0eb52ff2
A
105 break;
106 case FORMERR:
107 case NOTIMP:
108 case REFUSED:
03fb6eb0 109 default:
0eb52ff2
A
110 h_errno = NO_RECOVERY;
111 res = -1;
112 break;
03fb6eb0
A
113 }
114 }
115
0eb52ff2
A
116 si_module_release(dns);
117 return res;
03fb6eb0
A
118}
119
03fb6eb0 120int
0eb52ff2 121res_query(const char *name, int class, int type, u_char *answer, int anslen)
03fb6eb0 122{
0eb52ff2 123 return _mdns_query(SI_CALL_DNS_QUERY, name, class, type, answer, anslen);
03fb6eb0
A
124}
125
0eb52ff2
A
126int
127res_search(const char *name, int class, int type, u_char *answer, int anslen)
03fb6eb0 128{
0eb52ff2 129 return _mdns_query(SI_CALL_DNS_SEARCH, name, class, type, answer, anslen);
03fb6eb0 130}