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