16e778a7eSPedro F. Giffuni /*-
26e778a7eSPedro F. Giffuni * SPDX-License-Identifier: (ISC AND BSD-3-Clause)
36e778a7eSPedro F. Giffuni *
4046c3635SPedro F. Giffuni * Portions Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
5046c3635SPedro F. Giffuni * Portions Copyright (C) 1996, 1997, 1988, 1999, 2001, 2003 Internet Software Consortium.
6046c3635SPedro F. Giffuni *
7046c3635SPedro F. Giffuni * Permission to use, copy, modify, and/or distribute this software for any
8046c3635SPedro F. Giffuni * purpose with or without fee is hereby granted, provided that the above
9046c3635SPedro F. Giffuni * copyright notice and this permission notice appear in all copies.
10046c3635SPedro F. Giffuni *
11046c3635SPedro F. Giffuni * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12046c3635SPedro F. Giffuni * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13046c3635SPedro F. Giffuni * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14046c3635SPedro F. Giffuni * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15046c3635SPedro F. Giffuni * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16046c3635SPedro F. Giffuni * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17046c3635SPedro F. Giffuni * PERFORMANCE OF THIS SOFTWARE.
18046c3635SPedro F. Giffuni */
19046c3635SPedro F. Giffuni
208a16b7a1SPedro F. Giffuni /*-
2165e96449SHajimu UMEMOTO * Copyright (c) 1985, 1993
2265e96449SHajimu UMEMOTO * The Regents of the University of California. All rights reserved.
2365e96449SHajimu UMEMOTO *
2465e96449SHajimu UMEMOTO * Redistribution and use in source and binary forms, with or without
2565e96449SHajimu UMEMOTO * modification, are permitted provided that the following conditions
2665e96449SHajimu UMEMOTO * are met:
2765e96449SHajimu UMEMOTO * 1. Redistributions of source code must retain the above copyright
2865e96449SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer.
2965e96449SHajimu UMEMOTO * 2. Redistributions in binary form must reproduce the above copyright
3065e96449SHajimu UMEMOTO * notice, this list of conditions and the following disclaimer in the
3165e96449SHajimu UMEMOTO * documentation and/or other materials provided with the distribution.
32fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors
3365e96449SHajimu UMEMOTO * may be used to endorse or promote products derived from this software
3465e96449SHajimu UMEMOTO * without specific prior written permission.
3565e96449SHajimu UMEMOTO *
3665e96449SHajimu UMEMOTO * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
3765e96449SHajimu UMEMOTO * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3865e96449SHajimu UMEMOTO * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3965e96449SHajimu UMEMOTO * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4065e96449SHajimu UMEMOTO * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4165e96449SHajimu UMEMOTO * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4265e96449SHajimu UMEMOTO * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4365e96449SHajimu UMEMOTO * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4465e96449SHajimu UMEMOTO * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4565e96449SHajimu UMEMOTO * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4665e96449SHajimu UMEMOTO * SUCH DAMAGE.
4765e96449SHajimu UMEMOTO */
4865e96449SHajimu UMEMOTO
4965e96449SHajimu UMEMOTO /*
5065e96449SHajimu UMEMOTO * Portions Copyright (c) 1993 by Digital Equipment Corporation.
5165e96449SHajimu UMEMOTO *
5265e96449SHajimu UMEMOTO * Permission to use, copy, modify, and distribute this software for any
5365e96449SHajimu UMEMOTO * purpose with or without fee is hereby granted, provided that the above
5465e96449SHajimu UMEMOTO * copyright notice and this permission notice appear in all copies, and that
5565e96449SHajimu UMEMOTO * the name of Digital Equipment Corporation not be used in advertising or
5665e96449SHajimu UMEMOTO * publicity pertaining to distribution of the document or software without
5765e96449SHajimu UMEMOTO * specific, written prior permission.
5865e96449SHajimu UMEMOTO *
5965e96449SHajimu UMEMOTO * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
6065e96449SHajimu UMEMOTO * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
6165e96449SHajimu UMEMOTO * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
6265e96449SHajimu UMEMOTO * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
6365e96449SHajimu UMEMOTO * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
6465e96449SHajimu UMEMOTO * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
6565e96449SHajimu UMEMOTO * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
6665e96449SHajimu UMEMOTO * SOFTWARE.
6765e96449SHajimu UMEMOTO */
6865e96449SHajimu UMEMOTO
6965e96449SHajimu UMEMOTO #include "port_before.h"
7065e96449SHajimu UMEMOTO #include <sys/param.h>
7165e96449SHajimu UMEMOTO #include <netinet/in.h>
7265e96449SHajimu UMEMOTO #include <arpa/nameser.h>
7365e96449SHajimu UMEMOTO #include <netdb.h>
7465e96449SHajimu UMEMOTO #include <resolv.h>
7565e96449SHajimu UMEMOTO #include <stdio.h>
7665e96449SHajimu UMEMOTO #include <string.h>
7765e96449SHajimu UMEMOTO #include "port_after.h"
7865e96449SHajimu UMEMOTO
7965e96449SHajimu UMEMOTO /* Options. Leave them on. */
808a615d0fSEnji Cooper #ifndef DEBUG
8165e96449SHajimu UMEMOTO #define DEBUG
828a615d0fSEnji Cooper #endif
8365e96449SHajimu UMEMOTO
8465e96449SHajimu UMEMOTO extern const char *_res_opcodes[];
8565e96449SHajimu UMEMOTO
86dde4a85dSHajimu UMEMOTO /*%
8765e96449SHajimu UMEMOTO * Form all types of queries.
8865e96449SHajimu UMEMOTO * Returns the size of the result or -1.
8965e96449SHajimu UMEMOTO */
9065e96449SHajimu UMEMOTO int
res_nmkquery(res_state statp,int op,const char * dname,int class,int type,const u_char * data,int datalen,const u_char * newrr_in,u_char * buf,int buflen)9165e96449SHajimu UMEMOTO res_nmkquery(res_state statp,
92dde4a85dSHajimu UMEMOTO int op, /*!< opcode of query */
93dde4a85dSHajimu UMEMOTO const char *dname, /*!< domain name */
94dde4a85dSHajimu UMEMOTO int class, int type, /*!< class and type of query */
95dde4a85dSHajimu UMEMOTO const u_char *data, /*!< resource record data */
96dde4a85dSHajimu UMEMOTO int datalen, /*!< length of data */
97dde4a85dSHajimu UMEMOTO const u_char *newrr_in, /*!< new rr for modify or append */
98dde4a85dSHajimu UMEMOTO u_char *buf, /*!< buffer to put query */
99dde4a85dSHajimu UMEMOTO int buflen) /*!< size of buffer */
10065e96449SHajimu UMEMOTO {
101ab96eeabSHajimu UMEMOTO HEADER *hp;
102ab96eeabSHajimu UMEMOTO u_char *cp, *ep;
103ab96eeabSHajimu UMEMOTO int n;
10465e96449SHajimu UMEMOTO u_char *dnptrs[20], **dpp, **lastdnptr;
10565e96449SHajimu UMEMOTO
10665e96449SHajimu UMEMOTO UNUSED(newrr_in);
10765e96449SHajimu UMEMOTO
10865e96449SHajimu UMEMOTO #ifdef DEBUG
10965e96449SHajimu UMEMOTO if (statp->options & RES_DEBUG)
11065e96449SHajimu UMEMOTO printf(";; res_nmkquery(%s, %s, %s, %s)\n",
11165e96449SHajimu UMEMOTO _res_opcodes[op], dname, p_class(class), p_type(type));
11265e96449SHajimu UMEMOTO #endif
11365e96449SHajimu UMEMOTO /*
11465e96449SHajimu UMEMOTO * Initialize header fields.
11565e96449SHajimu UMEMOTO */
11665e96449SHajimu UMEMOTO if ((buf == NULL) || (buflen < HFIXEDSZ))
11765e96449SHajimu UMEMOTO return (-1);
11865e96449SHajimu UMEMOTO memset(buf, 0, HFIXEDSZ);
11965e96449SHajimu UMEMOTO hp = (HEADER *) buf;
120046c3635SPedro F. Giffuni statp->id = res_nrandomid(statp);
121046c3635SPedro F. Giffuni hp->id = htons(statp->id);
12265e96449SHajimu UMEMOTO hp->opcode = op;
12365e96449SHajimu UMEMOTO hp->rd = (statp->options & RES_RECURSE) != 0U;
12465e96449SHajimu UMEMOTO hp->rcode = NOERROR;
12565e96449SHajimu UMEMOTO cp = buf + HFIXEDSZ;
12665e96449SHajimu UMEMOTO ep = buf + buflen;
12765e96449SHajimu UMEMOTO dpp = dnptrs;
12865e96449SHajimu UMEMOTO *dpp++ = buf;
12965e96449SHajimu UMEMOTO *dpp++ = NULL;
130bf51882aSPedro F. Giffuni lastdnptr = dnptrs + nitems(dnptrs);
13165e96449SHajimu UMEMOTO /*
13265e96449SHajimu UMEMOTO * perform opcode specific processing
13365e96449SHajimu UMEMOTO */
13465e96449SHajimu UMEMOTO switch (op) {
13565e96449SHajimu UMEMOTO case QUERY: /*FALLTHROUGH*/
13665e96449SHajimu UMEMOTO case NS_NOTIFY_OP:
13765e96449SHajimu UMEMOTO if (ep - cp < QFIXEDSZ)
13865e96449SHajimu UMEMOTO return (-1);
13965e96449SHajimu UMEMOTO if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
14065e96449SHajimu UMEMOTO lastdnptr)) < 0)
14165e96449SHajimu UMEMOTO return (-1);
14265e96449SHajimu UMEMOTO cp += n;
14365e96449SHajimu UMEMOTO ns_put16(type, cp);
14465e96449SHajimu UMEMOTO cp += INT16SZ;
14565e96449SHajimu UMEMOTO ns_put16(class, cp);
14665e96449SHajimu UMEMOTO cp += INT16SZ;
14765e96449SHajimu UMEMOTO hp->qdcount = htons(1);
14865e96449SHajimu UMEMOTO if (op == QUERY || data == NULL)
14965e96449SHajimu UMEMOTO break;
15065e96449SHajimu UMEMOTO /*
15165e96449SHajimu UMEMOTO * Make an additional record for completion domain.
15265e96449SHajimu UMEMOTO */
15365e96449SHajimu UMEMOTO if ((ep - cp) < RRFIXEDSZ)
15465e96449SHajimu UMEMOTO return (-1);
15565e96449SHajimu UMEMOTO n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ,
15665e96449SHajimu UMEMOTO dnptrs, lastdnptr);
15765e96449SHajimu UMEMOTO if (n < 0)
15865e96449SHajimu UMEMOTO return (-1);
15965e96449SHajimu UMEMOTO cp += n;
16065e96449SHajimu UMEMOTO ns_put16(T_NULL, cp);
16165e96449SHajimu UMEMOTO cp += INT16SZ;
16265e96449SHajimu UMEMOTO ns_put16(class, cp);
16365e96449SHajimu UMEMOTO cp += INT16SZ;
16465e96449SHajimu UMEMOTO ns_put32(0, cp);
16565e96449SHajimu UMEMOTO cp += INT32SZ;
16665e96449SHajimu UMEMOTO ns_put16(0, cp);
16765e96449SHajimu UMEMOTO cp += INT16SZ;
16865e96449SHajimu UMEMOTO hp->arcount = htons(1);
16965e96449SHajimu UMEMOTO break;
17065e96449SHajimu UMEMOTO
17165e96449SHajimu UMEMOTO case IQUERY:
17265e96449SHajimu UMEMOTO /*
17365e96449SHajimu UMEMOTO * Initialize answer section
17465e96449SHajimu UMEMOTO */
17565e96449SHajimu UMEMOTO if (ep - cp < 1 + RRFIXEDSZ + datalen)
17665e96449SHajimu UMEMOTO return (-1);
177dde4a85dSHajimu UMEMOTO *cp++ = '\0'; /*%< no domain name */
17865e96449SHajimu UMEMOTO ns_put16(type, cp);
17965e96449SHajimu UMEMOTO cp += INT16SZ;
18065e96449SHajimu UMEMOTO ns_put16(class, cp);
18165e96449SHajimu UMEMOTO cp += INT16SZ;
18265e96449SHajimu UMEMOTO ns_put32(0, cp);
18365e96449SHajimu UMEMOTO cp += INT32SZ;
18465e96449SHajimu UMEMOTO ns_put16(datalen, cp);
18565e96449SHajimu UMEMOTO cp += INT16SZ;
18665e96449SHajimu UMEMOTO if (datalen) {
18765e96449SHajimu UMEMOTO memcpy(cp, data, datalen);
18865e96449SHajimu UMEMOTO cp += datalen;
18965e96449SHajimu UMEMOTO }
19065e96449SHajimu UMEMOTO hp->ancount = htons(1);
19165e96449SHajimu UMEMOTO break;
19265e96449SHajimu UMEMOTO
19365e96449SHajimu UMEMOTO default:
19465e96449SHajimu UMEMOTO return (-1);
19565e96449SHajimu UMEMOTO }
19665e96449SHajimu UMEMOTO return (cp - buf);
19765e96449SHajimu UMEMOTO }
19865e96449SHajimu UMEMOTO
19965e96449SHajimu UMEMOTO #ifdef RES_USE_EDNS0
20065e96449SHajimu UMEMOTO /* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
20165e96449SHajimu UMEMOTO
20265e96449SHajimu UMEMOTO int
res_nopt(res_state statp,int n0,u_char * buf,int buflen,int anslen)20365e96449SHajimu UMEMOTO res_nopt(res_state statp,
204dde4a85dSHajimu UMEMOTO int n0, /*%< current offset in buffer */
205dde4a85dSHajimu UMEMOTO u_char *buf, /*%< buffer to put query */
206dde4a85dSHajimu UMEMOTO int buflen, /*%< size of buffer */
207dde4a85dSHajimu UMEMOTO int anslen) /*%< UDP answer buffer size */
20865e96449SHajimu UMEMOTO {
209ab96eeabSHajimu UMEMOTO HEADER *hp;
210ab96eeabSHajimu UMEMOTO u_char *cp, *ep;
21165e96449SHajimu UMEMOTO u_int16_t flags = 0;
21265e96449SHajimu UMEMOTO
21365e96449SHajimu UMEMOTO #ifdef DEBUG
21465e96449SHajimu UMEMOTO if ((statp->options & RES_DEBUG) != 0U)
21565e96449SHajimu UMEMOTO printf(";; res_nopt()\n");
21665e96449SHajimu UMEMOTO #endif
21765e96449SHajimu UMEMOTO
21865e96449SHajimu UMEMOTO hp = (HEADER *) buf;
21965e96449SHajimu UMEMOTO cp = buf + n0;
22065e96449SHajimu UMEMOTO ep = buf + buflen;
22165e96449SHajimu UMEMOTO
22265e96449SHajimu UMEMOTO if ((ep - cp) < 1 + RRFIXEDSZ)
22365e96449SHajimu UMEMOTO return (-1);
22465e96449SHajimu UMEMOTO
225dde4a85dSHajimu UMEMOTO *cp++ = 0; /*%< "." */
22654ebdd63SHajimu UMEMOTO ns_put16(ns_t_opt, cp); /*%< TYPE */
22765e96449SHajimu UMEMOTO cp += INT16SZ;
228ab96eeabSHajimu UMEMOTO if (anslen > 0xffff)
229ab96eeabSHajimu UMEMOTO anslen = 0xffff; /* limit to 16bit value */
230dde4a85dSHajimu UMEMOTO ns_put16(anslen & 0xffff, cp); /*%< CLASS = UDP payload size */
23165e96449SHajimu UMEMOTO cp += INT16SZ;
232dde4a85dSHajimu UMEMOTO *cp++ = NOERROR; /*%< extended RCODE */
233dde4a85dSHajimu UMEMOTO *cp++ = 0; /*%< EDNS version */
23454ebdd63SHajimu UMEMOTO
23565e96449SHajimu UMEMOTO if (statp->options & RES_USE_DNSSEC) {
23665e96449SHajimu UMEMOTO #ifdef DEBUG
23765e96449SHajimu UMEMOTO if (statp->options & RES_DEBUG)
23865e96449SHajimu UMEMOTO printf(";; res_opt()... ENDS0 DNSSEC\n");
23965e96449SHajimu UMEMOTO #endif
24065e96449SHajimu UMEMOTO flags |= NS_OPT_DNSSEC_OK;
24165e96449SHajimu UMEMOTO }
24265e96449SHajimu UMEMOTO ns_put16(flags, cp);
24365e96449SHajimu UMEMOTO cp += INT16SZ;
24454ebdd63SHajimu UMEMOTO
24554ebdd63SHajimu UMEMOTO ns_put16(0U, cp); /*%< RDLEN */
24665e96449SHajimu UMEMOTO cp += INT16SZ;
24754ebdd63SHajimu UMEMOTO
24865e96449SHajimu UMEMOTO hp->arcount = htons(ntohs(hp->arcount) + 1);
24965e96449SHajimu UMEMOTO
25065e96449SHajimu UMEMOTO return (cp - buf);
25165e96449SHajimu UMEMOTO }
25254ebdd63SHajimu UMEMOTO
25354ebdd63SHajimu UMEMOTO /*
254*b4ce0ff1SGordon Bergling * Construct variable data (RDATA) block for OPT pseudo-RR, append it
25554ebdd63SHajimu UMEMOTO * to the buffer, then update the RDLEN field (previously set to zero by
25654ebdd63SHajimu UMEMOTO * res_nopt()) with the new RDATA length.
25754ebdd63SHajimu UMEMOTO */
25854ebdd63SHajimu UMEMOTO int
res_nopt_rdata(res_state statp,int n0,u_char * buf,int buflen,u_char * rdata,u_short code,u_short len,u_char * data)25954ebdd63SHajimu UMEMOTO res_nopt_rdata(res_state statp,
26054ebdd63SHajimu UMEMOTO int n0, /*%< current offset in buffer */
26154ebdd63SHajimu UMEMOTO u_char *buf, /*%< buffer to put query */
26254ebdd63SHajimu UMEMOTO int buflen, /*%< size of buffer */
26354ebdd63SHajimu UMEMOTO u_char *rdata, /*%< ptr to start of opt rdata */
26454ebdd63SHajimu UMEMOTO u_short code, /*%< OPTION-CODE */
26554ebdd63SHajimu UMEMOTO u_short len, /*%< OPTION-LENGTH */
26654ebdd63SHajimu UMEMOTO u_char *data) /*%< OPTION_DATA */
26754ebdd63SHajimu UMEMOTO {
26854ebdd63SHajimu UMEMOTO register u_char *cp, *ep;
26954ebdd63SHajimu UMEMOTO
27054ebdd63SHajimu UMEMOTO #ifdef DEBUG
27154ebdd63SHajimu UMEMOTO if ((statp->options & RES_DEBUG) != 0U)
27254ebdd63SHajimu UMEMOTO printf(";; res_nopt_rdata()\n");
27354ebdd63SHajimu UMEMOTO #endif
27454ebdd63SHajimu UMEMOTO
27554ebdd63SHajimu UMEMOTO cp = buf + n0;
27654ebdd63SHajimu UMEMOTO ep = buf + buflen;
27754ebdd63SHajimu UMEMOTO
27854ebdd63SHajimu UMEMOTO if ((ep - cp) < (4 + len))
27954ebdd63SHajimu UMEMOTO return (-1);
28054ebdd63SHajimu UMEMOTO
28154ebdd63SHajimu UMEMOTO if (rdata < (buf + 2) || rdata >= ep)
28254ebdd63SHajimu UMEMOTO return (-1);
28354ebdd63SHajimu UMEMOTO
28454ebdd63SHajimu UMEMOTO ns_put16(code, cp);
28554ebdd63SHajimu UMEMOTO cp += INT16SZ;
28654ebdd63SHajimu UMEMOTO
28754ebdd63SHajimu UMEMOTO ns_put16(len, cp);
28854ebdd63SHajimu UMEMOTO cp += INT16SZ;
28954ebdd63SHajimu UMEMOTO
29054ebdd63SHajimu UMEMOTO memcpy(cp, data, len);
29154ebdd63SHajimu UMEMOTO cp += len;
29254ebdd63SHajimu UMEMOTO
29354ebdd63SHajimu UMEMOTO len = cp - rdata;
29454ebdd63SHajimu UMEMOTO ns_put16(len, rdata - 2); /* Update RDLEN field */
29554ebdd63SHajimu UMEMOTO
29654ebdd63SHajimu UMEMOTO return (cp - buf);
29754ebdd63SHajimu UMEMOTO }
29865e96449SHajimu UMEMOTO #endif
299dde4a85dSHajimu UMEMOTO
300dde4a85dSHajimu UMEMOTO /*! \file */
301