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