2 * Copyright (C) 2000, 2001 Internet Software Consortium.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
9 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
10 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
11 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
13 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
14 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: lwres_grbn.c,v 1.1 2004/03/15 20:35:25 as 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_grbnrequest_render(lwres_context_t
*ctx
, lwres_grbnrequest_t
*req
,
36 lwres_lwpacket_t
*pkt
, lwres_buffer_t
*b
)
41 size_t payload_length
;
42 lwres_uint16_t datalen
;
46 REQUIRE(req
->name
!= 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
);
57 return (LWRES_R_NOMEMORY
);
59 lwres_buffer_init(b
, buf
, buflen
);
62 pkt
->version
= LWRES_LWPACKETVERSION_0
;
63 pkt
->pktflags
&= ~LWRES_LWPACKETFLAG_RESPONSE
;
64 pkt
->opcode
= LWRES_OPCODE_GETRDATABYNAME
;
69 ret
= lwres_lwpacket_renderheader(b
, pkt
);
70 if (ret
!= LWRES_R_SUCCESS
) {
71 lwres_buffer_invalidate(b
);
76 INSIST(SPACE_OK(b
, payload_length
));
81 lwres_buffer_putuint32(b
, req
->flags
);
86 lwres_buffer_putuint16(b
, req
->rdclass
);
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
);
107 lwres_grbnresponse_render(lwres_context_t
*ctx
, lwres_grbnresponse_t
*req
,
108 lwres_lwpacket_t
*pkt
, lwres_buffer_t
*b
)
113 size_t payload_length
;
114 lwres_uint16_t datalen
;
117 REQUIRE(ctx
!= NULL
);
118 REQUIRE(req
!= NULL
);
119 REQUIRE(pkt
!= 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;
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
);
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
;
145 ret
= lwres_lwpacket_renderheader(b
, pkt
);
146 if (ret
!= LWRES_R_SUCCESS
) {
147 lwres_buffer_invalidate(b
);
148 CTXFREE(buf
, buflen
);
153 * Check space needed here.
155 INSIST(SPACE_OK(b
, payload_length
));
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
);
194 lwres_grbnrequest_parse(lwres_context_t
*ctx
, lwres_buffer_t
*b
,
195 lwres_lwpacket_t
*pkt
, lwres_grbnrequest_t
**structp
)
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
);
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
)
229 if (LWRES_BUFFER_REMAINING(b
) != 0)
230 return (LWRES_R_TRAILINGDATA
);
232 grbn
= CTXMALLOC(sizeof(lwres_grbnrequest_t
));
234 return (LWRES_R_NOMEMORY
);
237 grbn
->rdclass
= rdclass
;
238 grbn
->rdtype
= rdtype
;
240 grbn
->namelen
= namelen
;
243 return (LWRES_R_SUCCESS
);
247 lwres_grbnresponse_parse(lwres_context_t
*ctx
, lwres_buffer_t
*b
,
248 lwres_lwpacket_t
*pkt
, lwres_grbnresponse_t
**structp
)
252 lwres_uint32_t flags
;
253 lwres_uint16_t rdclass
, rdtype
;
255 lwres_uint16_t nrdatas
, nsigs
;
256 lwres_grbnresponse_t
*grbn
;
258 REQUIRE(ctx
!= NULL
);
259 REQUIRE(pkt
!= NULL
);
261 REQUIRE(structp
!= NULL
&& *structp
== 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
));
286 return (LWRES_R_NOMEMORY
);
288 grbn
->rdatalen
= NULL
;
294 grbn
->rdclass
= rdclass
;
295 grbn
->rdtype
= rdtype
;
297 grbn
->nrdatas
= nrdatas
;
301 grbn
->rdatas
= CTXMALLOC(sizeof(char *) * nrdatas
);
302 if (grbn
->rdatas
== NULL
) {
303 ret
= LWRES_R_NOMEMORY
;
307 grbn
->rdatalen
= CTXMALLOC(sizeof(lwres_uint16_t
) * nrdatas
);
308 if (grbn
->rdatalen
== NULL
) {
309 ret
= LWRES_R_NOMEMORY
;
315 grbn
->sigs
= CTXMALLOC(sizeof(char *) * nsigs
);
316 if (grbn
->sigs
== NULL
) {
317 ret
= LWRES_R_NOMEMORY
;
321 grbn
->siglen
= CTXMALLOC(sizeof(lwres_uint16_t
) * nsigs
);
322 if (grbn
->siglen
== NULL
) {
323 ret
= LWRES_R_NOMEMORY
;
329 * Now, pull off the real name.
331 ret
= lwres_string_parse(b
, &grbn
->realname
, &grbn
->realnamelen
);
332 if (ret
!= LWRES_R_SUCCESS
)
336 * Parse off the rdatas.
338 for (x
= 0 ; x
< grbn
->nrdatas
; x
++) {
339 ret
= lwres_data_parse(b
, &grbn
->rdatas
[x
],
341 if (ret
!= LWRES_R_SUCCESS
)
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
)
354 if (LWRES_BUFFER_REMAINING(b
) != 0) {
355 ret
= LWRES_R_TRAILINGDATA
;
360 return (LWRES_R_SUCCESS
);
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
));
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
);
390 CTXFREE(grbn
, sizeof(lwres_grbnrequest_t
));
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
);
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
));