9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/*
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * Use is subject to license terms.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/*
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib *
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * Permission to use, copy, modify, and/or distribute this software for any
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * purpose with or without fee is hereby granted, provided that the above
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * copyright notice and this permission notice appear in all copies.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib *
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * PERFORMANCE OF THIS SOFTWARE.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#ifndef lint
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibstatic const char rcsid[] = "$Id: ns_newmsg.c,v 1.3 2009/02/26 10:48:57 marka Exp $";
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#endif
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#include <port_before.h>
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#include <arpa/nameser.h>
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#include <assert.h>
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#include <errno.h>
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#include <string.h>
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib#include <port_after.h>
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibstatic int rdcpy(ns_newmsg *, ns_type, const u_char *, size_t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Initialize a "newmsg" object to empty.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibint
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibns_newmsg_init(u_char *buffer, size_t bufsiz, ns_newmsg *handle) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_msg *msg = &handle->msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib memset(handle, 0, sizeof *handle);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_msg = buffer;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_eom = buffer + bufsiz;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_sect = ns_s_qd;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_rrnum = 0;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_msg_ptr = buffer + NS_HFIXEDSZ;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->dnptrs[0] = msg->_msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->dnptrs[1] = NULL;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->lastdnptr = &handle->dnptrs[sizeof handle->dnptrs /
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib sizeof handle->dnptrs[0] - 1];
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (0);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Initialize a "newmsg" object by copying an existing parsed message.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibint
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibns_newmsg_copy(ns_newmsg *handle, ns_msg *msg) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_flag flag;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_sect sect;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_newmsg_id(handle, ns_msg_id(*msg));
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib for (flag = ns_f_qr; flag < ns_f_max; flag++)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_newmsg_flag(handle, flag, ns_msg_getflag(*msg, flag));
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib for (sect = ns_s_qd; sect < ns_s_max; sect++) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib int i, count;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib count = ns_msg_count(*msg, sect);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib for (i = 0; i < count; i++) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr2 rr;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib int x;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (ns_parserr2(msg, sect, i, &rr) < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (sect == ns_s_qd)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib x = ns_newmsg_q(handle,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_nname(rr),
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_type(rr),
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_class(rr));
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib else
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib x = ns_newmsg_rr(handle, sect,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_nname(rr),
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_type(rr),
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_class(rr),
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_ttl(rr),
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_rdlen(rr),
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_rr_rdata(rr));
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (x < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (0);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Set the message-ID in a "newmsg" object.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibvoid
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibns_newmsg_id(ns_newmsg *handle, u_int16_t id) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_msg *msg = &handle->msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_id = id;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Set a flag (including rcode or opcode) in a "newmsg" object.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibvoid
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibns_newmsg_flag(ns_newmsg *handle, ns_flag flag, u_int value) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib extern struct _ns_flagdata _ns_flagdata[16];
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib struct _ns_flagdata *fd = &_ns_flagdata[flag];
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_msg *msg = &handle->msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib assert(flag < ns_f_max);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_flags &= (~fd->mask);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_flags |= (value << fd->shift);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Add a question (or zone, if it's an update) to a "newmsg" object.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibint
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibns_newmsg_q(ns_newmsg *handle, ns_nname_ct qname,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_type qtype, ns_class qclass)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib{
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_msg *msg = &handle->msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib u_char *t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib int n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (msg->_sect != ns_s_qd) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib errno = ENODEV;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t = (u_char *) (unsigned long) msg->_msg_ptr;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (msg->_rrnum == 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_sections[ns_s_qd] = t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib n = ns_name_pack(qname, t, msg->_eom - t,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->dnptrs, handle->lastdnptr);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (n < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t += n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (t + QFIXEDSZ >= msg->_eom) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib errno = EMSGSIZE;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(qtype, t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(qclass, t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_msg_ptr = t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_counts[ns_s_qd] = ++msg->_rrnum;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (0);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Add an RR to a "newmsg" object.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibint
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibns_newmsg_rr(ns_newmsg *handle, ns_sect sect,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_nname_ct name, ns_type type,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_class rr_class, u_int32_t ttl,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib u_int16_t rdlen, const u_char *rdata)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib{
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_msg *msg = &handle->msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib u_char *t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib int n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (sect < msg->_sect) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib errno = ENODEV;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t = (u_char *) (unsigned long) msg->_msg_ptr;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (sect > msg->_sect) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_sect = sect;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_sections[sect] = t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_rrnum = 0;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib n = ns_name_pack(name, t, msg->_eom - t,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->dnptrs, handle->lastdnptr);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (n < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t += n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (t + RRFIXEDSZ + rdlen >= msg->_eom) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib errno = EMSGSIZE;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(type, t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(rr_class, t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT32(ttl, t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_msg_ptr = t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (rdcpy(handle, type, rdata, rdlen) < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_counts[sect] = ++msg->_rrnum;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (0);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Complete a "newmsg" object and return its size for use in write().
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib * (Note: the "newmsg" object is also made ready for ns_parserr() etc.)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibsize_t
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibns_newmsg_done(ns_newmsg *handle) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_msg *msg = &handle->msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_sect sect;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib u_char *t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t = (u_char *) (unsigned long) msg->_msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(msg->_id, t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(msg->_flags, t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib for (sect = 0; sect < ns_s_max; sect++)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(msg->_counts[sect], t);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_eom = msg->_msg_ptr;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_sect = ns_s_max;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_rrnum = -1;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_msg_ptr = NULL;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (msg->_eom - msg->_msg);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Private. */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib/* Copy an RDATA, using compression pointers where RFC1035 permits.
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibstatic int
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaibrdcpy(ns_newmsg *handle, ns_type type, const u_char *rdata, size_t rdlen) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib ns_msg *msg = &handle->msg;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib u_char *p = (u_char *) (unsigned long) msg->_msg_ptr;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib u_char *t = p + NS_INT16SZ;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib u_char *s = t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib int n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib switch (type) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib case ns_t_soa:
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib /* MNAME. */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib n = ns_name_pack(rdata, t, msg->_eom - t,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->dnptrs, handle->lastdnptr);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (n < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t += n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (ns_name_skip(&rdata, msg->_eom) < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib /* ANAME. */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib n = ns_name_pack(rdata, t, msg->_eom - t,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->dnptrs, handle->lastdnptr);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (n < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t += n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (ns_name_skip(&rdata, msg->_eom) < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib /* Serial, Refresh, Retry, Expiry, and Minimum. */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if ((msg->_eom - t) < (NS_INT32SZ * 5)) {
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib errno = EMSGSIZE;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib memcpy(t, rdata, NS_INT32SZ * 5);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t += (NS_INT32SZ * 5);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib break;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib case ns_t_ptr:
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib case ns_t_cname:
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib case ns_t_ns:
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib /* PTRDNAME, CNAME, or NSDNAME. */
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib n = ns_name_pack(rdata, t, msg->_eom - t,
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib handle->dnptrs, handle->lastdnptr);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib if (n < 0)
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (-1);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t += n;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib break;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib default:
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib memcpy(t, rdata, rdlen);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib t += rdlen;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib }
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib NS_PUT16(t - s, p);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib msg->_msg_ptr = t;
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib return (0);
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib}
9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829Rao Shoaib