2 * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or 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.2.8.8 2007/09/24 17:26:10 each Exp $ */
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"
35 lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
36 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
41 size_t payload_length;
45 REQUIRE(req->addr.family != 0);
46 REQUIRE(req->addr.length != 0);
50 payload_length = 4 + 4 + 2 + + req->addr.length;
52 buflen = LWRES_LWPACKET_LENGTH + payload_length;
53 buf = CTXMALLOC(buflen);
55 return (LWRES_R_NOMEMORY);
56 lwres_buffer_init(b, buf, buflen);
59 pkt->version = LWRES_LWPACKETVERSION_0;
60 pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
61 pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
66 ret = lwres_lwpacket_renderheader(b, pkt);
67 if (ret != LWRES_R_SUCCESS) {
68 lwres_buffer_invalidate(b);
73 INSIST(SPACE_OK(b, payload_length));
76 * Put the length and the data. We know this will fit because we
77 * just checked for it.
79 lwres_buffer_putuint32(b, req->flags);
80 lwres_buffer_putuint32(b, req->addr.family);
81 lwres_buffer_putuint16(b, req->addr.length);
82 lwres_buffer_putmem(b, (unsigned char *)req->addr.address,
85 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
87 return (LWRES_R_SUCCESS);
91 lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
92 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
97 size_t payload_length;
98 lwres_uint16_t datalen;
101 REQUIRE(ctx != NULL);
102 REQUIRE(req != NULL);
103 REQUIRE(pkt != NULL);
107 * Calculate packet size.
109 payload_length = 4; /* flags */
110 payload_length += 2; /* naliases */
111 payload_length += 2 + req->realnamelen + 1; /* real name encoding */
112 for (x = 0; x < req->naliases; x++) /* each alias */
113 payload_length += 2 + req->aliaslen[x] + 1;
115 buflen = LWRES_LWPACKET_LENGTH + payload_length;
116 buf = CTXMALLOC(buflen);
118 return (LWRES_R_NOMEMORY);
119 lwres_buffer_init(b, buf, buflen);
121 pkt->length = buflen;
122 pkt->version = LWRES_LWPACKETVERSION_0;
123 pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
124 pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
128 ret = lwres_lwpacket_renderheader(b, pkt);
129 if (ret != LWRES_R_SUCCESS) {
130 lwres_buffer_invalidate(b);
131 CTXFREE(buf, buflen);
135 INSIST(SPACE_OK(b, payload_length));
136 lwres_buffer_putuint32(b, req->flags);
138 /* encode naliases */
139 lwres_buffer_putuint16(b, req->naliases);
141 /* encode the real name */
142 datalen = req->realnamelen;
143 lwres_buffer_putuint16(b, datalen);
144 lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
145 lwres_buffer_putuint8(b, 0);
147 /* encode the aliases */
148 for (x = 0; x < req->naliases; x++) {
149 datalen = req->aliaslen[x];
150 lwres_buffer_putuint16(b, datalen);
151 lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
153 lwres_buffer_putuint8(b, 0);
156 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
158 return (LWRES_R_SUCCESS);
162 lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
163 lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp)
166 lwres_gnbarequest_t *gnba;
168 REQUIRE(ctx != NULL);
169 REQUIRE(pkt != NULL);
171 REQUIRE(structp != NULL && *structp == NULL);
173 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
174 return (LWRES_R_FAILURE);
176 if (!SPACE_REMAINING(b, 4))
177 return (LWRES_R_UNEXPECTEDEND);
179 gnba = CTXMALLOC(sizeof(lwres_gnbarequest_t));
181 return (LWRES_R_NOMEMORY);
183 gnba->flags = lwres_buffer_getuint32(b);
185 ret = lwres_addr_parse(b, &gnba->addr);
186 if (ret != LWRES_R_SUCCESS)
189 if (LWRES_BUFFER_REMAINING(b) != 0) {
190 ret = LWRES_R_TRAILINGDATA;
195 return (LWRES_R_SUCCESS);
199 lwres_gnbarequest_free(ctx, &gnba);
205 lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
206 lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
210 lwres_uint32_t flags;
211 lwres_uint16_t naliases;
212 lwres_gnbaresponse_t *gnba;
214 REQUIRE(ctx != NULL);
215 REQUIRE(pkt != NULL);
217 REQUIRE(structp != NULL && *structp == NULL);
221 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
222 return (LWRES_R_FAILURE);
225 * Pull off flags & naliases
227 if (!SPACE_REMAINING(b, 4 + 2))
228 return (LWRES_R_UNEXPECTEDEND);
229 flags = lwres_buffer_getuint32(b);
230 naliases = lwres_buffer_getuint16(b);
232 gnba = CTXMALLOC(sizeof(lwres_gnbaresponse_t));
234 return (LWRES_R_NOMEMORY);
236 gnba->aliases = NULL;
237 gnba->aliaslen = NULL;
240 gnba->naliases = naliases;
243 gnba->aliases = CTXMALLOC(sizeof(char *) * naliases);
244 if (gnba->aliases == NULL) {
245 ret = LWRES_R_NOMEMORY;
249 gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
250 if (gnba->aliaslen == NULL) {
251 ret = LWRES_R_NOMEMORY;
257 * Now, pull off the real name.
259 ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen);
260 if (ret != LWRES_R_SUCCESS)
264 * Parse off the aliases.
266 for (x = 0; x < gnba->naliases; x++) {
267 ret = lwres_string_parse(b, &gnba->aliases[x],
269 if (ret != LWRES_R_SUCCESS)
273 if (LWRES_BUFFER_REMAINING(b) != 0) {
274 ret = LWRES_R_TRAILINGDATA;
279 return (LWRES_R_SUCCESS);
283 if (gnba->aliases != NULL)
284 CTXFREE(gnba->aliases, sizeof(char *) * naliases);
285 if (gnba->aliaslen != NULL)
286 CTXFREE(gnba->aliaslen,
287 sizeof(lwres_uint16_t) * naliases);
288 CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
295 lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp)
297 lwres_gnbarequest_t *gnba;
299 REQUIRE(ctx != NULL);
300 REQUIRE(structp != NULL && *structp != NULL);
305 CTXFREE(gnba, sizeof(lwres_gnbarequest_t));
309 lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp)
311 lwres_gnbaresponse_t *gnba;
313 REQUIRE(ctx != NULL);
314 REQUIRE(structp != NULL && *structp != NULL);
319 if (gnba->naliases > 0) {
320 CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
321 CTXFREE(gnba->aliaslen,
322 sizeof(lwres_uint16_t) * gnba->naliases);
324 if (gnba->base != NULL)
325 CTXFREE(gnba->base, gnba->baselen);
326 CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));