64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff/*
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 2000-2002, 2004, 2005, 2007, 2013, 2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
8327cdb88fdbf306eb4c37fe00a29aac4c2f55c5Evan Hunt/* $Id: lwres_gnba.c,v 1.28 2007/09/24 17:18:25 each Exp $ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file lwres_gnba.c
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein These are low-level routines for creating and parsing lightweight
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein resolver address-to-name lookup request and response messages.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein There are four main functions for the getnamebyaddr opcode. One
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein render function converts a getnamebyaddr request structure --
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbarequest_t -- to the lightweight resolver's canonical
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein format. It is complemented by a parse function that converts a
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein packet in this canonical format to a getnamebyaddr request
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein structure. Another render function converts the getnamebyaddr
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein response structure -- lwres_gnbaresponse_t to the canonical format.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein This is complemented by a parse function which converts a packet in
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews canonical format to a getnamebyaddr response structure.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein These structures are defined in \link lwres.h <lwres/lwres.h.>\endlink They are shown
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein below.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein\code
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeintypedef struct {
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_uint32_t flags;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_addr_t addr;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein} lwres_gnbarequest_t;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeintypedef struct {
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_uint32_t flags;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_uint16_t naliases;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews char *realname;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews char **aliases;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_uint16_t realnamelen;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_uint16_t *aliaslen;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews void *base;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews size_t baselen;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein} lwres_gnbaresponse_t;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein\endcode
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbarequest_render() uses resolver context ctx to convert
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein getnamebyaddr request structure req to canonical format. The packet
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein header structure pkt is initialised and transferred to buffer b.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein The contents of *req are then appended to the buffer in canonical
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein format. lwres_gnbaresponse_render() performs the same task, except
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein it converts a getnamebyaddr response structure lwres_gnbaresponse_t
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein to the lightweight resolver's canonical format.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbarequest_parse() uses context ctx to convert the contents
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein of packet pkt to a lwres_gnbarequest_t structure. Buffer b provides
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein space to be used for storing this structure. When the function
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein succeeds, the resulting lwres_gnbarequest_t is made available
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews through *structp. lwres_gnbaresponse_parse() offers the same
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrewssemantics as lwres_gnbarequest_parse() except it yields a
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbaresponse_t structure.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbaresponse_free() and lwres_gnbarequest_free() release the
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews memory in resolver context ctx that was allocated to the
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_gnbaresponse_t or lwres_gnbarequest_t structures referenced
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews via structp. Any memory associated with ancillary buffers and
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein strings for those structures is also discarded.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein\section lwres_gbna_return Return Values
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein The getnamebyaddr opcode functions lwres_gnbarequest_render(),
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbaresponse_render() lwres_gnbarequest_parse() and
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbaresponse_parse() all return #LWRES_R_SUCCESS on success.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein They return #LWRES_R_NOMEMORY if memory allocation fails.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein #LWRES_R_UNEXPECTEDEND is returned if the available space in the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein buffer b is too small to accommodate the packet header or the
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbarequest_t and lwres_gnbaresponse_t structures.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein lwres_gnbarequest_parse() and lwres_gnbaresponse_parse() will
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein return #LWRES_R_UNEXPECTEDEND if the buffer is not empty after
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein decoding the received packet. These functions will return
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein #LWRES_R_FAILURE if pktflags in the packet header structure
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein #lwres_lwpacket_t indicate that the packet is not a response to an
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein earlier query.
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein\section lwres_gbna_see See Also
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein \link lwpacket.c lwres_packet\endlink
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <config.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <assert.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <stdlib.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <string.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <lwres/lwbuffer.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <lwres/lwpacket.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include <lwres/lwres.h>
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff#include <lwres/result.h>
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include "context_p.h"
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff#include "assert_p.h"
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses resolver context ctx to convert getnamebyaddr request structure req to canonical format. */
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Grafflwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_lwpacket_t *pkt, lwres_buffer_t *b)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff unsigned char *buf;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff size_t buflen;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff int ret;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff size_t payload_length;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(ctx != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(req != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(req->addr.family != 0);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(req->addr.length != 0);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(pkt != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(b != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff payload_length = 4 + 4 + 2 + + req->addr.length;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buf = CTXMALLOC(buflen);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (buf == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews pkt->length = (lwres_uint32_t)buflen;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->version = LWRES_LWPACKETVERSION_0;
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->result = 0;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->authtype = 0;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->authlength = 0;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff ret = lwres_lwpacket_renderheader(b, pkt);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (ret != LWRES_R_SUCCESS) {
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_buffer_invalidate(b);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff CTXFREE(buf, buflen);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff return (ret);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff }
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff INSIST(SPACE_OK(b, payload_length));
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /*
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * Put the length and the data. We know this will fit because we
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * just checked for it.
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff */
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff lwres_buffer_putuint32(b, req->flags);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_buffer_putuint32(b, req->addr.family);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_buffer_putuint16(b, req->addr.length);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence lwres_buffer_putmem(b, (unsigned char *)req->addr.address,
6ba0a8a5e7c3a8fba18cdac329582321ac34ea5eAndreas Gustafsson req->addr.length);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Converts a getnamebyaddr response structure lwres_gnbaresponse_t to the lightweight resolver's canonical format. */
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Grafflwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_lwpacket_t *pkt, lwres_buffer_t *b)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff unsigned char *buf;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff size_t buflen;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff int ret;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff size_t payload_length;
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff lwres_uint16_t datalen;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff int x;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(ctx != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(req != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(pkt != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(b != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff /*
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff * Calculate packet size.
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff */
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff payload_length = 4; /* flags */
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff payload_length += 2; /* naliases */
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff payload_length += 2 + req->realnamelen + 1; /* real name encoding */
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (x = 0; x < req->naliases; x++) /* each alias */
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff payload_length += 2 + req->aliaslen[x] + 1;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buf = CTXMALLOC(buflen);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (buf == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews pkt->length = (lwres_uint32_t)buflen;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->version = LWRES_LWPACKETVERSION_0;
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->authtype = 0;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff pkt->authlength = 0;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff ret = lwres_lwpacket_renderheader(b, pkt);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (ret != LWRES_R_SUCCESS) {
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_buffer_invalidate(b);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff CTXFREE(buf, buflen);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff return (ret);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff }
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff INSIST(SPACE_OK(b, payload_length));
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff lwres_buffer_putuint32(b, req->flags);
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /* encode naliases */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_buffer_putuint16(b, req->naliases);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /* encode the real name */
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff datalen = req->realnamelen;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_buffer_putuint16(b, datalen);
6ba0a8a5e7c3a8fba18cdac329582321ac34ea5eAndreas Gustafsson lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff lwres_buffer_putuint8(b, 0);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /* encode the aliases */
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (x = 0; x < req->naliases; x++) {
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff datalen = req->aliaslen[x];
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_buffer_putuint16(b, datalen);
6ba0a8a5e7c3a8fba18cdac329582321ac34ea5eAndreas Gustafsson lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
6ba0a8a5e7c3a8fba18cdac329582321ac34ea5eAndreas Gustafsson datalen);
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff lwres_buffer_putuint8(b, 0);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff }
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses context ctx to convert the contents of packet pkt to a lwres_gnbarequest_t structure. */
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
88ed7381f16a72409061875ddeda598f477e5ef6Michael Grafflwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff int ret;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff lwres_gnbarequest_t *gnba;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(ctx != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(pkt != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(b != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(structp != NULL && *structp == NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_FAILURE);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
9549a96654ead15b264c9159d48eb485e4f9db55Mark Andrews if (!SPACE_REMAINING(b, 4))
9549a96654ead15b264c9159d48eb485e4f9db55Mark Andrews return (LWRES_R_UNEXPECTEDEND);
9549a96654ead15b264c9159d48eb485e4f9db55Mark Andrews
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff gnba = CTXMALLOC(sizeof(lwres_gnbarequest_t));
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff if (gnba == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff gnba->flags = lwres_buffer_getuint32(b);
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff ret = lwres_addr_parse(b, &gnba->addr);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (ret != LWRES_R_SUCCESS)
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff goto out;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff if (LWRES_BUFFER_REMAINING(b) != 0) {
031ce3bc62d273c5bd99596e01aa95c7ed33bbd7Brian Wellington ret = LWRES_R_TRAILINGDATA;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff goto out;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff }
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff *structp = gnba;
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff out:
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff if (gnba != NULL)
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff lwres_gnbarequest_free(ctx, &gnba);
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff return (ret);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Offers the same semantics as lwres_gnbarequest_parse() except it yields a lwres_gnbaresponse_t structure. */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
b81306ccd14066cb7378f7f74bbf3843b5a88985Michael Grafflwres_result_t
88ed7381f16a72409061875ddeda598f477e5ef6Michael Grafflwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff int ret;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff unsigned int x;
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff lwres_uint32_t flags;
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff lwres_uint16_t naliases;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff lwres_gnbaresponse_t *gnba;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(ctx != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(pkt != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(b != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(structp != NULL && *structp == NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff gnba = NULL;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_FAILURE);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff /*
031ce3bc62d273c5bd99596e01aa95c7ed33bbd7Brian Wellington * Pull off flags & naliases
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff */
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff if (!SPACE_REMAINING(b, 4 + 2))
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_UNEXPECTEDEND);
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff flags = lwres_buffer_getuint32(b);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff naliases = lwres_buffer_getuint16(b);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff gnba = CTXMALLOC(sizeof(lwres_gnbaresponse_t));
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff if (gnba == NULL)
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_NOMEMORY);
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff gnba->base = NULL;
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff gnba->aliases = NULL;
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff gnba->aliaslen = NULL;
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff gnba->flags = flags;
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff gnba->naliases = naliases;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff if (naliases > 0) {
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff gnba->aliases = CTXMALLOC(sizeof(char *) * naliases);
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff if (gnba->aliases == NULL) {
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff ret = LWRES_R_NOMEMORY;
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff goto out;
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff }
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff if (gnba->aliaslen == NULL) {
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff ret = LWRES_R_NOMEMORY;
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff goto out;
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff }
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff }
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff /*
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff * Now, pull off the real name.
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff */
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (ret != LWRES_R_SUCCESS)
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff goto out;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff /*
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff * Parse off the aliases.
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff */
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (x = 0; x < gnba->naliases; x++) {
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff ret = lwres_string_parse(b, &gnba->aliases[x],
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff &gnba->aliaslen[x]);
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff if (ret != LWRES_R_SUCCESS)
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff goto out;
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff }
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff if (LWRES_BUFFER_REMAINING(b) != 0) {
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff ret = LWRES_R_TRAILINGDATA;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff goto out;
28dff2287e42c8b83eda2abb95667b4596dc994bMichael Graff }
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff *structp = gnba;
8cd870e3f5e3db9808a4a0d6f98db3d1a5348e40Michael Graff return (LWRES_R_SUCCESS);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff out:
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff if (gnba != NULL) {
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff if (gnba->aliases != NULL)
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff CTXFREE(gnba->aliases, sizeof(char *) * naliases);
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff if (gnba->aliaslen != NULL)
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff CTXFREE(gnba->aliaslen,
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff sizeof(lwres_uint16_t) * naliases);
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff }
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff return (ret);
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx that was allocated to the lwres_gnbarequest_t. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graffvoid
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_gnbarequest_t *gnba;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(ctx != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(structp != NULL && *structp != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff gnba = *structp;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff *structp = NULL;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff CTXFREE(gnba, sizeof(lwres_gnbarequest_t));
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graffvoid
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp)
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff{
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff lwres_gnbaresponse_t *gnba;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(ctx != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(structp != NULL && *structp != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff gnba = *structp;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff *structp = NULL;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
12e302d5c728c7ecdafeee7f7467f219a7a504afMichael Graff if (gnba->naliases > 0) {
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff CTXFREE(gnba->aliaslen,
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff sizeof(lwres_uint16_t) * gnba->naliases);
12e302d5c728c7ecdafeee7f7467f219a7a504afMichael Graff }
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff if (gnba->base != NULL)
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff CTXFREE(gnba->base, gnba->baselen);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Graff}