2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: getrrset.c,v 1.11.2.5 2004/03/09 06:12:33 marka Exp $ */
26 #include <lwres/lwres.h>
27 #include <lwres/net.h>
28 #include <lwres/netdb.h> /* XXX #include <netdb.h> */
33 lwresult_to_result(lwres_result_t lwresult) {
35 case LWRES_R_SUCCESS: return (ERRSET_SUCCESS);
36 case LWRES_R_NOMEMORY: return (ERRSET_NOMEMORY);
37 case LWRES_R_NOTFOUND: return (ERRSET_NONAME);
38 case LWRES_R_TYPENOTFOUND: return (ERRSET_NODATA);
39 default: return (ERRSET_FAIL);
44 * malloc / calloc functions that guarantee to only
45 * return NULL if there is an error, like they used
46 * to before the ANSI C committee broke them.
50 sane_malloc(size_t size) {
53 return (malloc(size));
57 sane_calloc(size_t number, size_t size) {
58 size_t len = number * size;
59 void *mem = sane_malloc(len);
66 lwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
67 unsigned int rdtype, unsigned int flags,
68 struct rrsetinfo **res)
70 lwres_context_t *lwrctx = NULL;
71 lwres_result_t lwresult;
72 lwres_grbnresponse_t *response = NULL;
73 struct rrsetinfo *rrset = NULL;
78 if (rdclass > 0xffff || rdtype > 0xffff) {
79 result = ERRSET_INVAL;
84 * Don't allow queries of class or type ANY
86 if (rdclass == 0xff || rdtype == 0xff) {
87 result = ERRSET_INVAL;
91 lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
92 if (lwresult != LWRES_R_SUCCESS) {
93 result = lwresult_to_result(lwresult);
96 (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
99 * If any input flags were defined, lwflags would be set here
105 lwresult = lwres_getrdatabyname(lwrctx, hostname,
106 (lwres_uint16_t)rdclass,
107 (lwres_uint16_t)rdtype,
109 if (lwresult != LWRES_R_SUCCESS) {
110 result = lwresult_to_result(lwresult);
114 rrset = sane_malloc(sizeof(struct rrsetinfo));
116 result = ERRSET_NOMEMORY;
119 rrset->rri_name = NULL;
120 rrset->rri_rdclass = response->rdclass;
121 rrset->rri_rdtype = response->rdtype;
122 rrset->rri_ttl = response->ttl;
123 rrset->rri_flags = 0;
124 rrset->rri_nrdatas = 0;
125 rrset->rri_rdatas = NULL;
126 rrset->rri_nsigs = 0;
127 rrset->rri_sigs = NULL;
129 rrset->rri_name = sane_malloc(response->realnamelen + 1);
130 if (rrset->rri_name == NULL) {
131 result = ERRSET_NOMEMORY;
134 strncpy(rrset->rri_name, response->realname, response->realnamelen);
135 rrset->rri_name[response->realnamelen] = 0;
137 if ((response->flags & LWRDATA_VALIDATED) != 0)
138 rrset->rri_flags |= RRSET_VALIDATED;
140 rrset->rri_nrdatas = response->nrdatas;
141 rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
142 sizeof(struct rdatainfo));
143 if (rrset->rri_rdatas == NULL) {
144 result = ERRSET_NOMEMORY;
147 for (i = 0; i < rrset->rri_nrdatas; i++) {
148 rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
149 rrset->rri_rdatas[i].rdi_data =
150 sane_malloc(rrset->rri_rdatas[i].rdi_length);
151 if (rrset->rri_rdatas[i].rdi_data == NULL) {
152 result = ERRSET_NOMEMORY;
155 memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
156 rrset->rri_rdatas[i].rdi_length);
158 rrset->rri_nsigs = response->nsigs;
159 rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
160 sizeof(struct rdatainfo));
161 if (rrset->rri_sigs == NULL) {
162 result = ERRSET_NOMEMORY;
165 for (i = 0; i < rrset->rri_nsigs; i++) {
166 rrset->rri_sigs[i].rdi_length = response->siglen[i];
167 rrset->rri_sigs[i].rdi_data =
168 sane_malloc(rrset->rri_sigs[i].rdi_length);
169 if (rrset->rri_sigs[i].rdi_data == NULL) {
170 result = ERRSET_NOMEMORY;
173 memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
174 rrset->rri_sigs[i].rdi_length);
177 lwres_grbnresponse_free(lwrctx, &response);
178 lwres_conf_clear(lwrctx);
179 lwres_context_destroy(&lwrctx);
181 return (ERRSET_SUCCESS);
184 lwres_freerrset(rrset);
185 if (response != NULL)
186 lwres_grbnresponse_free(lwrctx, &response);
187 if (lwrctx != NULL) {
188 lwres_conf_clear(lwrctx);
189 lwres_context_destroy(&lwrctx);
195 lwres_freerrset(struct rrsetinfo *rrset) {
197 for (i = 0; i < rrset->rri_nrdatas; i++) {
198 if (rrset->rri_rdatas[i].rdi_data == NULL)
200 free(rrset->rri_rdatas[i].rdi_data);
202 free(rrset->rri_rdatas);
203 for (i = 0; i < rrset->rri_nsigs; i++) {
204 if (rrset->rri_sigs[i].rdi_data == NULL)
206 free(rrset->rri_sigs[i].rdi_data);
208 free(rrset->rri_sigs);
209 free(rrset->rri_name);