0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 2000-2002, 2004, 2005, 2007, 2013, 2016 Internet Systems Consortium, Inc. ("ISC")
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/.
8327cdb88fdbf306eb4c37fe00a29aac4c2f55c5Evan Hunt/* $Id: lwres_gnba.c,v 1.28 2007/09/24 17:18:25 each Exp $ */
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 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 These structures are defined in \link lwres.h <lwres/lwres.h.>\endlink They are shown
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austeintypedef struct {
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_uint32_t flags;
2bdfb330af70122f9ca5aae2556a112a3010e9efMark Andrews lwres_addr_t addr;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein} lwres_gnbarequest_t;
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 size_t baselen;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein} lwres_gnbaresponse_t;
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 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 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\section lwres_gbna_return Return Values
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\section lwres_gbna_see See Also
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein \link lwpacket.c lwres_packet\endlink
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses resolver context ctx to convert getnamebyaddr request structure req to canonical format. */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Grafflwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff payload_length = 4 + 4 + 2 + + req->addr.length;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * Put the length and the data. We know this will fit because we
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * just checked for it.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence lwres_buffer_putmem(b, (unsigned char *)req->addr.address,
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Converts a getnamebyaddr response structure lwres_gnbaresponse_t to the lightweight resolver's canonical format. */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Grafflwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff * Calculate packet size.
46fb173b203096492b9a97e38f259defaf195fe1Michael Graff payload_length += 2 + req->realnamelen + 1; /* real name encoding */
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (x = 0; x < req->naliases; x++) /* each alias */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff buflen = LWRES_LWPACKET_LENGTH + payload_length;
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews lwres_buffer_init(b, buf, (unsigned int)buflen);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /* encode naliases */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /* encode the real name */
6ba0a8a5e7c3a8fba18cdac329582321ac34ea5eAndreas Gustafsson lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /* encode the aliases */
6ba0a8a5e7c3a8fba18cdac329582321ac34ea5eAndreas Gustafsson lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Uses context ctx to convert the contents of packet pkt to a lwres_gnbarequest_t structure. */
88ed7381f16a72409061875ddeda598f477e5ef6Michael Grafflwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp)
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff gnba = CTXMALLOC(sizeof(lwres_gnbarequest_t));
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Offers the same semantics as lwres_gnbarequest_parse() except it yields a lwres_gnbaresponse_t structure. */
88ed7381f16a72409061875ddeda598f477e5ef6Michael Grafflwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff unsigned int x;
58ff88cca7c169f7fbebc9b6e93bbba1fb345157Michael Graff if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
031ce3bc62d273c5bd99596e01aa95c7ed33bbd7Brian Wellington * Pull off flags & naliases
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff gnba = CTXMALLOC(sizeof(lwres_gnbaresponse_t));
e721270c5ddb4f7022c8e56a265e9ac1fdac2422Michael Graff gnba->aliases = CTXMALLOC(sizeof(char *) * naliases);
7a166c5c61a5aaa6eeb929bed152dc0a6b128e3dMichael Graff gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff * Now, pull off the real name.
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen);
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff * Parse off the aliases.
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff ret = lwres_string_parse(b, &gnba->aliases[x],
88ed7381f16a72409061875ddeda598f477e5ef6Michael Graff CTXFREE(gnba->aliases, sizeof(char *) * naliases);
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx that was allocated to the lwres_gnbarequest_t. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp)
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*% Release the memory in resolver context ctx that was allocated to the lwres_gnbaresponse_t. */
64bed6c54393c2d213db83e9b171fb7c318cfc8eMichael Grafflwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp)
3b248999e6246309a6685b18903e78f97136ddbaMichael Graff CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);