xref: /titanic_51/usr/src/lib/libresolv2/common/resolv/res_data.c (revision 4e567b4443d7a1680a7319275e5288eef2c92319)
17c478bd9Sstevel@tonic-gate /*
2*4e567b44SStacey Marshall  * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
37c478bd9Sstevel@tonic-gate  */
47c478bd9Sstevel@tonic-gate 
59525b14bSRao Shoaib 
67c478bd9Sstevel@tonic-gate /*
79525b14bSRao Shoaib  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
87c478bd9Sstevel@tonic-gate  * Copyright (c) 1995-1999 by Internet Software Consortium.
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, and distribute this software for any
117c478bd9Sstevel@tonic-gate  * purpose with or without fee is hereby granted, provided that the above
127c478bd9Sstevel@tonic-gate  * copyright notice and this permission notice appear in all copies.
137c478bd9Sstevel@tonic-gate  *
149525b14bSRao Shoaib  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
159525b14bSRao Shoaib  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
169525b14bSRao Shoaib  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
179525b14bSRao Shoaib  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
189525b14bSRao Shoaib  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
199525b14bSRao Shoaib  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
209525b14bSRao Shoaib  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate #if defined(LIBC_SCCS) && !defined(lint)
249525b14bSRao Shoaib static const char rcsid[] = "$Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp $";
257c478bd9Sstevel@tonic-gate #endif /* LIBC_SCCS and not lint */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include "port_before.h"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <sys/param.h>
317c478bd9Sstevel@tonic-gate #include <sys/socket.h>
327c478bd9Sstevel@tonic-gate #include <sys/time.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include <netinet/in.h>
357c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
367c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <ctype.h>
397c478bd9Sstevel@tonic-gate #include <netdb.h>
407c478bd9Sstevel@tonic-gate #include <resolv.h>
417c478bd9Sstevel@tonic-gate #include <res_update.h>
427c478bd9Sstevel@tonic-gate #include <stdio.h>
437c478bd9Sstevel@tonic-gate #include <stdlib.h>
447c478bd9Sstevel@tonic-gate #include <string.h>
457c478bd9Sstevel@tonic-gate #include <unistd.h>
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #include "port_after.h"
487c478bd9Sstevel@tonic-gate 
499525b14bSRao Shoaib #ifndef	ORIGINAL_ISC_CODE
507c478bd9Sstevel@tonic-gate #pragma weak	__fp_nquery	=	fp_nquery
517c478bd9Sstevel@tonic-gate #pragma weak	__fp_query	=	fp_query
527c478bd9Sstevel@tonic-gate #pragma weak	__p_query	=	p_query
537c478bd9Sstevel@tonic-gate #pragma weak	__hostalias	=	hostalias
549525b14bSRao Shoaib #pragma weak	__res_randomid	=	res_randomid
557c478bd9Sstevel@tonic-gate #endif
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate const char *_res_opcodes[] = {
587c478bd9Sstevel@tonic-gate 	"QUERY",
597c478bd9Sstevel@tonic-gate 	"IQUERY",
607c478bd9Sstevel@tonic-gate 	"CQUERYM",
619525b14bSRao Shoaib 	"CQUERYU",	/*%< experimental */
629525b14bSRao Shoaib 	"NOTIFY",	/*%< experimental */
637c478bd9Sstevel@tonic-gate 	"UPDATE",
647c478bd9Sstevel@tonic-gate 	"6",
657c478bd9Sstevel@tonic-gate 	"7",
667c478bd9Sstevel@tonic-gate 	"8",
677c478bd9Sstevel@tonic-gate 	"9",
687c478bd9Sstevel@tonic-gate 	"10",
697c478bd9Sstevel@tonic-gate 	"11",
707c478bd9Sstevel@tonic-gate 	"12",
717c478bd9Sstevel@tonic-gate 	"13",
727c478bd9Sstevel@tonic-gate 	"ZONEINIT",
737c478bd9Sstevel@tonic-gate 	"ZONEREF",
747c478bd9Sstevel@tonic-gate };
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate #ifdef BIND_UPDATE
777c478bd9Sstevel@tonic-gate const char *_res_sectioncodes[] = {
787c478bd9Sstevel@tonic-gate 	"ZONE",
797c478bd9Sstevel@tonic-gate 	"PREREQUISITES",
807c478bd9Sstevel@tonic-gate 	"UPDATE",
817c478bd9Sstevel@tonic-gate 	"ADDITIONAL",
827c478bd9Sstevel@tonic-gate };
837c478bd9Sstevel@tonic-gate #endif
847c478bd9Sstevel@tonic-gate 
859525b14bSRao Shoaib #undef _res
867c478bd9Sstevel@tonic-gate #ifndef __BIND_NOSTATIC
877c478bd9Sstevel@tonic-gate struct __res_state _res
887c478bd9Sstevel@tonic-gate # if defined(__BIND_RES_TEXT)
899525b14bSRao Shoaib 	= { RES_TIMEOUT, }	/*%< Motorola, et al. */
907c478bd9Sstevel@tonic-gate # endif
917c478bd9Sstevel@tonic-gate         ;
927c478bd9Sstevel@tonic-gate 
93*4e567b44SStacey Marshall #ifdef	ORIGINAL_ISC_CODE
949525b14bSRao Shoaib #if defined(DO_PTHREADS) || defined(__linux)
959525b14bSRao Shoaib #define _res (*__res_state())
969525b14bSRao Shoaib #endif
97*4e567b44SStacey Marshall #endif
989525b14bSRao Shoaib 
997c478bd9Sstevel@tonic-gate /* Proto. */
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate int  res_ourserver_p(const res_state, const struct sockaddr_in *);
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate int
1047c478bd9Sstevel@tonic-gate res_init(void) {
1057c478bd9Sstevel@tonic-gate 	extern int __res_vinit(res_state, int);
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	/*
1087c478bd9Sstevel@tonic-gate 	 * These three fields used to be statically initialized.  This made
1097c478bd9Sstevel@tonic-gate 	 * it hard to use this code in a shared library.  It is necessary,
1107c478bd9Sstevel@tonic-gate 	 * now that we're doing dynamic initialization here, that we preserve
1117c478bd9Sstevel@tonic-gate 	 * the old semantics: if an application modifies one of these three
1127c478bd9Sstevel@tonic-gate 	 * fields of _res before res_init() is called, res_init() will not
1137c478bd9Sstevel@tonic-gate 	 * alter them.  Of course, if an application is setting them to
1147c478bd9Sstevel@tonic-gate 	 * _zero_ before calling res_init(), hoping to override what used
1157c478bd9Sstevel@tonic-gate 	 * to be the static default, we can't detect it and unexpected results
1167c478bd9Sstevel@tonic-gate 	 * will follow.  Zero for any of these fields would make no sense,
1177c478bd9Sstevel@tonic-gate 	 * so one can safely assume that the applications were already getting
1187c478bd9Sstevel@tonic-gate 	 * unexpected results.
1197c478bd9Sstevel@tonic-gate 	 *
1207c478bd9Sstevel@tonic-gate 	 * _res.options is tricky since some apps were known to diddle the bits
1217c478bd9Sstevel@tonic-gate 	 * before res_init() was first called. We can't replicate that semantic
1227c478bd9Sstevel@tonic-gate 	 * with dynamic initialization (they may have turned bits off that are
1237c478bd9Sstevel@tonic-gate 	 * set in RES_DEFAULT).  Our solution is to declare such applications
1247c478bd9Sstevel@tonic-gate 	 * "broken".  They could fool us by setting RES_INIT but none do (yet).
1257c478bd9Sstevel@tonic-gate 	 */
1267c478bd9Sstevel@tonic-gate 	if (!_res.retrans)
1277c478bd9Sstevel@tonic-gate 		_res.retrans = RES_TIMEOUT;
1287c478bd9Sstevel@tonic-gate 	if (!_res.retry)
1297c478bd9Sstevel@tonic-gate 		_res.retry = 4;
1307c478bd9Sstevel@tonic-gate 	if (!(_res.options & RES_INIT))
1317c478bd9Sstevel@tonic-gate 		_res.options = RES_DEFAULT;
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	/*
1347c478bd9Sstevel@tonic-gate 	 * This one used to initialize implicitly to zero, so unless the app
1357c478bd9Sstevel@tonic-gate 	 * has set it to something in particular, we can randomize it now.
1367c478bd9Sstevel@tonic-gate 	 */
1377c478bd9Sstevel@tonic-gate 	if (!_res.id)
1389525b14bSRao Shoaib 		_res.id = res_nrandomid(&_res);
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 	return (__res_vinit(&_res, 1));
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate void
1447c478bd9Sstevel@tonic-gate p_query(const u_char *msg) {
1457c478bd9Sstevel@tonic-gate 	fp_query(msg, stdout);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate void
1497c478bd9Sstevel@tonic-gate fp_query(const u_char *msg, FILE *file) {
1507c478bd9Sstevel@tonic-gate 	fp_nquery(msg, PACKETSZ, file);
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate void
1547c478bd9Sstevel@tonic-gate fp_nquery(const u_char *msg, int len, FILE *file) {
1559525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1)
1567c478bd9Sstevel@tonic-gate 		return;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	res_pquery(&_res, msg, len, file);
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate int
1629525b14bSRao Shoaib res_mkquery(int op,			/*!< opcode of query  */
1639525b14bSRao Shoaib 	    const char *dname,		/*!< domain name  */
1649525b14bSRao Shoaib 	    int class, int type,	/*!< class and type of query  */
1659525b14bSRao Shoaib 	    const u_char *data,		/*!< resource record data  */
1669525b14bSRao Shoaib 	    int datalen,		/*!< length of data  */
1679525b14bSRao Shoaib 	    const u_char *newrr_in,	/*!< new rr for modify or append  */
1689525b14bSRao Shoaib 	    u_char *buf,		/*!< buffer to put query  */
1699525b14bSRao Shoaib 	    int buflen)			/*!< size of buffer  */
1707c478bd9Sstevel@tonic-gate {
1719525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1727c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1737c478bd9Sstevel@tonic-gate 		return (-1);
1747c478bd9Sstevel@tonic-gate 	}
1757c478bd9Sstevel@tonic-gate 	return (res_nmkquery(&_res, op, dname, class, type,
1767c478bd9Sstevel@tonic-gate 			     data, datalen,
1777c478bd9Sstevel@tonic-gate 			     newrr_in, buf, buflen));
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate int
1817c478bd9Sstevel@tonic-gate res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
1829525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1837c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1847c478bd9Sstevel@tonic-gate 		return (-1);
1857c478bd9Sstevel@tonic-gate 	}
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate int
1919525b14bSRao Shoaib res_query(const char *name,	/*!< domain name  */
1929525b14bSRao Shoaib 	  int class, int type,	/*!< class and type of query  */
1939525b14bSRao Shoaib 	  u_char *answer,	/*!< buffer to put answer  */
1949525b14bSRao Shoaib 	  int anslen)		/*!< size of answer buffer  */
1957c478bd9Sstevel@tonic-gate {
1969525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
1977c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
1987c478bd9Sstevel@tonic-gate 		return (-1);
1997c478bd9Sstevel@tonic-gate 	}
2007c478bd9Sstevel@tonic-gate 	return (res_nquery(&_res, name, class, type, answer, anslen));
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate void
2047c478bd9Sstevel@tonic-gate res_send_setqhook(res_send_qhook hook) {
2057c478bd9Sstevel@tonic-gate 	_res.qhook = hook;
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate void
2097c478bd9Sstevel@tonic-gate res_send_setrhook(res_send_rhook hook) {
2107c478bd9Sstevel@tonic-gate 	_res.rhook = hook;
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate int
2147c478bd9Sstevel@tonic-gate res_isourserver(const struct sockaddr_in *inp) {
2157c478bd9Sstevel@tonic-gate 	return (res_ourserver_p(&_res, inp));
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate int
2197c478bd9Sstevel@tonic-gate res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
2209525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2217c478bd9Sstevel@tonic-gate 		/* errno should have been set by res_init() in this case. */
2227c478bd9Sstevel@tonic-gate 		return (-1);
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	return (res_nsend(&_res, buf, buflen, ans, anssiz));
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate int
2297c478bd9Sstevel@tonic-gate res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
2307c478bd9Sstevel@tonic-gate 	       u_char *ans, int anssiz)
2317c478bd9Sstevel@tonic-gate {
2329525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2337c478bd9Sstevel@tonic-gate 		/* errno should have been set by res_init() in this case. */
2347c478bd9Sstevel@tonic-gate 		return (-1);
2357c478bd9Sstevel@tonic-gate 	}
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate void
2417c478bd9Sstevel@tonic-gate res_close(void) {
2427c478bd9Sstevel@tonic-gate 	res_nclose(&_res);
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate int
2467c478bd9Sstevel@tonic-gate res_update(ns_updrec *rrecp_in) {
2479525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2487c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2497c478bd9Sstevel@tonic-gate 		return (-1);
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	return (res_nupdate(&_res, rrecp_in, NULL));
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate int
2569525b14bSRao Shoaib res_search(const char *name,	/*!< domain name  */
2579525b14bSRao Shoaib 	   int class, int type,	/*!< class and type of query  */
2589525b14bSRao Shoaib 	   u_char *answer,	/*!< buffer to put answer  */
2599525b14bSRao Shoaib 	   int anslen)		/*!< size of answer  */
2607c478bd9Sstevel@tonic-gate {
2619525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2627c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2637c478bd9Sstevel@tonic-gate 		return (-1);
2647c478bd9Sstevel@tonic-gate 	}
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	return (res_nsearch(&_res, name, class, type, answer, anslen));
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate int
2707c478bd9Sstevel@tonic-gate res_querydomain(const char *name,
2717c478bd9Sstevel@tonic-gate 		const char *domain,
2729525b14bSRao Shoaib 		int class, int type,	/*!< class and type of query  */
2739525b14bSRao Shoaib 		u_char *answer,		/*!< buffer to put answer  */
2749525b14bSRao Shoaib 		int anslen)		/*!< size of answer  */
2757c478bd9Sstevel@tonic-gate {
2769525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2777c478bd9Sstevel@tonic-gate 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2787c478bd9Sstevel@tonic-gate 		return (-1);
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	return (res_nquerydomain(&_res, name, domain,
2827c478bd9Sstevel@tonic-gate 				 class, type,
2837c478bd9Sstevel@tonic-gate 				 answer, anslen));
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate 
2869525b14bSRao Shoaib u_int
2879525b14bSRao Shoaib res_randomid(void) {
2889525b14bSRao Shoaib 	if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
2899525b14bSRao Shoaib 		RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
2909525b14bSRao Shoaib 		return (-1);
2919525b14bSRao Shoaib 	}
2929525b14bSRao Shoaib 
2939525b14bSRao Shoaib 	return (res_nrandomid(&_res));
2949525b14bSRao Shoaib }
2959525b14bSRao Shoaib 
2967c478bd9Sstevel@tonic-gate const char *
2977c478bd9Sstevel@tonic-gate hostalias(const char *name) {
2987c478bd9Sstevel@tonic-gate 	static char abuf[MAXDNAME];
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	return (res_hostalias(&_res, name, abuf, sizeof abuf));
3017c478bd9Sstevel@tonic-gate }
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate #ifdef ultrix
3047c478bd9Sstevel@tonic-gate int
3057c478bd9Sstevel@tonic-gate local_hostname_length(const char *hostname) {
3067c478bd9Sstevel@tonic-gate 	int len_host, len_domain;
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	if (!*_res.defdname)
3097c478bd9Sstevel@tonic-gate 		res_init();
3107c478bd9Sstevel@tonic-gate 	len_host = strlen(hostname);
3117c478bd9Sstevel@tonic-gate 	len_domain = strlen(_res.defdname);
3127c478bd9Sstevel@tonic-gate 	if (len_host > len_domain &&
3137c478bd9Sstevel@tonic-gate 	    !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
3147c478bd9Sstevel@tonic-gate 	    hostname[len_host - len_domain - 1] == '.')
3157c478bd9Sstevel@tonic-gate 		return (len_host - len_domain - 1);
3167c478bd9Sstevel@tonic-gate 	return (0);
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate #endif /*ultrix*/
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate #endif
3219525b14bSRao Shoaib 
3229525b14bSRao Shoaib /*! \file */
323