165e96449SHajimu UMEMOTO /* 2046c3635SPedro F. Giffuni * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") 3046c3635SPedro F. Giffuni * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003 Internet Software Consortium. 4046c3635SPedro F. Giffuni * 5046c3635SPedro F. Giffuni * Permission to use, copy, modify, and/or distribute this software for any 6046c3635SPedro F. Giffuni * purpose with or without fee is hereby granted, provided that the above 7046c3635SPedro F. Giffuni * copyright notice and this permission notice appear in all copies. 8046c3635SPedro F. Giffuni * 9046c3635SPedro F. Giffuni * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10046c3635SPedro F. Giffuni * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11046c3635SPedro F. Giffuni * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12046c3635SPedro F. Giffuni * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13046c3635SPedro F. Giffuni * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14046c3635SPedro F. Giffuni * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15046c3635SPedro F. Giffuni * PERFORMANCE OF THIS SOFTWARE. 16046c3635SPedro F. Giffuni */ 17046c3635SPedro F. Giffuni 18046c3635SPedro F. Giffuni /* 1965e96449SHajimu UMEMOTO * Copyright (c) 1985, 1993 2065e96449SHajimu UMEMOTO * The Regents of the University of California. All rights reserved. 2165e96449SHajimu UMEMOTO * 2265e96449SHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without 2365e96449SHajimu UMEMOTO * modification, are permitted provided that the following conditions 2465e96449SHajimu UMEMOTO * are met: 2565e96449SHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright 2665e96449SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer. 2765e96449SHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright 2865e96449SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the 2965e96449SHajimu UMEMOTO * documentation and/or other materials provided with the distribution. 30fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 3165e96449SHajimu UMEMOTO * may be used to endorse or promote products derived from this software 3265e96449SHajimu UMEMOTO * without specific prior written permission. 3365e96449SHajimu UMEMOTO * 3465e96449SHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 3565e96449SHajimu UMEMOTO * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 3665e96449SHajimu UMEMOTO * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3765e96449SHajimu UMEMOTO * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3865e96449SHajimu UMEMOTO * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3965e96449SHajimu UMEMOTO * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4065e96449SHajimu UMEMOTO * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4165e96449SHajimu UMEMOTO * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4265e96449SHajimu UMEMOTO * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4365e96449SHajimu UMEMOTO * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 4465e96449SHajimu UMEMOTO * SUCH DAMAGE. 4565e96449SHajimu UMEMOTO */ 4665e96449SHajimu UMEMOTO 4765e96449SHajimu UMEMOTO /* 4865e96449SHajimu UMEMOTO * Portions Copyright (c) 1993 by Digital Equipment Corporation. 4965e96449SHajimu UMEMOTO * 5065e96449SHajimu UMEMOTO * Permission to use, copy, modify, and distribute this software for any 5165e96449SHajimu UMEMOTO * purpose with or without fee is hereby granted, provided that the above 5265e96449SHajimu UMEMOTO * copyright notice and this permission notice appear in all copies, and that 5365e96449SHajimu UMEMOTO * the name of Digital Equipment Corporation not be used in advertising or 5465e96449SHajimu UMEMOTO * publicity pertaining to distribution of the document or software without 5565e96449SHajimu UMEMOTO * specific, written prior permission. 5665e96449SHajimu UMEMOTO * 5765e96449SHajimu UMEMOTO * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 5865e96449SHajimu UMEMOTO * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 5965e96449SHajimu UMEMOTO * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 6065e96449SHajimu UMEMOTO * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 6165e96449SHajimu UMEMOTO * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 6265e96449SHajimu UMEMOTO * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 6365e96449SHajimu UMEMOTO * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 6465e96449SHajimu UMEMOTO * SOFTWARE. 6565e96449SHajimu UMEMOTO */ 6665e96449SHajimu UMEMOTO 6765e96449SHajimu UMEMOTO #if defined(LIBC_SCCS) && !defined(lint) 6865e96449SHajimu UMEMOTO static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; 69046c3635SPedro F. Giffuni static const char rcsid[] = "$Id: res_mkquery.c,v 1.10 2008/12/11 09:59:00 marka Exp $"; 7065e96449SHajimu UMEMOTO #endif /* LIBC_SCCS and not lint */ 71ab96eeabSHajimu UMEMOTO #include <sys/cdefs.h> 72ab96eeabSHajimu UMEMOTO __FBSDID("$FreeBSD$"); 7365e96449SHajimu UMEMOTO 7465e96449SHajimu UMEMOTO #include "port_before.h" 7565e96449SHajimu UMEMOTO #include <sys/param.h> 7665e96449SHajimu UMEMOTO #include <netinet/in.h> 7765e96449SHajimu UMEMOTO #include <arpa/nameser.h> 7865e96449SHajimu UMEMOTO #include <netdb.h> 7965e96449SHajimu UMEMOTO #include <resolv.h> 8065e96449SHajimu UMEMOTO #include <stdio.h> 8165e96449SHajimu UMEMOTO #include <string.h> 8265e96449SHajimu UMEMOTO #include "port_after.h" 8365e96449SHajimu UMEMOTO 8465e96449SHajimu UMEMOTO /* Options. Leave them on. */ 858a615d0fSEnji Cooper #ifndef DEBUG 8665e96449SHajimu UMEMOTO #define DEBUG 878a615d0fSEnji Cooper #endif 8865e96449SHajimu UMEMOTO 8965e96449SHajimu UMEMOTO extern const char *_res_opcodes[]; 9065e96449SHajimu UMEMOTO 91dde4a85dSHajimu UMEMOTO /*% 9265e96449SHajimu UMEMOTO * Form all types of queries. 9365e96449SHajimu UMEMOTO * Returns the size of the result or -1. 9465e96449SHajimu UMEMOTO */ 9565e96449SHajimu UMEMOTO int 9665e96449SHajimu UMEMOTO res_nmkquery(res_state statp, 97dde4a85dSHajimu UMEMOTO int op, /*!< opcode of query */ 98dde4a85dSHajimu UMEMOTO const char *dname, /*!< domain name */ 99dde4a85dSHajimu UMEMOTO int class, int type, /*!< class and type of query */ 100dde4a85dSHajimu UMEMOTO const u_char *data, /*!< resource record data */ 101dde4a85dSHajimu UMEMOTO int datalen, /*!< length of data */ 102dde4a85dSHajimu UMEMOTO const u_char *newrr_in, /*!< new rr for modify or append */ 103dde4a85dSHajimu UMEMOTO u_char *buf, /*!< buffer to put query */ 104dde4a85dSHajimu UMEMOTO int buflen) /*!< size of buffer */ 10565e96449SHajimu UMEMOTO { 106ab96eeabSHajimu UMEMOTO HEADER *hp; 107ab96eeabSHajimu UMEMOTO u_char *cp, *ep; 108ab96eeabSHajimu UMEMOTO int n; 10965e96449SHajimu UMEMOTO u_char *dnptrs[20], **dpp, **lastdnptr; 11065e96449SHajimu UMEMOTO 11165e96449SHajimu UMEMOTO UNUSED(newrr_in); 11265e96449SHajimu UMEMOTO 11365e96449SHajimu UMEMOTO #ifdef DEBUG 11465e96449SHajimu UMEMOTO if (statp->options & RES_DEBUG) 11565e96449SHajimu UMEMOTO printf(";; res_nmkquery(%s, %s, %s, %s)\n", 11665e96449SHajimu UMEMOTO _res_opcodes[op], dname, p_class(class), p_type(type)); 11765e96449SHajimu UMEMOTO #endif 11865e96449SHajimu UMEMOTO /* 11965e96449SHajimu UMEMOTO * Initialize header fields. 12065e96449SHajimu UMEMOTO */ 12165e96449SHajimu UMEMOTO if ((buf == NULL) || (buflen < HFIXEDSZ)) 12265e96449SHajimu UMEMOTO return (-1); 12365e96449SHajimu UMEMOTO memset(buf, 0, HFIXEDSZ); 12465e96449SHajimu UMEMOTO hp = (HEADER *) buf; 125046c3635SPedro F. Giffuni statp->id = res_nrandomid(statp); 126046c3635SPedro F. Giffuni hp->id = htons(statp->id); 12765e96449SHajimu UMEMOTO hp->opcode = op; 12865e96449SHajimu UMEMOTO hp->rd = (statp->options & RES_RECURSE) != 0U; 12965e96449SHajimu UMEMOTO hp->rcode = NOERROR; 13065e96449SHajimu UMEMOTO cp = buf + HFIXEDSZ; 13165e96449SHajimu UMEMOTO ep = buf + buflen; 13265e96449SHajimu UMEMOTO dpp = dnptrs; 13365e96449SHajimu UMEMOTO *dpp++ = buf; 13465e96449SHajimu UMEMOTO *dpp++ = NULL; 135bf51882aSPedro F. Giffuni lastdnptr = dnptrs + nitems(dnptrs); 13665e96449SHajimu UMEMOTO /* 13765e96449SHajimu UMEMOTO * perform opcode specific processing 13865e96449SHajimu UMEMOTO */ 13965e96449SHajimu UMEMOTO switch (op) { 14065e96449SHajimu UMEMOTO case QUERY: /*FALLTHROUGH*/ 14165e96449SHajimu UMEMOTO case NS_NOTIFY_OP: 14265e96449SHajimu UMEMOTO if (ep - cp < QFIXEDSZ) 14365e96449SHajimu UMEMOTO return (-1); 14465e96449SHajimu UMEMOTO if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs, 14565e96449SHajimu UMEMOTO lastdnptr)) < 0) 14665e96449SHajimu UMEMOTO return (-1); 14765e96449SHajimu UMEMOTO cp += n; 14865e96449SHajimu UMEMOTO ns_put16(type, cp); 14965e96449SHajimu UMEMOTO cp += INT16SZ; 15065e96449SHajimu UMEMOTO ns_put16(class, cp); 15165e96449SHajimu UMEMOTO cp += INT16SZ; 15265e96449SHajimu UMEMOTO hp->qdcount = htons(1); 15365e96449SHajimu UMEMOTO if (op == QUERY || data == NULL) 15465e96449SHajimu UMEMOTO break; 15565e96449SHajimu UMEMOTO /* 15665e96449SHajimu UMEMOTO * Make an additional record for completion domain. 15765e96449SHajimu UMEMOTO */ 15865e96449SHajimu UMEMOTO if ((ep - cp) < RRFIXEDSZ) 15965e96449SHajimu UMEMOTO return (-1); 16065e96449SHajimu UMEMOTO n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ, 16165e96449SHajimu UMEMOTO dnptrs, lastdnptr); 16265e96449SHajimu UMEMOTO if (n < 0) 16365e96449SHajimu UMEMOTO return (-1); 16465e96449SHajimu UMEMOTO cp += n; 16565e96449SHajimu UMEMOTO ns_put16(T_NULL, cp); 16665e96449SHajimu UMEMOTO cp += INT16SZ; 16765e96449SHajimu UMEMOTO ns_put16(class, cp); 16865e96449SHajimu UMEMOTO cp += INT16SZ; 16965e96449SHajimu UMEMOTO ns_put32(0, cp); 17065e96449SHajimu UMEMOTO cp += INT32SZ; 17165e96449SHajimu UMEMOTO ns_put16(0, cp); 17265e96449SHajimu UMEMOTO cp += INT16SZ; 17365e96449SHajimu UMEMOTO hp->arcount = htons(1); 17465e96449SHajimu UMEMOTO break; 17565e96449SHajimu UMEMOTO 17665e96449SHajimu UMEMOTO case IQUERY: 17765e96449SHajimu UMEMOTO /* 17865e96449SHajimu UMEMOTO * Initialize answer section 17965e96449SHajimu UMEMOTO */ 18065e96449SHajimu UMEMOTO if (ep - cp < 1 + RRFIXEDSZ + datalen) 18165e96449SHajimu UMEMOTO return (-1); 182dde4a85dSHajimu UMEMOTO *cp++ = '\0'; /*%< no domain name */ 18365e96449SHajimu UMEMOTO ns_put16(type, cp); 18465e96449SHajimu UMEMOTO cp += INT16SZ; 18565e96449SHajimu UMEMOTO ns_put16(class, cp); 18665e96449SHajimu UMEMOTO cp += INT16SZ; 18765e96449SHajimu UMEMOTO ns_put32(0, cp); 18865e96449SHajimu UMEMOTO cp += INT32SZ; 18965e96449SHajimu UMEMOTO ns_put16(datalen, cp); 19065e96449SHajimu UMEMOTO cp += INT16SZ; 19165e96449SHajimu UMEMOTO if (datalen) { 19265e96449SHajimu UMEMOTO memcpy(cp, data, datalen); 19365e96449SHajimu UMEMOTO cp += datalen; 19465e96449SHajimu UMEMOTO } 19565e96449SHajimu UMEMOTO hp->ancount = htons(1); 19665e96449SHajimu UMEMOTO break; 19765e96449SHajimu UMEMOTO 19865e96449SHajimu UMEMOTO default: 19965e96449SHajimu UMEMOTO return (-1); 20065e96449SHajimu UMEMOTO } 20165e96449SHajimu UMEMOTO return (cp - buf); 20265e96449SHajimu UMEMOTO } 20365e96449SHajimu UMEMOTO 20465e96449SHajimu UMEMOTO #ifdef RES_USE_EDNS0 20565e96449SHajimu UMEMOTO /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */ 20665e96449SHajimu UMEMOTO 20765e96449SHajimu UMEMOTO int 20865e96449SHajimu UMEMOTO res_nopt(res_state statp, 209dde4a85dSHajimu UMEMOTO int n0, /*%< current offset in buffer */ 210dde4a85dSHajimu UMEMOTO u_char *buf, /*%< buffer to put query */ 211dde4a85dSHajimu UMEMOTO int buflen, /*%< size of buffer */ 212dde4a85dSHajimu UMEMOTO int anslen) /*%< UDP answer buffer size */ 21365e96449SHajimu UMEMOTO { 214ab96eeabSHajimu UMEMOTO HEADER *hp; 215ab96eeabSHajimu UMEMOTO u_char *cp, *ep; 21665e96449SHajimu UMEMOTO u_int16_t flags = 0; 21765e96449SHajimu UMEMOTO 21865e96449SHajimu UMEMOTO #ifdef DEBUG 21965e96449SHajimu UMEMOTO if ((statp->options & RES_DEBUG) != 0U) 22065e96449SHajimu UMEMOTO printf(";; res_nopt()\n"); 22165e96449SHajimu UMEMOTO #endif 22265e96449SHajimu UMEMOTO 22365e96449SHajimu UMEMOTO hp = (HEADER *) buf; 22465e96449SHajimu UMEMOTO cp = buf + n0; 22565e96449SHajimu UMEMOTO ep = buf + buflen; 22665e96449SHajimu UMEMOTO 22765e96449SHajimu UMEMOTO if ((ep - cp) < 1 + RRFIXEDSZ) 22865e96449SHajimu UMEMOTO return (-1); 22965e96449SHajimu UMEMOTO 230dde4a85dSHajimu UMEMOTO *cp++ = 0; /*%< "." */ 23154ebdd63SHajimu UMEMOTO ns_put16(ns_t_opt, cp); /*%< TYPE */ 23265e96449SHajimu UMEMOTO cp += INT16SZ; 233ab96eeabSHajimu UMEMOTO if (anslen > 0xffff) 234ab96eeabSHajimu UMEMOTO anslen = 0xffff; /* limit to 16bit value */ 235dde4a85dSHajimu UMEMOTO ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */ 23665e96449SHajimu UMEMOTO cp += INT16SZ; 237dde4a85dSHajimu UMEMOTO *cp++ = NOERROR; /*%< extended RCODE */ 238dde4a85dSHajimu UMEMOTO *cp++ = 0; /*%< EDNS version */ 23954ebdd63SHajimu UMEMOTO 24065e96449SHajimu UMEMOTO if (statp->options & RES_USE_DNSSEC) { 24165e96449SHajimu UMEMOTO #ifdef DEBUG 24265e96449SHajimu UMEMOTO if (statp->options & RES_DEBUG) 24365e96449SHajimu UMEMOTO printf(";; res_opt()... ENDS0 DNSSEC\n"); 24465e96449SHajimu UMEMOTO #endif 24565e96449SHajimu UMEMOTO flags |= NS_OPT_DNSSEC_OK; 24665e96449SHajimu UMEMOTO } 24765e96449SHajimu UMEMOTO ns_put16(flags, cp); 24865e96449SHajimu UMEMOTO cp += INT16SZ; 24954ebdd63SHajimu UMEMOTO 25054ebdd63SHajimu UMEMOTO ns_put16(0U, cp); /*%< RDLEN */ 25165e96449SHajimu UMEMOTO cp += INT16SZ; 25254ebdd63SHajimu UMEMOTO 25365e96449SHajimu UMEMOTO hp->arcount = htons(ntohs(hp->arcount) + 1); 25465e96449SHajimu UMEMOTO 25565e96449SHajimu UMEMOTO return (cp - buf); 25665e96449SHajimu UMEMOTO } 25754ebdd63SHajimu UMEMOTO 25854ebdd63SHajimu UMEMOTO /* 25954ebdd63SHajimu UMEMOTO * Construct variable data (RDATA) block for OPT psuedo-RR, append it 26054ebdd63SHajimu UMEMOTO * to the buffer, then update the RDLEN field (previously set to zero by 26154ebdd63SHajimu UMEMOTO * res_nopt()) with the new RDATA length. 26254ebdd63SHajimu UMEMOTO */ 26354ebdd63SHajimu UMEMOTO int 26454ebdd63SHajimu UMEMOTO res_nopt_rdata(res_state statp, 26554ebdd63SHajimu UMEMOTO int n0, /*%< current offset in buffer */ 26654ebdd63SHajimu UMEMOTO u_char *buf, /*%< buffer to put query */ 26754ebdd63SHajimu UMEMOTO int buflen, /*%< size of buffer */ 26854ebdd63SHajimu UMEMOTO u_char *rdata, /*%< ptr to start of opt rdata */ 26954ebdd63SHajimu UMEMOTO u_short code, /*%< OPTION-CODE */ 27054ebdd63SHajimu UMEMOTO u_short len, /*%< OPTION-LENGTH */ 27154ebdd63SHajimu UMEMOTO u_char *data) /*%< OPTION_DATA */ 27254ebdd63SHajimu UMEMOTO { 27354ebdd63SHajimu UMEMOTO register u_char *cp, *ep; 27454ebdd63SHajimu UMEMOTO 27554ebdd63SHajimu UMEMOTO #ifdef DEBUG 27654ebdd63SHajimu UMEMOTO if ((statp->options & RES_DEBUG) != 0U) 27754ebdd63SHajimu UMEMOTO printf(";; res_nopt_rdata()\n"); 27854ebdd63SHajimu UMEMOTO #endif 27954ebdd63SHajimu UMEMOTO 28054ebdd63SHajimu UMEMOTO cp = buf + n0; 28154ebdd63SHajimu UMEMOTO ep = buf + buflen; 28254ebdd63SHajimu UMEMOTO 28354ebdd63SHajimu UMEMOTO if ((ep - cp) < (4 + len)) 28454ebdd63SHajimu UMEMOTO return (-1); 28554ebdd63SHajimu UMEMOTO 28654ebdd63SHajimu UMEMOTO if (rdata < (buf + 2) || rdata >= ep) 28754ebdd63SHajimu UMEMOTO return (-1); 28854ebdd63SHajimu UMEMOTO 28954ebdd63SHajimu UMEMOTO ns_put16(code, cp); 29054ebdd63SHajimu UMEMOTO cp += INT16SZ; 29154ebdd63SHajimu UMEMOTO 29254ebdd63SHajimu UMEMOTO ns_put16(len, cp); 29354ebdd63SHajimu UMEMOTO cp += INT16SZ; 29454ebdd63SHajimu UMEMOTO 29554ebdd63SHajimu UMEMOTO memcpy(cp, data, len); 29654ebdd63SHajimu UMEMOTO cp += len; 29754ebdd63SHajimu UMEMOTO 29854ebdd63SHajimu UMEMOTO len = cp - rdata; 29954ebdd63SHajimu UMEMOTO ns_put16(len, rdata - 2); /* Update RDLEN field */ 30054ebdd63SHajimu UMEMOTO 30154ebdd63SHajimu UMEMOTO return (cp - buf); 30254ebdd63SHajimu UMEMOTO } 30365e96449SHajimu UMEMOTO #endif 304dde4a85dSHajimu UMEMOTO 305dde4a85dSHajimu UMEMOTO /*! \file */ 306