1 /* $NetBSD: lwpacket.c,v 1.4 2014/12/10 04:38:02 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 2000, 2001 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* Id: lwpacket.c,v 1.18 2007/06/19 23:47:22 tbox Exp */ 21 22 /*! \file */ 23 24 /** 25 * These functions rely on a struct lwres_lwpacket which is defined in 26 * \link lwpacket.h lwres/lwpacket.h.\endlink 27 * 28 * The following opcodes are currently defined: 29 * 30 * \li #LWRES_OPCODE_NOOP 31 * Success is always returned and the packet contents are 32 * echoed. The \link lwres_noop.c lwres_noop_*()\endlink functions should be used for this 33 * type. 34 * 35 * \li #LWRES_OPCODE_GETADDRSBYNAME 36 * returns all known addresses for a given name. The 37 * \link lwres_gabn.c lwres_gabn_*()\endlink functions should be used for this type. 38 * 39 * \li #LWRES_OPCODE_GETNAMEBYADDR 40 * return the hostname for the given address. The 41 * \link lwres_gnba.c lwres_gnba_*() \endlink functions should be used for this type. 42 * 43 * lwres_lwpacket_renderheader() transfers the contents of lightweight 44 * resolver packet structure #lwres_lwpacket_t *pkt in network byte 45 * order to the lightweight resolver buffer, *b. 46 * 47 * lwres_lwpacket_parseheader() performs the converse operation. It 48 * transfers data in network byte order from buffer *b to resolver 49 * packet *pkt. The contents of the buffer b should correspond to a 50 * #lwres_lwpacket_t. 51 * 52 * \section lwpacket_return Return Values 53 * 54 * Successful calls to lwres_lwpacket_renderheader() and 55 * lwres_lwpacket_parseheader() return #LWRES_R_SUCCESS. If there is 56 * insufficient space to copy data between the buffer *b and 57 * lightweight resolver packet *pkt both functions return 58 * #LWRES_R_UNEXPECTEDEND. 59 */ 60 61 #include <config.h> 62 63 #include <assert.h> 64 #include <stdlib.h> 65 #include <string.h> 66 67 #include <lwres/lwbuffer.h> 68 #include <lwres/lwpacket.h> 69 #include <lwres/result.h> 70 71 #include "assert_p.h" 72 73 /*% Length of Packet */ 74 #define LWPACKET_LENGTH \ 75 (sizeof(lwres_uint16_t) * 4 + sizeof(lwres_uint32_t) * 5) 76 77 /*% transfers the contents of lightweight resolver packet structure lwres_lwpacket_t *pkt in network byte order to the lightweight resolver buffer, *b. */ 78 79 lwres_result_t 80 lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) { 81 REQUIRE(b != NULL); 82 REQUIRE(pkt != NULL); 83 84 if (!SPACE_OK(b, LWPACKET_LENGTH)) 85 return (LWRES_R_UNEXPECTEDEND); 86 87 lwres_buffer_putuint32(b, pkt->length); 88 lwres_buffer_putuint16(b, pkt->version); 89 lwres_buffer_putuint16(b, pkt->pktflags); 90 lwres_buffer_putuint32(b, pkt->serial); 91 lwres_buffer_putuint32(b, pkt->opcode); 92 lwres_buffer_putuint32(b, pkt->result); 93 lwres_buffer_putuint32(b, pkt->recvlength); 94 lwres_buffer_putuint16(b, pkt->authtype); 95 lwres_buffer_putuint16(b, pkt->authlength); 96 97 return (LWRES_R_SUCCESS); 98 } 99 100 /*% transfers data in network byte order from buffer *b to resolver packet *pkt. The contents of the buffer b should correspond to a lwres_lwpacket_t. */ 101 102 lwres_result_t 103 lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) { 104 lwres_uint32_t space; 105 106 REQUIRE(b != NULL); 107 REQUIRE(pkt != NULL); 108 109 space = LWRES_BUFFER_REMAINING(b); 110 if (space < LWPACKET_LENGTH) 111 return (LWRES_R_UNEXPECTEDEND); 112 113 pkt->length = lwres_buffer_getuint32(b); 114 /* 115 * XXXBEW/MLG Checking that the buffer is long enough probably 116 * shouldn't be done here, since this function is supposed to just 117 * parse the header. 118 */ 119 if (pkt->length > space) 120 return (LWRES_R_UNEXPECTEDEND); 121 pkt->version = lwres_buffer_getuint16(b); 122 pkt->pktflags = lwres_buffer_getuint16(b); 123 pkt->serial = lwres_buffer_getuint32(b); 124 pkt->opcode = lwres_buffer_getuint32(b); 125 pkt->result = lwres_buffer_getuint32(b); 126 pkt->recvlength = lwres_buffer_getuint32(b); 127 pkt->authtype = lwres_buffer_getuint16(b); 128 pkt->authlength = lwres_buffer_getuint16(b); 129 130 return (LWRES_R_SUCCESS); 131 } 132