Add BIND 9.2.4rc7.
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / lwres / lwres_gnba.c
blob3da747453141bcf353f048d7daf73bd801248933
1 /*
2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2002 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_gnba.c,v 1.20.2.3 2004/03/09 06:12:35 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_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_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;
43 REQUIRE(ctx != NULL);
44 REQUIRE(req != NULL);
45 REQUIRE(req->addr.family != 0);
46 REQUIRE(req->addr.length != 0);
47 REQUIRE(req->addr.address != NULL);
48 REQUIRE(pkt != NULL);
49 REQUIRE(b != NULL);
51 payload_length = 4 + 4 + 2 + + req->addr.length;
53 buflen = LWRES_LWPACKET_LENGTH + payload_length;
54 buf = CTXMALLOC(buflen);
55 if (buf == NULL)
56 return (LWRES_R_NOMEMORY);
57 lwres_buffer_init(b, buf, buflen);
59 pkt->length = buflen;
60 pkt->version = LWRES_LWPACKETVERSION_0;
61 pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
62 pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
63 pkt->result = 0;
64 pkt->authtype = 0;
65 pkt->authlength = 0;
67 ret = lwres_lwpacket_renderheader(b, pkt);
68 if (ret != LWRES_R_SUCCESS) {
69 lwres_buffer_invalidate(b);
70 CTXFREE(buf, buflen);
71 return (ret);
74 INSIST(SPACE_OK(b, payload_length));
77 * Put the length and the data. We know this will fit because we
78 * just checked for it.
80 lwres_buffer_putuint32(b, req->flags);
81 lwres_buffer_putuint32(b, req->addr.family);
82 lwres_buffer_putuint16(b, req->addr.length);
83 lwres_buffer_putmem(b, (unsigned char *)req->addr.address,
84 req->addr.length);
86 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
88 return (LWRES_R_SUCCESS);
91 lwres_result_t
92 lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
93 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
95 unsigned char *buf;
96 size_t buflen;
97 int ret;
98 size_t payload_length;
99 lwres_uint16_t datalen;
100 int x;
102 REQUIRE(ctx != NULL);
103 REQUIRE(req != NULL);
104 REQUIRE(pkt != NULL);
105 REQUIRE(b != NULL);
108 * Calculate packet size.
110 payload_length = 4; /* flags */
111 payload_length += 2; /* naliases */
112 payload_length += 2 + req->realnamelen + 1; /* real name encoding */
113 for (x = 0 ; x < req->naliases ; x++) /* each alias */
114 payload_length += 2 + req->aliaslen[x] + 1;
116 buflen = LWRES_LWPACKET_LENGTH + payload_length;
117 buf = CTXMALLOC(buflen);
118 if (buf == NULL)
119 return (LWRES_R_NOMEMORY);
120 lwres_buffer_init(b, buf, buflen);
122 pkt->length = buflen;
123 pkt->version = LWRES_LWPACKETVERSION_0;
124 pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
125 pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
126 pkt->authtype = 0;
127 pkt->authlength = 0;
129 ret = lwres_lwpacket_renderheader(b, pkt);
130 if (ret != LWRES_R_SUCCESS) {
131 lwres_buffer_invalidate(b);
132 CTXFREE(buf, buflen);
133 return (ret);
136 INSIST(SPACE_OK(b, payload_length));
137 lwres_buffer_putuint32(b, req->flags);
139 /* encode naliases */
140 lwres_buffer_putuint16(b, req->naliases);
142 /* encode the real name */
143 datalen = req->realnamelen;
144 lwres_buffer_putuint16(b, datalen);
145 lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
146 lwres_buffer_putuint8(b, 0);
148 /* encode the aliases */
149 for (x = 0 ; x < req->naliases ; x++) {
150 datalen = req->aliaslen[x];
151 lwres_buffer_putuint16(b, datalen);
152 lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
153 datalen);
154 lwres_buffer_putuint8(b, 0);
157 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
159 return (LWRES_R_SUCCESS);
162 lwres_result_t
163 lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
164 lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp)
166 int ret;
167 lwres_gnbarequest_t *gnba;
169 REQUIRE(ctx != NULL);
170 REQUIRE(pkt != NULL);
171 REQUIRE(b != NULL);
172 REQUIRE(structp != NULL && *structp == NULL);
174 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
175 return (LWRES_R_FAILURE);
177 if (!SPACE_REMAINING(b, 4))
178 return (LWRES_R_UNEXPECTEDEND);
180 gnba = CTXMALLOC(sizeof(lwres_gnbarequest_t));
181 if (gnba == NULL)
182 return (LWRES_R_NOMEMORY);
184 gnba->flags = lwres_buffer_getuint32(b);
186 ret = lwres_addr_parse(b, &gnba->addr);
187 if (ret != LWRES_R_SUCCESS)
188 goto out;
190 if (LWRES_BUFFER_REMAINING(b) != 0) {
191 ret = LWRES_R_TRAILINGDATA;
192 goto out;
195 *structp = gnba;
196 return (LWRES_R_SUCCESS);
198 out:
199 if (gnba != NULL)
200 lwres_gnbarequest_free(ctx, &gnba);
202 return (ret);
205 lwres_result_t
206 lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
207 lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
209 int ret;
210 unsigned int x;
211 lwres_uint32_t flags;
212 lwres_uint16_t naliases;
213 lwres_gnbaresponse_t *gnba;
215 REQUIRE(ctx != NULL);
216 REQUIRE(pkt != NULL);
217 REQUIRE(b != NULL);
218 REQUIRE(structp != NULL && *structp == NULL);
220 gnba = NULL;
222 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
223 return (LWRES_R_FAILURE);
226 * Pull off flags & naliases
228 if (!SPACE_REMAINING(b, 4 + 2))
229 return (LWRES_R_UNEXPECTEDEND);
230 flags = lwres_buffer_getuint32(b);
231 naliases = lwres_buffer_getuint16(b);
233 gnba = CTXMALLOC(sizeof(lwres_gnbaresponse_t));
234 if (gnba == NULL)
235 return (LWRES_R_NOMEMORY);
236 gnba->base = NULL;
237 gnba->aliases = NULL;
238 gnba->aliaslen = NULL;
240 gnba->flags = flags;
241 gnba->naliases = naliases;
243 if (naliases > 0) {
244 gnba->aliases = CTXMALLOC(sizeof(char *) * naliases);
245 if (gnba->aliases == NULL) {
246 ret = LWRES_R_NOMEMORY;
247 goto out;
250 gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
251 if (gnba->aliaslen == NULL) {
252 ret = LWRES_R_NOMEMORY;
253 goto out;
258 * Now, pull off the real name.
260 ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen);
261 if (ret != LWRES_R_SUCCESS)
262 goto out;
265 * Parse off the aliases.
267 for (x = 0 ; x < gnba->naliases ; x++) {
268 ret = lwres_string_parse(b, &gnba->aliases[x],
269 &gnba->aliaslen[x]);
270 if (ret != LWRES_R_SUCCESS)
271 goto out;
274 if (LWRES_BUFFER_REMAINING(b) != 0) {
275 ret = LWRES_R_TRAILINGDATA;
276 goto out;
279 *structp = gnba;
280 return (LWRES_R_SUCCESS);
282 out:
283 if (gnba != NULL) {
284 if (gnba->aliases != NULL)
285 CTXFREE(gnba->aliases, sizeof(char *) * naliases);
286 if (gnba->aliaslen != NULL)
287 CTXFREE(gnba->aliaslen,
288 sizeof(lwres_uint16_t) * naliases);
289 CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
292 return (ret);
295 void
296 lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp)
298 lwres_gnbarequest_t *gnba;
300 REQUIRE(ctx != NULL);
301 REQUIRE(structp != NULL && *structp != NULL);
303 gnba = *structp;
304 *structp = NULL;
306 CTXFREE(gnba, sizeof(lwres_gnbarequest_t));
309 void
310 lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp)
312 lwres_gnbaresponse_t *gnba;
314 REQUIRE(ctx != NULL);
315 REQUIRE(structp != NULL && *structp != NULL);
317 gnba = *structp;
318 *structp = NULL;
320 if (gnba->naliases > 0) {
321 CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
322 CTXFREE(gnba->aliaslen,
323 sizeof(lwres_uint16_t) * gnba->naliases);
325 if (gnba->base != NULL)
326 CTXFREE(gnba->base, gnba->baselen);
327 CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));