11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$NetBSD: res_mkquery.c,v 1.6 2006/01/24 17:40:32 christos Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2008  Android Open Source Project (query id randomization)
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1985, 1993
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    The Regents of the University of California.  All rights reserved.
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    documentation and/or other materials provided with the distribution.
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. All advertising materials mentioning features or use of this software
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    must display the following acknowledgement:
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 	This product includes software developed by the University of
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 	California, Berkeley and its contributors.
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 4. Neither the name of the University nor the names of its contributors
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    may be used to endorse or promote products derived from this software
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    without specific prior written permission.
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1993 by Digital Equipment Corporation.
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies, and that
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the name of Digital Equipment Corporation not be used in advertising or
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * publicity pertaining to distribution of the document or software without
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * specific, written prior permission.
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SOFTWARE.
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies.
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h>
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(LIBC_SCCS) && !defined(lint)
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef notdef
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char sccsid[] = "@(#)res_mkquery.c	8.1 (Berkeley) 6/4/93";
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char rcsid[] = "Id: res_mkquery.c,v 1.1.2.2.4.2 2004/03/16 12:34:18 marka Exp";
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__RCSID("$NetBSD: res_mkquery.c,v 1.6 2006/01/24 17:40:32 christos Exp $");
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* LIBC_SCCS and not lint */
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h>
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h>
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netinet/in.h>
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "arpa_nameser.h"
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netdb.h>
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_private.h"
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <resolv.h>
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Options.  Leave them on. */
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DEBUG
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DEBUG
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef lint
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define UNUSED(a)	(void)&a
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define UNUSED(a)	a = a
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern const char *_res_opcodes[];
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Form all types of queries.
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Returns the size of the result or -1.
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nmkquery(res_state statp,
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     int op,			/* opcode of query */
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     const char *dname,		/* domain name */
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     int class, int type,	/* class and type of query */
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     const u_char *data,	/* resource record data */
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     int datalen,		/* length of data */
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     const u_char *newrr_in,	/* new rr for modify or append */
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     u_char *buf,		/* buffer to put query */
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     int buflen)		/* size of buffer */
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	register HEADER *hp;
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	register u_char *cp, *ep;
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	register int n;
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_char *dnptrs[20], **dpp, **lastdnptr;
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	UNUSED(newrr_in);
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (statp->options & RES_DEBUG)
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		printf(";; res_nmkquery(%s, %s, %s, %s)\n",
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		       _res_opcodes[op], dname, p_class(class), p_type(type));
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Initialize header fields.
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((buf == NULL) || (buflen < HFIXEDSZ))
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	memset(buf, 0, HFIXEDSZ);
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = (HEADER *)(void *)buf;
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->id = htons(res_randomid());
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->opcode = op;
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->rd = (statp->options & RES_RECURSE) != 0U;
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->rcode = NOERROR;
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp = buf + HFIXEDSZ;
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ep = buf + buflen;
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	dpp = dnptrs;
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*dpp++ = buf;
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*dpp++ = NULL;
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * perform opcode specific processing
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch (op) {
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case QUERY:	/*FALLTHROUGH*/
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case NS_NOTIFY_OP:
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ep - cp < QFIXEDSZ)
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs,
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    lastdnptr)) < 0)
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += n;
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(type, cp);
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(class, cp);
1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		hp->qdcount = htons(1);
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (op == QUERY || data == NULL)
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Make an additional record for completion domain.
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((ep - cp) < RRFIXEDSZ)
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ,
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    dnptrs, lastdnptr);
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (n < 0)
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += n;
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(T_NULL, cp);
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(class, cp);
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put32(0, cp);
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT32SZ;
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(0, cp);
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		hp->arcount = htons(1);
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case IQUERY:
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Initialize answer section
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ep - cp < 1 + RRFIXEDSZ + datalen)
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*cp++ = '\0';	/* no domain name */
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(type, cp);
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(class, cp);
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put32(0, cp);
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT32SZ;
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ns_put16(datalen, cp);
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cp += INT16SZ;
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (datalen) {
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			memcpy(cp, data, (size_t)datalen);
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			cp += datalen;
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		hp->ancount = htons(1);
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	default:
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (cp - buf);
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef RES_USE_EDNS0
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef T_OPT
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define T_OPT	41
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nopt(res_state statp,
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 int n0,		/* current offset in buffer */
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 u_char *buf,		/* buffer to put query */
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 int buflen,		/* size of buffer */
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 int anslen)		/* UDP answer buffer size */
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	register HEADER *hp;
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	register u_char *cp, *ep;
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_int16_t flags = 0;
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((statp->options & RES_DEBUG) != 0U)
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		printf(";; res_nopt()\n");
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp = (HEADER *)(void *)buf;
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp = buf + n0;
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ep = buf + buflen;
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((ep - cp) < 1 + RRFIXEDSZ)
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*cp++ = 0;	/* "." */
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ns_put16(T_OPT, cp);	/* TYPE */
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp += INT16SZ;
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ns_put16(anslen & 0xffff, cp);	/* CLASS = UDP payload size */
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp += INT16SZ;
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*cp++ = NOERROR;	/* extended RCODE */
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*cp++ = 0;		/* EDNS version */
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (statp->options & RES_USE_DNSSEC) {
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (statp->options & RES_DEBUG)
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			printf(";; res_opt()... ENDS0 DNSSEC\n");
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		flags |= NS_OPT_DNSSEC_OK;
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ns_put16(flags, cp);
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp += INT16SZ;
2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ns_put16(0, cp);	/* RDLEN */
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cp += INT16SZ;
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->arcount = htons(ntohs(hp->arcount) + 1);
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (cp - buf);
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
277