Import bind-9.3.4
[dragonfly.git] / contrib / bind-9.3 / lib / lwres / lwres_grbn.c
blobf8147fc622e8dbb87de2fc84835dd4ab9dda6f9e
1 /*
2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001 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: lwres_grbn.c,v 1.4.12.3 2004/03/08 09:05:11 marka Exp $ */
20 #include <config.h>
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #include <lwres/lwbuffer.h>
27 #include <lwres/lwpacket.h>
28 #include <lwres/lwres.h>
29 #include <lwres/result.h>
31 #include "context_p.h"
32 #include "assert_p.h"
34 lwres_result_t
35 lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
36 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
38 unsigned char *buf;
39 size_t buflen;
40 int ret;
41 size_t payload_length;
42 lwres_uint16_t datalen;
44 REQUIRE(ctx != NULL);
45 REQUIRE(req != NULL);
46 REQUIRE(req->name != NULL);
47 REQUIRE(pkt != NULL);
48 REQUIRE(b != NULL);
50 datalen = strlen(req->name);
52 payload_length = 4 + 2 + 2 + 2 + req->namelen + 1;
54 buflen = LWRES_LWPACKET_LENGTH + payload_length;
55 buf = CTXMALLOC(buflen);
56 if (buf == NULL)
57 return (LWRES_R_NOMEMORY);
59 lwres_buffer_init(b, buf, buflen);
61 pkt->length = buflen;
62 pkt->version = LWRES_LWPACKETVERSION_0;
63 pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
64 pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
65 pkt->result = 0;
66 pkt->authtype = 0;
67 pkt->authlength = 0;
69 ret = lwres_lwpacket_renderheader(b, pkt);
70 if (ret != LWRES_R_SUCCESS) {
71 lwres_buffer_invalidate(b);
72 CTXFREE(buf, buflen);
73 return (ret);
76 INSIST(SPACE_OK(b, payload_length));
79 * Flags.
81 lwres_buffer_putuint32(b, req->flags);
84 * Class.
86 lwres_buffer_putuint16(b, req->rdclass);
89 * Type.
91 lwres_buffer_putuint16(b, req->rdtype);
94 * Put the length and the data. We know this will fit because we
95 * just checked for it.
97 lwres_buffer_putuint16(b, datalen);
98 lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
99 lwres_buffer_putuint8(b, 0); /* trailing NUL */
101 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
103 return (LWRES_R_SUCCESS);
106 lwres_result_t
107 lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
108 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
110 unsigned char *buf;
111 size_t buflen;
112 int ret;
113 size_t payload_length;
114 lwres_uint16_t datalen;
115 int x;
117 REQUIRE(ctx != NULL);
118 REQUIRE(req != NULL);
119 REQUIRE(pkt != NULL);
120 REQUIRE(b != NULL);
122 /* flags, class, type, ttl, nrdatas, nsigs */
123 payload_length = 4 + 2 + 2 + 4 + 2 + 2;
124 /* real name encoding */
125 payload_length += 2 + req->realnamelen + 1;
126 /* each rr */
127 for (x = 0; x < req->nrdatas; x++)
128 payload_length += 2 + req->rdatalen[x];
129 for (x = 0; x < req->nsigs; x++)
130 payload_length += 2 + req->siglen[x];
132 buflen = LWRES_LWPACKET_LENGTH + payload_length;
133 buf = CTXMALLOC(buflen);
134 if (buf == NULL)
135 return (LWRES_R_NOMEMORY);
136 lwres_buffer_init(b, buf, buflen);
138 pkt->length = buflen;
139 pkt->version = LWRES_LWPACKETVERSION_0;
140 pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
141 pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
142 pkt->authtype = 0;
143 pkt->authlength = 0;
145 ret = lwres_lwpacket_renderheader(b, pkt);
146 if (ret != LWRES_R_SUCCESS) {
147 lwres_buffer_invalidate(b);
148 CTXFREE(buf, buflen);
149 return (ret);
153 * Check space needed here.
155 INSIST(SPACE_OK(b, payload_length));
157 /* Flags. */
158 lwres_buffer_putuint32(b, req->flags);
160 /* encode class, type, ttl, and nrdatas */
161 lwres_buffer_putuint16(b, req->rdclass);
162 lwres_buffer_putuint16(b, req->rdtype);
163 lwres_buffer_putuint32(b, req->ttl);
164 lwres_buffer_putuint16(b, req->nrdatas);
165 lwres_buffer_putuint16(b, req->nsigs);
167 /* encode the real name */
168 datalen = req->realnamelen;
169 lwres_buffer_putuint16(b, datalen);
170 lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
171 lwres_buffer_putuint8(b, 0);
173 /* encode the rdatas */
174 for (x = 0; x < req->nrdatas; x++) {
175 datalen = req->rdatalen[x];
176 lwres_buffer_putuint16(b, datalen);
177 lwres_buffer_putmem(b, req->rdatas[x], datalen);
180 /* encode the signatures */
181 for (x = 0; x < req->nsigs; x++) {
182 datalen = req->siglen[x];
183 lwres_buffer_putuint16(b, datalen);
184 lwres_buffer_putmem(b, req->sigs[x], datalen);
187 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
188 INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
190 return (LWRES_R_SUCCESS);
193 lwres_result_t
194 lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
195 lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp)
197 int ret;
198 char *name;
199 lwres_grbnrequest_t *grbn;
200 lwres_uint32_t flags;
201 lwres_uint16_t rdclass, rdtype;
202 lwres_uint16_t namelen;
204 REQUIRE(ctx != NULL);
205 REQUIRE(pkt != NULL);
206 REQUIRE(b != NULL);
207 REQUIRE(structp != NULL && *structp == NULL);
209 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
210 return (LWRES_R_FAILURE);
212 if (!SPACE_REMAINING(b, 4 + 2 + 2))
213 return (LWRES_R_UNEXPECTEDEND);
216 * Pull off the flags, class, and type.
218 flags = lwres_buffer_getuint32(b);
219 rdclass = lwres_buffer_getuint16(b);
220 rdtype = lwres_buffer_getuint16(b);
223 * Pull off the name itself
225 ret = lwres_string_parse(b, &name, &namelen);
226 if (ret != LWRES_R_SUCCESS)
227 return (ret);
229 if (LWRES_BUFFER_REMAINING(b) != 0)
230 return (LWRES_R_TRAILINGDATA);
232 grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t));
233 if (grbn == NULL)
234 return (LWRES_R_NOMEMORY);
236 grbn->flags = flags;
237 grbn->rdclass = rdclass;
238 grbn->rdtype = rdtype;
239 grbn->name = name;
240 grbn->namelen = namelen;
242 *structp = grbn;
243 return (LWRES_R_SUCCESS);
246 lwres_result_t
247 lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
248 lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp)
250 lwres_result_t ret;
251 unsigned int x;
252 lwres_uint32_t flags;
253 lwres_uint16_t rdclass, rdtype;
254 lwres_uint32_t ttl;
255 lwres_uint16_t nrdatas, nsigs;
256 lwres_grbnresponse_t *grbn;
258 REQUIRE(ctx != NULL);
259 REQUIRE(pkt != NULL);
260 REQUIRE(b != NULL);
261 REQUIRE(structp != NULL && *structp == NULL);
263 grbn = NULL;
265 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
266 return (LWRES_R_FAILURE);
269 * Pull off the flags, class, type, ttl, nrdatas, and nsigs
271 if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2))
272 return (LWRES_R_UNEXPECTEDEND);
273 flags = lwres_buffer_getuint32(b);
274 rdclass = lwres_buffer_getuint16(b);
275 rdtype = lwres_buffer_getuint16(b);
276 ttl = lwres_buffer_getuint32(b);
277 nrdatas = lwres_buffer_getuint16(b);
278 nsigs = lwres_buffer_getuint16(b);
281 * Pull off the name itself
284 grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t));
285 if (grbn == NULL)
286 return (LWRES_R_NOMEMORY);
287 grbn->rdatas = NULL;
288 grbn->rdatalen = NULL;
289 grbn->sigs = NULL;
290 grbn->siglen = NULL;
291 grbn->base = NULL;
293 grbn->flags = flags;
294 grbn->rdclass = rdclass;
295 grbn->rdtype = rdtype;
296 grbn->ttl = ttl;
297 grbn->nrdatas = nrdatas;
298 grbn->nsigs = nsigs;
300 if (nrdatas > 0) {
301 grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas);
302 if (grbn->rdatas == NULL) {
303 ret = LWRES_R_NOMEMORY;
304 goto out;
307 grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas);
308 if (grbn->rdatalen == NULL) {
309 ret = LWRES_R_NOMEMORY;
310 goto out;
314 if (nsigs > 0) {
315 grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs);
316 if (grbn->sigs == NULL) {
317 ret = LWRES_R_NOMEMORY;
318 goto out;
321 grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs);
322 if (grbn->siglen == NULL) {
323 ret = LWRES_R_NOMEMORY;
324 goto out;
329 * Now, pull off the real name.
331 ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen);
332 if (ret != LWRES_R_SUCCESS)
333 goto out;
336 * Parse off the rdatas.
338 for (x = 0; x < grbn->nrdatas; x++) {
339 ret = lwres_data_parse(b, &grbn->rdatas[x],
340 &grbn->rdatalen[x]);
341 if (ret != LWRES_R_SUCCESS)
342 goto out;
346 * Parse off the signatures.
348 for (x = 0; x < grbn->nsigs; x++) {
349 ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]);
350 if (ret != LWRES_R_SUCCESS)
351 goto out;
354 if (LWRES_BUFFER_REMAINING(b) != 0) {
355 ret = LWRES_R_TRAILINGDATA;
356 goto out;
359 *structp = grbn;
360 return (LWRES_R_SUCCESS);
362 out:
363 if (grbn != NULL) {
364 if (grbn->rdatas != NULL)
365 CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas);
366 if (grbn->rdatalen != NULL)
367 CTXFREE(grbn->rdatalen,
368 sizeof(lwres_uint16_t) * nrdatas);
369 if (grbn->sigs != NULL)
370 CTXFREE(grbn->sigs, sizeof(char *) * nsigs);
371 if (grbn->siglen != NULL)
372 CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs);
373 CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
376 return (ret);
379 void
380 lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp)
382 lwres_grbnrequest_t *grbn;
384 REQUIRE(ctx != NULL);
385 REQUIRE(structp != NULL && *structp != NULL);
387 grbn = *structp;
388 *structp = NULL;
390 CTXFREE(grbn, sizeof(lwres_grbnrequest_t));
393 void
394 lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp)
396 lwres_grbnresponse_t *grbn;
398 REQUIRE(ctx != NULL);
399 REQUIRE(structp != NULL && *structp != NULL);
401 grbn = *structp;
402 *structp = NULL;
404 if (grbn->nrdatas > 0) {
405 CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas);
406 CTXFREE(grbn->rdatalen,
407 sizeof(lwres_uint16_t) * grbn->nrdatas);
409 if (grbn->nsigs > 0) {
410 CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs);
411 CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs);
413 if (grbn->base != NULL)
414 CTXFREE(grbn->base, grbn->baselen);
415 CTXFREE(grbn, sizeof(lwres_grbnresponse_t));