xref: /aosp_15_r20/bionic/libc/dns/resolv/res_debug.c (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
1*8d67ca89SAndroid Build Coastguard Worker /*	$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $	*/
2*8d67ca89SAndroid Build Coastguard Worker 
3*8d67ca89SAndroid Build Coastguard Worker /*
4*8d67ca89SAndroid Build Coastguard Worker  * Portions Copyright (C) 2004, 2005, 2008, 2009  Internet Systems Consortium, Inc. ("ISC")
5*8d67ca89SAndroid Build Coastguard Worker  * Portions Copyright (C) 1996-2003  Internet Software Consortium.
6*8d67ca89SAndroid Build Coastguard Worker  *
7*8d67ca89SAndroid Build Coastguard Worker  * Permission to use, copy, modify, and/or distribute this software for any
8*8d67ca89SAndroid Build Coastguard Worker  * purpose with or without fee is hereby granted, provided that the above
9*8d67ca89SAndroid Build Coastguard Worker  * copyright notice and this permission notice appear in all copies.
10*8d67ca89SAndroid Build Coastguard Worker  *
11*8d67ca89SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*8d67ca89SAndroid Build Coastguard Worker  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*8d67ca89SAndroid Build Coastguard Worker  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*8d67ca89SAndroid Build Coastguard Worker  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*8d67ca89SAndroid Build Coastguard Worker  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*8d67ca89SAndroid Build Coastguard Worker  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*8d67ca89SAndroid Build Coastguard Worker  * PERFORMANCE OF THIS SOFTWARE.
18*8d67ca89SAndroid Build Coastguard Worker  */
19*8d67ca89SAndroid Build Coastguard Worker 
20*8d67ca89SAndroid Build Coastguard Worker /*
21*8d67ca89SAndroid Build Coastguard Worker  * Copyright (c) 1985
22*8d67ca89SAndroid Build Coastguard Worker  *    The Regents of the University of California.  All rights reserved.
23*8d67ca89SAndroid Build Coastguard Worker  *
24*8d67ca89SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
25*8d67ca89SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
26*8d67ca89SAndroid Build Coastguard Worker  * are met:
27*8d67ca89SAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
28*8d67ca89SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
29*8d67ca89SAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
30*8d67ca89SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
31*8d67ca89SAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
32*8d67ca89SAndroid Build Coastguard Worker  * 3. All advertising materials mentioning features or use of this software
33*8d67ca89SAndroid Build Coastguard Worker  *    must display the following acknowledgement:
34*8d67ca89SAndroid Build Coastguard Worker  * 	This product includes software developed by the University of
35*8d67ca89SAndroid Build Coastguard Worker  * 	California, Berkeley and its contributors.
36*8d67ca89SAndroid Build Coastguard Worker  * 4. Neither the name of the University nor the names of its contributors
37*8d67ca89SAndroid Build Coastguard Worker  *    may be used to endorse or promote products derived from this software
38*8d67ca89SAndroid Build Coastguard Worker  *    without specific prior written permission.
39*8d67ca89SAndroid Build Coastguard Worker  *
40*8d67ca89SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
41*8d67ca89SAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*8d67ca89SAndroid Build Coastguard Worker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43*8d67ca89SAndroid Build Coastguard Worker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44*8d67ca89SAndroid Build Coastguard Worker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45*8d67ca89SAndroid Build Coastguard Worker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46*8d67ca89SAndroid Build Coastguard Worker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47*8d67ca89SAndroid Build Coastguard Worker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48*8d67ca89SAndroid Build Coastguard Worker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49*8d67ca89SAndroid Build Coastguard Worker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50*8d67ca89SAndroid Build Coastguard Worker  * SUCH DAMAGE.
51*8d67ca89SAndroid Build Coastguard Worker  */
52*8d67ca89SAndroid Build Coastguard Worker 
53*8d67ca89SAndroid Build Coastguard Worker /*
54*8d67ca89SAndroid Build Coastguard Worker  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
55*8d67ca89SAndroid Build Coastguard Worker  *
56*8d67ca89SAndroid Build Coastguard Worker  * Permission to use, copy, modify, and distribute this software for any
57*8d67ca89SAndroid Build Coastguard Worker  * purpose with or without fee is hereby granted, provided that the above
58*8d67ca89SAndroid Build Coastguard Worker  * copyright notice and this permission notice appear in all copies, and that
59*8d67ca89SAndroid Build Coastguard Worker  * the name of Digital Equipment Corporation not be used in advertising or
60*8d67ca89SAndroid Build Coastguard Worker  * publicity pertaining to distribution of the document or software without
61*8d67ca89SAndroid Build Coastguard Worker  * specific, written prior permission.
62*8d67ca89SAndroid Build Coastguard Worker  *
63*8d67ca89SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
64*8d67ca89SAndroid Build Coastguard Worker  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
65*8d67ca89SAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
66*8d67ca89SAndroid Build Coastguard Worker  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
67*8d67ca89SAndroid Build Coastguard Worker  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
68*8d67ca89SAndroid Build Coastguard Worker  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
69*8d67ca89SAndroid Build Coastguard Worker  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
70*8d67ca89SAndroid Build Coastguard Worker  * SOFTWARE.
71*8d67ca89SAndroid Build Coastguard Worker  */
72*8d67ca89SAndroid Build Coastguard Worker 
73*8d67ca89SAndroid Build Coastguard Worker /*
74*8d67ca89SAndroid Build Coastguard Worker  * Portions Copyright (c) 1995 by International Business Machines, Inc.
75*8d67ca89SAndroid Build Coastguard Worker  *
76*8d67ca89SAndroid Build Coastguard Worker  * International Business Machines, Inc. (hereinafter called IBM) grants
77*8d67ca89SAndroid Build Coastguard Worker  * permission under its copyrights to use, copy, modify, and distribute this
78*8d67ca89SAndroid Build Coastguard Worker  * Software with or without fee, provided that the above copyright notice and
79*8d67ca89SAndroid Build Coastguard Worker  * all paragraphs of this notice appear in all copies, and that the name of IBM
80*8d67ca89SAndroid Build Coastguard Worker  * not be used in connection with the marketing of any product incorporating
81*8d67ca89SAndroid Build Coastguard Worker  * the Software or modifications thereof, without specific, written prior
82*8d67ca89SAndroid Build Coastguard Worker  * permission.
83*8d67ca89SAndroid Build Coastguard Worker  *
84*8d67ca89SAndroid Build Coastguard Worker  * To the extent it has a right to do so, IBM grants an immunity from suit
85*8d67ca89SAndroid Build Coastguard Worker  * under its patents, if any, for the use, sale or manufacture of products to
86*8d67ca89SAndroid Build Coastguard Worker  * the extent that such products are used for performing Domain Name System
87*8d67ca89SAndroid Build Coastguard Worker  * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
88*8d67ca89SAndroid Build Coastguard Worker  * granted for any product per se or for any other function of any product.
89*8d67ca89SAndroid Build Coastguard Worker  *
90*8d67ca89SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
91*8d67ca89SAndroid Build Coastguard Worker  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
92*8d67ca89SAndroid Build Coastguard Worker  * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
93*8d67ca89SAndroid Build Coastguard Worker  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
94*8d67ca89SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
95*8d67ca89SAndroid Build Coastguard Worker  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
96*8d67ca89SAndroid Build Coastguard Worker  */
97*8d67ca89SAndroid Build Coastguard Worker 
98*8d67ca89SAndroid Build Coastguard Worker #include <sys/cdefs.h>
99*8d67ca89SAndroid Build Coastguard Worker #if defined(LIBC_SCCS) && !defined(lint)
100*8d67ca89SAndroid Build Coastguard Worker #ifdef notdef
101*8d67ca89SAndroid Build Coastguard Worker static const char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
102*8d67ca89SAndroid Build Coastguard Worker static const char rcsid[] = "Id: res_debug.c,v 1.19 2009/02/26 11:20:20 tbox Exp";
103*8d67ca89SAndroid Build Coastguard Worker #else
104*8d67ca89SAndroid Build Coastguard Worker __RCSID("$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $");
105*8d67ca89SAndroid Build Coastguard Worker #endif
106*8d67ca89SAndroid Build Coastguard Worker #endif /* LIBC_SCCS and not lint */
107*8d67ca89SAndroid Build Coastguard Worker 
108*8d67ca89SAndroid Build Coastguard Worker 
109*8d67ca89SAndroid Build Coastguard Worker 
110*8d67ca89SAndroid Build Coastguard Worker #include <sys/types.h>
111*8d67ca89SAndroid Build Coastguard Worker #include <sys/param.h>
112*8d67ca89SAndroid Build Coastguard Worker #include <sys/socket.h>
113*8d67ca89SAndroid Build Coastguard Worker 
114*8d67ca89SAndroid Build Coastguard Worker #include <netinet/in.h>
115*8d67ca89SAndroid Build Coastguard Worker #include <arpa/inet.h>
116*8d67ca89SAndroid Build Coastguard Worker #include <arpa/nameser.h>
117*8d67ca89SAndroid Build Coastguard Worker 
118*8d67ca89SAndroid Build Coastguard Worker #include <ctype.h>
119*8d67ca89SAndroid Build Coastguard Worker #include <errno.h>
120*8d67ca89SAndroid Build Coastguard Worker #include <math.h>
121*8d67ca89SAndroid Build Coastguard Worker #include <netdb.h>
122*8d67ca89SAndroid Build Coastguard Worker #include "resolv_private.h"
123*8d67ca89SAndroid Build Coastguard Worker #include <stdio.h>
124*8d67ca89SAndroid Build Coastguard Worker #include <stdlib.h>
125*8d67ca89SAndroid Build Coastguard Worker #include <string.h>
126*8d67ca89SAndroid Build Coastguard Worker #include <strings.h>
127*8d67ca89SAndroid Build Coastguard Worker #include <time.h>
128*8d67ca89SAndroid Build Coastguard Worker 
129*8d67ca89SAndroid Build Coastguard Worker extern const char * const _res_sectioncodes[];
130*8d67ca89SAndroid Build Coastguard Worker 
131*8d67ca89SAndroid Build Coastguard Worker __LIBC_HIDDEN__ const char* const _res_opcodes[] = {
132*8d67ca89SAndroid Build Coastguard Worker   "QUERY",
133*8d67ca89SAndroid Build Coastguard Worker   "IQUERY",
134*8d67ca89SAndroid Build Coastguard Worker   "CQUERYM",
135*8d67ca89SAndroid Build Coastguard Worker   "CQUERYU",  /* experimental */
136*8d67ca89SAndroid Build Coastguard Worker   "NOTIFY",  /* experimental */
137*8d67ca89SAndroid Build Coastguard Worker   "UPDATE",
138*8d67ca89SAndroid Build Coastguard Worker   "6",
139*8d67ca89SAndroid Build Coastguard Worker   "7",
140*8d67ca89SAndroid Build Coastguard Worker   "8",
141*8d67ca89SAndroid Build Coastguard Worker   "9",
142*8d67ca89SAndroid Build Coastguard Worker   "10",
143*8d67ca89SAndroid Build Coastguard Worker   "11",
144*8d67ca89SAndroid Build Coastguard Worker   "12",
145*8d67ca89SAndroid Build Coastguard Worker   "13",
146*8d67ca89SAndroid Build Coastguard Worker   "ZONEINIT",
147*8d67ca89SAndroid Build Coastguard Worker   "ZONEREF",
148*8d67ca89SAndroid Build Coastguard Worker };
149*8d67ca89SAndroid Build Coastguard Worker 
150*8d67ca89SAndroid Build Coastguard Worker #ifndef _LIBC
151*8d67ca89SAndroid Build Coastguard Worker /*
152*8d67ca89SAndroid Build Coastguard Worker  * Print the current options.
153*8d67ca89SAndroid Build Coastguard Worker  */
154*8d67ca89SAndroid Build Coastguard Worker void
fp_resstat(const res_state statp,FILE * file)155*8d67ca89SAndroid Build Coastguard Worker fp_resstat(const res_state statp, FILE *file) {
156*8d67ca89SAndroid Build Coastguard Worker 	u_long mask;
157*8d67ca89SAndroid Build Coastguard Worker 
158*8d67ca89SAndroid Build Coastguard Worker 	fprintf(file, ";; res options:");
159*8d67ca89SAndroid Build Coastguard Worker 	for (mask = 1;  mask != 0U;  mask <<= 1)
160*8d67ca89SAndroid Build Coastguard Worker 		if (statp->options & mask)
161*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " %s", p_option(mask));
162*8d67ca89SAndroid Build Coastguard Worker 	putc('\n', file);
163*8d67ca89SAndroid Build Coastguard Worker }
164*8d67ca89SAndroid Build Coastguard Worker #endif
165*8d67ca89SAndroid Build Coastguard Worker 
166*8d67ca89SAndroid Build Coastguard Worker static void
do_section(const res_state statp,ns_msg * handle,ns_sect section,int pflag,FILE * file)167*8d67ca89SAndroid Build Coastguard Worker do_section(const res_state statp,
168*8d67ca89SAndroid Build Coastguard Worker 	   ns_msg *handle, ns_sect section,
169*8d67ca89SAndroid Build Coastguard Worker 	   int pflag, FILE *file)
170*8d67ca89SAndroid Build Coastguard Worker {
171*8d67ca89SAndroid Build Coastguard Worker 	int n, sflag, rrnum;
172*8d67ca89SAndroid Build Coastguard Worker 	int buflen = 2048;
173*8d67ca89SAndroid Build Coastguard Worker 	char *buf;
174*8d67ca89SAndroid Build Coastguard Worker 	ns_opcode opcode;
175*8d67ca89SAndroid Build Coastguard Worker 	ns_rr rr;
176*8d67ca89SAndroid Build Coastguard Worker 
177*8d67ca89SAndroid Build Coastguard Worker 	/*
178*8d67ca89SAndroid Build Coastguard Worker 	 * Print answer records.
179*8d67ca89SAndroid Build Coastguard Worker 	 */
180*8d67ca89SAndroid Build Coastguard Worker 	sflag = (int)(statp->pfcode & pflag);
181*8d67ca89SAndroid Build Coastguard Worker 	if (statp->pfcode && !sflag)
182*8d67ca89SAndroid Build Coastguard Worker 		return;
183*8d67ca89SAndroid Build Coastguard Worker 
184*8d67ca89SAndroid Build Coastguard Worker 	buf = malloc((size_t)buflen);
185*8d67ca89SAndroid Build Coastguard Worker 	if (buf == NULL) {
186*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file, ";; memory allocation failure\n");
187*8d67ca89SAndroid Build Coastguard Worker 		return;
188*8d67ca89SAndroid Build Coastguard Worker 	}
189*8d67ca89SAndroid Build Coastguard Worker 
190*8d67ca89SAndroid Build Coastguard Worker 	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
191*8d67ca89SAndroid Build Coastguard Worker 	rrnum = 0;
192*8d67ca89SAndroid Build Coastguard Worker 	for (;;) {
193*8d67ca89SAndroid Build Coastguard Worker 		if (ns_parserr(handle, section, rrnum, &rr)) {
194*8d67ca89SAndroid Build Coastguard Worker 			if (errno != ENODEV)
195*8d67ca89SAndroid Build Coastguard Worker 				fprintf(file, ";; ns_parserr: %s\n",
196*8d67ca89SAndroid Build Coastguard Worker 					strerror(errno));
197*8d67ca89SAndroid Build Coastguard Worker 			else if (rrnum > 0 && sflag != 0 &&
198*8d67ca89SAndroid Build Coastguard Worker 				 (statp->pfcode & RES_PRF_HEAD1))
199*8d67ca89SAndroid Build Coastguard Worker 				putc('\n', file);
200*8d67ca89SAndroid Build Coastguard Worker 			goto cleanup;
201*8d67ca89SAndroid Build Coastguard Worker 		}
202*8d67ca89SAndroid Build Coastguard Worker 		if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
203*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, ";; %s SECTION:\n",
204*8d67ca89SAndroid Build Coastguard Worker 				p_section(section, opcode));
205*8d67ca89SAndroid Build Coastguard Worker 		if (section == ns_s_qd)
206*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, ";;\t%s, type = %s, class = %s\n",
207*8d67ca89SAndroid Build Coastguard Worker 				ns_rr_name(rr),
208*8d67ca89SAndroid Build Coastguard Worker 				p_type(ns_rr_type(rr)),
209*8d67ca89SAndroid Build Coastguard Worker 				p_class(ns_rr_class(rr)));
210*8d67ca89SAndroid Build Coastguard Worker 		else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
211*8d67ca89SAndroid Build Coastguard Worker 			size_t rdatalen, ttl;
212*8d67ca89SAndroid Build Coastguard Worker 			uint16_t optcode, optlen;
213*8d67ca89SAndroid Build Coastguard Worker 
214*8d67ca89SAndroid Build Coastguard Worker 			rdatalen = ns_rr_rdlen(rr);
215*8d67ca89SAndroid Build Coastguard Worker 			ttl = ns_rr_ttl(rr);
216*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file,
217*8d67ca89SAndroid Build Coastguard Worker 				"; EDNS: version: %zu, udp=%u, flags=%04zx\n",
218*8d67ca89SAndroid Build Coastguard Worker 				(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
219*8d67ca89SAndroid Build Coastguard Worker 			while (rdatalen >= 4) {
220*8d67ca89SAndroid Build Coastguard Worker 				const u_char *cp = ns_rr_rdata(rr);
221*8d67ca89SAndroid Build Coastguard Worker 				int i;
222*8d67ca89SAndroid Build Coastguard Worker 
223*8d67ca89SAndroid Build Coastguard Worker 				GETSHORT(optcode, cp);
224*8d67ca89SAndroid Build Coastguard Worker 				GETSHORT(optlen, cp);
225*8d67ca89SAndroid Build Coastguard Worker 
226*8d67ca89SAndroid Build Coastguard Worker 				if (optcode == NS_OPT_NSID) {
227*8d67ca89SAndroid Build Coastguard Worker 					fputs("; NSID: ", file);
228*8d67ca89SAndroid Build Coastguard Worker 					if (optlen == 0) {
229*8d67ca89SAndroid Build Coastguard Worker 						fputs("; NSID\n", file);
230*8d67ca89SAndroid Build Coastguard Worker 					} else {
231*8d67ca89SAndroid Build Coastguard Worker 						fputs("; NSID: ", file);
232*8d67ca89SAndroid Build Coastguard Worker 						for (i = 0; i < optlen; i++)
233*8d67ca89SAndroid Build Coastguard Worker 							fprintf(file, "%02x ",
234*8d67ca89SAndroid Build Coastguard Worker 								cp[i]);
235*8d67ca89SAndroid Build Coastguard Worker 						fputs(" (",file);
236*8d67ca89SAndroid Build Coastguard Worker 						for (i = 0; i < optlen; i++)
237*8d67ca89SAndroid Build Coastguard Worker 							fprintf(file, "%c",
238*8d67ca89SAndroid Build Coastguard Worker 								isprint(cp[i])?
239*8d67ca89SAndroid Build Coastguard Worker 								cp[i] : '.');
240*8d67ca89SAndroid Build Coastguard Worker 						fputs(")\n", file);
241*8d67ca89SAndroid Build Coastguard Worker 					}
242*8d67ca89SAndroid Build Coastguard Worker 				} else {
243*8d67ca89SAndroid Build Coastguard Worker 					if (optlen == 0) {
244*8d67ca89SAndroid Build Coastguard Worker 						fprintf(file, "; OPT=%u\n",
245*8d67ca89SAndroid Build Coastguard Worker 							optcode);
246*8d67ca89SAndroid Build Coastguard Worker 					} else {
247*8d67ca89SAndroid Build Coastguard Worker 						fprintf(file, "; OPT=%u: ",
248*8d67ca89SAndroid Build Coastguard Worker 							optcode);
249*8d67ca89SAndroid Build Coastguard Worker 						for (i = 0; i < optlen; i++)
250*8d67ca89SAndroid Build Coastguard Worker 							fprintf(file, "%02x ",
251*8d67ca89SAndroid Build Coastguard Worker 								cp[i]);
252*8d67ca89SAndroid Build Coastguard Worker 						fputs(" (",file);
253*8d67ca89SAndroid Build Coastguard Worker 						for (i = 0; i < optlen; i++)
254*8d67ca89SAndroid Build Coastguard Worker 							fprintf(file, "%c",
255*8d67ca89SAndroid Build Coastguard Worker 								isprint(cp[i]) ?
256*8d67ca89SAndroid Build Coastguard Worker 									cp[i] : '.');
257*8d67ca89SAndroid Build Coastguard Worker 						fputs(")\n", file);
258*8d67ca89SAndroid Build Coastguard Worker 					}
259*8d67ca89SAndroid Build Coastguard Worker 				}
260*8d67ca89SAndroid Build Coastguard Worker 				rdatalen -= 4 + optlen;
261*8d67ca89SAndroid Build Coastguard Worker 			}
262*8d67ca89SAndroid Build Coastguard Worker 		} else {
263*8d67ca89SAndroid Build Coastguard Worker 			n = ns_sprintrr(handle, &rr, NULL, NULL,
264*8d67ca89SAndroid Build Coastguard Worker 					buf, (u_int)buflen);
265*8d67ca89SAndroid Build Coastguard Worker 			if (n < 0) {
266*8d67ca89SAndroid Build Coastguard Worker 				if (errno == ENOSPC) {
267*8d67ca89SAndroid Build Coastguard Worker 					free(buf);
268*8d67ca89SAndroid Build Coastguard Worker 					buf = NULL;
269*8d67ca89SAndroid Build Coastguard Worker 					if (buflen < 131072)
270*8d67ca89SAndroid Build Coastguard Worker 						buf = malloc((size_t)(buflen += 1024));
271*8d67ca89SAndroid Build Coastguard Worker 					if (buf == NULL) {
272*8d67ca89SAndroid Build Coastguard Worker 						fprintf(file,
273*8d67ca89SAndroid Build Coastguard Worker 				              ";; memory allocation failure\n");
274*8d67ca89SAndroid Build Coastguard Worker 					      return;
275*8d67ca89SAndroid Build Coastguard Worker 					}
276*8d67ca89SAndroid Build Coastguard Worker 					continue;
277*8d67ca89SAndroid Build Coastguard Worker 				}
278*8d67ca89SAndroid Build Coastguard Worker 				fprintf(file, ";; ns_sprintrr: %s\n",
279*8d67ca89SAndroid Build Coastguard Worker 					strerror(errno));
280*8d67ca89SAndroid Build Coastguard Worker 				goto cleanup;
281*8d67ca89SAndroid Build Coastguard Worker 			}
282*8d67ca89SAndroid Build Coastguard Worker 			fputs(buf, file);
283*8d67ca89SAndroid Build Coastguard Worker 			fputc('\n', file);
284*8d67ca89SAndroid Build Coastguard Worker 		}
285*8d67ca89SAndroid Build Coastguard Worker 		rrnum++;
286*8d67ca89SAndroid Build Coastguard Worker 	}
287*8d67ca89SAndroid Build Coastguard Worker  cleanup:
288*8d67ca89SAndroid Build Coastguard Worker 	if (buf != NULL)
289*8d67ca89SAndroid Build Coastguard Worker 		free(buf);
290*8d67ca89SAndroid Build Coastguard Worker }
291*8d67ca89SAndroid Build Coastguard Worker 
292*8d67ca89SAndroid Build Coastguard Worker /*
293*8d67ca89SAndroid Build Coastguard Worker  * Print the contents of a query.
294*8d67ca89SAndroid Build Coastguard Worker  * This is intended to be primarily a debugging routine.
295*8d67ca89SAndroid Build Coastguard Worker  */
296*8d67ca89SAndroid Build Coastguard Worker void
res_pquery(const res_state statp,const u_char * msg,int len,FILE * file)297*8d67ca89SAndroid Build Coastguard Worker res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) {
298*8d67ca89SAndroid Build Coastguard Worker 	ns_msg handle;
299*8d67ca89SAndroid Build Coastguard Worker 	int qdcount, ancount, nscount, arcount;
300*8d67ca89SAndroid Build Coastguard Worker 	u_int opcode, rcode, id;
301*8d67ca89SAndroid Build Coastguard Worker 
302*8d67ca89SAndroid Build Coastguard Worker 	if (ns_initparse(msg, len, &handle) < 0) {
303*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
304*8d67ca89SAndroid Build Coastguard Worker 		return;
305*8d67ca89SAndroid Build Coastguard Worker 	}
306*8d67ca89SAndroid Build Coastguard Worker 	opcode = ns_msg_getflag(handle, ns_f_opcode);
307*8d67ca89SAndroid Build Coastguard Worker 	rcode = ns_msg_getflag(handle, ns_f_rcode);
308*8d67ca89SAndroid Build Coastguard Worker 	id = ns_msg_id(handle);
309*8d67ca89SAndroid Build Coastguard Worker 	qdcount = ns_msg_count(handle, ns_s_qd);
310*8d67ca89SAndroid Build Coastguard Worker 	ancount = ns_msg_count(handle, ns_s_an);
311*8d67ca89SAndroid Build Coastguard Worker 	nscount = ns_msg_count(handle, ns_s_ns);
312*8d67ca89SAndroid Build Coastguard Worker 	arcount = ns_msg_count(handle, ns_s_ar);
313*8d67ca89SAndroid Build Coastguard Worker 
314*8d67ca89SAndroid Build Coastguard Worker 	/*
315*8d67ca89SAndroid Build Coastguard Worker 	 * Print header fields.
316*8d67ca89SAndroid Build Coastguard Worker 	 */
317*8d67ca89SAndroid Build Coastguard Worker 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode)
318*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file,
319*8d67ca89SAndroid Build Coastguard Worker 			";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
320*8d67ca89SAndroid Build Coastguard Worker 			_res_opcodes[opcode], p_rcode((int)rcode), id);
321*8d67ca89SAndroid Build Coastguard Worker 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX))
322*8d67ca89SAndroid Build Coastguard Worker 		putc(';', file);
323*8d67ca89SAndroid Build Coastguard Worker 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) {
324*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file, "; flags:");
325*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_qr))
326*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " qr");
327*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_aa))
328*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " aa");
329*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_tc))
330*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " tc");
331*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_rd))
332*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " rd");
333*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_ra))
334*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " ra");
335*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_z))
336*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " ??");
337*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_ad))
338*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " ad");
339*8d67ca89SAndroid Build Coastguard Worker 		if (ns_msg_getflag(handle, ns_f_cd))
340*8d67ca89SAndroid Build Coastguard Worker 			fprintf(file, " cd");
341*8d67ca89SAndroid Build Coastguard Worker 	}
342*8d67ca89SAndroid Build Coastguard Worker 	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) {
343*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file, "; %s: %d",
344*8d67ca89SAndroid Build Coastguard Worker 			p_section(ns_s_qd, (int)opcode), qdcount);
345*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file, ", %s: %d",
346*8d67ca89SAndroid Build Coastguard Worker 			p_section(ns_s_an, (int)opcode), ancount);
347*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file, ", %s: %d",
348*8d67ca89SAndroid Build Coastguard Worker 			p_section(ns_s_ns, (int)opcode), nscount);
349*8d67ca89SAndroid Build Coastguard Worker 		fprintf(file, ", %s: %d",
350*8d67ca89SAndroid Build Coastguard Worker 			p_section(ns_s_ar, (int)opcode), arcount);
351*8d67ca89SAndroid Build Coastguard Worker 	}
352*8d67ca89SAndroid Build Coastguard Worker 	if ((!statp->pfcode) || (statp->pfcode &
353*8d67ca89SAndroid Build Coastguard Worker 		(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
354*8d67ca89SAndroid Build Coastguard Worker 		putc('\n',file);
355*8d67ca89SAndroid Build Coastguard Worker 	}
356*8d67ca89SAndroid Build Coastguard Worker 	/*
357*8d67ca89SAndroid Build Coastguard Worker 	 * Print the various sections.
358*8d67ca89SAndroid Build Coastguard Worker 	 */
359*8d67ca89SAndroid Build Coastguard Worker 	do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file);
360*8d67ca89SAndroid Build Coastguard Worker 	do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file);
361*8d67ca89SAndroid Build Coastguard Worker 	do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file);
362*8d67ca89SAndroid Build Coastguard Worker 	do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file);
363*8d67ca89SAndroid Build Coastguard Worker 	if (qdcount == 0 && ancount == 0 &&
364*8d67ca89SAndroid Build Coastguard Worker 	    nscount == 0 && arcount == 0)
365*8d67ca89SAndroid Build Coastguard Worker 		putc('\n', file);
366*8d67ca89SAndroid Build Coastguard Worker }
367*8d67ca89SAndroid Build Coastguard Worker 
368*8d67ca89SAndroid Build Coastguard Worker const u_char *
p_cdnname(const u_char * cp,const u_char * msg,int len,FILE * file)369*8d67ca89SAndroid Build Coastguard Worker p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
370*8d67ca89SAndroid Build Coastguard Worker 	char name[MAXDNAME];
371*8d67ca89SAndroid Build Coastguard Worker 	int n;
372*8d67ca89SAndroid Build Coastguard Worker 
373*8d67ca89SAndroid Build Coastguard Worker 	if ((n = dn_expand(msg, msg + len, cp, name, (int)sizeof name)) < 0)
374*8d67ca89SAndroid Build Coastguard Worker 		return (NULL);
375*8d67ca89SAndroid Build Coastguard Worker 	if (name[0] == '\0')
376*8d67ca89SAndroid Build Coastguard Worker 		putc('.', file);
377*8d67ca89SAndroid Build Coastguard Worker 	else
378*8d67ca89SAndroid Build Coastguard Worker 		fputs(name, file);
379*8d67ca89SAndroid Build Coastguard Worker 	return (cp + n);
380*8d67ca89SAndroid Build Coastguard Worker }
381*8d67ca89SAndroid Build Coastguard Worker 
382*8d67ca89SAndroid Build Coastguard Worker const u_char *
p_cdname(const u_char * cp,const u_char * msg,FILE * file)383*8d67ca89SAndroid Build Coastguard Worker p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
384*8d67ca89SAndroid Build Coastguard Worker 	return (p_cdnname(cp, msg, PACKETSZ, file));
385*8d67ca89SAndroid Build Coastguard Worker }
386*8d67ca89SAndroid Build Coastguard Worker 
387*8d67ca89SAndroid Build Coastguard Worker /* Return a fully-qualified domain name from a compressed name (with
388*8d67ca89SAndroid Build Coastguard Worker    length supplied).  */
389*8d67ca89SAndroid Build Coastguard Worker 
390*8d67ca89SAndroid Build Coastguard Worker const u_char *
p_fqnname(const u_char * cp,const u_char * msg,int msglen,char * name,int namelen)391*8d67ca89SAndroid Build Coastguard Worker p_fqnname(const u_char *cp, const u_char *msg, int msglen, char *name,
392*8d67ca89SAndroid Build Coastguard Worker     int namelen)
393*8d67ca89SAndroid Build Coastguard Worker {
394*8d67ca89SAndroid Build Coastguard Worker 	int n;
395*8d67ca89SAndroid Build Coastguard Worker 	size_t newlen;
396*8d67ca89SAndroid Build Coastguard Worker 
397*8d67ca89SAndroid Build Coastguard Worker 	if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
398*8d67ca89SAndroid Build Coastguard Worker 		return (NULL);
399*8d67ca89SAndroid Build Coastguard Worker 	newlen = strlen(name);
400*8d67ca89SAndroid Build Coastguard Worker 	if (newlen == 0 || name[newlen - 1] != '.') {
401*8d67ca89SAndroid Build Coastguard Worker 		if ((int)newlen + 1 >= namelen)	/* Lack space for final dot */
402*8d67ca89SAndroid Build Coastguard Worker 			return (NULL);
403*8d67ca89SAndroid Build Coastguard Worker 		else
404*8d67ca89SAndroid Build Coastguard Worker 			strcpy(name + newlen, ".");
405*8d67ca89SAndroid Build Coastguard Worker 	}
406*8d67ca89SAndroid Build Coastguard Worker 	return (cp + n);
407*8d67ca89SAndroid Build Coastguard Worker }
408*8d67ca89SAndroid Build Coastguard Worker 
409*8d67ca89SAndroid Build Coastguard Worker /* XXX:	the rest of these functions need to become length-limited, too. */
410*8d67ca89SAndroid Build Coastguard Worker 
411*8d67ca89SAndroid Build Coastguard Worker const u_char *
p_fqname(const u_char * cp,const u_char * msg,FILE * file)412*8d67ca89SAndroid Build Coastguard Worker p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
413*8d67ca89SAndroid Build Coastguard Worker 	char name[MAXDNAME];
414*8d67ca89SAndroid Build Coastguard Worker 	const u_char *n;
415*8d67ca89SAndroid Build Coastguard Worker 
416*8d67ca89SAndroid Build Coastguard Worker 	n = p_fqnname(cp, msg, MAXCDNAME, name, (int)sizeof name);
417*8d67ca89SAndroid Build Coastguard Worker 	if (n == NULL)
418*8d67ca89SAndroid Build Coastguard Worker 		return (NULL);
419*8d67ca89SAndroid Build Coastguard Worker 	fputs(name, file);
420*8d67ca89SAndroid Build Coastguard Worker 	return (n);
421*8d67ca89SAndroid Build Coastguard Worker }
422*8d67ca89SAndroid Build Coastguard Worker 
423*8d67ca89SAndroid Build Coastguard Worker /*
424*8d67ca89SAndroid Build Coastguard Worker  * Names of RR classes and qclasses.  Classes and qclasses are the same, except
425*8d67ca89SAndroid Build Coastguard Worker  * that C_ANY is a qclass but not a class.  (You can ask for records of class
426*8d67ca89SAndroid Build Coastguard Worker  * C_ANY, but you can't have any records of that class in the database.)
427*8d67ca89SAndroid Build Coastguard Worker  */
428*8d67ca89SAndroid Build Coastguard Worker const struct res_sym __p_class_syms[] = {
429*8d67ca89SAndroid Build Coastguard Worker 	{C_IN,		"IN",		(char *)0},
430*8d67ca89SAndroid Build Coastguard Worker 	{C_CHAOS,	"CH",		(char *)0},
431*8d67ca89SAndroid Build Coastguard Worker 	{C_CHAOS,	"CHAOS",	(char *)0},
432*8d67ca89SAndroid Build Coastguard Worker 	{C_HS,		"HS",		(char *)0},
433*8d67ca89SAndroid Build Coastguard Worker 	{C_HS,		"HESIOD",	(char *)0},
434*8d67ca89SAndroid Build Coastguard Worker 	{C_ANY,		"ANY",		(char *)0},
435*8d67ca89SAndroid Build Coastguard Worker 	{C_NONE,	"NONE",		(char *)0},
436*8d67ca89SAndroid Build Coastguard Worker 	{C_IN, 		(char *)0,	(char *)0}
437*8d67ca89SAndroid Build Coastguard Worker };
438*8d67ca89SAndroid Build Coastguard Worker 
439*8d67ca89SAndroid Build Coastguard Worker /*
440*8d67ca89SAndroid Build Coastguard Worker  * Names of message sections.
441*8d67ca89SAndroid Build Coastguard Worker  */
442*8d67ca89SAndroid Build Coastguard Worker static const struct res_sym __p_default_section_syms[] = {
443*8d67ca89SAndroid Build Coastguard Worker 	{ns_s_qd,	"QUERY",	(char *)0},
444*8d67ca89SAndroid Build Coastguard Worker 	{ns_s_an,	"ANSWER",	(char *)0},
445*8d67ca89SAndroid Build Coastguard Worker 	{ns_s_ns,	"AUTHORITY",	(char *)0},
446*8d67ca89SAndroid Build Coastguard Worker 	{ns_s_ar,	"ADDITIONAL",	(char *)0},
447*8d67ca89SAndroid Build Coastguard Worker 	{0,             (char *)0,	(char *)0}
448*8d67ca89SAndroid Build Coastguard Worker };
449*8d67ca89SAndroid Build Coastguard Worker 
450*8d67ca89SAndroid Build Coastguard Worker static const struct res_sym __p_update_section_syms[] = {
451*8d67ca89SAndroid Build Coastguard Worker 	{S_ZONE,	"ZONE",		(char *)0},
452*8d67ca89SAndroid Build Coastguard Worker 	{S_PREREQ,	"PREREQUISITE",	(char *)0},
453*8d67ca89SAndroid Build Coastguard Worker 	{S_UPDATE,	"UPDATE",	(char *)0},
454*8d67ca89SAndroid Build Coastguard Worker 	{S_ADDT,	"ADDITIONAL",	(char *)0},
455*8d67ca89SAndroid Build Coastguard Worker 	{0,             (char *)0,	(char *)0}
456*8d67ca89SAndroid Build Coastguard Worker };
457*8d67ca89SAndroid Build Coastguard Worker 
458*8d67ca89SAndroid Build Coastguard Worker const struct res_sym __p_key_syms[] = {
459*8d67ca89SAndroid Build Coastguard Worker 	{NS_ALG_MD5RSA,		"RSA",		"RSA KEY with MD5 hash"},
460*8d67ca89SAndroid Build Coastguard Worker 	{NS_ALG_DH,		"DH",		"Diffie Hellman"},
461*8d67ca89SAndroid Build Coastguard Worker 	{NS_ALG_DSA,		"DSA",		"Digital Signature Algorithm"},
462*8d67ca89SAndroid Build Coastguard Worker 	{NS_ALG_EXPIRE_ONLY,	"EXPIREONLY",	"No algorithm"},
463*8d67ca89SAndroid Build Coastguard Worker 	{NS_ALG_PRIVATE_OID,	"PRIVATE",	"Algorithm obtained from OID"},
464*8d67ca89SAndroid Build Coastguard Worker 	{0,			NULL,		NULL}
465*8d67ca89SAndroid Build Coastguard Worker };
466*8d67ca89SAndroid Build Coastguard Worker 
467*8d67ca89SAndroid Build Coastguard Worker const struct res_sym __p_cert_syms[] = {
468*8d67ca89SAndroid Build Coastguard Worker 	{cert_t_pkix,	"PKIX",		"PKIX (X.509v3) Certificate"},
469*8d67ca89SAndroid Build Coastguard Worker 	{cert_t_spki,	"SPKI",		"SPKI certificate"},
470*8d67ca89SAndroid Build Coastguard Worker 	{cert_t_pgp,	"PGP",		"PGP certificate"},
471*8d67ca89SAndroid Build Coastguard Worker 	{cert_t_url,	"URL",		"URL Private"},
472*8d67ca89SAndroid Build Coastguard Worker 	{cert_t_oid,	"OID",		"OID Private"},
473*8d67ca89SAndroid Build Coastguard Worker 	{0,		NULL,		NULL}
474*8d67ca89SAndroid Build Coastguard Worker };
475*8d67ca89SAndroid Build Coastguard Worker 
476*8d67ca89SAndroid Build Coastguard Worker /*
477*8d67ca89SAndroid Build Coastguard Worker  * Names of RR types and qtypes.  Types and qtypes are the same, except
478*8d67ca89SAndroid Build Coastguard Worker  * that T_ANY is a qtype but not a type.  (You can ask for records of type
479*8d67ca89SAndroid Build Coastguard Worker  * T_ANY, but you can't have any records of that type in the database.)
480*8d67ca89SAndroid Build Coastguard Worker  */
481*8d67ca89SAndroid Build Coastguard Worker const struct res_sym __p_type_syms[] = {
482*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_a,	"A",		"address"},
483*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_ns,	"NS",		"name server"},
484*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_md,	"MD",		"mail destination (deprecated)"},
485*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_mf,	"MF",		"mail forwarder (deprecated)"},
486*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_cname,	"CNAME",	"canonical name"},
487*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_soa,	"SOA",		"start of authority"},
488*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_mb,	"MB",		"mailbox"},
489*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_mg,	"MG",		"mail group member"},
490*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_mr,	"MR",		"mail rename"},
491*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_null,	"NULL",		"null"},
492*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_wks,	"WKS",		"well-known service (deprecated)"},
493*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_ptr,	"PTR",		"domain name pointer"},
494*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_hinfo,	"HINFO",	"host information"},
495*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_minfo,	"MINFO",	"mailbox information"},
496*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_mx,	"MX",		"mail exchanger"},
497*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_txt,	"TXT",		"text"},
498*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_rp,	"RP",		"responsible person"},
499*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_afsdb,	"AFSDB",	"DCE or AFS server"},
500*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_x25,	"X25",		"X25 address"},
501*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_isdn,	"ISDN",		"ISDN address"},
502*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_rt,	"RT",		"router"},
503*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_nsap,	"NSAP",		"nsap address"},
504*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_nsap_ptr,	"NSAP_PTR",	"domain name pointer"},
505*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_sig,	"SIG",		"signature"},
506*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_key,	"KEY",		"key"},
507*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_px,	"PX",		"mapping information"},
508*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_gpos,	"GPOS",		"geographical position (withdrawn)"},
509*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_aaaa,	"AAAA",		"IPv6 address"},
510*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_loc,	"LOC",		"location"},
511*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_nxt,	"NXT",		"next valid name (unimplemented)"},
512*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_eid,	"EID",		"endpoint identifier (unimplemented)"},
513*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_nimloc,	"NIMLOC",	"NIMROD locator (unimplemented)"},
514*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_srv,	"SRV",		"server selection"},
515*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_atma,	"ATMA",		"ATM address (unimplemented)"},
516*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_naptr,	"NAPTR",	"naptr"},
517*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_kx,	"KX",		"key exchange"},
518*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_cert,	"CERT",		"certificate"},
519*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_a6,	"A",		"IPv6 address (experminental)"},
520*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_dname,	"DNAME",	"non-terminal redirection"},
521*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_opt,	"OPT",		"opt"},
522*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_apl,	"apl",		"apl"},
523*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_ds,	"DS",		"delegation signer"},
524*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_sshfp,	"SSFP",		"SSH fingerprint"},
525*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_ipseckey,	"IPSECKEY",	"IPSEC key"},
526*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_rrsig,	"RRSIG",	"rrsig"},
527*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_nsec,	"NSEC",		"nsec"},
528*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_dnskey,	"DNSKEY",	"DNS key"},
529*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_dhcid,	"DHCID",       "dynamic host configuration identifier"},
530*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_nsec3,	"NSEC3",	"nsec3"},
531*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_nsec3param, "NSEC3PARAM", "NSEC3 parameters"},
532*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_hip,	"HIP",		"host identity protocol"},
533*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_spf,	"SPF",		"sender policy framework"},
534*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_tkey,	"TKEY",		"tkey"},
535*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_tsig,	"TSIG",		"transaction signature"},
536*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_ixfr,	"IXFR",		"incremental zone transfer"},
537*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_axfr,	"AXFR",		"zone transfer"},
538*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_zxfr,	"ZXFR",		"compressed zone transfer"},
539*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_mailb,	"MAILB",	"mailbox-related data (deprecated)"},
540*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_maila,	"MAILA",	"mail agent (deprecated)"},
541*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_naptr,	"NAPTR",	"URN Naming Authority"},
542*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_kx,	"KX",		"Key Exchange"},
543*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_cert,	"CERT",		"Certificate"},
544*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_a6,	"A6",		"IPv6 Address"},
545*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_dname,	"DNAME",	"dname"},
546*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_sink,	"SINK",		"Kitchen Sink (experimental)"},
547*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_opt,	"OPT",		"EDNS Options"},
548*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_any,	"ANY",		"\"any\""},
549*8d67ca89SAndroid Build Coastguard Worker 	{ns_t_dlv,	"DLV",		"DNSSEC look-aside validation"},
550*8d67ca89SAndroid Build Coastguard Worker 	{0, 		NULL,		NULL}
551*8d67ca89SAndroid Build Coastguard Worker };
552*8d67ca89SAndroid Build Coastguard Worker 
553*8d67ca89SAndroid Build Coastguard Worker /*
554*8d67ca89SAndroid Build Coastguard Worker  * Names of DNS rcodes.
555*8d67ca89SAndroid Build Coastguard Worker  */
556*8d67ca89SAndroid Build Coastguard Worker const struct res_sym __p_rcode_syms[] = {
557*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_noerror,	"NOERROR",		"no error"},
558*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_formerr,	"FORMERR",		"format error"},
559*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_servfail,	"SERVFAIL",		"server failed"},
560*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_nxdomain,	"NXDOMAIN",		"no such domain name"},
561*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_notimpl,	"NOTIMP",		"not implemented"},
562*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_refused,	"REFUSED",		"refused"},
563*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_yxdomain,	"YXDOMAIN",		"domain name exists"},
564*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_yxrrset,	"YXRRSET",		"rrset exists"},
565*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_nxrrset,	"NXRRSET",		"rrset doesn't exist"},
566*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_notauth,	"NOTAUTH",		"not authoritative"},
567*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_notzone,	"NOTZONE",		"Not in zone"},
568*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_max,	"",			""},
569*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_badsig,	"BADSIG",		"bad signature"},
570*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_badkey,	"BADKEY",		"bad key"},
571*8d67ca89SAndroid Build Coastguard Worker 	{ns_r_badtime,	"BADTIME",		"bad time"},
572*8d67ca89SAndroid Build Coastguard Worker 	{0, 		NULL,			NULL}
573*8d67ca89SAndroid Build Coastguard Worker };
574*8d67ca89SAndroid Build Coastguard Worker 
575*8d67ca89SAndroid Build Coastguard Worker int
sym_ston(const struct res_sym * syms,const char * name,int * success)576*8d67ca89SAndroid Build Coastguard Worker sym_ston(const struct res_sym *syms, const char *name, int *success) {
577*8d67ca89SAndroid Build Coastguard Worker 	for (; syms->name != 0; syms++) {
578*8d67ca89SAndroid Build Coastguard Worker 		if (strcasecmp (name, syms->name) == 0) {
579*8d67ca89SAndroid Build Coastguard Worker 			if (success)
580*8d67ca89SAndroid Build Coastguard Worker 				*success = 1;
581*8d67ca89SAndroid Build Coastguard Worker 			return (syms->number);
582*8d67ca89SAndroid Build Coastguard Worker 		}
583*8d67ca89SAndroid Build Coastguard Worker 	}
584*8d67ca89SAndroid Build Coastguard Worker 	if (success)
585*8d67ca89SAndroid Build Coastguard Worker 		*success = 0;
586*8d67ca89SAndroid Build Coastguard Worker 	return (syms->number);		/* The default value. */
587*8d67ca89SAndroid Build Coastguard Worker }
588*8d67ca89SAndroid Build Coastguard Worker 
589*8d67ca89SAndroid Build Coastguard Worker const char *
sym_ntos(const struct res_sym * syms,int number,int * success)590*8d67ca89SAndroid Build Coastguard Worker sym_ntos(const struct res_sym *syms, int number, int *success) {
591*8d67ca89SAndroid Build Coastguard Worker 	static char unname[20];
592*8d67ca89SAndroid Build Coastguard Worker 
593*8d67ca89SAndroid Build Coastguard Worker 	for (; syms->name != 0; syms++) {
594*8d67ca89SAndroid Build Coastguard Worker 		if (number == syms->number) {
595*8d67ca89SAndroid Build Coastguard Worker 			if (success)
596*8d67ca89SAndroid Build Coastguard Worker 				*success = 1;
597*8d67ca89SAndroid Build Coastguard Worker 			return (syms->name);
598*8d67ca89SAndroid Build Coastguard Worker 		}
599*8d67ca89SAndroid Build Coastguard Worker 	}
600*8d67ca89SAndroid Build Coastguard Worker 
601*8d67ca89SAndroid Build Coastguard Worker 	snprintf(unname, sizeof(unname), "%d", number);		/* XXX nonreentrant */
602*8d67ca89SAndroid Build Coastguard Worker 	if (success)
603*8d67ca89SAndroid Build Coastguard Worker 		*success = 0;
604*8d67ca89SAndroid Build Coastguard Worker 	return (unname);
605*8d67ca89SAndroid Build Coastguard Worker }
606*8d67ca89SAndroid Build Coastguard Worker 
607*8d67ca89SAndroid Build Coastguard Worker const char *
sym_ntop(const struct res_sym * syms,int number,int * success)608*8d67ca89SAndroid Build Coastguard Worker sym_ntop(const struct res_sym *syms, int number, int *success) {
609*8d67ca89SAndroid Build Coastguard Worker 	static char unname[20];
610*8d67ca89SAndroid Build Coastguard Worker 
611*8d67ca89SAndroid Build Coastguard Worker 	for (; syms->name != 0; syms++) {
612*8d67ca89SAndroid Build Coastguard Worker 		if (number == syms->number) {
613*8d67ca89SAndroid Build Coastguard Worker 			if (success)
614*8d67ca89SAndroid Build Coastguard Worker 				*success = 1;
615*8d67ca89SAndroid Build Coastguard Worker 			return (syms->humanname);
616*8d67ca89SAndroid Build Coastguard Worker 		}
617*8d67ca89SAndroid Build Coastguard Worker 	}
618*8d67ca89SAndroid Build Coastguard Worker 	snprintf(unname, sizeof(unname), "%d", number);		/* XXX nonreentrant */
619*8d67ca89SAndroid Build Coastguard Worker 	if (success)
620*8d67ca89SAndroid Build Coastguard Worker 		*success = 0;
621*8d67ca89SAndroid Build Coastguard Worker 	return (unname);
622*8d67ca89SAndroid Build Coastguard Worker }
623*8d67ca89SAndroid Build Coastguard Worker 
624*8d67ca89SAndroid Build Coastguard Worker /*
625*8d67ca89SAndroid Build Coastguard Worker  * Return a string for the type.
626*8d67ca89SAndroid Build Coastguard Worker  */
627*8d67ca89SAndroid Build Coastguard Worker const char *
p_type(int type)628*8d67ca89SAndroid Build Coastguard Worker p_type(int type) {
629*8d67ca89SAndroid Build Coastguard Worker 	int success;
630*8d67ca89SAndroid Build Coastguard Worker 	const char *result;
631*8d67ca89SAndroid Build Coastguard Worker 	static char typebuf[20];
632*8d67ca89SAndroid Build Coastguard Worker 
633*8d67ca89SAndroid Build Coastguard Worker 	result = sym_ntos(__p_type_syms, type, &success);
634*8d67ca89SAndroid Build Coastguard Worker 	if (success)
635*8d67ca89SAndroid Build Coastguard Worker 		return (result);
636*8d67ca89SAndroid Build Coastguard Worker 	if (type < 0 || type > 0xffff)
637*8d67ca89SAndroid Build Coastguard Worker 		return ("BADTYPE");
638*8d67ca89SAndroid Build Coastguard Worker 	snprintf(typebuf, sizeof(typebuf), "TYPE%d", type);
639*8d67ca89SAndroid Build Coastguard Worker 	return (typebuf);
640*8d67ca89SAndroid Build Coastguard Worker }
641*8d67ca89SAndroid Build Coastguard Worker 
642*8d67ca89SAndroid Build Coastguard Worker /*
643*8d67ca89SAndroid Build Coastguard Worker  * Return a string for the type.
644*8d67ca89SAndroid Build Coastguard Worker  */
645*8d67ca89SAndroid Build Coastguard Worker const char *
p_section(int section,int opcode)646*8d67ca89SAndroid Build Coastguard Worker p_section(int section, int opcode) {
647*8d67ca89SAndroid Build Coastguard Worker 	const struct res_sym *symbols;
648*8d67ca89SAndroid Build Coastguard Worker 
649*8d67ca89SAndroid Build Coastguard Worker 	switch (opcode) {
650*8d67ca89SAndroid Build Coastguard Worker 	case ns_o_update:
651*8d67ca89SAndroid Build Coastguard Worker 		symbols = __p_update_section_syms;
652*8d67ca89SAndroid Build Coastguard Worker 		break;
653*8d67ca89SAndroid Build Coastguard Worker 	default:
654*8d67ca89SAndroid Build Coastguard Worker 		symbols = __p_default_section_syms;
655*8d67ca89SAndroid Build Coastguard Worker 		break;
656*8d67ca89SAndroid Build Coastguard Worker 	}
657*8d67ca89SAndroid Build Coastguard Worker 	return (sym_ntos(symbols, section, (int *)0));
658*8d67ca89SAndroid Build Coastguard Worker }
659*8d67ca89SAndroid Build Coastguard Worker 
660*8d67ca89SAndroid Build Coastguard Worker /*
661*8d67ca89SAndroid Build Coastguard Worker  * Return a mnemonic for class.
662*8d67ca89SAndroid Build Coastguard Worker  */
663*8d67ca89SAndroid Build Coastguard Worker const char *
p_class(int class)664*8d67ca89SAndroid Build Coastguard Worker p_class(int class) {
665*8d67ca89SAndroid Build Coastguard Worker 	int success;
666*8d67ca89SAndroid Build Coastguard Worker 	const char *result;
667*8d67ca89SAndroid Build Coastguard Worker 	static char classbuf[20];
668*8d67ca89SAndroid Build Coastguard Worker 
669*8d67ca89SAndroid Build Coastguard Worker 	result = sym_ntos(__p_class_syms, class, &success);
670*8d67ca89SAndroid Build Coastguard Worker 	if (success)
671*8d67ca89SAndroid Build Coastguard Worker 		return (result);
672*8d67ca89SAndroid Build Coastguard Worker 	if (class < 0 || class > 0xffff)
673*8d67ca89SAndroid Build Coastguard Worker 		return ("BADCLASS");
674*8d67ca89SAndroid Build Coastguard Worker 	snprintf(classbuf, sizeof(classbuf), "CLASS%d", class);
675*8d67ca89SAndroid Build Coastguard Worker 	return (classbuf);
676*8d67ca89SAndroid Build Coastguard Worker }
677*8d67ca89SAndroid Build Coastguard Worker 
678*8d67ca89SAndroid Build Coastguard Worker /*
679*8d67ca89SAndroid Build Coastguard Worker  * Return a mnemonic for an option
680*8d67ca89SAndroid Build Coastguard Worker  */
681*8d67ca89SAndroid Build Coastguard Worker const char *
p_option(u_long option)682*8d67ca89SAndroid Build Coastguard Worker p_option(u_long option) {
683*8d67ca89SAndroid Build Coastguard Worker 	static char nbuf[40];
684*8d67ca89SAndroid Build Coastguard Worker 
685*8d67ca89SAndroid Build Coastguard Worker 	switch (option) {
686*8d67ca89SAndroid Build Coastguard Worker 	case RES_INIT:		return "init";
687*8d67ca89SAndroid Build Coastguard Worker 	case RES_DEBUG:		return "debug";
688*8d67ca89SAndroid Build Coastguard Worker 	case RES_AAONLY:	return "aaonly(unimpl)";
689*8d67ca89SAndroid Build Coastguard Worker 	case RES_USEVC:		return "usevc";
690*8d67ca89SAndroid Build Coastguard Worker 	case RES_PRIMARY:	return "primry(unimpl)";
691*8d67ca89SAndroid Build Coastguard Worker 	case RES_IGNTC:		return "igntc";
692*8d67ca89SAndroid Build Coastguard Worker 	case RES_RECURSE:	return "recurs";
693*8d67ca89SAndroid Build Coastguard Worker 	case RES_DEFNAMES:	return "defnam";
694*8d67ca89SAndroid Build Coastguard Worker 	case RES_STAYOPEN:	return "styopn";
695*8d67ca89SAndroid Build Coastguard Worker 	case RES_DNSRCH:	return "dnsrch";
696*8d67ca89SAndroid Build Coastguard Worker 	case RES_INSECURE1:	return "insecure1";
697*8d67ca89SAndroid Build Coastguard Worker 	case RES_INSECURE2:	return "insecure2";
698*8d67ca89SAndroid Build Coastguard Worker 	case RES_NOALIASES:	return "noaliases";
699*8d67ca89SAndroid Build Coastguard Worker 	case RES_USE_INET6:	return "inet6";
700*8d67ca89SAndroid Build Coastguard Worker #ifdef RES_USE_EDNS0	/* KAME extension */
701*8d67ca89SAndroid Build Coastguard Worker 	case RES_USE_EDNS0:	return "edns0";
702*8d67ca89SAndroid Build Coastguard Worker #endif
703*8d67ca89SAndroid Build Coastguard Worker #ifdef RES_USE_DNAME
704*8d67ca89SAndroid Build Coastguard Worker 	case RES_USE_DNAME:	return "dname";
705*8d67ca89SAndroid Build Coastguard Worker #endif
706*8d67ca89SAndroid Build Coastguard Worker #ifdef RES_USE_DNSSEC
707*8d67ca89SAndroid Build Coastguard Worker 	case RES_USE_DNSSEC:	return "dnssec";
708*8d67ca89SAndroid Build Coastguard Worker #endif
709*8d67ca89SAndroid Build Coastguard Worker #ifdef RES_NOTLDQUERY
710*8d67ca89SAndroid Build Coastguard Worker 	case RES_NOTLDQUERY:	return "no-tld-query";
711*8d67ca89SAndroid Build Coastguard Worker #endif
712*8d67ca89SAndroid Build Coastguard Worker #ifdef RES_NO_NIBBLE2
713*8d67ca89SAndroid Build Coastguard Worker 	case RES_NO_NIBBLE2:	return "no-nibble2";
714*8d67ca89SAndroid Build Coastguard Worker #endif
715*8d67ca89SAndroid Build Coastguard Worker 				/* XXX nonreentrant */
716*8d67ca89SAndroid Build Coastguard Worker 	default:		snprintf(nbuf, sizeof(nbuf), "?0x%lx?", (u_long)option);
717*8d67ca89SAndroid Build Coastguard Worker 				return (nbuf);
718*8d67ca89SAndroid Build Coastguard Worker 	}
719*8d67ca89SAndroid Build Coastguard Worker }
720*8d67ca89SAndroid Build Coastguard Worker 
721*8d67ca89SAndroid Build Coastguard Worker /*
722*8d67ca89SAndroid Build Coastguard Worker  * Return a mnemonic for a time to live.
723*8d67ca89SAndroid Build Coastguard Worker  */
724*8d67ca89SAndroid Build Coastguard Worker const char *
p_time(u_int32_t value)725*8d67ca89SAndroid Build Coastguard Worker p_time(u_int32_t value) {
726*8d67ca89SAndroid Build Coastguard Worker 	static char nbuf[40];		/* XXX nonreentrant */
727*8d67ca89SAndroid Build Coastguard Worker 
728*8d67ca89SAndroid Build Coastguard Worker 	if (ns_format_ttl((u_long)value, nbuf, sizeof nbuf) < 0)
729*8d67ca89SAndroid Build Coastguard Worker 		snprintf(nbuf, sizeof(nbuf), "%u", value);
730*8d67ca89SAndroid Build Coastguard Worker 	return (nbuf);
731*8d67ca89SAndroid Build Coastguard Worker }
732*8d67ca89SAndroid Build Coastguard Worker 
733*8d67ca89SAndroid Build Coastguard Worker /*
734*8d67ca89SAndroid Build Coastguard Worker  * Return a string for the rcode.
735*8d67ca89SAndroid Build Coastguard Worker  */
736*8d67ca89SAndroid Build Coastguard Worker const char *
p_rcode(int rcode)737*8d67ca89SAndroid Build Coastguard Worker p_rcode(int rcode) {
738*8d67ca89SAndroid Build Coastguard Worker 	return (sym_ntos(__p_rcode_syms, rcode, (int *)0));
739*8d67ca89SAndroid Build Coastguard Worker }
740*8d67ca89SAndroid Build Coastguard Worker 
741*8d67ca89SAndroid Build Coastguard Worker /*
742*8d67ca89SAndroid Build Coastguard Worker  * Return a string for a res_sockaddr_union.
743*8d67ca89SAndroid Build Coastguard Worker  */
744*8d67ca89SAndroid Build Coastguard Worker const char *
p_sockun(union res_sockaddr_union u,char * buf,size_t size)745*8d67ca89SAndroid Build Coastguard Worker p_sockun(union res_sockaddr_union u, char *buf, size_t size) {
746*8d67ca89SAndroid Build Coastguard Worker 	char ret[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:123.123.123.123"];
747*8d67ca89SAndroid Build Coastguard Worker 
748*8d67ca89SAndroid Build Coastguard Worker 	switch (u.sin.sin_family) {
749*8d67ca89SAndroid Build Coastguard Worker 	case AF_INET:
750*8d67ca89SAndroid Build Coastguard Worker 		inet_ntop(AF_INET, &u.sin.sin_addr, ret, (socklen_t)sizeof ret);
751*8d67ca89SAndroid Build Coastguard Worker 		break;
752*8d67ca89SAndroid Build Coastguard Worker #ifdef HAS_INET6_STRUCTS
753*8d67ca89SAndroid Build Coastguard Worker 	case AF_INET6:
754*8d67ca89SAndroid Build Coastguard Worker 		inet_ntop(AF_INET6, &u.sin6.sin6_addr, ret, sizeof ret);
755*8d67ca89SAndroid Build Coastguard Worker 		break;
756*8d67ca89SAndroid Build Coastguard Worker #endif
757*8d67ca89SAndroid Build Coastguard Worker 	default:
758*8d67ca89SAndroid Build Coastguard Worker 		snprintf(ret, sizeof(ret), "[af%d]", u.sin.sin_family);
759*8d67ca89SAndroid Build Coastguard Worker 		break;
760*8d67ca89SAndroid Build Coastguard Worker 	}
761*8d67ca89SAndroid Build Coastguard Worker 	if (size > 0U) {
762*8d67ca89SAndroid Build Coastguard Worker 		strncpy(buf, ret, size - 1);
763*8d67ca89SAndroid Build Coastguard Worker 		buf[size - 1] = '0';
764*8d67ca89SAndroid Build Coastguard Worker 	}
765*8d67ca89SAndroid Build Coastguard Worker 	return (buf);
766*8d67ca89SAndroid Build Coastguard Worker }
767*8d67ca89SAndroid Build Coastguard Worker 
768*8d67ca89SAndroid Build Coastguard Worker /*
769*8d67ca89SAndroid Build Coastguard Worker  * routines to convert between on-the-wire RR format and zone file format.
770*8d67ca89SAndroid Build Coastguard Worker  * Does not contain conversion to/from decimal degrees; divide or multiply
771*8d67ca89SAndroid Build Coastguard Worker  * by 60*60*1000 for that.
772*8d67ca89SAndroid Build Coastguard Worker  */
773*8d67ca89SAndroid Build Coastguard Worker 
774*8d67ca89SAndroid Build Coastguard Worker static const unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
775*8d67ca89SAndroid Build Coastguard Worker 				      1000000,10000000,100000000,1000000000};
776*8d67ca89SAndroid Build Coastguard Worker 
777*8d67ca89SAndroid Build Coastguard Worker /* takes an XeY precision/size value, returns a string representation. */
778*8d67ca89SAndroid Build Coastguard Worker static const char *
precsize_ntoa(u_int32_t prec)779*8d67ca89SAndroid Build Coastguard Worker precsize_ntoa(u_int32_t prec)
780*8d67ca89SAndroid Build Coastguard Worker {
781*8d67ca89SAndroid Build Coastguard Worker 	static char retbuf[sizeof "90000000.00"];	/* XXX nonreentrant */
782*8d67ca89SAndroid Build Coastguard Worker 	unsigned long val;
783*8d67ca89SAndroid Build Coastguard Worker 	int mantissa, exponent;
784*8d67ca89SAndroid Build Coastguard Worker 
785*8d67ca89SAndroid Build Coastguard Worker 	mantissa = (int)((prec >> 4) & 0x0f) % 10;
786*8d67ca89SAndroid Build Coastguard Worker 	exponent = (int)((prec >> 0) & 0x0f) % 10;
787*8d67ca89SAndroid Build Coastguard Worker 
788*8d67ca89SAndroid Build Coastguard Worker 	val = mantissa * poweroften[exponent];
789*8d67ca89SAndroid Build Coastguard Worker 
790*8d67ca89SAndroid Build Coastguard Worker 	(void) snprintf(retbuf, sizeof(retbuf), "%lu.%.2lu", val/100, val%100);
791*8d67ca89SAndroid Build Coastguard Worker 	return (retbuf);
792*8d67ca89SAndroid Build Coastguard Worker }
793*8d67ca89SAndroid Build Coastguard Worker 
794*8d67ca89SAndroid Build Coastguard Worker /* converts ascii size/precision X * 10**Y(cm) to 0xXY.  moves pointer. */
795*8d67ca89SAndroid Build Coastguard Worker static u_int8_t
precsize_aton(const char ** strptr)796*8d67ca89SAndroid Build Coastguard Worker precsize_aton(const char **strptr) {
797*8d67ca89SAndroid Build Coastguard Worker 	unsigned int mval = 0, cmval = 0;
798*8d67ca89SAndroid Build Coastguard Worker 	u_int8_t retval = 0;
799*8d67ca89SAndroid Build Coastguard Worker 	const char *cp;
800*8d67ca89SAndroid Build Coastguard Worker 	int exponent;
801*8d67ca89SAndroid Build Coastguard Worker 	int mantissa;
802*8d67ca89SAndroid Build Coastguard Worker 
803*8d67ca89SAndroid Build Coastguard Worker 	cp = *strptr;
804*8d67ca89SAndroid Build Coastguard Worker 
805*8d67ca89SAndroid Build Coastguard Worker 	while (isdigit((unsigned char)*cp))
806*8d67ca89SAndroid Build Coastguard Worker 		mval = mval * 10 + (*cp++ - '0');
807*8d67ca89SAndroid Build Coastguard Worker 
808*8d67ca89SAndroid Build Coastguard Worker 	if (*cp == '.') {		/* centimeters */
809*8d67ca89SAndroid Build Coastguard Worker 		cp++;
810*8d67ca89SAndroid Build Coastguard Worker 		if (isdigit((unsigned char)*cp)) {
811*8d67ca89SAndroid Build Coastguard Worker 			cmval = (*cp++ - '0') * 10;
812*8d67ca89SAndroid Build Coastguard Worker 			if (isdigit((unsigned char)*cp)) {
813*8d67ca89SAndroid Build Coastguard Worker 				cmval += (*cp++ - '0');
814*8d67ca89SAndroid Build Coastguard Worker 			}
815*8d67ca89SAndroid Build Coastguard Worker 		}
816*8d67ca89SAndroid Build Coastguard Worker 	}
817*8d67ca89SAndroid Build Coastguard Worker 	cmval = (mval * 100) + cmval;
818*8d67ca89SAndroid Build Coastguard Worker 
819*8d67ca89SAndroid Build Coastguard Worker 	for (exponent = 0; exponent < 9; exponent++)
820*8d67ca89SAndroid Build Coastguard Worker 		if (cmval < poweroften[exponent+1])
821*8d67ca89SAndroid Build Coastguard Worker 			break;
822*8d67ca89SAndroid Build Coastguard Worker 
823*8d67ca89SAndroid Build Coastguard Worker 	mantissa = cmval / poweroften[exponent];
824*8d67ca89SAndroid Build Coastguard Worker 	if (mantissa > 9)
825*8d67ca89SAndroid Build Coastguard Worker 		mantissa = 9;
826*8d67ca89SAndroid Build Coastguard Worker 
827*8d67ca89SAndroid Build Coastguard Worker 	retval = (mantissa << 4) | exponent;
828*8d67ca89SAndroid Build Coastguard Worker 
829*8d67ca89SAndroid Build Coastguard Worker 	*strptr = cp;
830*8d67ca89SAndroid Build Coastguard Worker 
831*8d67ca89SAndroid Build Coastguard Worker 	return (retval);
832*8d67ca89SAndroid Build Coastguard Worker }
833*8d67ca89SAndroid Build Coastguard Worker 
834*8d67ca89SAndroid Build Coastguard Worker /* converts ascii lat/lon to unsigned encoded 32-bit number.  moves pointer. */
835*8d67ca89SAndroid Build Coastguard Worker static u_int32_t
latlon2ul(const char ** latlonstrptr,int * which)836*8d67ca89SAndroid Build Coastguard Worker latlon2ul(const char **latlonstrptr, int *which) {
837*8d67ca89SAndroid Build Coastguard Worker 	const char *cp;
838*8d67ca89SAndroid Build Coastguard Worker 	u_int32_t retval;
839*8d67ca89SAndroid Build Coastguard Worker 	int deg = 0, min = 0, secs = 0, secsfrac = 0;
840*8d67ca89SAndroid Build Coastguard Worker 
841*8d67ca89SAndroid Build Coastguard Worker 	cp = *latlonstrptr;
842*8d67ca89SAndroid Build Coastguard Worker 
843*8d67ca89SAndroid Build Coastguard Worker 	while (isdigit((unsigned char)*cp))
844*8d67ca89SAndroid Build Coastguard Worker 		deg = deg * 10 + (*cp++ - '0');
845*8d67ca89SAndroid Build Coastguard Worker 
846*8d67ca89SAndroid Build Coastguard Worker 	while (isspace((unsigned char)*cp))
847*8d67ca89SAndroid Build Coastguard Worker 		cp++;
848*8d67ca89SAndroid Build Coastguard Worker 
849*8d67ca89SAndroid Build Coastguard Worker 	if (!(isdigit((unsigned char)*cp)))
850*8d67ca89SAndroid Build Coastguard Worker 		goto fndhemi;
851*8d67ca89SAndroid Build Coastguard Worker 
852*8d67ca89SAndroid Build Coastguard Worker 	while (isdigit((unsigned char)*cp))
853*8d67ca89SAndroid Build Coastguard Worker 		min = min * 10 + (*cp++ - '0');
854*8d67ca89SAndroid Build Coastguard Worker 
855*8d67ca89SAndroid Build Coastguard Worker 	while (isspace((unsigned char)*cp))
856*8d67ca89SAndroid Build Coastguard Worker 		cp++;
857*8d67ca89SAndroid Build Coastguard Worker 
858*8d67ca89SAndroid Build Coastguard Worker 	if (!(isdigit((unsigned char)*cp)))
859*8d67ca89SAndroid Build Coastguard Worker 		goto fndhemi;
860*8d67ca89SAndroid Build Coastguard Worker 
861*8d67ca89SAndroid Build Coastguard Worker 	while (isdigit((unsigned char)*cp))
862*8d67ca89SAndroid Build Coastguard Worker 		secs = secs * 10 + (*cp++ - '0');
863*8d67ca89SAndroid Build Coastguard Worker 
864*8d67ca89SAndroid Build Coastguard Worker 	if (*cp == '.') {		/* decimal seconds */
865*8d67ca89SAndroid Build Coastguard Worker 		cp++;
866*8d67ca89SAndroid Build Coastguard Worker 		if (isdigit((unsigned char)*cp)) {
867*8d67ca89SAndroid Build Coastguard Worker 			secsfrac = (*cp++ - '0') * 100;
868*8d67ca89SAndroid Build Coastguard Worker 			if (isdigit((unsigned char)*cp)) {
869*8d67ca89SAndroid Build Coastguard Worker 				secsfrac += (*cp++ - '0') * 10;
870*8d67ca89SAndroid Build Coastguard Worker 				if (isdigit((unsigned char)*cp)) {
871*8d67ca89SAndroid Build Coastguard Worker 					secsfrac += (*cp++ - '0');
872*8d67ca89SAndroid Build Coastguard Worker 				}
873*8d67ca89SAndroid Build Coastguard Worker 			}
874*8d67ca89SAndroid Build Coastguard Worker 		}
875*8d67ca89SAndroid Build Coastguard Worker 	}
876*8d67ca89SAndroid Build Coastguard Worker 
877*8d67ca89SAndroid Build Coastguard Worker 	while (!isspace((unsigned char)*cp))	/* if any trailing garbage */
878*8d67ca89SAndroid Build Coastguard Worker 		cp++;
879*8d67ca89SAndroid Build Coastguard Worker 
880*8d67ca89SAndroid Build Coastguard Worker 	while (isspace((unsigned char)*cp))
881*8d67ca89SAndroid Build Coastguard Worker 		cp++;
882*8d67ca89SAndroid Build Coastguard Worker 
883*8d67ca89SAndroid Build Coastguard Worker  fndhemi:
884*8d67ca89SAndroid Build Coastguard Worker 	switch (*cp) {
885*8d67ca89SAndroid Build Coastguard Worker 	case 'N': case 'n':
886*8d67ca89SAndroid Build Coastguard Worker 	case 'E': case 'e':
887*8d67ca89SAndroid Build Coastguard Worker 		retval = ((unsigned)1<<31)
888*8d67ca89SAndroid Build Coastguard Worker 			+ (((((deg * 60) + min) * 60) + secs) * 1000)
889*8d67ca89SAndroid Build Coastguard Worker 			+ secsfrac;
890*8d67ca89SAndroid Build Coastguard Worker 		break;
891*8d67ca89SAndroid Build Coastguard Worker 	case 'S': case 's':
892*8d67ca89SAndroid Build Coastguard Worker 	case 'W': case 'w':
893*8d67ca89SAndroid Build Coastguard Worker 		retval = ((unsigned)1<<31)
894*8d67ca89SAndroid Build Coastguard Worker 			- (((((deg * 60) + min) * 60) + secs) * 1000)
895*8d67ca89SAndroid Build Coastguard Worker 			- secsfrac;
896*8d67ca89SAndroid Build Coastguard Worker 		break;
897*8d67ca89SAndroid Build Coastguard Worker 	default:
898*8d67ca89SAndroid Build Coastguard Worker 		retval = 0;	/* invalid value -- indicates error */
899*8d67ca89SAndroid Build Coastguard Worker 		break;
900*8d67ca89SAndroid Build Coastguard Worker 	}
901*8d67ca89SAndroid Build Coastguard Worker 
902*8d67ca89SAndroid Build Coastguard Worker 	switch (*cp) {
903*8d67ca89SAndroid Build Coastguard Worker 	case 'N': case 'n':
904*8d67ca89SAndroid Build Coastguard Worker 	case 'S': case 's':
905*8d67ca89SAndroid Build Coastguard Worker 		*which = 1;	/* latitude */
906*8d67ca89SAndroid Build Coastguard Worker 		break;
907*8d67ca89SAndroid Build Coastguard Worker 	case 'E': case 'e':
908*8d67ca89SAndroid Build Coastguard Worker 	case 'W': case 'w':
909*8d67ca89SAndroid Build Coastguard Worker 		*which = 2;	/* longitude */
910*8d67ca89SAndroid Build Coastguard Worker 		break;
911*8d67ca89SAndroid Build Coastguard Worker 	default:
912*8d67ca89SAndroid Build Coastguard Worker 		*which = 0;	/* error */
913*8d67ca89SAndroid Build Coastguard Worker 		break;
914*8d67ca89SAndroid Build Coastguard Worker 	}
915*8d67ca89SAndroid Build Coastguard Worker 
916*8d67ca89SAndroid Build Coastguard Worker 	cp++;			/* skip the hemisphere */
917*8d67ca89SAndroid Build Coastguard Worker 
918*8d67ca89SAndroid Build Coastguard Worker 	while (!isspace((unsigned char)*cp))	/* if any trailing garbage */
919*8d67ca89SAndroid Build Coastguard Worker 		cp++;
920*8d67ca89SAndroid Build Coastguard Worker 
921*8d67ca89SAndroid Build Coastguard Worker 	while (isspace((unsigned char)*cp))	/* move to next field */
922*8d67ca89SAndroid Build Coastguard Worker 		cp++;
923*8d67ca89SAndroid Build Coastguard Worker 
924*8d67ca89SAndroid Build Coastguard Worker 	*latlonstrptr = cp;
925*8d67ca89SAndroid Build Coastguard Worker 
926*8d67ca89SAndroid Build Coastguard Worker 	return (retval);
927*8d67ca89SAndroid Build Coastguard Worker }
928*8d67ca89SAndroid Build Coastguard Worker 
929*8d67ca89SAndroid Build Coastguard Worker /* converts a zone file representation in a string to an RDATA on-the-wire
930*8d67ca89SAndroid Build Coastguard Worker  * representation. */
931*8d67ca89SAndroid Build Coastguard Worker int
loc_aton(const char * ascii,u_char * binary)932*8d67ca89SAndroid Build Coastguard Worker loc_aton(const char *ascii, u_char *binary)
933*8d67ca89SAndroid Build Coastguard Worker {
934*8d67ca89SAndroid Build Coastguard Worker 	const char *cp, *maxcp;
935*8d67ca89SAndroid Build Coastguard Worker 	u_char *bcp;
936*8d67ca89SAndroid Build Coastguard Worker 
937*8d67ca89SAndroid Build Coastguard Worker 	u_int32_t latit = 0, longit = 0, alt = 0;
938*8d67ca89SAndroid Build Coastguard Worker 	u_int32_t lltemp1 = 0, lltemp2 = 0;
939*8d67ca89SAndroid Build Coastguard Worker 	int altmeters = 0, altfrac = 0, altsign = 1;
940*8d67ca89SAndroid Build Coastguard Worker 	u_int8_t hp = 0x16;	/* default = 1e6 cm = 10000.00m = 10km */
941*8d67ca89SAndroid Build Coastguard Worker 	u_int8_t vp = 0x13;	/* default = 1e3 cm = 10.00m */
942*8d67ca89SAndroid Build Coastguard Worker 	u_int8_t siz = 0x12;	/* default = 1e2 cm = 1.00m */
943*8d67ca89SAndroid Build Coastguard Worker 	int which1 = 0, which2 = 0;
944*8d67ca89SAndroid Build Coastguard Worker 
945*8d67ca89SAndroid Build Coastguard Worker 	cp = ascii;
946*8d67ca89SAndroid Build Coastguard Worker 	maxcp = cp + strlen(ascii);
947*8d67ca89SAndroid Build Coastguard Worker 
948*8d67ca89SAndroid Build Coastguard Worker 	lltemp1 = latlon2ul(&cp, &which1);
949*8d67ca89SAndroid Build Coastguard Worker 
950*8d67ca89SAndroid Build Coastguard Worker 	lltemp2 = latlon2ul(&cp, &which2);
951*8d67ca89SAndroid Build Coastguard Worker 
952*8d67ca89SAndroid Build Coastguard Worker 	switch (which1 + which2) {
953*8d67ca89SAndroid Build Coastguard Worker 	case 3:			/* 1 + 2, the only valid combination */
954*8d67ca89SAndroid Build Coastguard Worker 		if ((which1 == 1) && (which2 == 2)) { /* normal case */
955*8d67ca89SAndroid Build Coastguard Worker 			latit = lltemp1;
956*8d67ca89SAndroid Build Coastguard Worker 			longit = lltemp2;
957*8d67ca89SAndroid Build Coastguard Worker 		} else if ((which1 == 2) && (which2 == 1)) { /* reversed */
958*8d67ca89SAndroid Build Coastguard Worker 			longit = lltemp1;
959*8d67ca89SAndroid Build Coastguard Worker 			latit = lltemp2;
960*8d67ca89SAndroid Build Coastguard Worker 		} else {	/* some kind of brokenness */
961*8d67ca89SAndroid Build Coastguard Worker 			return (0);
962*8d67ca89SAndroid Build Coastguard Worker 		}
963*8d67ca89SAndroid Build Coastguard Worker 		break;
964*8d67ca89SAndroid Build Coastguard Worker 	default:		/* we didn't get one of each */
965*8d67ca89SAndroid Build Coastguard Worker 		return (0);
966*8d67ca89SAndroid Build Coastguard Worker 	}
967*8d67ca89SAndroid Build Coastguard Worker 
968*8d67ca89SAndroid Build Coastguard Worker 	/* altitude */
969*8d67ca89SAndroid Build Coastguard Worker 	if (*cp == '-') {
970*8d67ca89SAndroid Build Coastguard Worker 		altsign = -1;
971*8d67ca89SAndroid Build Coastguard Worker 		cp++;
972*8d67ca89SAndroid Build Coastguard Worker 	}
973*8d67ca89SAndroid Build Coastguard Worker 
974*8d67ca89SAndroid Build Coastguard Worker 	if (*cp == '+')
975*8d67ca89SAndroid Build Coastguard Worker 		cp++;
976*8d67ca89SAndroid Build Coastguard Worker 
977*8d67ca89SAndroid Build Coastguard Worker 	while (isdigit((unsigned char)*cp))
978*8d67ca89SAndroid Build Coastguard Worker 		altmeters = altmeters * 10 + (*cp++ - '0');
979*8d67ca89SAndroid Build Coastguard Worker 
980*8d67ca89SAndroid Build Coastguard Worker 	if (*cp == '.') {		/* decimal meters */
981*8d67ca89SAndroid Build Coastguard Worker 		cp++;
982*8d67ca89SAndroid Build Coastguard Worker 		if (isdigit((unsigned char)*cp)) {
983*8d67ca89SAndroid Build Coastguard Worker 			altfrac = (*cp++ - '0') * 10;
984*8d67ca89SAndroid Build Coastguard Worker 			if (isdigit((unsigned char)*cp)) {
985*8d67ca89SAndroid Build Coastguard Worker 				altfrac += (*cp++ - '0');
986*8d67ca89SAndroid Build Coastguard Worker 			}
987*8d67ca89SAndroid Build Coastguard Worker 		}
988*8d67ca89SAndroid Build Coastguard Worker 	}
989*8d67ca89SAndroid Build Coastguard Worker 
990*8d67ca89SAndroid Build Coastguard Worker 	alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
991*8d67ca89SAndroid Build Coastguard Worker 
992*8d67ca89SAndroid Build Coastguard Worker 	while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
993*8d67ca89SAndroid Build Coastguard Worker 		cp++;
994*8d67ca89SAndroid Build Coastguard Worker 
995*8d67ca89SAndroid Build Coastguard Worker 	while (isspace((unsigned char)*cp) && (cp < maxcp))
996*8d67ca89SAndroid Build Coastguard Worker 		cp++;
997*8d67ca89SAndroid Build Coastguard Worker 
998*8d67ca89SAndroid Build Coastguard Worker 	if (cp >= maxcp)
999*8d67ca89SAndroid Build Coastguard Worker 		goto defaults;
1000*8d67ca89SAndroid Build Coastguard Worker 
1001*8d67ca89SAndroid Build Coastguard Worker 	siz = precsize_aton(&cp);
1002*8d67ca89SAndroid Build Coastguard Worker 
1003*8d67ca89SAndroid Build Coastguard Worker 	while (!isspace((unsigned char)*cp) && (cp < maxcp))	/* if trailing garbage or m */
1004*8d67ca89SAndroid Build Coastguard Worker 		cp++;
1005*8d67ca89SAndroid Build Coastguard Worker 
1006*8d67ca89SAndroid Build Coastguard Worker 	while (isspace((unsigned char)*cp) && (cp < maxcp))
1007*8d67ca89SAndroid Build Coastguard Worker 		cp++;
1008*8d67ca89SAndroid Build Coastguard Worker 
1009*8d67ca89SAndroid Build Coastguard Worker 	if (cp >= maxcp)
1010*8d67ca89SAndroid Build Coastguard Worker 		goto defaults;
1011*8d67ca89SAndroid Build Coastguard Worker 
1012*8d67ca89SAndroid Build Coastguard Worker 	hp = precsize_aton(&cp);
1013*8d67ca89SAndroid Build Coastguard Worker 
1014*8d67ca89SAndroid Build Coastguard Worker 	while (!isspace((unsigned char)*cp) && (cp < maxcp))	/* if trailing garbage or m */
1015*8d67ca89SAndroid Build Coastguard Worker 		cp++;
1016*8d67ca89SAndroid Build Coastguard Worker 
1017*8d67ca89SAndroid Build Coastguard Worker 	while (isspace((unsigned char)*cp) && (cp < maxcp))
1018*8d67ca89SAndroid Build Coastguard Worker 		cp++;
1019*8d67ca89SAndroid Build Coastguard Worker 
1020*8d67ca89SAndroid Build Coastguard Worker 	if (cp >= maxcp)
1021*8d67ca89SAndroid Build Coastguard Worker 		goto defaults;
1022*8d67ca89SAndroid Build Coastguard Worker 
1023*8d67ca89SAndroid Build Coastguard Worker 	vp = precsize_aton(&cp);
1024*8d67ca89SAndroid Build Coastguard Worker 
1025*8d67ca89SAndroid Build Coastguard Worker  defaults:
1026*8d67ca89SAndroid Build Coastguard Worker 
1027*8d67ca89SAndroid Build Coastguard Worker 	bcp = binary;
1028*8d67ca89SAndroid Build Coastguard Worker 	*bcp++ = (u_int8_t) 0;	/* version byte */
1029*8d67ca89SAndroid Build Coastguard Worker 	*bcp++ = siz;
1030*8d67ca89SAndroid Build Coastguard Worker 	*bcp++ = hp;
1031*8d67ca89SAndroid Build Coastguard Worker 	*bcp++ = vp;
1032*8d67ca89SAndroid Build Coastguard Worker 	PUTLONG(latit,bcp);
1033*8d67ca89SAndroid Build Coastguard Worker 	PUTLONG(longit,bcp);
1034*8d67ca89SAndroid Build Coastguard Worker 	PUTLONG(alt,bcp);
1035*8d67ca89SAndroid Build Coastguard Worker 
1036*8d67ca89SAndroid Build Coastguard Worker 	return (16);		/* size of RR in octets */
1037*8d67ca89SAndroid Build Coastguard Worker }
1038*8d67ca89SAndroid Build Coastguard Worker 
1039*8d67ca89SAndroid Build Coastguard Worker /* takes an on-the-wire LOC RR and formats it in a human readable format. */
1040*8d67ca89SAndroid Build Coastguard Worker const char *
loc_ntoa(const u_char * binary,char * ascii,size_t bufsiz)1041*8d67ca89SAndroid Build Coastguard Worker loc_ntoa(const u_char *binary, char *ascii, size_t bufsiz)
1042*8d67ca89SAndroid Build Coastguard Worker {
1043*8d67ca89SAndroid Build Coastguard Worker 	static const char *error = "?";
1044*8d67ca89SAndroid Build Coastguard Worker 	static char tmpbuf[sizeof
1045*8d67ca89SAndroid Build Coastguard Worker "1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
1046*8d67ca89SAndroid Build Coastguard Worker 	const u_char *cp = binary;
1047*8d67ca89SAndroid Build Coastguard Worker 
1048*8d67ca89SAndroid Build Coastguard Worker 	int latdeg, latmin, latsec, latsecfrac;
1049*8d67ca89SAndroid Build Coastguard Worker 	int longdeg, longmin, longsec, longsecfrac;
1050*8d67ca89SAndroid Build Coastguard Worker 	char northsouth, eastwest;
1051*8d67ca89SAndroid Build Coastguard Worker 	const char *altsign;
1052*8d67ca89SAndroid Build Coastguard Worker 	int altmeters, altfrac;
1053*8d67ca89SAndroid Build Coastguard Worker 
1054*8d67ca89SAndroid Build Coastguard Worker 	const u_int32_t referencealt = 100000 * 100;
1055*8d67ca89SAndroid Build Coastguard Worker 
1056*8d67ca89SAndroid Build Coastguard Worker 	int32_t latval, longval, altval;
1057*8d67ca89SAndroid Build Coastguard Worker 	u_int32_t templ;
1058*8d67ca89SAndroid Build Coastguard Worker 	u_int8_t sizeval, hpval, vpval, versionval;
1059*8d67ca89SAndroid Build Coastguard Worker 
1060*8d67ca89SAndroid Build Coastguard Worker 	char *sizestr, *hpstr, *vpstr;
1061*8d67ca89SAndroid Build Coastguard Worker 
1062*8d67ca89SAndroid Build Coastguard Worker 	versionval = *cp++;
1063*8d67ca89SAndroid Build Coastguard Worker 
1064*8d67ca89SAndroid Build Coastguard Worker 	if (ascii == NULL)
1065*8d67ca89SAndroid Build Coastguard Worker 		ascii = tmpbuf;
1066*8d67ca89SAndroid Build Coastguard Worker 
1067*8d67ca89SAndroid Build Coastguard Worker 	if (versionval) {
1068*8d67ca89SAndroid Build Coastguard Worker 		(void) snprintf(ascii, bufsiz, "; error: unknown LOC RR version");
1069*8d67ca89SAndroid Build Coastguard Worker 		return (ascii);
1070*8d67ca89SAndroid Build Coastguard Worker 	}
1071*8d67ca89SAndroid Build Coastguard Worker 
1072*8d67ca89SAndroid Build Coastguard Worker 	sizeval = *cp++;
1073*8d67ca89SAndroid Build Coastguard Worker 
1074*8d67ca89SAndroid Build Coastguard Worker 	hpval = *cp++;
1075*8d67ca89SAndroid Build Coastguard Worker 	vpval = *cp++;
1076*8d67ca89SAndroid Build Coastguard Worker 
1077*8d67ca89SAndroid Build Coastguard Worker 	GETLONG(templ, cp);
1078*8d67ca89SAndroid Build Coastguard Worker 	latval = (templ - ((unsigned)1<<31));
1079*8d67ca89SAndroid Build Coastguard Worker 
1080*8d67ca89SAndroid Build Coastguard Worker 	GETLONG(templ, cp);
1081*8d67ca89SAndroid Build Coastguard Worker 	longval = (templ - ((unsigned)1<<31));
1082*8d67ca89SAndroid Build Coastguard Worker 
1083*8d67ca89SAndroid Build Coastguard Worker 	GETLONG(templ, cp);
1084*8d67ca89SAndroid Build Coastguard Worker 	if (templ < referencealt) { /* below WGS 84 spheroid */
1085*8d67ca89SAndroid Build Coastguard Worker 		altval = referencealt - templ;
1086*8d67ca89SAndroid Build Coastguard Worker 		altsign = "-";
1087*8d67ca89SAndroid Build Coastguard Worker 	} else {
1088*8d67ca89SAndroid Build Coastguard Worker 		altval = templ - referencealt;
1089*8d67ca89SAndroid Build Coastguard Worker 		altsign = "";
1090*8d67ca89SAndroid Build Coastguard Worker 	}
1091*8d67ca89SAndroid Build Coastguard Worker 
1092*8d67ca89SAndroid Build Coastguard Worker 	if (latval < 0) {
1093*8d67ca89SAndroid Build Coastguard Worker 		northsouth = 'S';
1094*8d67ca89SAndroid Build Coastguard Worker 		latval = -latval;
1095*8d67ca89SAndroid Build Coastguard Worker 	} else
1096*8d67ca89SAndroid Build Coastguard Worker 		northsouth = 'N';
1097*8d67ca89SAndroid Build Coastguard Worker 
1098*8d67ca89SAndroid Build Coastguard Worker 	latsecfrac = latval % 1000;
1099*8d67ca89SAndroid Build Coastguard Worker 	latval = latval / 1000;
1100*8d67ca89SAndroid Build Coastguard Worker 	latsec = latval % 60;
1101*8d67ca89SAndroid Build Coastguard Worker 	latval = latval / 60;
1102*8d67ca89SAndroid Build Coastguard Worker 	latmin = latval % 60;
1103*8d67ca89SAndroid Build Coastguard Worker 	latval = latval / 60;
1104*8d67ca89SAndroid Build Coastguard Worker 	latdeg = latval;
1105*8d67ca89SAndroid Build Coastguard Worker 
1106*8d67ca89SAndroid Build Coastguard Worker 	if (longval < 0) {
1107*8d67ca89SAndroid Build Coastguard Worker 		eastwest = 'W';
1108*8d67ca89SAndroid Build Coastguard Worker 		longval = -longval;
1109*8d67ca89SAndroid Build Coastguard Worker 	} else
1110*8d67ca89SAndroid Build Coastguard Worker 		eastwest = 'E';
1111*8d67ca89SAndroid Build Coastguard Worker 
1112*8d67ca89SAndroid Build Coastguard Worker 	longsecfrac = longval % 1000;
1113*8d67ca89SAndroid Build Coastguard Worker 	longval = longval / 1000;
1114*8d67ca89SAndroid Build Coastguard Worker 	longsec = longval % 60;
1115*8d67ca89SAndroid Build Coastguard Worker 	longval = longval / 60;
1116*8d67ca89SAndroid Build Coastguard Worker 	longmin = longval % 60;
1117*8d67ca89SAndroid Build Coastguard Worker 	longval = longval / 60;
1118*8d67ca89SAndroid Build Coastguard Worker 	longdeg = longval;
1119*8d67ca89SAndroid Build Coastguard Worker 
1120*8d67ca89SAndroid Build Coastguard Worker 	altfrac = altval % 100;
1121*8d67ca89SAndroid Build Coastguard Worker 	altmeters = (altval / 100);
1122*8d67ca89SAndroid Build Coastguard Worker 
1123*8d67ca89SAndroid Build Coastguard Worker 	sizestr = strdup(precsize_ntoa((u_int32_t)sizeval));
1124*8d67ca89SAndroid Build Coastguard Worker 	hpstr = strdup(precsize_ntoa((u_int32_t)hpval));
1125*8d67ca89SAndroid Build Coastguard Worker 	vpstr = strdup(precsize_ntoa((u_int32_t)vpval));
1126*8d67ca89SAndroid Build Coastguard Worker 
1127*8d67ca89SAndroid Build Coastguard Worker 	snprintf(ascii, bufsiz,
1128*8d67ca89SAndroid Build Coastguard Worker 	    "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm",
1129*8d67ca89SAndroid Build Coastguard Worker 		latdeg, latmin, latsec, latsecfrac, northsouth,
1130*8d67ca89SAndroid Build Coastguard Worker 		longdeg, longmin, longsec, longsecfrac, eastwest,
1131*8d67ca89SAndroid Build Coastguard Worker 		altsign, altmeters, altfrac,
1132*8d67ca89SAndroid Build Coastguard Worker 		(sizestr != NULL) ? sizestr : error,
1133*8d67ca89SAndroid Build Coastguard Worker 		(hpstr != NULL) ? hpstr : error,
1134*8d67ca89SAndroid Build Coastguard Worker 		(vpstr != NULL) ? vpstr : error);
1135*8d67ca89SAndroid Build Coastguard Worker 
1136*8d67ca89SAndroid Build Coastguard Worker 	if (sizestr != NULL)
1137*8d67ca89SAndroid Build Coastguard Worker 		free(sizestr);
1138*8d67ca89SAndroid Build Coastguard Worker 	if (hpstr != NULL)
1139*8d67ca89SAndroid Build Coastguard Worker 		free(hpstr);
1140*8d67ca89SAndroid Build Coastguard Worker 	if (vpstr != NULL)
1141*8d67ca89SAndroid Build Coastguard Worker 		free(vpstr);
1142*8d67ca89SAndroid Build Coastguard Worker 
1143*8d67ca89SAndroid Build Coastguard Worker 	return (ascii);
1144*8d67ca89SAndroid Build Coastguard Worker }
1145*8d67ca89SAndroid Build Coastguard Worker 
1146*8d67ca89SAndroid Build Coastguard Worker 
1147*8d67ca89SAndroid Build Coastguard Worker /* Return the number of DNS hierarchy levels in the name. */
1148*8d67ca89SAndroid Build Coastguard Worker int
dn_count_labels(const char * name)1149*8d67ca89SAndroid Build Coastguard Worker dn_count_labels(const char *name) {
1150*8d67ca89SAndroid Build Coastguard Worker 	size_t len, i, count;
1151*8d67ca89SAndroid Build Coastguard Worker 
1152*8d67ca89SAndroid Build Coastguard Worker 	len = strlen(name);
1153*8d67ca89SAndroid Build Coastguard Worker 	for (i = 0, count = 0; i < len; i++) {
1154*8d67ca89SAndroid Build Coastguard Worker 		/* XXX need to check for \. or use named's nlabels(). */
1155*8d67ca89SAndroid Build Coastguard Worker 		if (name[i] == '.')
1156*8d67ca89SAndroid Build Coastguard Worker 			count++;
1157*8d67ca89SAndroid Build Coastguard Worker 	}
1158*8d67ca89SAndroid Build Coastguard Worker 
1159*8d67ca89SAndroid Build Coastguard Worker 	/* don't count initial wildcard */
1160*8d67ca89SAndroid Build Coastguard Worker 	if (name[0] == '*')
1161*8d67ca89SAndroid Build Coastguard Worker 		if (count)
1162*8d67ca89SAndroid Build Coastguard Worker 			count--;
1163*8d67ca89SAndroid Build Coastguard Worker 
1164*8d67ca89SAndroid Build Coastguard Worker 	/* don't count the null label for root. */
1165*8d67ca89SAndroid Build Coastguard Worker 	/* if terminating '.' not found, must adjust */
1166*8d67ca89SAndroid Build Coastguard Worker 	/* count to include last label */
1167*8d67ca89SAndroid Build Coastguard Worker 	if (len > 0 && name[len-1] != '.')
1168*8d67ca89SAndroid Build Coastguard Worker 		count++;
1169*8d67ca89SAndroid Build Coastguard Worker 	_DIAGASSERT(__type_fit(int, count));
1170*8d67ca89SAndroid Build Coastguard Worker 	return (int)count;
1171*8d67ca89SAndroid Build Coastguard Worker }
1172*8d67ca89SAndroid Build Coastguard Worker 
1173*8d67ca89SAndroid Build Coastguard Worker 
1174*8d67ca89SAndroid Build Coastguard Worker /*
1175*8d67ca89SAndroid Build Coastguard Worker  * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1176*8d67ca89SAndroid Build Coastguard Worker  * SIG records are required to be printed like this, by the Secure DNS RFC.
1177*8d67ca89SAndroid Build Coastguard Worker  */
1178*8d67ca89SAndroid Build Coastguard Worker char *
p_secstodate(u_long secs)1179*8d67ca89SAndroid Build Coastguard Worker p_secstodate (u_long secs) {
1180*8d67ca89SAndroid Build Coastguard Worker 	/* XXX nonreentrant */
1181*8d67ca89SAndroid Build Coastguard Worker 	static char output[15];		/* YYYYMMDDHHMMSS and null */
1182*8d67ca89SAndroid Build Coastguard Worker 	time_t myclock = secs;
1183*8d67ca89SAndroid Build Coastguard Worker 	struct tm *mytime;
1184*8d67ca89SAndroid Build Coastguard Worker #ifdef HAVE_TIME_R
1185*8d67ca89SAndroid Build Coastguard Worker 	struct tm res;
1186*8d67ca89SAndroid Build Coastguard Worker 
1187*8d67ca89SAndroid Build Coastguard Worker 	mytime = gmtime_r(&myclock, &res);
1188*8d67ca89SAndroid Build Coastguard Worker #else
1189*8d67ca89SAndroid Build Coastguard Worker 	mytime = gmtime(&myclock);
1190*8d67ca89SAndroid Build Coastguard Worker #endif
1191*8d67ca89SAndroid Build Coastguard Worker 	mytime->tm_year += 1900;
1192*8d67ca89SAndroid Build Coastguard Worker 	mytime->tm_mon += 1;
1193*8d67ca89SAndroid Build Coastguard Worker 	snprintf(output, sizeof(output), "%04d%02d%02d%02d%02d%02d",
1194*8d67ca89SAndroid Build Coastguard Worker 		mytime->tm_year, mytime->tm_mon, mytime->tm_mday,
1195*8d67ca89SAndroid Build Coastguard Worker 		mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
1196*8d67ca89SAndroid Build Coastguard Worker 	return (output);
1197*8d67ca89SAndroid Build Coastguard Worker }
1198*8d67ca89SAndroid Build Coastguard Worker 
1199*8d67ca89SAndroid Build Coastguard Worker u_int16_t
res_nametoclass(const char * buf,int * successp)1200*8d67ca89SAndroid Build Coastguard Worker res_nametoclass(const char *buf, int *successp) {
1201*8d67ca89SAndroid Build Coastguard Worker 	unsigned long result;
1202*8d67ca89SAndroid Build Coastguard Worker 	char *endptr;
1203*8d67ca89SAndroid Build Coastguard Worker 	int success;
1204*8d67ca89SAndroid Build Coastguard Worker 
1205*8d67ca89SAndroid Build Coastguard Worker 	result = sym_ston(__p_class_syms, buf, &success);
1206*8d67ca89SAndroid Build Coastguard Worker 	if (success)
1207*8d67ca89SAndroid Build Coastguard Worker 		goto done;
1208*8d67ca89SAndroid Build Coastguard Worker 
1209*8d67ca89SAndroid Build Coastguard Worker 	if (strncasecmp(buf, "CLASS", 5) != 0 ||
1210*8d67ca89SAndroid Build Coastguard Worker 	    !isdigit((unsigned char)buf[5]))
1211*8d67ca89SAndroid Build Coastguard Worker 		goto done;
1212*8d67ca89SAndroid Build Coastguard Worker 	errno = 0;
1213*8d67ca89SAndroid Build Coastguard Worker 	result = strtoul(buf + 5, &endptr, 10);
1214*8d67ca89SAndroid Build Coastguard Worker 	if (errno == 0 && *endptr == '\0' && result <= 0xffffU)
1215*8d67ca89SAndroid Build Coastguard Worker 		success = 1;
1216*8d67ca89SAndroid Build Coastguard Worker  done:
1217*8d67ca89SAndroid Build Coastguard Worker 	if (successp)
1218*8d67ca89SAndroid Build Coastguard Worker 		*successp = success;
1219*8d67ca89SAndroid Build Coastguard Worker 	return (u_int16_t)(result);
1220*8d67ca89SAndroid Build Coastguard Worker }
1221*8d67ca89SAndroid Build Coastguard Worker 
1222*8d67ca89SAndroid Build Coastguard Worker u_int16_t
res_nametotype(const char * buf,int * successp)1223*8d67ca89SAndroid Build Coastguard Worker res_nametotype(const char *buf, int *successp) {
1224*8d67ca89SAndroid Build Coastguard Worker 	unsigned long result;
1225*8d67ca89SAndroid Build Coastguard Worker 	char *endptr;
1226*8d67ca89SAndroid Build Coastguard Worker 	int success;
1227*8d67ca89SAndroid Build Coastguard Worker 
1228*8d67ca89SAndroid Build Coastguard Worker 	result = sym_ston(__p_type_syms, buf, &success);
1229*8d67ca89SAndroid Build Coastguard Worker 	if (success)
1230*8d67ca89SAndroid Build Coastguard Worker 		goto done;
1231*8d67ca89SAndroid Build Coastguard Worker 
1232*8d67ca89SAndroid Build Coastguard Worker 	if (strncasecmp(buf, "type", 4) != 0 ||
1233*8d67ca89SAndroid Build Coastguard Worker 	    !isdigit((unsigned char)buf[4]))
1234*8d67ca89SAndroid Build Coastguard Worker 		goto done;
1235*8d67ca89SAndroid Build Coastguard Worker 	errno = 0;
1236*8d67ca89SAndroid Build Coastguard Worker 	result = strtoul(buf + 4, &endptr, 10);
1237*8d67ca89SAndroid Build Coastguard Worker 	if (errno == 0 && *endptr == '\0' && result <= 0xffffU)
1238*8d67ca89SAndroid Build Coastguard Worker 		success = 1;
1239*8d67ca89SAndroid Build Coastguard Worker  done:
1240*8d67ca89SAndroid Build Coastguard Worker 	if (successp)
1241*8d67ca89SAndroid Build Coastguard Worker 		*successp = success;
1242*8d67ca89SAndroid Build Coastguard Worker 	return (u_int16_t)(result);
1243*8d67ca89SAndroid Build Coastguard Worker }
1244