summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/res_debug.c
diff options
context:
space:
mode:
authordownsj <>1997-03-13 19:07:41 +0000
committerdownsj <>1997-03-13 19:07:41 +0000
commit05882f672fb3bf8797e68cc2d68f8406e1cb7b07 (patch)
treef9cdfe48f1a2f821eb8d11d33976f3f19cd834db /src/lib/libc/net/res_debug.c
parentb0e0ca363d82adf8768f67857659b9590e0e6954 (diff)
downloadopenbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.tar.gz
openbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.tar.bz2
openbsd-05882f672fb3bf8797e68cc2d68f8406e1cb7b07.zip
Integrate BIND 4.9.5 resolver and associated routines.
Includes the DNS aware getnetby*() routines and IPv6 support.
Diffstat (limited to 'src/lib/libc/net/res_debug.c')
-rw-r--r--src/lib/libc/net/res_debug.c1055
1 files changed, 874 insertions, 181 deletions
diff --git a/src/lib/libc/net/res_debug.c b/src/lib/libc/net/res_debug.c
index ae6c030a1f..7fd6d4a21c 100644
--- a/src/lib/libc/net/res_debug.c
+++ b/src/lib/libc/net/res_debug.c
@@ -1,7 +1,11 @@
1/*- 1/* $OpenBSD: res_debug.c,v 1.5 1997/03/13 19:07:37 downsj Exp $ */
2
3/*
4 * ++Copyright++ 1985, 1990, 1993
5 * -
2 * Copyright (c) 1985, 1990, 1993 6 * Copyright (c) 1985, 1990, 1993
3 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
4 * 8 *
5 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
7 * are met: 11 * are met:
@@ -48,63 +52,61 @@
48 * 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
49 * SOFTWARE. 53 * SOFTWARE.
50 * - 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.
51 * --Copyright-- 77 * --Copyright--
52 */ 78 */
53 79
54#if defined(LIBC_SCCS) && !defined(lint) 80#if defined(LIBC_SCCS) && !defined(lint)
55static char rcsid[] = "$OpenBSD: res_debug.c,v 1.4 1996/09/15 09:31:18 tholo Exp $"; 81#if 0
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 $";
84#else
85static char rcsid[] = "$OpenBSD: res_debug.c,v 1.5 1997/03/13 19:07:37 downsj Exp $";
86#endif
56#endif /* LIBC_SCCS and not lint */ 87#endif /* LIBC_SCCS and not lint */
57 88
58#include <sys/param.h> 89#include <sys/param.h>
90#include <sys/types.h>
91#include <sys/socket.h>
59#include <netinet/in.h> 92#include <netinet/in.h>
60#include <arpa/inet.h> 93#include <arpa/inet.h>
61#include <arpa/nameser.h> 94#include <arpa/nameser.h>
95
96#include <ctype.h>
97#include <netdb.h>
62#include <resolv.h> 98#include <resolv.h>
63#include <stdio.h> 99#include <stdio.h>
100#include <time.h>
101
102#include <stdlib.h>
64#include <string.h> 103#include <string.h>
65#include <netdb.h>
66 104
67void __fp_query(); 105extern const char *_res_opcodes[];
68 106extern const char *_res_resultcodes[];
69char *_res_opcodes[] = {
70 "QUERY",
71 "IQUERY",
72 "CQUERYM",
73 "CQUERYU", /* experimental */
74 "NOTIFY", /* experimental */
75 "5",
76 "6",
77 "7",
78 "8",
79 "UPDATEA",
80 "UPDATED",
81 "UPDATEDA",
82 "UPDATEM",
83 "UPDATEMA",
84 "ZONEINIT",
85 "ZONEREF",
86};
87 107
88char *_res_resultcodes[] = { 108/* XXX: we should use getservbyport() instead. */
89 "NOERROR", 109static const char *
90 "FORMERR",
91 "SERVFAIL",
92 "NXDOMAIN",
93 "NOTIMP",
94 "REFUSED",
95 "6",
96 "7",
97 "8",
98 "9",
99 "10",
100 "11",
101 "12",
102 "13",
103 "14",
104 "NOCHANGE",
105};
106
107static char *
108dewks(wks) 110dewks(wks)
109 int wks; 111 int wks;
110{ 112{
@@ -200,7 +202,8 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)
200 */ 202 */
201 sflag = (_res.pfcode & pflag); 203 sflag = (_res.pfcode & pflag);
202 if (n = ntohs(cnt)) { 204 if (n = ntohs(cnt)) {
203 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 205 if ((!_res.pfcode) ||
206 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
204 fprintf(file, hs); 207 fprintf(file, hs);
205 while (--n >= 0) { 208 while (--n >= 0) {
206 if ((!_res.pfcode) || sflag) { 209 if ((!_res.pfcode) || sflag) {
@@ -208,20 +211,21 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)
208 } else { 211 } else {
209 unsigned int dlen; 212 unsigned int dlen;
210 cp += __dn_skipname(cp, cp + MAXCDNAME); 213 cp += __dn_skipname(cp, cp + MAXCDNAME);
211 cp += sizeof(u_int16_t); 214 cp += INT16SZ;
212 cp += sizeof(u_int16_t); 215 cp += INT16SZ;
213 cp += sizeof(u_int32_t); 216 cp += INT32SZ;
214 dlen = _getshort((u_char*)cp); 217 dlen = _getshort((u_char*)cp);
215 cp += sizeof(u_int16_t); 218 cp += INT16SZ;
216 cp += dlen; 219 cp += dlen;
217 } 220 }
218 if ((cp - msg) > len) 221 if ((cp - msg) > len)
219 return (NULL); 222 return (NULL);
220 } 223 }
221 if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) 224 if ((!_res.pfcode) ||
225 ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
222 putc('\n', file); 226 putc('\n', file);
223 } 227 }
224 return(cp); 228 return (cp);
225} 229}
226 230
227void 231void
@@ -268,7 +272,7 @@ __fp_nquery(msg, len, file)
268 if ((_res.options & RES_INIT) == 0 && res_init() == -1) 272 if ((_res.options & RES_INIT) == 0 && res_init() == -1)
269 return; 273 return;
270 274
271#define TruncTest(x) if (x >= endMark) goto trunc 275#define TruncTest(x) if (x > endMark) goto trunc
272#define ErrorTest(x) if (x == NULL) goto error 276#define ErrorTest(x) if (x == NULL) goto error
273 277
274 /* 278 /*
@@ -276,9 +280,9 @@ __fp_nquery(msg, len, file)
276 */ 280 */
277 hp = (HEADER *)msg; 281 hp = (HEADER *)msg;
278 cp = msg + HFIXEDSZ; 282 cp = msg + HFIXEDSZ;
279 endMark = cp + len; 283 endMark = msg + len;
280 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { 284 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
281 fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d", 285 fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
282 _res_opcodes[hp->opcode], 286 _res_opcodes[hp->opcode],
283 _res_resultcodes[hp->rcode], 287 _res_resultcodes[hp->rcode],
284 ntohs(hp->id)); 288 ntohs(hp->id));
@@ -287,22 +291,28 @@ __fp_nquery(msg, len, file)
287 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX)) 291 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
288 putc(';', file); 292 putc(';', file);
289 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { 293 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
290 fprintf(file,"; flags:"); 294 fprintf(file, "; flags:");
291 if (hp->qr) 295 if (hp->qr)
292 fprintf(file," qr"); 296 fprintf(file, " qr");
293 if (hp->aa) 297 if (hp->aa)
294 fprintf(file," aa"); 298 fprintf(file, " aa");
295 if (hp->tc) 299 if (hp->tc)
296 fprintf(file," tc"); 300 fprintf(file, " tc");
297 if (hp->rd) 301 if (hp->rd)
298 fprintf(file," rd"); 302 fprintf(file, " rd");
299 if (hp->ra) 303 if (hp->ra)
300 fprintf(file," ra"); 304 fprintf(file, " ra");
305 if (hp->unused)
306 fprintf(file, " UNUSED-BIT-ON");
307 if (hp->ad)
308 fprintf(file, " ad");
309 if (hp->cd)
310 fprintf(file, " cd");
301 } 311 }
302 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { 312 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
303 fprintf(file,"; Ques: %d", ntohs(hp->qdcount)); 313 fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
304 fprintf(file,", Ans: %d", ntohs(hp->ancount)); 314 fprintf(file, ", Ans: %d", ntohs(hp->ancount));
305 fprintf(file,", Auth: %d", ntohs(hp->nscount)); 315 fprintf(file, ", Auth: %d", ntohs(hp->nscount));
306 fprintf(file, ", Addit: %d", ntohs(hp->arcount)); 316 fprintf(file, ", Addit: %d", ntohs(hp->arcount));
307 } 317 }
308 if ((!_res.pfcode) || (_res.pfcode & 318 if ((!_res.pfcode) || (_res.pfcode &
@@ -314,10 +324,10 @@ __fp_nquery(msg, len, file)
314 */ 324 */
315 if (n = ntohs(hp->qdcount)) { 325 if (n = ntohs(hp->qdcount)) {
316 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 326 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
317 fprintf(file,";; QUESTIONS:\n"); 327 fprintf(file, ";; QUESTIONS:\n");
318 while (--n >= 0) { 328 while (--n >= 0) {
319 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 329 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
320 fprintf(file,";;\t"); 330 fprintf(file, ";;\t");
321 TruncTest(cp); 331 TruncTest(cp);
322 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) 332 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
323 cp = p_cdnname(cp, msg, len, file); 333 cp = p_cdnname(cp, msg, len, file);
@@ -372,7 +382,7 @@ __fp_nquery(msg, len, file)
372 return; 382 return;
373 trunc: 383 trunc:
374 fprintf(file, "\n;; ...truncated\n"); 384 fprintf(file, "\n;; ...truncated\n");
375 return; 385 return;
376 error: 386 error:
377 fprintf(file, "\n;; ...malformed\n"); 387 fprintf(file, "\n;; ...malformed\n");
378} 388}
@@ -411,6 +421,30 @@ __p_cdname(cp, msg, file)
411 return (p_cdnname(cp, msg, PACKETSZ, file)); 421 return (p_cdnname(cp, msg, PACKETSZ, file));
412} 422}
413 423
424
425/* Return a fully-qualified domain name from a compressed name (with
426 length supplied). */
427
428const u_char *
429__p_fqnname(cp, msg, msglen, name, namelen)
430 const u_char *cp, *msg;
431 int msglen;
432 char *name;
433 int namelen;
434{
435 int n, newlen;
436
437 if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
438 return (NULL);
439 newlen = strlen (name);
440 if (newlen == 0 || name[newlen - 1] != '.')
441 if (newlen+1 >= namelen) /* Lack space for final dot */
442 return (NULL);
443 else
444 strcpy(name + newlen, ".");
445 return (cp + n);
446}
447
414/* XXX: the rest of these functions need to become length-limited, too. (vix) 448/* XXX: the rest of these functions need to become length-limited, too. (vix)
415 */ 449 */
416 450
@@ -420,18 +454,13 @@ __p_fqname(cp, msg, file)
420 FILE *file; 454 FILE *file;
421{ 455{
422 char name[MAXDNAME]; 456 char name[MAXDNAME];
423 int n; 457 const u_char *n;
424 458
425 if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0) 459 n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
460 if (n == NULL)
426 return (NULL); 461 return (NULL);
427 if (name[0] == '\0') { 462 fputs(name, file);
428 putc('.', file); 463 return (n);
429 } else {
430 fputs(name, file);
431 if (name[strlen(name) - 1] != '.')
432 putc('.', file);
433 }
434 return (cp + n);
435} 464}
436 465
437/* 466/*
@@ -447,21 +476,27 @@ __p_rr(cp, msg, file)
447 const u_char *cp1, *cp2; 476 const u_char *cp1, *cp2;
448 u_int32_t tmpttl, t; 477 u_int32_t tmpttl, t;
449 int lcnt; 478 int lcnt;
479 u_int16_t keyflags;
480 char rrname[MAXDNAME]; /* The fqdn of this RR */
481 char base64_key[MAX_KEY_BASE64];
450 482
451 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 483 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
452 h_errno = NETDB_INTERNAL; 484 h_errno = NETDB_INTERNAL;
453 return (NULL); 485 return (NULL);
454 } 486 }
455 if ((cp = p_fqname(cp, msg, file)) == NULL) 487 cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
488 if (!cp)
456 return (NULL); /* compression error */ 489 return (NULL); /* compression error */
457 type = _getshort(cp); 490 fputs(rrname, file);
458 cp += sizeof(u_int16_t); 491
459 class = _getshort(cp); 492 type = _getshort((u_char*)cp);
460 cp += sizeof(u_int16_t); 493 cp += INT16SZ;
461 tmpttl = _getlong(cp); 494 class = _getshort((u_char*)cp);
462 cp += sizeof(u_int32_t); 495 cp += INT16SZ;
463 dlen = _getshort(cp); 496 tmpttl = _getlong((u_char*)cp);
464 cp += sizeof(u_int16_t); 497 cp += INT32SZ;
498 dlen = _getshort((u_char*)cp);
499 cp += INT16SZ;
465 cp1 = cp; 500 cp1 = cp;
466 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) 501 if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
467 fprintf(file, "\t%lu", (u_long)tmpttl); 502 fprintf(file, "\t%lu", (u_long)tmpttl);
@@ -476,9 +511,9 @@ __p_rr(cp, msg, file)
476 switch (class) { 511 switch (class) {
477 case C_IN: 512 case C_IN:
478 case C_HS: 513 case C_HS:
479 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 514 bcopy(cp, (char *)&inaddr, INADDRSZ);
480 if (dlen == 4) { 515 if (dlen == 4) {
481 fprintf(file,"\t%s", inet_ntoa(inaddr)); 516 fprintf(file, "\t%s", inet_ntoa(inaddr));
482 cp += dlen; 517 cp += dlen;
483 } else if (dlen == 7) { 518 } else if (dlen == 7) {
484 char *address; 519 char *address;
@@ -486,11 +521,11 @@ __p_rr(cp, msg, file)
486 u_short port; 521 u_short port;
487 522
488 address = inet_ntoa(inaddr); 523 address = inet_ntoa(inaddr);
489 cp += sizeof(inaddr); 524 cp += INADDRSZ;
490 protocol = *cp; 525 protocol = *(u_char*)cp;
491 cp += sizeof(u_char); 526 cp += sizeof (u_char);
492 port = _getshort(cp); 527 port = _getshort((u_char*)cp);
493 cp += sizeof(u_int16_t); 528 cp += INT16SZ;
494 fprintf(file, "\t%s\t; proto %d, port %d", 529 fprintf(file, "\t%s\t; proto %d, port %d",
495 address, protocol, port); 530 address, protocol, port);
496 } 531 }
@@ -513,15 +548,27 @@ __p_rr(cp, msg, file)
513 case T_HINFO: 548 case T_HINFO:
514 case T_ISDN: 549 case T_ISDN:
515 cp2 = cp + dlen; 550 cp2 = cp + dlen;
516 if (n = *cp++) { 551 (void) fputs("\t\"", file);
517 fprintf(file,"\t%.*s", n, cp); 552 if ((n = (unsigned char) *cp++) != 0) {
518 cp += n; 553 for (c = n; c > 0 && cp < cp2; c--) {
554 if (strchr("\n\"\\", *cp))
555 (void) putc('\\', file);
556 (void) putc(*cp++, file);
557 }
519 } 558 }
520 if ((cp < cp2) && (n = *cp++)) { 559 putc('"', file);
521 fprintf(file,"\t%.*s", n, cp); 560 if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
522 cp += n; 561 (void) fputs ("\t\"", file);
523 } else if (type == T_HINFO) 562 for (c = n; c > 0 && cp < cp2; c--) {
563 if (strchr("\n\"\\", *cp))
564 (void) putc('\\', file);
565 (void) putc(*cp++, file);
566 }
567 putc('"', file);
568 } else if (type == T_HINFO) {
569 (void) fputs("\"?\"", file);
524 fprintf(file, "\n;; *** Warning *** OS-type missing"); 570 fprintf(file, "\n;; *** Warning *** OS-type missing");
571 }
525 break; 572 break;
526 573
527 case T_SOA: 574 case T_SOA:
@@ -532,18 +579,18 @@ __p_rr(cp, msg, file)
532 if ((cp = p_fqname(cp, msg, file)) == NULL) 579 if ((cp = p_fqname(cp, msg, file)) == NULL)
533 return (NULL); 580 return (NULL);
534 fputs(" (\n", file); 581 fputs(" (\n", file);
535 t = _getlong(cp); cp += sizeof(u_int32_t); 582 t = _getlong((u_char*)cp); cp += INT32SZ;
536 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); 583 fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
537 t = _getlong(cp); cp += sizeof(u_int32_t); 584 t = _getlong((u_char*)cp); cp += INT32SZ;
538 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", 585 fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
539 (u_long)t, __p_time(t)); 586 (u_long)t, __p_time(t));
540 t = _getlong(cp); cp += sizeof(u_int32_t); 587 t = _getlong((u_char*)cp); cp += INT32SZ;
541 fprintf(file, "\t\t\t%lu\t; retry (%s)\n", 588 fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
542 (u_long)t, __p_time(t)); 589 (u_long)t, __p_time(t));
543 t = _getlong(cp); cp += sizeof(u_int32_t); 590 t = _getlong((u_char*)cp); cp += INT32SZ;
544 fprintf(file, "\t\t\t%lu\t; expire (%s)\n", 591 fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
545 (u_long)t, __p_time(t)); 592 (u_long)t, __p_time(t));
546 t = _getlong(cp); cp += sizeof(u_int32_t); 593 t = _getlong((u_char*)cp); cp += INT32SZ;
547 fprintf(file, "\t\t\t%lu )\t; minimum (%s)", 594 fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
548 (u_long)t, __p_time(t)); 595 (u_long)t, __p_time(t));
549 break; 596 break;
@@ -551,14 +598,14 @@ __p_rr(cp, msg, file)
551 case T_MX: 598 case T_MX:
552 case T_AFSDB: 599 case T_AFSDB:
553 case T_RT: 600 case T_RT:
554 fprintf(file, "\t%d ", _getshort(cp)); 601 fprintf(file, "\t%d ", _getshort((u_char*)cp));
555 cp += INT16SZ; 602 cp += INT16SZ;
556 if ((cp = p_fqname(cp, msg, file)) == NULL) 603 if ((cp = p_fqname(cp, msg, file)) == NULL)
557 return (NULL); 604 return (NULL);
558 break; 605 break;
559 606
560 case T_PX: 607 case T_PX:
561 fprintf(file, "\t%d ", _getshort(cp)); 608 fprintf(file, "\t%d ", _getshort((u_char*)cp));
562 cp += INT16SZ; 609 cp += INT16SZ;
563 if ((cp = p_fqname(cp, msg, file)) == NULL) 610 if ((cp = p_fqname(cp, msg, file)) == NULL)
564 return (NULL); 611 return (NULL);
@@ -567,28 +614,93 @@ __p_rr(cp, msg, file)
567 return (NULL); 614 return (NULL);
568 break; 615 break;
569 616
570 case T_TXT:
571 case T_X25: 617 case T_X25:
618 cp2 = cp + dlen;
572 (void) fputs("\t\"", file); 619 (void) fputs("\t\"", file);
620 if ((n = (unsigned char) *cp++) != 0) {
621 for (c = n; c > 0 && cp < cp2; c--) {
622 if (strchr("\n\"\\", *cp))
623 (void) putc('\\', file);
624 (void) putc(*cp++, file);
625 }
626 }
627 putc('"', file);
628 break;
629
630 case T_TXT:
631 (void) putc('\t', file);
573 cp2 = cp1 + dlen; 632 cp2 = cp1 + dlen;
574 while (cp < cp2) { 633 while (cp < cp2) {
634 putc('"', file);
575 if (n = (unsigned char) *cp++) { 635 if (n = (unsigned char) *cp++) {
576 for (c = n; c > 0 && cp < cp2; c--) 636 for (c = n; c > 0 && cp < cp2; c--) {
577 if ((*cp == '\n') || (*cp == '"')) { 637 if (strchr("\n\"\\", *cp))
578 (void) putc('\\', file); 638 (void) putc('\\', file);
579 (void) putc(*cp++, file); 639 (void) putc(*cp++, file);
580 } else 640 }
581 (void) putc(*cp++, file);
582 } 641 }
642 putc('"', file);
643 if (cp < cp2)
644 putc(' ', file);
583 } 645 }
584 putc('"', file); 646 break;
585 break;
586 647
587 case T_NSAP: 648 case T_NSAP:
588 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); 649 (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
589 cp += dlen; 650 cp += dlen;
590 break; 651 break;
591 652
653 case T_AAAA: {
654 char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
655
656 fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t));
657 cp += dlen;
658 break;
659 }
660
661 case T_LOC: {
662 char t[255];
663
664 fprintf(file, "\t%s", loc_ntoa(cp, t));
665 cp += dlen;
666 break;
667 }
668
669 case T_NAPTR: {
670 u_int order, preference;
671
672 order = _getshort(cp); cp += INT16SZ;
673 preference = _getshort(cp); cp += INT16SZ;
674 fprintf(file, "\t%u %u ",order, preference);
675 /* Flags */
676 n = *cp++;
677 fprintf(file,"\"%.*s\" ", (int)n, cp);
678 cp += n;
679 /* Service */
680 n = *cp++;
681 fprintf(file,"\"%.*s\" ", (int)n, cp);
682 cp += n;
683 /* Regexp */
684 n = *cp++;
685 fprintf(file,"\"%.*s\" ", (int)n, cp);
686 cp += n;
687 if ((cp = p_fqname(cp, msg, file)) == NULL)
688 return (NULL);
689 break;
690 }
691
692 case T_SRV: {
693 u_int priority, weight, port;
694
695 priority = _getshort(cp); cp += INT16SZ;
696 weight = _getshort(cp); cp += INT16SZ;
697 port = _getshort(cp); cp += INT16SZ;
698 fprintf(file, "\t%u %u %u ", priority, weight, port);
699 if ((cp = p_fqname(cp, msg, file)) == NULL)
700 return (NULL);
701 break;
702 }
703
592 case T_MINFO: 704 case T_MINFO:
593 case T_RP: 705 case T_RP:
594 putc('\t', file); 706 putc('\t', file);
@@ -601,33 +713,33 @@ __p_rr(cp, msg, file)
601 713
602 case T_UINFO: 714 case T_UINFO:
603 putc('\t', file); 715 putc('\t', file);
604 fputs((char *) cp, file); 716 fputs((char *)cp, file);
605 cp += dlen; 717 cp += dlen;
606 break; 718 break;
607 719
608 case T_UID: 720 case T_UID:
609 case T_GID: 721 case T_GID:
610 if (dlen == 4) { 722 if (dlen == 4) {
611 fprintf(file,"\t%u", _getlong(cp)); 723 fprintf(file, "\t%u", _getlong((u_char*)cp));
612 cp += sizeof(int32_t); 724 cp += INT32SZ;
613 } 725 }
614 break; 726 break;
615 727
616 case T_WKS: 728 case T_WKS:
617 if (dlen < sizeof(u_int32_t) + 1) 729 if (dlen < INT32SZ + 1)
618 break; 730 break;
619 bcopy(cp, (char *)&inaddr, sizeof(inaddr)); 731 bcopy(cp, (char *)&inaddr, INADDRSZ);
620 cp += sizeof(u_int32_t); 732 cp += INT32SZ;
621 fprintf(file, "\t%s %s ( ", 733 fprintf(file, "\t%s %s ( ",
622 inet_ntoa(inaddr), 734 inet_ntoa(inaddr),
623 deproto((int) *cp)); 735 deproto((int) *cp));
624 cp += sizeof(u_char); 736 cp += sizeof (u_char);
625 n = 0; 737 n = 0;
626 lcnt = 0; 738 lcnt = 0;
627 while (cp < cp1 + dlen) { 739 while (cp < cp1 + dlen) {
628 c = *cp++; 740 c = *cp++;
629 do { 741 do {
630 if (c & 0200) { 742 if (c & 0200) {
631 if (lcnt == 0) { 743 if (lcnt == 0) {
632 fputs("\n\t\t\t", file); 744 fputs("\n\t\t\t", file);
633 lcnt = 5; 745 lcnt = 5;
@@ -636,12 +748,78 @@ __p_rr(cp, msg, file)
636 putc(' ', file); 748 putc(' ', file);
637 lcnt--; 749 lcnt--;
638 } 750 }
639 c <<= 1; 751 c <<= 1;
640 } while (++n & 07); 752 } while (++n & 07);
641 } 753 }
642 putc(')', file); 754 putc(')', file);
643 break; 755 break;
644 756
757 case T_KEY:
758 putc('\t', file);
759 keyflags = _getshort(cp);
760 cp += 2;
761 fprintf(file,"0x%04x", keyflags ); /* flags */
762 fprintf(file," %u", *cp++); /* protocol */
763 fprintf(file," %u (", *cp++); /* algorithm */
764
765 n = b64_ntop(cp, (cp1 + dlen) - cp,
766 base64_key, sizeof base64_key);
767 for (c = 0; c < n; ++c) {
768 if (0 == (c & 0x3F))
769 fprintf(file, "\n\t");
770 putc(base64_key[c], file); /* public key data */
771 }
772
773 fprintf(file, " )");
774 if (n < 0)
775 fprintf(file, "\t; BAD BASE64");
776 fflush(file);
777 cp = cp1 + dlen;
778 break;
779
780 case T_SIG:
781 type = _getshort((u_char*)cp);
782 cp += INT16SZ;
783 fprintf(file, " %s", p_type(type));
784 fprintf(file, "\t%d", *cp++); /* algorithm */
785 /* Check label value and print error if wrong. */
786 n = *cp++;
787 c = dn_count_labels (rrname);
788 if (n != c)
789 fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
790 n, c);
791 /* orig ttl */
792 n = _getlong((u_char*)cp);
793 if (n != tmpttl)
794 fprintf(file, " %u", n);
795 cp += INT32SZ;
796 /* sig expire */
797 fprintf(file, " (\n\t%s",
798 __p_secstodate(_getlong((u_char*)cp)));
799 cp += INT32SZ;
800 /* time signed */
801 fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
802 cp += INT32SZ;
803 /* sig footprint */
804 fprintf(file," %u ", _getshort((u_char*)cp));
805 cp += INT16SZ;
806 /* signer's name */
807 cp = p_fqname(cp, msg, file);
808 n = b64_ntop(cp, (cp1 + dlen) - cp,
809 base64_key, sizeof base64_key);
810 for (c = 0; c < n; c++) {
811 if (0 == (c & 0x3F))
812 fprintf (file, "\n\t");
813 putc(base64_key[c], file); /* signature */
814 }
815 /* Clean up... */
816 fprintf(file, " )");
817 if (n < 0)
818 fprintf(file, "\t; BAD BASE64");
819 fflush(file);
820 cp = cp1+dlen;
821 break;
822
645#ifdef ALLOW_T_UNSPEC 823#ifdef ALLOW_T_UNSPEC
646 case T_UNSPEC: 824 case T_UNSPEC:
647 { 825 {
@@ -660,7 +838,7 @@ __p_rr(cp, msg, file)
660#endif /* ALLOW_T_UNSPEC */ 838#endif /* ALLOW_T_UNSPEC */
661 839
662 default: 840 default:
663 fprintf(file,"\t?%d?", type); 841 fprintf(file, "\t?%d?", type);
664 cp += dlen; 842 cp += dlen;
665 } 843 }
666#if 0 844#if 0
@@ -669,7 +847,7 @@ __p_rr(cp, msg, file)
669 putc('\n', file); 847 putc('\n', file);
670#endif 848#endif
671 if (cp - cp1 != dlen) { 849 if (cp - cp1 != dlen) {
672 fprintf(file,";; packet size error (found %d, dlen was %d)\n", 850 fprintf(file, ";; packet size error (found %d, dlen was %d)\n",
673 cp - cp1, dlen); 851 cp - cp1, dlen);
674 cp = NULL; 852 cp = NULL;
675 } 853 }
@@ -677,54 +855,144 @@ __p_rr(cp, msg, file)
677} 855}
678 856
679/* 857/*
858 * Names of RR classes and qclasses. Classes and qclasses are the same, except
859 * that C_ANY is a qclass but not a class. (You can ask for records of class
860 * C_ANY, but you can't have any records of that class in the database.)
861 */
862const struct res_sym __p_class_syms[] = {
863 {C_IN, "IN"},
864 {C_CHAOS, "CHAOS"},
865 {C_HS, "HS"},
866 {C_HS, "HESIOD"},
867 {C_ANY, "ANY"},
868 {C_IN, (char *)0}
869};
870
871/*
872 * Names of RR types and qtypes. Types and qtypes are the same, except
873 * that T_ANY is a qtype but not a type. (You can ask for records of type
874 * T_ANY, but you can't have any records of that type in the database.)
875 */
876const struct res_sym __p_type_syms[] = {
877 {T_A, "A", "address"},
878 {T_NS, "NS", "name server"},
879 {T_MD, "MD", "mail destination (deprecated)"},
880 {T_MF, "MF", "mail forwarder (deprecated)"},
881 {T_CNAME, "CNAME", "canonical name"},
882 {T_SOA, "SOA", "start of authority"},
883 {T_MB, "MB", "mailbox"},
884 {T_MG, "MG", "mail group member"},
885 {T_MR, "MR", "mail rename"},
886 {T_NULL, "NULL", "null"},
887 {T_WKS, "WKS", "well-known service (deprecated)"},
888 {T_PTR, "PTR", "domain name pointer"},
889 {T_HINFO, "HINFO", "host information"},
890 {T_MINFO, "MINFO", "mailbox information"},
891 {T_MX, "MX", "mail exchanger"},
892 {T_TXT, "TXT", "text"},
893 {T_RP, "RP", "responsible person"},
894 {T_AFSDB, "AFSDB", "DCE or AFS server"},
895 {T_X25, "X25", "X25 address"},
896 {T_ISDN, "ISDN", "ISDN address"},
897 {T_RT, "RT", "router"},
898 {T_NSAP, "NSAP", "nsap address"},
899 {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
900 {T_SIG, "SIG", "signature"},
901 {T_KEY, "KEY", "key"},
902 {T_PX, "PX", "mapping information"},
903 {T_GPOS, "GPOS", "geographical position (withdrawn)"},
904 {T_AAAA, "AAAA", "IPv6 address"},
905 {T_LOC, "LOC", "location"},
906 {T_NXT, "NXT", "next valid name (unimplemented)"},
907 {T_EID, "EID", "endpoint identifier (unimplemented)"},
908 {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
909 {T_SRV, "SRV", "server selection"},
910 {T_ATMA, "ATMA", "ATM address (unimplemented)"},
911 {T_IXFR, "IXFR", "incremental zone transfer"},
912 {T_AXFR, "AXFR", "zone transfer"},
913 {T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
914 {T_MAILA, "MAILA", "mail agent (deprecated)"},
915 {T_UINFO, "UINFO", "user information (nonstandard)"},
916 {T_UID, "UID", "user ID (nonstandard)"},
917 {T_GID, "GID", "group ID (nonstandard)"},
918 {T_NAPTR, "NAPTR", "URN Naming Authority"},
919#ifdef ALLOW_T_UNSPEC
920 {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"},
921#endif /* ALLOW_T_UNSPEC */
922 {T_ANY, "ANY", "\"any\""},
923 {0, NULL, NULL}
924};
925
926int
927__sym_ston(syms, name, success)
928 const struct res_sym *syms;
929 char *name;
930 int *success;
931{
932 for (NULL; syms->name != 0; syms++) {
933 if (strcasecmp (name, syms->name) == 0) {
934 if (success)
935 *success = 1;
936 return (syms->number);
937 }
938 }
939 if (success)
940 *success = 0;
941 return (syms->number); /* The default value. */
942}
943
944const char *
945__sym_ntos(syms, number, success)
946 const struct res_sym *syms;
947 int number;
948 int *success;
949{
950 static char unname[20];
951
952 for (NULL; syms->name != 0; syms++) {
953 if (number == syms->number) {
954 if (success)
955 *success = 1;
956 return (syms->name);
957 }
958 }
959
960 sprintf (unname, "%d", number);
961 if (success)
962 *success = 0;
963 return (unname);
964}
965
966
967const char *
968__sym_ntop(syms, number, success)
969 const struct res_sym *syms;
970 int number;
971 int *success;
972{
973 static char unname[20];
974
975 for (NULL; syms->name != 0; syms++) {
976 if (number == syms->number) {
977 if (success)
978 *success = 1;
979 return (syms->humanname);
980 }
981 }
982 sprintf(unname, "%d", number);
983 if (success)
984 *success = 0;
985 return (unname);
986}
987
988/*
680 * Return a string for the type 989 * Return a string for the type
681 */ 990 */
682const char * 991const char *
683__p_type(type) 992__p_type(type)
684 int type; 993 int type;
685{ 994{
686 static char nbuf[20]; 995 return (__sym_ntos (__p_type_syms, type, (int *)0));
687
688 switch (type) {
689 case T_A: return "A";
690 case T_NS: return "NS";
691 case T_CNAME: return "CNAME";
692 case T_SOA: return "SOA";
693 case T_MB: return "MB";
694 case T_MG: return "MG";
695 case T_MR: return "MR";
696 case T_NULL: return "NULL";
697 case T_WKS: return "WKS";
698 case T_PTR: return "PTR";
699 case T_HINFO: return "HINFO";
700 case T_MINFO: return "MINFO";
701 case T_MX: return "MX";
702 case T_TXT: return "TXT";
703 case T_RP: return "RP";
704 case T_AFSDB: return "AFSDB";
705 case T_X25: return "X25";
706 case T_ISDN: return "ISDN";
707 case T_RT: return "RT";
708 case T_NSAP: return "NSAP";
709 case T_NSAP_PTR: return "NSAP_PTR";
710 case T_SIG: return "SIG";
711 case T_KEY: return "KEY";
712 case T_PX: return "PX";
713 case T_GPOS: return "GPOS";
714 case T_AAAA: return "AAAA";
715 case T_LOC: return "LOC";
716 case T_AXFR: return "AXFR";
717 case T_MAILB: return "MAILB";
718 case T_MAILA: return "MAILA";
719 case T_ANY: return "ANY";
720 case T_UINFO: return "UINFO";
721 case T_UID: return "UID";
722 case T_GID: return "GID";
723#ifdef ALLOW_T_UNSPEC
724 case T_UNSPEC: return "UNSPEC";
725#endif /* ALLOW_T_UNSPEC */
726 default: (void)sprintf(nbuf, "%d", type); return (nbuf);
727 }
728} 996}
729 997
730/* 998/*
@@ -734,14 +1002,7 @@ const char *
734__p_class(class) 1002__p_class(class)
735 int class; 1003 int class;
736{ 1004{
737 static char nbuf[20]; 1005 return (__sym_ntos (__p_class_syms, class, (int *)0));
738
739 switch (class) {
740 case C_IN: return "IN";
741 case C_HS: return "HS";
742 case C_ANY: return "ANY";
743 default: (void)sprintf(nbuf, "%d", class); return (nbuf);
744 }
745} 1006}
746 1007
747/* 1008/*
@@ -774,8 +1035,8 @@ __p_option(option)
774/* 1035/*
775 * Return a mnemonic for a time to live 1036 * Return a mnemonic for a time to live
776 */ 1037 */
777char * 1038const char *
778__p_time(value) 1039p_time(value)
779 u_int32_t value; 1040 u_int32_t value;
780{ 1041{
781 static char nbuf[40]; 1042 static char nbuf[40];
@@ -784,7 +1045,7 @@ __p_time(value)
784 1045
785 if (value == 0) { 1046 if (value == 0) {
786 strcpy(nbuf, "0 secs"); 1047 strcpy(nbuf, "0 secs");
787 return(nbuf); 1048 return (nbuf);
788 } 1049 }
789 1050
790 secs = value % 60; 1051 secs = value % 60;
@@ -819,5 +1080,437 @@ __p_time(value)
819 *p++ = ' '; 1080 *p++ = ' ';
820 (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); 1081 (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
821 } 1082 }
822 return(nbuf); 1083 return (nbuf);
1084}
1085
1086/*
1087 * routines to convert between on-the-wire RR format and zone file format.
1088 * Does not contain conversion to/from decimal degrees; divide or multiply
1089 * by 60*60*1000 for that.
1090 */
1091
1092static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
1093 1000000,10000000,100000000,1000000000};
1094
1095/* takes an XeY precision/size value, returns a string representation. */
1096static const char *
1097precsize_ntoa(prec)
1098 u_int8_t prec;
1099{
1100 static char retbuf[sizeof "90000000.00"];
1101 unsigned long val;
1102 int mantissa, exponent;
1103
1104 mantissa = (int)((prec >> 4) & 0x0f) % 10;
1105 exponent = (int)((prec >> 0) & 0x0f) % 10;
1106
1107 val = mantissa * poweroften[exponent];
1108
1109 (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
1110 return (retbuf);
1111}
1112
1113/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
1114static u_int8_t
1115precsize_aton(strptr)
1116 char **strptr;
1117{
1118 unsigned int mval = 0, cmval = 0;
1119 u_int8_t retval = 0;
1120 register char *cp;
1121 register int exponent;
1122 register int mantissa;
1123
1124 cp = *strptr;
1125
1126 while (isdigit(*cp))
1127 mval = mval * 10 + (*cp++ - '0');
1128
1129 if (*cp == '.') { /* centimeters */
1130 cp++;
1131 if (isdigit(*cp)) {
1132 cmval = (*cp++ - '0') * 10;
1133 if (isdigit(*cp)) {
1134 cmval += (*cp++ - '0');
1135 }
1136 }
1137 }
1138 cmval = (mval * 100) + cmval;
1139
1140 for (exponent = 0; exponent < 9; exponent++)
1141 if (cmval < poweroften[exponent+1])
1142 break;
1143
1144 mantissa = cmval / poweroften[exponent];
1145 if (mantissa > 9)
1146 mantissa = 9;
1147
1148 retval = (mantissa << 4) | exponent;
1149
1150 *strptr = cp;
1151
1152 return (retval);
1153}
1154
1155/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
1156static u_int32_t
1157latlon2ul(latlonstrptr,which)
1158 char **latlonstrptr;
1159 int *which;
1160{
1161 register char *cp;
1162 u_int32_t retval;
1163 int deg = 0, min = 0, secs = 0, secsfrac = 0;
1164
1165 cp = *latlonstrptr;
1166
1167 while (isdigit(*cp))
1168 deg = deg * 10 + (*cp++ - '0');
1169
1170 while (isspace(*cp))
1171 cp++;
1172
1173 if (!(isdigit(*cp)))
1174 goto fndhemi;
1175
1176 while (isdigit(*cp))
1177 min = min * 10 + (*cp++ - '0');
1178
1179 while (isspace(*cp))
1180 cp++;
1181
1182 if (!(isdigit(*cp)))
1183 goto fndhemi;
1184
1185 while (isdigit(*cp))
1186 secs = secs * 10 + (*cp++ - '0');
1187
1188 if (*cp == '.') { /* decimal seconds */
1189 cp++;
1190 if (isdigit(*cp)) {
1191 secsfrac = (*cp++ - '0') * 100;
1192 if (isdigit(*cp)) {
1193 secsfrac += (*cp++ - '0') * 10;
1194 if (isdigit(*cp)) {
1195 secsfrac += (*cp++ - '0');
1196 }
1197 }
1198 }
1199 }
1200
1201 while (!isspace(*cp)) /* if any trailing garbage */
1202 cp++;
1203
1204 while (isspace(*cp))
1205 cp++;
1206
1207 fndhemi:
1208 switch (*cp) {
1209 case 'N': case 'n':
1210 case 'E': case 'e':
1211 retval = ((unsigned)1<<31)
1212 + (((((deg * 60) + min) * 60) + secs) * 1000)
1213 + secsfrac;
1214 break;
1215 case 'S': case 's':
1216 case 'W': case 'w':
1217 retval = ((unsigned)1<<31)
1218 - (((((deg * 60) + min) * 60) + secs) * 1000)
1219 - secsfrac;
1220 break;
1221 default:
1222 retval = 0; /* invalid value -- indicates error */
1223 break;
1224 }
1225
1226 switch (*cp) {
1227 case 'N': case 'n':
1228 case 'S': case 's':
1229 *which = 1; /* latitude */
1230 break;
1231 case 'E': case 'e':
1232 case 'W': case 'w':
1233 *which = 2; /* longitude */
1234 break;
1235 default:
1236 *which = 0; /* error */
1237 break;
1238 }
1239
1240 cp++; /* skip the hemisphere */
1241
1242 while (!isspace(*cp)) /* if any trailing garbage */
1243 cp++;
1244
1245 while (isspace(*cp)) /* move to next field */
1246 cp++;
1247
1248 *latlonstrptr = cp;
1249
1250 return (retval);
1251}
1252
1253/* converts a zone file representation in a string to an RDATA on-the-wire
1254 * representation. */
1255int
1256loc_aton(ascii, binary)
1257 const char *ascii;
1258 u_char *binary;
1259{
1260 const char *cp, *maxcp;
1261 u_char *bcp;
1262
1263 u_int32_t latit = 0, longit = 0, alt = 0;
1264 u_int32_t lltemp1 = 0, lltemp2 = 0;
1265 int altmeters = 0, altfrac = 0, altsign = 1;
1266 u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1267 u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
1268 u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
1269 int which1 = 0, which2 = 0;
1270
1271 cp = ascii;
1272 maxcp = cp + strlen(ascii);
1273
1274 lltemp1 = latlon2ul(&cp, &which1);
1275
1276 lltemp2 = latlon2ul(&cp, &which2);
1277
1278 switch (which1 + which2) {
1279 case 3: /* 1 + 2, the only valid combination */
1280 if ((which1 == 1) && (which2 == 2)) { /* normal case */
1281 latit = lltemp1;
1282 longit = lltemp2;
1283 } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
1284 longit = lltemp1;
1285 latit = lltemp2;
1286 } else { /* some kind of brokenness */
1287 return (0);
1288 }
1289 break;
1290 default: /* we didn't get one of each */
1291 return (0);
1292 }
1293
1294 /* altitude */
1295 if (*cp == '-') {
1296 altsign = -1;
1297 cp++;
1298 }
1299
1300 if (*cp == '+')
1301 cp++;
1302
1303 while (isdigit(*cp))
1304 altmeters = altmeters * 10 + (*cp++ - '0');
1305
1306 if (*cp == '.') { /* decimal meters */
1307 cp++;
1308 if (isdigit(*cp)) {
1309 altfrac = (*cp++ - '0') * 10;
1310 if (isdigit(*cp)) {
1311 altfrac += (*cp++ - '0');
1312 }
1313 }
1314 }
1315
1316 alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
1317
1318 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1319 cp++;
1320
1321 while (isspace(*cp) && (cp < maxcp))
1322 cp++;
1323
1324 if (cp >= maxcp)
1325 goto defaults;
1326
1327 siz = precsize_aton(&cp);
1328
1329 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1330 cp++;
1331
1332 while (isspace(*cp) && (cp < maxcp))
1333 cp++;
1334
1335 if (cp >= maxcp)
1336 goto defaults;
1337
1338 hp = precsize_aton(&cp);
1339
1340 while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
1341 cp++;
1342
1343 while (isspace(*cp) && (cp < maxcp))
1344 cp++;
1345
1346 if (cp >= maxcp)
1347 goto defaults;
1348
1349 vp = precsize_aton(&cp);
1350
1351 defaults:
1352
1353 bcp = binary;
1354 *bcp++ = (u_int8_t) 0; /* version byte */
1355 *bcp++ = siz;
1356 *bcp++ = hp;
1357 *bcp++ = vp;
1358 PUTLONG(latit,bcp);
1359 PUTLONG(longit,bcp);
1360 PUTLONG(alt,bcp);
1361
1362 return (16); /* size of RR in octets */
1363}
1364
1365/* takes an on-the-wire LOC RR and formats it in a human readable format. */
1366const char *
1367loc_ntoa(binary, ascii)
1368 const u_char *binary;
1369 char *ascii;
1370{
1371 static char *error = "?";
1372 register const u_char *cp = binary;
1373
1374 int latdeg, latmin, latsec, latsecfrac;
1375 int longdeg, longmin, longsec, longsecfrac;
1376 char northsouth, eastwest;
1377 int altmeters, altfrac, altsign;
1378
1379 const int referencealt = 100000 * 100;
1380
1381 int32_t latval, longval, altval;
1382 u_int32_t templ;
1383 u_int8_t sizeval, hpval, vpval, versionval;
1384
1385 char *sizestr, *hpstr, *vpstr;
1386
1387 versionval = *cp++;
1388
1389 if (versionval) {
1390 sprintf(ascii, "; error: unknown LOC RR version");
1391 return (ascii);
1392 }
1393
1394 sizeval = *cp++;
1395
1396 hpval = *cp++;
1397 vpval = *cp++;
1398
1399 GETLONG(templ, cp);
1400 latval = (templ - ((unsigned)1<<31));
1401
1402 GETLONG(templ, cp);
1403 longval = (templ - ((unsigned)1<<31));
1404
1405 GETLONG(templ, cp);
1406 if (templ < referencealt) { /* below WGS 84 spheroid */
1407 altval = referencealt - templ;
1408 altsign = -1;
1409 } else {
1410 altval = templ - referencealt;
1411 altsign = 1;
1412 }
1413
1414 if (latval < 0) {
1415 northsouth = 'S';
1416 latval = -latval;
1417 } else
1418 northsouth = 'N';
1419
1420 latsecfrac = latval % 1000;
1421 latval = latval / 1000;
1422 latsec = latval % 60;
1423 latval = latval / 60;
1424 latmin = latval % 60;
1425 latval = latval / 60;
1426 latdeg = latval;
1427
1428 if (longval < 0) {
1429 eastwest = 'W';
1430 longval = -longval;
1431 } else
1432 eastwest = 'E';
1433
1434 longsecfrac = longval % 1000;
1435 longval = longval / 1000;
1436 longsec = longval % 60;
1437 longval = longval / 60;
1438 longmin = longval % 60;
1439 longval = longval / 60;
1440 longdeg = longval;
1441
1442 altfrac = altval % 100;
1443 altmeters = (altval / 100) * altsign;
1444
1445 if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
1446 sizestr = error;
1447 if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
1448 hpstr = error;
1449 if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
1450 vpstr = error;
1451
1452 sprintf(ascii,
1453 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1454 latdeg, latmin, latsec, latsecfrac, northsouth,
1455 longdeg, longmin, longsec, longsecfrac, eastwest,
1456 altmeters, altfrac, sizestr, hpstr, vpstr);
1457
1458 if (sizestr != error)
1459 free(sizestr);
1460 if (hpstr != error)
1461 free(hpstr);
1462 if (vpstr != error)
1463 free(vpstr);
1464
1465 return (ascii);
1466}
1467
1468
1469/* Return the number of DNS hierarchy levels in the name. */
1470int
1471__dn_count_labels(name)
1472 char *name;
1473{
1474 int i, len, count;
1475
1476 len = strlen(name);
1477
1478 for(i = 0, count = 0; i < len; i++) {
1479 if (name[i] == '.')
1480 count++;
1481 }
1482
1483 /* don't count initial wildcard */
1484 if (name[0] == '*')
1485 if (count)
1486 count--;
1487
1488 /* don't count the null label for root. */
1489 /* if terminating '.' not found, must adjust */
1490 /* count to include last label */
1491 if (len > 0 && name[len-1] != '.')
1492 count++;
1493 return (count);
1494}
1495
1496
1497/*
1498 * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
1499 * SIG records are required to be printed like this, by the Secure DNS RFC.
1500 */
1501char *
1502__p_secstodate (secs)
1503 unsigned long secs;
1504{
1505 static char output[15]; /* YYYYMMDDHHMMSS and null */
1506 time_t clock = secs;
1507 struct tm *time;
1508
1509 time = gmtime(&clock);
1510 time->tm_year += 1900;
1511 time->tm_mon += 1;
1512 sprintf(output, "%04d%02d%02d%02d%02d%02d",
1513 time->tm_year, time->tm_mon, time->tm_mday,
1514 time->tm_hour, time->tm_min, time->tm_sec);
1515 return (output);
823} 1516}