summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/res_debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/net/res_debug.c')
-rw-r--r--src/lib/libc/net/res_debug.c1524
1 files changed, 1170 insertions, 354 deletions
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
index d841293f18..b39e9a3b14 100644
--- a/src/lib/libc/net/res_debug.c
+++ b/src/lib/libc/net/res_debug.c
@@ -1,9 +1,11 @@
1/* $NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $ */ 1/* $OpenBSD: res_debug.c,v 1.16 2003/03/04 00:29:17 itojun Exp $ */
2 2
3/*- 3/*
4 * ++Copyright++ 1985, 1990, 1993
5 * -
4 * Copyright (c) 1985, 1990, 1993 6 * Copyright (c) 1985, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
6 * 8 *
7 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
9 * are met: 11 * are met:
@@ -50,174 +52,194 @@
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 52 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51 * SOFTWARE. 53 * SOFTWARE.
52 * - 54 * -
55 * Portions Copyright (c) 1995 by International Business Machines, Inc.
56 *
57 * International Business Machines, Inc. (hereinafter called IBM) grants
58 * permission under its copyrights to use, copy, modify, and distribute this
59 * Software with or without fee, provided that the above copyright notice and
60 * all paragraphs of this notice appear in all copies, and that the name of IBM
61 * not be used in connection with the marketing of any product incorporating
62 * the Software or modifications thereof, without specific, written prior
63 * permission.
64 *
65 * To the extent it has a right to do so, IBM grants an immunity from suit
66 * under its patents, if any, for the use, sale or manufacture of products to
67 * the extent that such products are used for performing Domain Name System
68 * dynamic updates in TCP/IP networks by means of the Software. No immunity is
69 * granted for any product per se or for any other function of any product.
70 *
71 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
72 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
73 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
74 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
75 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
76 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
53 * --Copyright-- 77 * --Copyright--
54 */ 78 */
55 79
56#if defined(LIBC_SCCS) && !defined(lint) 80#if defined(LIBC_SCCS) && !defined(lint)
57#if 0 81#if 0
58static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; 82static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
83static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $";
59#else 84#else
60static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $"; 85static char rcsid[] = "$OpenBSD: res_debug.c,v 1.16 2003/03/04 00:29:17 itojun Exp $";
61#endif 86#endif
62#endif /* LIBC_SCCS and not lint */ 87#endif /* LIBC_SCCS and not lint */
63 88
64#include <sys/param.h> 89#include <sys/param.h>
90#include <sys/types.h>
91#include <sys/socket.h>
65#include <netinet/in.h> 92#include <netinet/in.h>
66#include <arpa/inet.h> 93#include <arpa/inet.h>
67#include <arpa/nameser.h> 94#include <arpa/nameser.h>
95
96#include <ctype.h>
97#include <netdb.h>
68#include <resolv.h> 98#include <resolv.h>
69#include <stdio.h> 99#include <stdio.h>
100#include <time.h>
101
102#include <stdlib.h>
70#include <string.h> 103#include <string.h>
71 104
72void __fp_query(); 105#include "thread_private.h"
73char *__p_class(), *__p_time(), *__p_type();
74char *p_cdname(), *p_fqname(), *p_rr();
75static char *p_option __P((u_int32_t));
76
77char *_res_opcodes[] = {
78 "QUERY",
79 "IQUERY",
80 "CQUERYM",
81 "CQUERYU",
82 "4",
83 "5",
84 "6",
85 "7",
86 "8",
87 "UPDATEA",
88 "UPDATED",
89 "UPDATEDA",
90 "UPDATEM",
91 "UPDATEMA",
92 "ZONEINIT",
93 "ZONEREF",
94};
95 106
96char *_res_resultcodes[] = { 107extern const char *_res_opcodes[];
97 "NOERROR", 108extern const char *_res_resultcodes[];
98 "FORMERR",
99 "SERVFAIL",
100 "NXDOMAIN",
101 "NOTIMP",
102 "REFUSED",
103 "6",
104 "7",
105 "8",
106 "9",
107 "10",
108 "11",
109 "12",
110 "13",
111 "14",
112 "NOCHANGE",
113};
114 109
115static char retbuf[16]; 110static const char *loc_ntoal(const u_char *binary, char *ascii, int ascii_len);
116 111
117static char * 112/* XXX: we should use getservbyport() instead. */
113static const char *
118dewks(wks) 114dewks(wks)
119 int wks; 115 int wks;
120{ 116{
117 static char nbuf[20];
118
121 switch (wks) { 119 switch (wks) {
122 case 5: return("rje"); 120 case 5: return "rje";
123 case 7: return("echo"); 121 case 7: return "echo";
124 case 9: return("discard"); 122 case 9: return "discard";
125 case 11: return("systat"); 123 case 11: return "systat";
126 case 13: return("daytime"); 124 case 13: return "daytime";
127 case 15: return("netstat"); 125 case 15: return "netstat";
128 case 17: return("qotd"); 126 case 17: return "qotd";
129 case 19: return("chargen"); 127 case 19: return "chargen";
130 case 20: return("ftp-data"); 128 case 20: return "ftp-data";
131 case 21: return("ftp"); 129 case 21: return "ftp";
132 case 23: return("telnet"); 130 case 23: return "telnet";
133 case 25: return("smtp"); 131 case 25: return "smtp";
134 case 37: return("time"); 132 case 37: return "time";
135 case 39: return("rlp"); 133 case 39: return "rlp";
136 case 42: return("name"); 134 case 42: return "name";
137 case 43: return("whois"); 135 case 43: return "whois";
138 case 53: return("domain"); 136 case 53: return "domain";
139 case 57: return("apts"); 137 case 57: return "apts";
140 case 59: return("apfs"); 138 case 59: return "apfs";
141 case 67: return("bootps"); 139 case 67: return "bootps";
142 case 68: return("bootpc"); 140 case 68: return "bootpc";
143 case 69: return("tftp"); 141 case 69: return "tftp";
144 case 77: return("rje"); 142 case 77: return "rje";
145 case 79: return("finger"); 143 case 79: return "finger";
146 case 87: return("link"); 144 case 87: return "link";
147 case 95: return("supdup"); 145 case 95: return "supdup";
148 case 100: return("newacct"); 146 case 100: return "newacct";
149 case 101: return("hostnames"); 147 case 101: return "hostnames";
150 case 102: return("iso-tsap"); 148 case 102: return "iso-tsap";
151 case 103: return("x400"); 149 case 103: return "x400";
152 case 104: return("x400-snd"); 150 case 104: return "x400-snd";
153 case 105: return("csnet-ns"); 151 case 105: return "csnet-ns";
154 case 109: return("pop-2"); 152 case 109: return "pop-2";
155 case 111: return("sunrpc"); 153 case 111: return "sunrpc";
156 case 113: return("auth"); 154 case 113: return "auth";
157 case 115: return("sftp"); 155 case 115: return "sftp";
158 case 117: return("uucp-path"); 156 case 117: return "uucp-path";
159 case 119: return("nntp"); 157 case 119: return "nntp";
160 case 121: return("erpc"); 158 case 121: return "erpc";
161 case 123: return("ntp"); 159 case 123: return "ntp";
162 case 133: return("statsrv"); 160 case 133: return "statsrv";
163 case 136: return("profile"); 161 case 136: return "profile";
164 case 144: return("NeWS"); 162 case 144: return "NeWS";
165 case 161: return("snmp"); 163 case 161: return "snmp";
166 case 162: return("snmp-trap"); 164 case 162: return "snmp-trap";
167 case 170: return("print-srv"); 165 case 170: return "print-srv";
168 default: (void) sprintf(retbuf, "%d", wks); return(retbuf); 166 default:
167 (void) snprintf(nbuf, sizeof nbuf, "%d", wks);
168 return (nbuf);
169 } 169 }
170} 170}
171 171
172static char * 172/* XXX: we should use getprotobynumber() instead. */
173static const char *
173deproto(protonum) 174deproto(protonum)
174 int protonum; 175 int protonum;
175{ 176{
177 static char nbuf[20];
178
176 switch (protonum) { 179 switch (protonum) {
177 case 1: return("icmp"); 180 case 1: return "icmp";
178 case 2: return("igmp"); 181 case 2: return "igmp";
179 case 3: return("ggp"); 182 case 3: return "ggp";
180 case 5: return("st"); 183 case 5: return "st";
181 case 6: return("tcp"); 184 case 6: return "tcp";
182 case 7: return("ucl"); 185 case 7: return "ucl";
183 case 8: return("egp"); 186 case 8: return "egp";
184 case 9: return("igp"); 187 case 9: return "igp";
185 case 11: return("nvp-II"); 188 case 11: return "nvp-II";
186 case 12: return("pup"); 189 case 12: return "pup";
187 case 16: return("chaos"); 190 case 16: return "chaos";
188 case 17: return("udp"); 191 case 17: return "udp";
189 default: (void) sprintf(retbuf, "%d", protonum); return(retbuf); 192 default:
193 (void) snprintf(nbuf, sizeof nbuf, "%d", protonum);
194 return (nbuf);
190 } 195 }
191} 196}
192 197
193static char * 198static const u_char *
194do_rrset(msg, cp, cnt, pflag, file, hs) 199do_rrset(msg, len, cp, cnt, pflag, file, hs)
195 int cnt, pflag; 200 int cnt, pflag, len;
196 char *cp,*msg, *hs; 201 const u_char *cp, *msg;
202 const char *hs;
197 FILE *file; 203 FILE *file;
198{ 204{
205 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
199 int n; 206 int n;
200 int sflag; 207 int sflag;
208
201 /* 209 /*
202 * Print answer records 210 * Print answer records.
203 */ 211 */
204 sflag = (_res.pfcode & pflag); 212 sflag = (_resp->pfcode & pflag);
205 if (n = ntohs(cnt)) { 213 if ((n = ntohs(cnt))) {
206 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 214 if ((!_resp->pfcode) ||
207 fprintf(file, hs); 215 ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
216 fprintf(file, "%s", hs);
208 while (--n >= 0) { 217 while (--n >= 0) {
209 cp = p_rr(cp, msg, file); 218 if ((!_resp->pfcode) || sflag) {
210 if ((cp-msg) > PACKETSZ) 219 cp = p_rr(cp, msg, file);
220 } else {
221 unsigned int dlen;
222 cp += __dn_skipname(cp, cp + MAXCDNAME);
223 cp += INT16SZ;
224 cp += INT16SZ;
225 cp += INT32SZ;
226 dlen = _getshort((u_char*)cp);
227 cp += INT16SZ;
228 cp += dlen;
229 }
230 if ((cp - msg) > len)
211 return (NULL); 231 return (NULL);
212 } 232 }
213 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 233 if ((!_resp->pfcode) ||
234 ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
214 putc('\n', file); 235 putc('\n', file);
215 } 236 }
216 return(cp); 237 return (cp);
217} 238}
218 239
240void
219__p_query(msg) 241__p_query(msg)
220 char *msg; 242 const u_char *msg;
221{ 243{
222 __fp_query(msg, stdout); 244 __fp_query(msg, stdout);
223} 245}
@@ -231,15 +253,14 @@ __fp_resstat(statp, file)
231 struct __res_state *statp; 253 struct __res_state *statp;
232 FILE *file; 254 FILE *file;
233{ 255{
234 int bit; 256 register u_long mask;
235 257
236 fprintf(file, ";; res options:"); 258 fprintf(file, ";; res options:");
237 if (!statp) 259 if (!statp)
238 statp = &_res; 260 statp = &_res;
239 for (bit = 0; bit < 32; bit++) { /* XXX 32 - bad assumption! */ 261 for (mask = 1; mask != 0; mask <<= 1)
240 if (statp->options & (1<<bit)) 262 if (statp->options & mask)
241 fprintf(file, " %s", p_option(1<<bit)); 263 fprintf(file, " %s", p_option(mask));
242 }
243 putc('\n', file); 264 putc('\n', file);
244} 265}
245 266
@@ -248,109 +269,152 @@ __fp_resstat(statp, file)
248 * This is intended to be primarily a debugging routine. 269 * This is intended to be primarily a debugging routine.
249 */ 270 */
250void 271void
251__fp_query(msg,file) 272__fp_nquery(msg, len, file)
252 char *msg; 273 const u_char *msg;
274 int len;
253 FILE *file; 275 FILE *file;
254{ 276{
255 register char *cp; 277 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
256 register HEADER *hp; 278 register const u_char *cp, *endMark;
279 register const HEADER *hp;
257 register int n; 280 register int n;
258 281
282 if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
283 return;
284
285#define TruncTest(x) if (x > endMark) goto trunc
286#define ErrorTest(x) if (x == NULL) goto error
287
259 /* 288 /*
260 * Print header fields. 289 * Print header fields.
261 */ 290 */
262 hp = (HEADER *)msg; 291 hp = (HEADER *)msg;
263 cp = msg + sizeof(HEADER); 292 cp = msg + HFIXEDSZ;
264 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { 293 endMark = msg + len;
265 fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", 294 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX) || hp->rcode) {
295 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %u",
266 _res_opcodes[hp->opcode], 296 _res_opcodes[hp->opcode],
267 _res_resultcodes[hp->rcode], 297 _res_resultcodes[hp->rcode],
268 ntohs(hp->id)); 298 ntohs(hp->id));
269 putc('\n', file); 299 putc('\n', file);
270 } 300 }
271 putc(';', file); 301 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX))
272 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { 302 putc(';', file);
273 fprintf(file,"; flags:"); 303 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD2)) {
304 fprintf(file, "; flags:");
274 if (hp->qr) 305 if (hp->qr)
275 fprintf(file," qr"); 306 fprintf(file, " qr");
276 if (hp->aa) 307 if (hp->aa)
277 fprintf(file," aa"); 308 fprintf(file, " aa");
278 if (hp->tc) 309 if (hp->tc)
279 fprintf(file," tc"); 310 fprintf(file, " tc");
280 if (hp->rd) 311 if (hp->rd)
281 fprintf(file," rd"); 312 fprintf(file, " rd");
282 if (hp->ra) 313 if (hp->ra)
283 fprintf(file," ra"); 314 fprintf(file, " ra");
284 if (hp->pr) 315 if (hp->unused)
285 fprintf(file," pr"); 316 fprintf(file, " UNUSED-BIT-ON");
317 if (hp->ad)
318 fprintf(file, " ad");
319 if (hp->cd)
320 fprintf(file, " cd");
286 } 321 }
287 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { 322 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD1)) {
288 fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); 323 fprintf(file, "; Ques: %u", ntohs(hp->qdcount));
289 fprintf(file,", Ans: %d", ntohs(hp->ancount)); 324 fprintf(file, ", Ans: %u", ntohs(hp->ancount));
290 fprintf(file,", Auth: %d", ntohs(hp->nscount)); 325 fprintf(file, ", Auth: %u", ntohs(hp->nscount));
291 fprintf(file,", Addit: %d\n", ntohs(hp->arcount)); 326 fprintf(file, ", Addit: %u", ntohs(hp->arcount));
292 } 327 }
293#if 0 328 if ((!_resp->pfcode) || (_resp->pfcode &
294 if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) { 329 (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
295 putc('\n',file); 330 putc('\n',file);
296 } 331 }
297#endif
298 /* 332 /*
299 * Print question records. 333 * Print question records.
300 */ 334 */
301 if (n = ntohs(hp->qdcount)) { 335 if ((n = ntohs(hp->qdcount))) {
302 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 336 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
303 fprintf(file,";; QUESTIONS:\n"); 337 fprintf(file, ";; QUESTIONS:\n");
304 while (--n >= 0) { 338 while (--n >= 0) {
305 fprintf(file,";;\t"); 339 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
306 cp = p_cdname(cp, msg, file); 340 fprintf(file, ";;\t");
307 if (cp == NULL) 341 TruncTest(cp);
308 return; 342 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
309 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 343 cp = p_cdnname(cp, msg, len, file);
344 else {
345 int n;
346 char name[MAXDNAME];
347
348 if ((n = dn_expand(msg, msg+len, cp, name,
349 sizeof name)) < 0)
350 cp = NULL;
351 else
352 cp += n;
353 }
354 ErrorTest(cp);
355 TruncTest(cp);
356 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
310 fprintf(file, ", type = %s", 357 fprintf(file, ", type = %s",
311 __p_type(_getshort(cp))); 358 __p_type(_getshort((u_char*)cp)));
312 cp += sizeof(u_int16_t); 359 cp += INT16SZ;
313 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 360 TruncTest(cp);
314 fprintf(file, ", class = %s\n\n", 361 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
315 __p_class(_getshort(cp))); 362 fprintf(file, ", class = %s\n",
316 cp += sizeof(u_int16_t); 363 __p_class(_getshort((u_char*)cp)));
364 cp += INT16SZ;
365 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
366 putc('\n', file);
317 } 367 }
318 } 368 }
319 /* 369 /*
320 * Print authoritative answer records 370 * Print authoritative answer records
321 */ 371 */
322 cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file, 372 TruncTest(cp);
373 cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
323 ";; ANSWERS:\n"); 374 ";; ANSWERS:\n");
324 if (cp == NULL) 375 ErrorTest(cp);
325 return;
326 376
327 /* 377 /*
328 * print name server records 378 * print name server records
329 */ 379 */
330 cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file, 380 TruncTest(cp);
381 cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
331 ";; AUTHORITY RECORDS:\n"); 382 ";; AUTHORITY RECORDS:\n");
332 if (!cp) 383 ErrorTest(cp);
333 return;
334 384
385 TruncTest(cp);
335 /* 386 /*
336 * print additional records 387 * print additional records
337 */ 388 */
338 cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file, 389 cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
339 ";; ADDITIONAL RECORDS:\n"); 390 ";; ADDITIONAL RECORDS:\n");
340 if (!cp) 391 ErrorTest(cp);
341 return; 392 return;
393 trunc:
394 fprintf(file, "\n;; ...truncated\n");
395 return;
396 error:
397 fprintf(file, "\n;; ...malformed\n");
342} 398}
343 399
344char * 400void
345p_cdname(cp, msg, file) 401__fp_query(msg, file)
346 char *cp, *msg; 402 const u_char *msg;
403 FILE *file;
404{
405 fp_nquery(msg, PACKETSZ, file);
406}
407
408const u_char *
409__p_cdnname(cp, msg, len, file)
410 const u_char *cp, *msg;
411 int len;
347 FILE *file; 412 FILE *file;
348{ 413{
349 char name[MAXDNAME]; 414 char name[MAXDNAME];
350 int n; 415 int n;
351 416
352 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 417 if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
353 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
354 return (NULL); 418 return (NULL);
355 if (name[0] == '\0') 419 if (name[0] == '\0')
356 putc('.', file); 420 putc('.', file);
@@ -359,55 +423,96 @@ p_cdname(cp, msg, file)
359 return (cp + n); 423 return (cp + n);
360} 424}
361 425
362char * 426const u_char *
363p_fqname(cp, msg, file) 427__p_cdname(cp, msg, file)
364 char *cp, *msg; 428 const u_char *cp, *msg;
365 FILE *file; 429 FILE *file;
366{ 430{
367 char name[MAXDNAME]; 431 return (p_cdnname(cp, msg, PACKETSZ, file));
368 int n, len; 432}
433
434
435/* Return a fully-qualified domain name from a compressed name (with
436 length supplied). */
437
438const u_char *
439__p_fqnname(cp, msg, msglen, name, namelen)
440 const u_char *cp, *msg;
441 int msglen;
442 char *name;
443 int namelen;
444{
445 int n, newlen;
369 446
370 if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME, 447 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
371 (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
372 return (NULL); 448 return (NULL);
373 if (name[0] == '\0') { 449 newlen = strlen(name);
374 putc('.', file); 450 if (newlen == 0 || name[newlen - 1] != '.') {
375 } else { 451 if (newlen + 1 >= namelen) /* Lack space for final dot */
376 fputs(name, file); 452 return (NULL);
377 if (name[strlen(name) - 1] != '.') 453 else
378 putc('.', file); 454 strlcpy(name + newlen, ".", namelen - newlen);
379 } 455 }
380 return (cp + n); 456 return (cp + n);
381} 457}
382 458
459/* XXX: the rest of these functions need to become length-limited, too. (vix)
460 */
461
462const u_char *
463__p_fqname(cp, msg, file)
464 const u_char *cp, *msg;
465 FILE *file;
466{
467 char name[MAXDNAME];
468 const u_char *n;
469
470 n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
471 if (n == NULL)
472 return (NULL);
473 fputs(name, file);
474 return (n);
475}
476
383/* 477/*
384 * Print resource record fields in human readable form. 478 * Print resource record fields in human readable form.
385 */ 479 */
386char * 480const u_char *
387p_rr(cp, msg, file) 481__p_rr(cp, msg, file)
388 char *cp, *msg; 482 const u_char *cp, *msg;
389 FILE *file; 483 FILE *file;
390{ 484{
485 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
391 int type, class, dlen, n, c; 486 int type, class, dlen, n, c;
392 struct in_addr inaddr; 487 struct in_addr inaddr;
393 char *cp1, *cp2; 488 const u_char *cp1, *cp2;
394 u_int32_t tmpttl, t; 489 u_int32_t tmpttl, t;
395 int lcnt; 490 int lcnt;
491 u_int16_t keyflags;
492 char rrname[MAXDNAME]; /* The fqdn of this RR */
493 char base64_key[MAX_KEY_BASE64];
396 494
397 if ((cp = p_fqname(cp, msg, file)) == NULL) 495 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
496 h_errno = NETDB_INTERNAL;
497 return (NULL);
498 }
499 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
500 if (!cp)
398 return (NULL); /* compression error */ 501 return (NULL); /* compression error */
399 type = _getshort(cp); 502 fputs(rrname, file);
400 cp += sizeof(u_int16_t); 503
401 class = _getshort(cp); 504 type = _getshort((u_char*)cp);
402 cp += sizeof(u_int16_t); 505 cp += INT16SZ;
403 tmpttl = _getlong(cp); 506 class = _getshort((u_char*)cp);
404 cp += sizeof(u_int32_t); 507 cp += INT16SZ;
405 dlen = _getshort(cp); 508 tmpttl = _getlong((u_char*)cp);
406 cp += sizeof(u_int16_t); 509 cp += INT32SZ;
510 dlen = _getshort((u_char*)cp);
511 cp += INT16SZ;
407 cp1 = cp; 512 cp1 = cp;
408 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) 513 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_TTLID))
409 fprintf(file, "\t%lu", tmpttl); 514 fprintf(file, "\t%lu", (u_long)tmpttl);
410 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) 515 if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_CLASS))
411 fprintf(file, "\t%s", __p_class(class)); 516 fprintf(file, "\t%s", __p_class(class));
412 fprintf(file, "\t%s", __p_type(type)); 517 fprintf(file, "\t%s", __p_type(type));
413 /* 518 /*
@@ -418,22 +523,22 @@ p_rr(cp, msg, file)
418 switch (class) { 523 switch (class) {
419 case C_IN: 524 case C_IN:
420 case C_HS: 525 case C_HS:
421 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 526 bcopy(cp, (char *)&inaddr, INADDRSZ);
422 if (dlen == 4) { 527 if (dlen == 4) {
423 fprintf(file,"\t%s", inet_ntoa(inaddr)); 528 fprintf(file, "\t%s", inet_ntoa(inaddr));
424 cp += dlen; 529 cp += dlen;
425 } else if (dlen == 7) { 530 } else if (dlen == 7) {
426 char *address; 531 char *address;
427 u_char protocol; 532 u_char protocol;
428 u_short port; 533 in_port_t port;
429 534
430 address = inet_ntoa(inaddr); 535 address = inet_ntoa(inaddr);
431 cp += sizeof(inaddr); 536 cp += INADDRSZ;
432 protocol = *(u_char*)cp; 537 protocol = *(u_char*)cp;
433 cp += sizeof(u_char); 538 cp += sizeof (u_char);
434 port = _getshort(cp); 539 port = _getshort((u_char*)cp);
435 cp += sizeof(u_int16_t); 540 cp += INT16SZ;
436 fprintf(file, "\t%s\t; proto %d, port %d", 541 fprintf(file, "\t%s\t; proto %u, port %u",
437 address, protocol, port); 542 address, protocol, port);
438 } 543 }
439 break; 544 break;
@@ -448,98 +553,205 @@ p_rr(cp, msg, file)
448 case T_NS: 553 case T_NS:
449 case T_PTR: 554 case T_PTR:
450 putc('\t', file); 555 putc('\t', file);
451 cp = p_fqname(cp, msg, file); 556 if ((cp = p_fqname(cp, msg, file)) == NULL)
557 return (NULL);
452 break; 558 break;
453 559
454 case T_HINFO: 560 case T_HINFO:
455 if (n = *cp++) { 561 case T_ISDN:
456 fprintf(file,"\t%.*s", n, cp); 562 cp2 = cp + dlen;
457 cp += n; 563 (void) fputs("\t\"", file);
564 if ((n = (unsigned char) *cp++) != 0) {
565 for (c = n; c > 0 && cp < cp2; c--) {
566 if (strchr("\n\"\\", *cp))
567 (void) putc('\\', file);
568 (void) putc(*cp++, file);
569 }
458 } 570 }
459 if (n = *cp++) { 571 putc('"', file);
460 fprintf(file,"\t%.*s", n, cp); 572 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
461 cp += n; 573 (void) fputs ("\t\"", file);
574 for (c = n; c > 0 && cp < cp2; c--) {
575 if (strchr("\n\"\\", *cp))
576 (void) putc('\\', file);
577 (void) putc(*cp++, file);
578 }
579 putc('"', file);
580 } else if (type == T_HINFO) {
581 (void) fputs("\"?\"", file);
582 fprintf(file, "\n;; *** Warning *** OS-type missing");
462 } 583 }
463 break; 584 break;
464 585
465 case T_SOA: 586 case T_SOA:
466 putc('\t', file); 587 putc('\t', file);
467 cp = p_fqname(cp, msg, file); /* origin */ 588 if ((cp = p_fqname(cp, msg, file)) == NULL)
589 return (NULL);
468 putc(' ', file); 590 putc(' ', file);
469 cp = p_fqname(cp, msg, file); /* mail addr */ 591 if ((cp = p_fqname(cp, msg, file)) == NULL)
592 return (NULL);
470 fputs(" (\n", file); 593 fputs(" (\n", file);
471 t = _getlong(cp); cp += sizeof(u_int32_t); 594 t = _getlong((u_char*)cp); cp += INT32SZ;
472 fprintf(file,"\t\t\t%lu\t; serial\n", t); 595 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
473 t = _getlong(cp); cp += sizeof(u_int32_t); 596 t = _getlong((u_char*)cp); cp += INT32SZ;
474 fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t)); 597 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
475 t = _getlong(cp); cp += sizeof(u_int32_t); 598 (u_long)t, __p_time(t));
476 fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t)); 599 t = _getlong((u_char*)cp); cp += INT32SZ;
477 t = _getlong(cp); cp += sizeof(u_int32_t); 600 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
478 fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t)); 601 (u_long)t, __p_time(t));
479 t = _getlong(cp); cp += sizeof(u_int32_t); 602 t = _getlong((u_char*)cp); cp += INT32SZ;
480 fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t)); 603 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
604 (u_long)t, __p_time(t));
605 t = _getlong((u_char*)cp); cp += INT32SZ;
606 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
607 (u_long)t, __p_time(t));
481 break; 608 break;
482 609
483 case T_MX: 610 case T_MX:
484 case T_AFSDB: 611 case T_AFSDB:
485 fprintf(file,"\t%d ", _getshort(cp)); 612 case T_RT:
486 cp += sizeof(u_int16_t); 613 fprintf(file, "\t%u ", _getshort((u_char*)cp));
487 cp = p_fqname(cp, msg, file); 614 cp += INT16SZ;
615 if ((cp = p_fqname(cp, msg, file)) == NULL)
616 return (NULL);
488 break; 617 break;
489 618
490 case T_TXT: 619 case T_PX:
620 fprintf(file, "\t%u ", _getshort((u_char*)cp));
621 cp += INT16SZ;
622 if ((cp = p_fqname(cp, msg, file)) == NULL)
623 return (NULL);
624 putc(' ', file);
625 if ((cp = p_fqname(cp, msg, file)) == NULL)
626 return (NULL);
627 break;
628
629 case T_X25:
630 cp2 = cp + dlen;
491 (void) fputs("\t\"", file); 631 (void) fputs("\t\"", file);
632 if ((n = (unsigned char) *cp++) != 0) {
633 for (c = n; c > 0 && cp < cp2; c--) {
634 if (strchr("\n\"\\", *cp))
635 (void) putc('\\', file);
636 (void) putc(*cp++, file);
637 }
638 }
639 putc('"', file);
640 break;
641
642 case T_TXT:
643 (void) putc('\t', file);
492 cp2 = cp1 + dlen; 644 cp2 = cp1 + dlen;
493 while (cp < cp2) { 645 while (cp < cp2) {
494 if (n = (unsigned char) *cp++) { 646 putc('"', file);
495 for (c = n; c > 0 && cp < cp2; c--) 647 if ((n = (unsigned char) *cp++)) {
496 if (*cp == '\n') { 648 for (c = n; c > 0 && cp < cp2; c--) {
497 (void) putc('\\', file); 649 if (strchr("\n\"\\", *cp))
498 (void) putc(*cp++, file); 650 (void) putc('\\', file);
499 } else 651 (void) putc(*cp++, file);
500 (void) putc(*cp++, file); 652 }
501 } 653 }
654 putc('"', file);
655 if (cp < cp2)
656 putc(' ', file);
502 } 657 }
503 putc('"', file); 658 break;
504 break; 659
660 case T_NSAP:
661 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
662 cp += dlen;
663 break;
664
665 case T_AAAA: {
666 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
667
668 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
669 cp += dlen;
670 break;
671 }
672
673 case T_LOC: {
674 char t[255];
675
676 fprintf(file, "\t%s", loc_ntoal(cp, t, sizeof t));
677 cp += dlen;
678 break;
679 }
680
681 case T_NAPTR: {
682 u_int order, preference;
683
684 order = _getshort(cp); cp += INT16SZ;
685 preference = _getshort(cp); cp += INT16SZ;
686 fprintf(file, "\t%u %u ",order, preference);
687 /* Flags */
688 n = *cp++;
689 fprintf(file,"\"%.*s\" ", (int)n, cp);
690 cp += n;
691 /* Service */
692 n = *cp++;
693 fprintf(file,"\"%.*s\" ", (int)n, cp);
694 cp += n;
695 /* Regexp */
696 n = *cp++;
697 fprintf(file,"\"%.*s\" ", (int)n, cp);
698 cp += n;
699 if ((cp = p_fqname(cp, msg, file)) == NULL)
700 return (NULL);
701 break;
702 }
703
704 case T_SRV: {
705 u_int priority, weight, port;
706
707 priority = _getshort(cp); cp += INT16SZ;
708 weight = _getshort(cp); cp += INT16SZ;
709 port = _getshort(cp); cp += INT16SZ;
710 fprintf(file, "\t%u %u %u ", priority, weight, port);
711 if ((cp = p_fqname(cp, msg, file)) == NULL)
712 return (NULL);
713 break;
714 }
505 715
506 case T_MINFO: 716 case T_MINFO:
507 case T_RP: 717 case T_RP:
508 putc('\t', file); 718 putc('\t', file);
509 cp = p_fqname(cp, msg, file); 719 if ((cp = p_fqname(cp, msg, file)) == NULL)
720 return (NULL);
510 putc(' ', file); 721 putc(' ', file);
511 cp = p_fqname(cp, msg, file); 722 if ((cp = p_fqname(cp, msg, file)) == NULL)
723 return (NULL);
512 break; 724 break;
513 725
514 case T_UINFO: 726 case T_UINFO:
515 putc('\t', file); 727 putc('\t', file);
516 fputs(cp, file); 728 fputs((char *)cp, file);
517 cp += dlen; 729 cp += dlen;
518 break; 730 break;
519 731
520 case T_UID: 732 case T_UID:
521 case T_GID: 733 case T_GID:
522 if (dlen == 4) { 734 if (dlen == 4) {
523 fprintf(file,"\t%u", _getlong(cp)); 735 fprintf(file, "\t%u", _getlong((u_char*)cp));
524 cp += sizeof(int32_t); 736 cp += INT32SZ;
525 } 737 }
526 break; 738 break;
527 739
528 case T_WKS: 740 case T_WKS:
529 if (dlen < sizeof(u_int32_t) + 1) 741 if (dlen < INT32SZ + 1)
530 break; 742 break;
531 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 743 bcopy(cp, (char *)&inaddr, INADDRSZ);
532 cp += sizeof(u_int32_t); 744 cp += INT32SZ;
533 fprintf(file, "\t%s %s ( ", 745 fprintf(file, "\t%s %s ( ",
534 inet_ntoa(inaddr), 746 inet_ntoa(inaddr),
535 deproto((int) *cp)); 747 deproto((int) *cp));
536 cp += sizeof(u_char); 748 cp += sizeof (u_char);
537 n = 0; 749 n = 0;
538 lcnt = 0; 750 lcnt = 0;
539 while (cp < cp1 + dlen) { 751 while (cp < cp1 + dlen) {
540 c = *cp++; 752 c = *cp++;
541 do { 753 do {
542 if (c & 0200) { 754 if (c & 0200) {
543 if (lcnt == 0) { 755 if (lcnt == 0) {
544 fputs("\n\t\t\t", file); 756 fputs("\n\t\t\t", file);
545 lcnt = 5; 757 lcnt = 5;
@@ -548,17 +760,83 @@ p_rr(cp, msg, file)
548 putc(' ', file); 760 putc(' ', file);
549 lcnt--; 761 lcnt--;
550 } 762 }
551 c <<= 1; 763 c <<= 1;
552 } while (++n & 07); 764 } while (++n & 07);
553 } 765 }
554 putc(')', file); 766 putc(')', file);
555 break; 767 break;
556 768
769 case T_KEY:
770 putc('\t', file);
771 keyflags = _getshort(cp);
772 cp += 2;
773 fprintf(file,"0x%04x", keyflags ); /* flags */
774 fprintf(file," %u", *cp++); /* protocol */
775 fprintf(file," %u (", *cp++); /* algorithm */
776
777 n = b64_ntop(cp, (cp1 + dlen) - cp,
778 base64_key, sizeof base64_key);
779 for (c = 0; c < n; ++c) {
780 if (0 == (c & 0x3F))
781 fprintf(file, "\n\t");
782 putc(base64_key[c], file); /* public key data */
783 }
784
785 fprintf(file, " )");
786 if (n < 0)
787 fprintf(file, "\t; BAD BASE64");
788 fflush(file);
789 cp = cp1 + dlen;
790 break;
791
792 case T_SIG:
793 type = _getshort((u_char*)cp);
794 cp += INT16SZ;
795 fprintf(file, " %s", p_type(type));
796 fprintf(file, "\t%u", *cp++); /* algorithm */
797 /* Check label value and print error if wrong. */
798 n = *cp++;
799 c = dn_count_labels (rrname);
800 if (n != c)
801 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
802 n, c);
803 /* orig ttl */
804 n = _getlong((u_char*)cp);
805 if (n != tmpttl)
806 fprintf(file, " %u", n);
807 cp += INT32SZ;
808 /* sig expire */
809 fprintf(file, " (\n\t%s",
810 __p_secstodate(_getlong((u_char*)cp)));
811 cp += INT32SZ;
812 /* time signed */
813 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
814 cp += INT32SZ;
815 /* sig footprint */
816 fprintf(file," %u ", _getshort((u_char*)cp));
817 cp += INT16SZ;
818 /* signer's name */
819 cp = p_fqname(cp, msg, file);
820 n = b64_ntop(cp, (cp1 + dlen) - cp,
821 base64_key, sizeof base64_key);
822 for (c = 0; c < n; c++) {
823 if (0 == (c & 0x3F))
824 fprintf (file, "\n\t");
825 putc(base64_key[c], file); /* signature */
826 }
827 /* Clean up... */
828 fprintf(file, " )");
829 if (n < 0)
830 fprintf(file, "\t; BAD BASE64");
831 fflush(file);
832 cp = cp1+dlen;
833 break;
834
557#ifdef ALLOW_T_UNSPEC 835#ifdef ALLOW_T_UNSPEC
558 case T_UNSPEC: 836 case T_UNSPEC:
559 { 837 {
560 int NumBytes = 8; 838 int NumBytes = 8;
561 char *DataPtr; 839 u_char *DataPtr;
562 int i; 840 int i;
563 841
564 if (dlen < NumBytes) NumBytes = dlen; 842 if (dlen < NumBytes) NumBytes = dlen;
@@ -572,7 +850,7 @@ p_rr(cp, msg, file)
572#endif /* ALLOW_T_UNSPEC */ 850#endif /* ALLOW_T_UNSPEC */
573 851
574 default: 852 default:
575 fprintf(file,"\t?%d?", type); 853 fprintf(file, "\t?%d?", type);
576 cp += dlen; 854 cp += dlen;
577 } 855 }
578#if 0 856#if 0
@@ -581,136 +859,210 @@ p_rr(cp, msg, file)
581 putc('\n', file); 859 putc('\n', file);
582#endif 860#endif
583 if (cp - cp1 != dlen) { 861 if (cp - cp1 != dlen) {
584 fprintf(file,";; packet size error (found %d, dlen was %d)\n", 862 fprintf(file, ";; packet size error (found %ld, dlen was %d)\n",
585 cp - cp1, dlen); 863 (long)(cp - cp1), dlen);
586 cp = NULL; 864 cp = NULL;
587 } 865 }
588 return (cp); 866 return (cp);
589} 867}
590 868
591static char nbuf[40]; 869/*
870 * Names of RR classes and qclasses. Classes and qclasses are the same, except
871 * that C_ANY is a qclass but not a class. (You can ask for records of class
872 * C_ANY, but you can't have any records of that class in the database.)
873 */
874const struct res_sym __p_class_syms[] = {
875 {C_IN, "IN"},
876 {C_CHAOS, "CHAOS"},
877 {C_HS, "HS"},
878 {C_HS, "HESIOD"},
879 {C_ANY, "ANY"},
880 {C_IN, (char *)0}
881};
592 882
593/* 883/*
594 * Return a string for the type 884 * Names of RR types and qtypes. Types and qtypes are the same, except
885 * that T_ANY is a qtype but not a type. (You can ask for records of type
886 * T_ANY, but you can't have any records of that type in the database.)
595 */ 887 */
596char * 888const struct res_sym __p_type_syms[] = {
597__p_type(type) 889 {T_A, "A", "address"},
598 int type; 890 {T_NS, "NS", "name server"},
599{ 891 {T_MD, "MD", "mail destination (deprecated)"},
600 switch (type) { 892 {T_MF, "MF", "mail forwarder (deprecated)"},
601 case T_A: 893 {T_CNAME, "CNAME", "canonical name"},
602 return("A"); 894 {T_SOA, "SOA", "start of authority"},
603 case T_NS: /* authoritative server */ 895 {T_MB, "MB", "mailbox"},
604 return("NS"); 896 {T_MG, "MG", "mail group member"},
605 case T_CNAME: /* canonical name */ 897 {T_MR, "MR", "mail rename"},
606 return("CNAME"); 898 {T_NULL, "NULL", "null"},
607 case T_SOA: /* start of authority zone */ 899 {T_WKS, "WKS", "well-known service (deprecated)"},
608 return("SOA"); 900 {T_PTR, "PTR", "domain name pointer"},
609 case T_MB: /* mailbox domain name */ 901 {T_HINFO, "HINFO", "host information"},
610 return("MB"); 902 {T_MINFO, "MINFO", "mailbox information"},
611 case T_MG: /* mail group member */ 903 {T_MX, "MX", "mail exchanger"},
612 return("MG"); 904 {T_TXT, "TXT", "text"},
613 case T_MR: /* mail rename name */ 905 {T_RP, "RP", "responsible person"},
614 return("MR"); 906 {T_AFSDB, "AFSDB", "DCE or AFS server"},
615 case T_NULL: /* null resource record */ 907 {T_X25, "X25", "X25 address"},
616 return("NULL"); 908 {T_ISDN, "ISDN", "ISDN address"},
617 case T_WKS: /* well known service */ 909 {T_RT, "RT", "router"},
618 return("WKS"); 910 {T_NSAP, "NSAP", "nsap address"},
619 case T_PTR: /* domain name pointer */ 911 {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
620 return("PTR"); 912 {T_SIG, "SIG", "signature"},
621 case T_HINFO: /* host information */ 913 {T_KEY, "KEY", "key"},
622 return("HINFO"); 914 {T_PX, "PX", "mapping information"},
623 case T_MINFO: /* mailbox information */ 915 {T_GPOS, "GPOS", "geographical position (withdrawn)"},
624 return("MINFO"); 916 {T_AAAA, "AAAA", "IPv6 address"},
625 case T_MX: /* mail routing info */ 917 {T_LOC, "LOC", "location"},
626 return("MX"); 918 {T_NXT, "NXT", "next valid name (unimplemented)"},
627 case T_TXT: /* text */ 919 {T_EID, "EID", "endpoint identifier (unimplemented)"},
628 return("TXT"); 920 {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
629 case T_RP: /* responsible person */ 921 {T_SRV, "SRV", "server selection"},
630 return("RP"); 922 {T_ATMA, "ATMA", "ATM address (unimplemented)"},
631 case T_AFSDB: /* AFS cell database */ 923 {T_IXFR, "IXFR", "incremental zone transfer"},
632 return("AFSDB"); 924 {T_AXFR, "AXFR", "zone transfer"},
633 case T_AXFR: /* zone transfer */ 925 {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
634 return("AXFR"); 926 {T_MAILA, "MAILA", "mail agent (deprecated)"},
635 case T_MAILB: /* mail box */ 927 {T_UINFO, "UINFO", "user information (nonstandard)"},
636 return("MAILB"); 928 {T_UID, "UID", "user ID (nonstandard)"},
637 case T_MAILA: /* mail address */ 929 {T_GID, "GID", "group ID (nonstandard)"},
638 return("MAILA"); 930 {T_NAPTR, "NAPTR", "URN Naming Authority"},
639 case T_ANY: /* matches any type */
640 return("ANY");
641 case T_UINFO:
642 return("UINFO");
643 case T_UID:
644 return("UID");
645 case T_GID:
646 return("GID");
647#ifdef ALLOW_T_UNSPEC 931#ifdef ALLOW_T_UNSPEC
648 case T_UNSPEC: 932 {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
649 return("UNSPEC");
650#endif /* ALLOW_T_UNSPEC */ 933#endif /* ALLOW_T_UNSPEC */
934 {T_ANY, "ANY", "\"any\""},
935 {0, NULL, NULL}
936};
651 937
652 default: 938int
653 (void)sprintf(nbuf, "%d", type); 939__sym_ston(syms, name, success)
654 return(nbuf); 940 const struct res_sym *syms;
941 char *name;
942 int *success;
943{
944 for (; syms->name != 0; syms++) {
945 if (strcasecmp (name, syms->name) == 0) {
946 if (success)
947 *success = 1;
948 return (syms->number);
949 }
950 }
951 if (success)
952 *success = 0;
953 return (syms->number); /* The default value. */
954}
955
956const char *
957__sym_ntos(syms, number, success)
958 const struct res_sym *syms;
959 int number;
960 int *success;
961{
962 static char unname[20];
963
964 for (; syms->name != 0; syms++) {
965 if (number == syms->number) {
966 if (success)
967 *success = 1;
968 return (syms->name);
969 }
970 }
971
972 snprintf(unname, sizeof unname, "%d", number);
973 if (success)
974 *success = 0;
975 return (unname);
976}
977
978
979const char *
980__sym_ntop(syms, number, success)
981 const struct res_sym *syms;
982 int number;
983 int *success;
984{
985 static char unname[20];
986
987 for (; syms->name != 0; syms++) {
988 if (number == syms->number) {
989 if (success)
990 *success = 1;
991 return (syms->humanname);
992 }
655 } 993 }
994 snprintf(unname, sizeof unname, "%d", number);
995 if (success)
996 *success = 0;
997 return (unname);
998}
999
1000/*
1001 * Return a string for the type
1002 */
1003const char *
1004__p_type(type)
1005 int type;
1006{
1007 return (__sym_ntos (__p_type_syms, type, (int *)0));
656} 1008}
657 1009
658/* 1010/*
659 * Return a mnemonic for class 1011 * Return a mnemonic for class
660 */ 1012 */
661char * 1013const char *
662__p_class(class) 1014__p_class(class)
663 int class; 1015 int class;
664{ 1016{
665 1017 return (__sym_ntos (__p_class_syms, class, (int *)0));
666 switch (class) {
667 case C_IN: /* internet class */
668 return("IN");
669 case C_HS: /* hesiod class */
670 return("HS");
671 case C_ANY: /* matches any class */
672 return("ANY");
673 default:
674 (void)sprintf(nbuf, "%d", class);
675 return(nbuf);
676 }
677} 1018}
678 1019
679/* 1020/*
680 * Return a mnemonic for an option 1021 * Return a mnemonic for an option
681 */ 1022 */
682static char * 1023const char *
683p_option(option) 1024__p_option(option)
684 u_int32_t option; 1025 u_long option;
685{ 1026{
1027 static char nbuf[40];
1028
686 switch (option) { 1029 switch (option) {
687 case RES_INIT: return "init"; 1030 case RES_INIT: return "init";
688 case RES_DEBUG: return "debug"; 1031 case RES_DEBUG: return "debug";
689 case RES_AAONLY: return "aaonly"; 1032 case RES_AAONLY: return "aaonly(unimpl)";
690 case RES_USEVC: return "usevc"; 1033 case RES_USEVC: return "usevc";
691 case RES_PRIMARY: return "primry"; 1034 case RES_PRIMARY: return "primry(unimpl)";
692 case RES_IGNTC: return "igntc"; 1035 case RES_IGNTC: return "igntc";
693 case RES_RECURSE: return "recurs"; 1036 case RES_RECURSE: return "recurs";
694 case RES_DEFNAMES: return "defnam"; 1037 case RES_DEFNAMES: return "defnam";
695 case RES_STAYOPEN: return "styopn"; 1038 case RES_STAYOPEN: return "styopn";
696 case RES_DNSRCH: return "dnsrch"; 1039 case RES_DNSRCH: return "dnsrch";
697 default: sprintf(nbuf, "?0x%x?", option); return nbuf; 1040 case RES_INSECURE1: return "insecure1";
1041 case RES_INSECURE2: return "insecure2";
1042 case RES_USE_INET6: return "inet6";
1043 case RES_USE_EDNS0: return "edns0";
1044 default:
1045 snprintf(nbuf, sizeof nbuf, "?0x%lx?", (u_long)option);
1046 return (nbuf);
698 } 1047 }
699} 1048}
700 1049
701/* 1050/*
702 * Return a mnemonic for a time to live 1051 * Return a mnemonic for a time to live
703 */ 1052 */
704char * 1053const char *
705__p_time(value) 1054p_time(value)
706 u_int32_t value; 1055 u_int32_t value;
707{ 1056{
1057 static char nbuf[40];
1058 char *ebuf;
708 int secs, mins, hours, days; 1059 int secs, mins, hours, days;
709 register char *p; 1060 register char *p;
1061 int tmp;
710 1062
711 if (value == 0) { 1063 if (value == 0) {
712 strcpy(nbuf, "0 secs"); 1064 strlcpy(nbuf, "0 secs", sizeof nbuf);
713 return(nbuf); 1065 return (nbuf);
714 } 1066 }
715 1067
716 secs = value % 60; 1068 secs = value % 60;
@@ -724,26 +1076,490 @@ __p_time(value)
724 1076
725#define PLURALIZE(x) x, (x == 1) ? "" : "s" 1077#define PLURALIZE(x) x, (x == 1) ? "" : "s"
726 p = nbuf; 1078 p = nbuf;
1079 ebuf = nbuf + sizeof(nbuf);
727 if (days) { 1080 if (days) {
728 (void)sprintf(p, "%d day%s", PLURALIZE(days)); 1081 if ((tmp = snprintf(p, ebuf - p, "%d day%s",
729 while (*++p); 1082 PLURALIZE(days))) >= ebuf - nbuf || tmp < 0)
1083 goto full;
1084 p += tmp;
730 } 1085 }
731 if (hours) { 1086 if (hours) {
732 if (days) 1087 if (days)
733 *p++ = ' '; 1088 *p++ = ' ';
734 (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); 1089 if (p >= ebuf)
735 while (*++p); 1090 goto full;
1091 if ((tmp = snprintf(p, ebuf - p, "%d hour%s",
1092 PLURALIZE(hours))) >= ebuf - nbuf || tmp < 0)
1093 goto full;
1094 p += tmp;
736 } 1095 }
737 if (mins) { 1096 if (mins) {
738 if (days || hours) 1097 if (days || hours)
739 *p++ = ' '; 1098 *p++ = ' ';
740 (void)sprintf(p, "%d min%s", PLURALIZE(mins)); 1099 if (p >= ebuf)
741 while (*++p); 1100 goto full;
1101 if ((tmp = snprintf(p, ebuf - p, "%d min%s",
1102 PLURALIZE(mins))) >= ebuf - nbuf || tmp < 0)
1103 goto full;
1104 p += tmp;
742 } 1105 }
743 if (secs || ! (days || hours || mins)) { 1106 if (secs || ! (days || hours || mins)) {
744 if (days || hours || mins) 1107 if (days || hours || mins)
745 *p++ = ' '; 1108 *p++ = ' ';
746 (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); 1109 if (p >= ebuf)
1110 goto full;
1111 if ((tmp = snprintf(p, ebuf - p, "%d sec%s",
1112 PLURALIZE(secs))) >= ebuf - nbuf || tmp < 0)
1113 goto full;
1114 }
1115 return (nbuf);
1116full:
1117 p = nbuf + sizeof(nbuf) - 4;
1118 *p++ = '.';
1119 *p++ = '.';
1120 *p++ = '.';
1121 *p++ = '\0';
1122 return (nbuf);
1123}
1124
1125/*
1126 * routines to convert between on-the-wire RR format and zone file format.
1127 * Does not contain conversion to/from decimal degrees; divide or multiply
1128 * by 60*60*1000 for that.
1129 */
1130
1131static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1132 1000000,10000000,100000000,1000000000};
1133
1134/* takes an XeY precision/size value, returns a string representation. */
1135static const char *
1136precsize_ntoa(prec)
1137 u_int8_t prec;
1138{
1139 static char retbuf[sizeof "90000000.00"];
1140 unsigned long val;
1141 int mantissa, exponent;
1142
1143 mantissa = (int)((prec >> 4) & 0x0f) % 10;
1144 exponent = (int)((prec >> 0) & 0x0f) % 10;
1145
1146 val = mantissa * poweroften[exponent];
1147
1148 (void) snprintf(retbuf, sizeof retbuf, "%ld.%.2ld", val/100, val%100);
1149 return (retbuf);
1150}
1151
1152/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1153static u_int8_t
1154precsize_aton(strptr)
1155 char **strptr;
1156{
1157 unsigned int mval = 0, cmval = 0;
1158 u_int8_t retval = 0;
1159 register char *cp;
1160 register int exponent;
1161 register int mantissa;
1162
1163 cp = *strptr;
1164
1165 while (isdigit(*cp))
1166 mval = mval * 10 + (*cp++ - '0');
1167
1168 if (*cp == '.') { /* centimeters */
1169 cp++;
1170 if (isdigit(*cp)) {
1171 cmval = (*cp++ - '0') * 10;
1172 if (isdigit(*cp)) {
1173 cmval += (*cp++ - '0');
1174 }
1175 }
1176 }
1177 cmval = (mval * 100) + cmval;
1178
1179 for (exponent = 0; exponent < 9; exponent++)
1180 if (cmval < poweroften[exponent+1])
1181 break;
1182
1183 mantissa = cmval / poweroften[exponent];
1184 if (mantissa > 9)
1185 mantissa = 9;
1186
1187 retval = (mantissa << 4) | exponent;
1188
1189 *strptr = cp;
1190
1191 return (retval);
1192}
1193
1194/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1195static u_int32_t
1196latlon2ul(latlonstrptr,which)
1197 char **latlonstrptr;
1198 int *which;
1199{
1200 register char *cp;
1201 u_int32_t retval;
1202 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1203
1204 cp = *latlonstrptr;
1205
1206 while (isdigit(*cp))
1207 deg = deg * 10 + (*cp++ - '0');
1208
1209 while (isspace(*cp))
1210 cp++;
1211
1212 if (!(isdigit(*cp)))
1213 goto fndhemi;
1214
1215 while (isdigit(*cp))
1216 min = min * 10 + (*cp++ - '0');
1217
1218 while (isspace(*cp))
1219 cp++;
1220
1221 if (!(isdigit(*cp)))
1222 goto fndhemi;
1223
1224 while (isdigit(*cp))
1225 secs = secs * 10 + (*cp++ - '0');
1226
1227 if (*cp == '.') { /* decimal seconds */
1228 cp++;
1229 if (isdigit(*cp)) {
1230 secsfrac = (*cp++ - '0') * 100;
1231 if (isdigit(*cp)) {
1232 secsfrac += (*cp++ - '0') * 10;
1233 if (isdigit(*cp)) {
1234 secsfrac += (*cp++ - '0');
1235 }
1236 }
1237 }
1238 }
1239
1240 while (!isspace(*cp)) /* if any trailing garbage */
1241 cp++;
1242
1243 while (isspace(*cp))
1244 cp++;
1245
1246 fndhemi:
1247 switch (*cp) {
1248 case 'N': case 'n':
1249 case 'E': case 'e':
1250 retval = ((unsigned)1<<31)
1251 + (((((deg * 60) + min) * 60) + secs) * 1000)
1252 + secsfrac;
1253 break;
1254 case 'S': case 's':
1255 case 'W': case 'w':
1256 retval = ((unsigned)1<<31)
1257 - (((((deg * 60) + min) * 60) + secs) * 1000)
1258 - secsfrac;
1259 break;
1260 default:
1261 retval = 0; /* invalid value -- indicates error */
1262 break;
1263 }
1264
1265 switch (*cp) {
1266 case 'N': case 'n':
1267 case 'S': case 's':
1268 *which = 1; /* latitude */
1269 break;
1270 case 'E': case 'e':
1271 case 'W': case 'w':
1272 *which = 2; /* longitude */
1273 break;
1274 default:
1275 *which = 0; /* error */
1276 break;
1277 }
1278
1279 cp++; /* skip the hemisphere */
1280
1281 while (!isspace(*cp)) /* if any trailing garbage */
1282 cp++;
1283
1284 while (isspace(*cp)) /* move to next field */
1285 cp++;
1286
1287 *latlonstrptr = cp;
1288
1289 return (retval);
1290}
1291
1292/* converts a zone file representation in a string to an RDATA on-the-wire
1293 * representation. */
1294int
1295loc_aton(ascii, binary)
1296 const char *ascii;
1297 u_char *binary;
1298{
1299 const char *maxcp;
1300 u_char *bcp;
1301 char *cp;
1302
1303 u_int32_t latit = 0, longit = 0, alt = 0;
1304 u_int32_t lltemp1 = 0, lltemp2 = 0;
1305 int altmeters = 0, altfrac = 0, altsign = 1;
1306 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1307 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1308 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1309 int which1 = 0, which2 = 0;
1310
1311 cp = (char *)ascii;
1312 maxcp = cp + strlen(ascii);
1313
1314 lltemp1 = latlon2ul(&cp, &which1);
1315
1316 lltemp2 = latlon2ul(&cp, &which2);
1317
1318 switch (which1 + which2) {
1319 case 3: /* 1 + 2, the only valid combination */
1320 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1321 latit = lltemp1;
1322 longit = lltemp2;
1323 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1324 longit = lltemp1;
1325 latit = lltemp2;
1326 } else { /* some kind of brokenness */
1327 return (0);
1328 }
1329 break;
1330 default: /* we didn't get one of each */
1331 return (0);
747 } 1332 }
748 return(nbuf); 1333
1334 /* altitude */
1335 if (*cp == '-') {
1336 altsign = -1;
1337 cp++;
1338 }
1339
1340 if (*cp == '+')
1341 cp++;
1342
1343 while (isdigit(*cp))
1344 altmeters = altmeters * 10 + (*cp++ - '0');
1345
1346 if (*cp == '.') { /* decimal meters */
1347 cp++;
1348 if (isdigit(*cp)) {
1349 altfrac = (*cp++ - '0') * 10;
1350 if (isdigit(*cp)) {
1351 altfrac += (*cp++ - '0');
1352 }
1353 }
1354 }
1355
1356 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1357
1358 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1359 cp++;
1360
1361 while (isspace(*cp) && (cp < maxcp))
1362 cp++;
1363
1364 if (cp >= maxcp)
1365 goto defaults;
1366
1367 siz = precsize_aton(&cp);
1368
1369 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1370 cp++;
1371
1372 while (isspace(*cp) && (cp < maxcp))
1373 cp++;
1374
1375 if (cp >= maxcp)
1376 goto defaults;
1377
1378 hp = precsize_aton(&cp);
1379
1380 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1381 cp++;
1382
1383 while (isspace(*cp) && (cp < maxcp))
1384 cp++;
1385
1386 if (cp >= maxcp)
1387 goto defaults;
1388
1389 vp = precsize_aton(&cp);
1390
1391 defaults:
1392
1393 bcp = binary;
1394 *bcp++ = (u_int8_t) 0; /* version byte */
1395 *bcp++ = siz;
1396 *bcp++ = hp;
1397 *bcp++ = vp;
1398 PUTLONG(latit,bcp);
1399 PUTLONG(longit,bcp);
1400 PUTLONG(alt,bcp);
1401
1402 return (16); /* size of RR in octets */
1403}
1404
1405const char *
1406loc_ntoa(binary, ascii)
1407 const u_char *binary;
1408 char *ascii;
1409{
1410 return loc_ntoal(binary, ascii, 255);
1411}
1412
1413/* takes an on-the-wire LOC RR and formats it in a human readable format. */
1414static const char *
1415loc_ntoal(binary, ascii, ascii_len)
1416 const u_char *binary;
1417 char *ascii;
1418 int ascii_len;
1419{
1420 static char *error = "?";
1421 register const u_char *cp = binary;
1422
1423 int latdeg, latmin, latsec, latsecfrac;
1424 int longdeg, longmin, longsec, longsecfrac;
1425 char northsouth, eastwest;
1426 int altmeters, altfrac, altsign;
1427
1428 const int referencealt = 100000 * 100;
1429
1430 int32_t latval, longval, altval;
1431 u_int32_t templ;
1432 u_int8_t sizeval, hpval, vpval, versionval;
1433
1434 char *sizestr, *hpstr, *vpstr;
1435
1436 versionval = *cp++;
1437
1438 if (versionval) {
1439 snprintf(ascii, ascii_len, "; error: unknown LOC RR version");
1440 return (ascii);
1441 }
1442
1443 sizeval = *cp++;
1444
1445 hpval = *cp++;
1446 vpval = *cp++;
1447
1448 GETLONG(templ, cp);
1449 latval = (templ - ((unsigned)1<<31));
1450
1451 GETLONG(templ, cp);
1452 longval = (templ - ((unsigned)1<<31));
1453
1454 GETLONG(templ, cp);
1455 if (templ < referencealt) { /* below WGS 84 spheroid */
1456 altval = referencealt - templ;
1457 altsign = -1;
1458 } else {
1459 altval = templ - referencealt;
1460 altsign = 1;
1461 }
1462
1463 if (latval < 0) {
1464 northsouth = 'S';
1465 latval = -latval;
1466 } else
1467 northsouth = 'N';
1468
1469 latsecfrac = latval % 1000;
1470 latval = latval / 1000;
1471 latsec = latval % 60;
1472 latval = latval / 60;
1473 latmin = latval % 60;
1474 latval = latval / 60;
1475 latdeg = latval;
1476
1477 if (longval < 0) {
1478 eastwest = 'W';
1479 longval = -longval;
1480 } else
1481 eastwest = 'E';
1482
1483 longsecfrac = longval % 1000;
1484 longval = longval / 1000;
1485 longsec = longval % 60;
1486 longval = longval / 60;
1487 longmin = longval % 60;
1488 longval = longval / 60;
1489 longdeg = longval;
1490
1491 altfrac = altval % 100;
1492 altmeters = (altval / 100) * altsign;
1493
1494 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1495 sizestr = error;
1496 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1497 hpstr = error;
1498 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1499 vpstr = error;
1500
1501 snprintf(ascii, ascii_len,
1502 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1503 latdeg, latmin, latsec, latsecfrac, northsouth,
1504 longdeg, longmin, longsec, longsecfrac, eastwest,
1505 altmeters, altfrac, sizestr, hpstr, vpstr);
1506
1507 if (sizestr != error)
1508 free(sizestr);
1509 if (hpstr != error)
1510 free(hpstr);
1511 if (vpstr != error)
1512 free(vpstr);
1513
1514 return (ascii);
1515}
1516
1517
1518/* Return the number of DNS hierarchy levels in the name. */
1519int
1520__dn_count_labels(name)
1521 char *name;
1522{
1523 int i, len, count;
1524
1525 len = strlen(name);
1526
1527 for(i = 0, count = 0; i < len; i++) {
1528 if (name[i] == '.')
1529 count++;
1530 }
1531
1532 /* don't count initial wildcard */
1533 if (name[0] == '*')
1534 if (count)
1535 count--;
1536
1537 /* don't count the null label for root. */
1538 /* if terminating '.' not found, must adjust */
1539 /* count to include last label */
1540 if (len > 0 && name[len-1] != '.')
1541 count++;
1542 return (count);
1543}
1544
1545
1546/*
1547 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1548 * SIG records are required to be printed like this, by the Secure DNS RFC.
1549 */
1550char *
1551__p_secstodate (secs)
1552 unsigned long secs;
1553{
1554 static char output[15]; /* YYYYMMDDHHMMSS and null */
1555 time_t clock = secs;
1556 struct tm *time;
1557
1558 time = gmtime(&clock);
1559 time->tm_year += 1900;
1560 time->tm_mon += 1;
1561 snprintf(output, sizeof output, "%04d%02d%02d%02d%02d%02d",
1562 time->tm_year, time->tm_mon, time->tm_mday,
1563 time->tm_hour, time->tm_min, time->tm_sec);
1564 return (output);
749} 1565}