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
);