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.2.8.4 2004/03/08 09:05:11 marka 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);
47 REQUIRE(req->addr.address != NULL);
51 payload_length = 4 + 4 + 2 + + req->addr.length;
53 buflen = LWRES_LWPACKET_LENGTH + payload_length;
54 buf = CTXMALLOC(buflen);
56 return (LWRES_R_NOMEMORY);
57 lwres_buffer_init(b, buf, buflen);
60 pkt->version = LWRES_LWPACKETVERSION_0;
61 pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
62 pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
67 ret = lwres_lwpacket_renderheader(b, pkt);
68 if (ret != LWRES_R_SUCCESS) {
69 lwres_buffer_invalidate(b);
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,
86 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
88 return (LWRES_R_SUCCESS);
92 lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
93 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
98 size_t payload_length;
99 lwres_uint16_t datalen;
102 REQUIRE(ctx != NULL);
103 REQUIRE(req != NULL);
104 REQUIRE(pkt != 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);
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;
129 ret = lwres_lwpacket_renderheader(b, pkt);
130 if (ret != LWRES_R_SUCCESS) {
131 lwres_buffer_invalidate(b);
132 CTXFREE(buf, buflen);
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],
154 lwres_buffer_putuint8(b, 0);
157 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
159 return (LWRES_R_SUCCESS);
163 lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
164 lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp)
167 lwres_gnbarequest_t *gnba;
169 REQUIRE(ctx != NULL);
170 REQUIRE(pkt != 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));
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)
190 if (LWRES_BUFFER_REMAINING(b) != 0) {
191 ret = LWRES_R_TRAILINGDATA;
196 return (LWRES_R_SUCCESS);
200 lwres_gnbarequest_free(ctx, &gnba);
206 lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
207 lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
211 lwres_uint32_t flags;
212 lwres_uint16_t naliases;
213 lwres_gnbaresponse_t *gnba;
215 REQUIRE(ctx != NULL);
216 REQUIRE(pkt != NULL);
218 REQUIRE(structp != NULL && *structp == 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));
235 return (LWRES_R_NOMEMORY);
237 gnba->aliases = NULL;
238 gnba->aliaslen = NULL;
241 gnba->naliases = naliases;
244 gnba->aliases = CTXMALLOC(sizeof(char *) * naliases);
245 if (gnba->aliases == NULL) {
246 ret = LWRES_R_NOMEMORY;
250 gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
251 if (gnba->aliaslen == NULL) {
252 ret = LWRES_R_NOMEMORY;
258 * Now, pull off the real name.
260 ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen);
261 if (ret != LWRES_R_SUCCESS)
265 * Parse off the aliases.
267 for (x = 0; x < gnba->naliases; x++) {
268 ret = lwres_string_parse(b, &gnba->aliases[x],
270 if (ret != LWRES_R_SUCCESS)
274 if (LWRES_BUFFER_REMAINING(b) != 0) {
275 ret = LWRES_R_TRAILINGDATA;
280 return (LWRES_R_SUCCESS);
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));
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);
306 CTXFREE(gnba, sizeof(lwres_gnbarequest_t));
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);
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));