2 * ++Copyright++ 1985, 1990, 1993
4 * Copyright (c) 1985, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
37 * Permission to use, copy, modify, and distribute this software for any
38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies, and that
40 * the name of Digital Equipment Corporation not be used in advertising or
41 * publicity pertaining to distribution of the document or software without
42 * specific, written prior permission.
44 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
45 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
47 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
48 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
49 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
50 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
56 #if defined(LIBC_SCCS) && !defined(lint)
57 static char sccsid
[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
58 static char rcsid
[] = "$Id$";
59 #endif /* LIBC_SCCS and not lint */
61 #include <sys/param.h>
62 #include <sys/types.h>
63 #include <sys/socket.h>
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
66 #include <arpa/nameser.h>
72 #if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
75 # include "../conf/portability.h"
78 #if defined(USE_OPTIONS_H)
79 # include "../conf/options.h"
82 extern const char *_res_opcodes
[];
83 extern const char *_res_resultcodes
[];
85 /* XXX: we should use getservbyport() instead. */
94 case 7: return "echo";
95 case 9: return "discard";
96 case 11: return "systat";
97 case 13: return "daytime";
98 case 15: return "netstat";
99 case 17: return "qotd";
100 case 19: return "chargen";
101 case 20: return "ftp-data";
102 case 21: return "ftp";
103 case 23: return "telnet";
104 case 25: return "smtp";
105 case 37: return "time";
106 case 39: return "rlp";
107 case 42: return "name";
108 case 43: return "whois";
109 case 53: return "domain";
110 case 57: return "apts";
111 case 59: return "apfs";
112 case 67: return "bootps";
113 case 68: return "bootpc";
114 case 69: return "tftp";
115 case 77: return "rje";
116 case 79: return "finger";
117 case 87: return "link";
118 case 95: return "supdup";
119 case 100: return "newacct";
120 case 101: return "hostnames";
121 case 102: return "iso-tsap";
122 case 103: return "x400";
123 case 104: return "x400-snd";
124 case 105: return "csnet-ns";
125 case 109: return "pop-2";
126 case 111: return "sunrpc";
127 case 113: return "auth";
128 case 115: return "sftp";
129 case 117: return "uucp-path";
130 case 119: return "nntp";
131 case 121: return "erpc";
132 case 123: return "ntp";
133 case 133: return "statsrv";
134 case 136: return "profile";
135 case 144: return "NeWS";
136 case 161: return "snmp";
137 case 162: return "snmp-trap";
138 case 170: return "print-srv";
139 default: (void) sprintf(nbuf
, "%d", wks
); return (nbuf
);
143 /* XXX: we should use getprotobynumber() instead. */
148 static char nbuf
[20];
151 case 1: return "icmp";
152 case 2: return "igmp";
153 case 3: return "ggp";
155 case 6: return "tcp";
156 case 7: return "ucl";
157 case 8: return "egp";
158 case 9: return "igp";
159 case 11: return "nvp-II";
160 case 12: return "pup";
161 case 16: return "chaos";
162 case 17: return "udp";
163 default: (void) sprintf(nbuf
, "%d", protonum
); return (nbuf
);
167 static const u_char
*
168 do_rrset(msg
, len
, cp
, cnt
, pflag
, file
, hs
)
170 const u_char
*cp
, *msg
;
178 * Print answer records.
180 sflag
= (_res
.pfcode
& pflag
);
181 if (n
= ntohs(cnt
)) {
182 if ((!_res
.pfcode
) ||
183 ((sflag
) && (_res
.pfcode
& RES_PRF_HEAD1
)))
186 if ((!_res
.pfcode
) || sflag
) {
187 cp
= p_rr(cp
, msg
, file
);
190 cp
+= __dn_skipname(cp
, cp
+ MAXCDNAME
);
194 dlen
= _getshort((u_char
*)cp
);
198 if ((cp
- msg
) > len
)
201 if ((!_res
.pfcode
) ||
202 ((sflag
) && (_res
.pfcode
& RES_PRF_HEAD1
)))
212 __fp_query(msg
, stdout
);
216 /* ultrix 4.0's packaging has some icky packaging. alias for it here.
217 * there is more junk of this kind over in res_comp.c.
228 * Print the current options.
229 * This is intended to be primarily a debugging routine.
232 __fp_resstat(statp
, file
)
233 struct __res_state
*statp
;
236 register u_long mask
;
238 fprintf(file
, ";; res options:");
241 for (mask
= 1; mask
!= 0; mask
<<= 1)
242 if (statp
->options
& mask
)
243 fprintf(file
, " %s", p_option(mask
));
248 * Print the contents of a query.
249 * This is intended to be primarily a debugging routine.
252 __fp_nquery(msg
, len
, file
)
257 register const u_char
*cp
, *endMark
;
258 register const HEADER
*hp
;
261 if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1)
264 #define TruncTest(x) if (x >= endMark) goto trunc
265 #define ErrorTest(x) if (x == NULL) goto error
268 * Print header fields.
273 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEADX
) || hp
->rcode
) {
274 fprintf(file
, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
275 _res_opcodes
[hp
->opcode
],
276 _res_resultcodes
[hp
->rcode
],
280 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEADX
))
282 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEAD2
)) {
283 fprintf(file
, "; flags:");
285 fprintf(file
, " qr");
287 fprintf(file
, " aa");
289 fprintf(file
, " tc");
291 fprintf(file
, " rd");
293 fprintf(file
, " ra");
295 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_HEAD1
)) {
296 fprintf(file
, "; Ques: %d", ntohs(hp
->qdcount
));
297 fprintf(file
, ", Ans: %d", ntohs(hp
->ancount
));
298 fprintf(file
, ", Auth: %d", ntohs(hp
->nscount
));
299 fprintf(file
, ", Addit: %d", ntohs(hp
->arcount
));
301 if ((!_res
.pfcode
) || (_res
.pfcode
&
302 (RES_PRF_HEADX
| RES_PRF_HEAD2
| RES_PRF_HEAD1
))) {
306 * Print question records.
308 if (n
= ntohs(hp
->qdcount
)) {
309 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
310 fprintf(file
, ";; QUESTIONS:\n");
312 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
313 fprintf(file
, ";;\t");
315 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
316 cp
= p_cdnname(cp
, msg
, len
, file
);
321 if ((n
= dn_expand(msg
, msg
+len
, cp
, name
,
329 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
330 fprintf(file
, ", type = %s",
331 __p_type(_getshort((u_char
*)cp
)));
334 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
335 fprintf(file
, ", class = %s\n",
336 __p_class(_getshort((u_char
*)cp
)));
338 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_QUES
))
343 * Print authoritative answer records
346 cp
= do_rrset(msg
, len
, cp
, hp
->ancount
, RES_PRF_ANS
, file
,
351 * print name server records
354 cp
= do_rrset(msg
, len
, cp
, hp
->nscount
, RES_PRF_AUTH
, file
,
355 ";; AUTHORITY RECORDS:\n");
360 * print additional records
362 cp
= do_rrset(msg
, len
, cp
, hp
->arcount
, RES_PRF_ADD
, file
,
363 ";; ADDITIONAL RECORDS:\n");
367 fprintf(file
, "\n;; ...truncated\n");
370 fprintf(file
, "\n;; ...malformed\n");
374 __fp_query(msg
, file
)
378 fp_nquery(msg
, PACKETSZ
, file
);
382 __p_cdnname(cp
, msg
, len
, file
)
383 const u_char
*cp
, *msg
;
390 if ((n
= dn_expand(msg
, msg
+ len
, cp
, name
, sizeof name
)) < 0)
400 __p_cdname(cp
, msg
, file
)
401 const u_char
*cp
, *msg
;
404 return (p_cdnname(cp
, msg
, PACKETSZ
, file
));
407 /* XXX: the rest of these functions need to become length-limited, too. (vix)
411 __p_fqname(cp
, msg
, file
)
412 const u_char
*cp
, *msg
;
418 if ((n
= dn_expand(msg
, cp
+ MAXCDNAME
, cp
, name
, sizeof name
)) < 0)
420 if (name
[0] == '\0') {
424 if (name
[strlen(name
) - 1] != '.')
431 * Print resource record fields in human readable form.
434 __p_rr(cp
, msg
, file
)
435 const u_char
*cp
, *msg
;
438 int type
, class, dlen
, n
, c
;
439 struct in_addr inaddr
;
440 const u_char
*cp1
, *cp2
;
444 if ((_res
.options
& RES_INIT
) == 0 && res_init() == -1) {
445 h_errno
= NETDB_INTERNAL
;
448 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
449 return (NULL
); /* compression error */
450 type
= _getshort((u_char
*)cp
);
452 class = _getshort((u_char
*)cp
);
454 tmpttl
= _getlong((u_char
*)cp
);
456 dlen
= _getshort((u_char
*)cp
);
459 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_TTLID
))
460 fprintf(file
, "\t%lu", (u_long
)tmpttl
);
461 if ((!_res
.pfcode
) || (_res
.pfcode
& RES_PRF_CLASS
))
462 fprintf(file
, "\t%s", __p_class(class));
463 fprintf(file
, "\t%s", __p_type(type
));
465 * Print type specific data, if appropriate
472 bcopy(cp
, (char *)&inaddr
, INADDRSZ
);
474 fprintf(file
, "\t%s", inet_ntoa(inaddr
));
476 } else if (dlen
== 7) {
481 address
= inet_ntoa(inaddr
);
483 protocol
= *(u_char
*)cp
;
484 cp
+= sizeof(u_char
);
485 port
= _getshort((u_char
*)cp
);
487 fprintf(file
, "\t%s\t; proto %d, port %d",
488 address
, protocol
, port
);
502 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
508 (void) fputs("\t\"", file
);
510 if ((n
= (unsigned char) *cp
++) != 0) {
511 for (c
= n
; c
> 0 && cp
< cp2
; c
--) {
512 if (strchr("\n\"\\", *cp
))
513 (void) putc('\\', file
);
514 (void) putc(*cp
++, file
);
518 if (cp
< cp2
&& (n
= (unsigned char) *cp
++) != 0) {
519 (void) fputs ("\t\"", file
);
520 for (c
= n
; c
> 0 && cp
< cp2
; c
--) {
521 if (strchr("\n\"\\", *cp
))
522 (void) putc('\\', file
);
523 (void) putc(*cp
++, file
);
526 } else if (type
== T_HINFO
) {
527 (void) fputs("\"?\"", file
);
528 fprintf(file
, "\n;; *** Warning *** OS-type missing");
534 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
537 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
540 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
541 fprintf(file
, "\t\t\t%lu\t; serial\n", (u_long
)t
);
542 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
543 fprintf(file
, "\t\t\t%lu\t; refresh (%s)\n",
544 (u_long
)t
, __p_time(t
));
545 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
546 fprintf(file
, "\t\t\t%lu\t; retry (%s)\n",
547 (u_long
)t
, __p_time(t
));
548 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
549 fprintf(file
, "\t\t\t%lu\t; expire (%s)\n",
550 (u_long
)t
, __p_time(t
));
551 t
= _getlong((u_char
*)cp
); cp
+= INT32SZ
;
552 fprintf(file
, "\t\t\t%lu )\t; minimum (%s)",
553 (u_long
)t
, __p_time(t
));
559 fprintf(file
, "\t%d ", _getshort((u_char
*)cp
));
561 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
566 fprintf(file
, "\t%d ", _getshort((u_char
*)cp
));
568 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
571 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
577 (void) fputs("\t\"", file
);
580 if (n
= (unsigned char) *cp
++) {
581 for (c
= n
; c
> 0 && cp
< cp2
; c
--) {
582 if (strchr("\n\"\\", *cp
))
583 (void) putc('\\', file
);
584 (void) putc(*cp
++, file
);
592 (void) fprintf(file
, "\t%s", inet_nsap_ntoa(dlen
, cp
, NULL
));
597 char t
[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
599 fprintf(file
, "\t%s\n", inet_ntop(AF_INET6
, cp
, t
, sizeof t
));
607 (void) fprintf(file
, "\t%s\n", loc_ntoa(cp
, t
));
615 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
618 if ((cp
= p_fqname(cp
, msg
, file
)) == NULL
)
624 fputs((char *)cp
, file
);
631 fprintf(file
, "\t%u", _getlong((u_char
*)cp
));
637 if (dlen
< INT32SZ
+ 1)
639 bcopy(cp
, (char *)&inaddr
, INADDRSZ
);
641 fprintf(file
, "\t%s %s ( ",
644 cp
+= sizeof(u_char
);
647 while (cp
< cp1
+ dlen
) {
652 fputs("\n\t\t\t", file
);
655 fputs(dewks(n
), file
);
665 #ifdef ALLOW_T_UNSPEC
672 if (dlen
< NumBytes
) NumBytes
= dlen
;
673 fprintf(file
, "\tFirst %d bytes of hex data:",
675 for (i
= 0, DataPtr
= cp
; i
< NumBytes
; i
++, DataPtr
++)
676 fprintf(file
, " %x", *DataPtr
);
680 #endif /* ALLOW_T_UNSPEC */
683 fprintf(file
, "\t?%d?", type
);
687 fprintf(file
, "\t; dlen=%d, ttl %s\n", dlen
, __p_time(tmpttl
));
691 if (cp
- cp1
!= dlen
) {
693 ";; packet size error (found %lu, dlen was %d)\n",
694 (unsigned long) (cp
- cp1
), dlen
);
701 * Return a string for the type
707 static char nbuf
[20];
710 case T_A
: return "A";
711 case T_NS
: return "NS";
712 case T_CNAME
: return "CNAME";
713 case T_SOA
: return "SOA";
714 case T_MB
: return "MB";
715 case T_MG
: return "MG";
716 case T_MR
: return "MR";
717 case T_NULL
: return "NULL";
718 case T_WKS
: return "WKS";
719 case T_PTR
: return "PTR";
720 case T_HINFO
: return "HINFO";
721 case T_MINFO
: return "MINFO";
722 case T_MX
: return "MX";
723 case T_TXT
: return "TXT";
724 case T_RP
: return "RP";
725 case T_AFSDB
: return "AFSDB";
726 case T_X25
: return "X25";
727 case T_ISDN
: return "ISDN";
728 case T_RT
: return "RT";
729 case T_NSAP
: return "NSAP";
730 case T_NSAP_PTR
: return "NSAP_PTR";
731 case T_SIG
: return "SIG";
732 case T_KEY
: return "KEY";
733 case T_PX
: return "PX";
734 case T_GPOS
: return "GPOS";
735 case T_AAAA
: return "AAAA";
736 case T_LOC
: return "LOC";
737 case T_AXFR
: return "AXFR";
738 case T_MAILB
: return "MAILB";
739 case T_MAILA
: return "MAILA";
740 case T_ANY
: return "ANY";
741 case T_UINFO
: return "UINFO";
742 case T_UID
: return "UID";
743 case T_GID
: return "GID";
744 #ifdef ALLOW_T_UNSPEC
745 case T_UNSPEC
: return "UNSPEC";
746 #endif /* ALLOW_T_UNSPEC */
747 default: (void)sprintf(nbuf
, "%d", type
); return (nbuf
);
752 * Return a mnemonic for class
758 static char nbuf
[20];
761 case C_IN
: return "IN";
762 case C_HS
: return "HS";
763 case C_ANY
: return "ANY";
764 default: (void)sprintf(nbuf
, "%d", class); return (nbuf
);
769 * Return a mnemonic for an option
775 static char nbuf
[40];
778 case RES_INIT
: return "init";
779 case RES_DEBUG
: return "debug";
780 case RES_AAONLY
: return "aaonly(unimpl)";
781 case RES_USEVC
: return "usevc";
782 case RES_PRIMARY
: return "primry(unimpl)";
783 case RES_IGNTC
: return "igntc";
784 case RES_RECURSE
: return "recurs";
785 case RES_DEFNAMES
: return "defnam";
786 case RES_STAYOPEN
: return "styopn";
787 case RES_DNSRCH
: return "dnsrch";
788 case RES_INSECURE1
: return "insecure1";
789 case RES_INSECURE2
: return "insecure2";
790 default: sprintf(nbuf
, "?0x%lx?", (u_long
)option
);
796 * Return a mnemonic for a time to live
802 static char nbuf
[40];
803 int secs
, mins
, hours
, days
;
807 strcpy(nbuf
, "0 secs");
820 #define PLURALIZE(x) x, (x == 1) ? "" : "s"
823 (void)sprintf(p
, "%d day%s", PLURALIZE(days
));
829 (void)sprintf(p
, "%d hour%s", PLURALIZE(hours
));
835 (void)sprintf(p
, "%d min%s", PLURALIZE(mins
));
838 if (secs
|| ! (days
|| hours
|| mins
)) {
839 if (days
|| hours
|| mins
)
841 (void)sprintf(p
, "%d sec%s", PLURALIZE(secs
));
847 * routines to convert between on-the-wire RR format and zone file format.
848 * Does not contain conversion to/from decimal degrees; divide or multiply
849 * by 60*60*1000 for that.
852 static unsigned int poweroften
[10] = {1, 10, 100, 1000, 10000, 100000,
853 1000000,10000000,100000000,1000000000};
855 /* takes an XeY precision/size value, returns a string representation. */
860 static char retbuf
[sizeof("90000000.00")];
862 int mantissa
, exponent
;
864 mantissa
= (int)((prec
>> 4) & 0x0f) % 10;
865 exponent
= (int)((prec
>> 0) & 0x0f) % 10;
867 val
= mantissa
* poweroften
[exponent
];
869 (void) sprintf(retbuf
, "%ld.%.2ld", val
/100, val
%100);
873 /* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
875 precsize_aton(strptr
)
878 unsigned int mval
= 0, cmval
= 0;
881 register int exponent
;
882 register int mantissa
;
887 mval
= mval
* 10 + (*cp
++ - '0');
889 if (*cp
== '.') { /* centimeters */
892 cmval
= (*cp
++ - '0') * 10;
894 cmval
+= (*cp
++ - '0');
898 cmval
= (mval
* 100) + cmval
;
900 for (exponent
= 0; exponent
< 9; exponent
++)
901 if (cmval
< poweroften
[exponent
+1])
904 mantissa
= cmval
/ poweroften
[exponent
];
908 retval
= (mantissa
<< 4) | exponent
;
915 /* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
917 latlon2ul(latlonstrptr
,which
)
923 int deg
= 0, min
= 0, secs
= 0, secsfrac
= 0;
928 deg
= deg
* 10 + (*cp
++ - '0');
937 min
= min
* 10 + (*cp
++ - '0');
946 secs
= secs
* 10 + (*cp
++ - '0');
948 if (*cp
== '.') { /* decimal seconds */
951 secsfrac
= (*cp
++ - '0') * 100;
953 secsfrac
+= (*cp
++ - '0') * 10;
955 secsfrac
+= (*cp
++ - '0');
961 while (!isspace(*cp
)) /* if any trailing garbage */
971 retval
= ((unsigned)1<<31)
972 + (((((deg
* 60) + min
) * 60) + secs
) * 1000)
977 retval
= ((unsigned)1<<31)
978 - (((((deg
* 60) + min
) * 60) + secs
) * 1000)
982 retval
= 0; /* invalid value -- indicates error */
989 *which
= 1; /* latitude */
993 *which
= 2; /* longitude */
996 *which
= 0; /* error */
1000 cp
++; /* skip the hemisphere */
1002 while (!isspace(*cp
)) /* if any trailing garbage */
1005 while (isspace(*cp
)) /* move to next field */
1013 /* converts a zone file representation in a string to an RDATA on-the-wire
1014 * representation. */
1016 loc_aton(ascii
, binary
)
1020 const char *cp
, *maxcp
;
1023 u_int32_t latit
= 0, longit
= 0, alt
= 0;
1024 u_int32_t lltemp1
= 0, lltemp2
= 0;
1025 int altmeters
= 0, altfrac
= 0, altsign
= 1;
1026 u_int8_t hp
= 0x16; /* default = 1e6 cm = 10000.00m = 10km */
1027 u_int8_t vp
= 0x13; /* default = 1e3 cm = 10.00m */
1028 u_int8_t siz
= 0x12; /* default = 1e2 cm = 1.00m */
1029 int which1
= 0, which2
= 0;
1032 maxcp
= cp
+ strlen(ascii
);
1034 lltemp1
= latlon2ul(&cp
, &which1
);
1036 lltemp2
= latlon2ul(&cp
, &which2
);
1038 switch (which1
+ which2
) {
1039 case 3: /* 1 + 2, the only valid combination */
1040 if ((which1
== 1) && (which2
== 2)) { /* normal case */
1043 } else if ((which1
== 2) && (which2
== 1)) { /* reversed */
1046 } else { /* some kind of brokenness */
1050 default: /* we didn't get one of each */
1063 while (isdigit(*cp
))
1064 altmeters
= altmeters
* 10 + (*cp
++ - '0');
1066 if (*cp
== '.') { /* decimal meters */
1069 altfrac
= (*cp
++ - '0') * 10;
1071 altfrac
+= (*cp
++ - '0');
1076 alt
= (10000000 + (altsign
* (altmeters
* 100 + altfrac
)));
1078 while (!isspace(*cp
) && (cp
< maxcp
)) /* if trailing garbage or m */
1081 while (isspace(*cp
) && (cp
< maxcp
))
1087 siz
= precsize_aton(&cp
);
1089 while (!isspace(*cp
) && (cp
< maxcp
)) /* if trailing garbage or m */
1092 while (isspace(*cp
) && (cp
< maxcp
))
1098 hp
= precsize_aton(&cp
);
1100 while (!isspace(*cp
) && (cp
< maxcp
)) /* if trailing garbage or m */
1103 while (isspace(*cp
) && (cp
< maxcp
))
1109 vp
= precsize_aton(&cp
);
1114 *bcp
++ = (u_int8_t
) 0; /* version byte */
1119 PUTLONG(longit
,bcp
);
1122 return (16); /* size of RR in octets */
1125 /* takes an on-the-wire LOC RR and formats it in a human readable format. */
1127 loc_ntoa(binary
, ascii
)
1128 const u_char
*binary
;
1131 static char *error
= "?";
1132 register const u_char
*cp
= binary
;
1134 int latdeg
, latmin
, latsec
, latsecfrac
;
1135 int longdeg
, longmin
, longsec
, longsecfrac
;
1136 char northsouth
, eastwest
;
1137 int altmeters
, altfrac
, altsign
;
1139 const int referencealt
= 100000 * 100;
1141 int32_t latval
, longval
, altval
;
1143 u_int8_t sizeval
, hpval
, vpval
, versionval
;
1145 char *sizestr
, *hpstr
, *vpstr
;
1150 sprintf(ascii
, "; error: unknown LOC RR version");
1160 latval
= (templ
- ((unsigned)1<<31));
1163 longval
= (templ
- ((unsigned)1<<31));
1166 if (templ
< referencealt
) { /* below WGS 84 spheroid */
1167 altval
= referencealt
- templ
;
1170 altval
= templ
- referencealt
;
1180 latsecfrac
= latval
% 1000;
1181 latval
= latval
/ 1000;
1182 latsec
= latval
% 60;
1183 latval
= latval
/ 60;
1184 latmin
= latval
% 60;
1185 latval
= latval
/ 60;
1194 longsecfrac
= longval
% 1000;
1195 longval
= longval
/ 1000;
1196 longsec
= longval
% 60;
1197 longval
= longval
/ 60;
1198 longmin
= longval
% 60;
1199 longval
= longval
/ 60;
1202 altfrac
= altval
% 100;
1203 altmeters
= (altval
/ 100) * altsign
;
1205 if ((sizestr
= strdup(precsize_ntoa(sizeval
))) == NULL
)
1207 if ((hpstr
= strdup(precsize_ntoa(hpval
))) == NULL
)
1209 if ((vpstr
= strdup(precsize_ntoa(vpval
))) == NULL
)
1213 "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
1214 latdeg
, latmin
, latsec
, latsecfrac
, northsouth
,
1215 longdeg
, longmin
, longsec
, longsecfrac
, eastwest
,
1216 altmeters
, altfrac
, sizestr
, hpstr
, vpstr
);
1218 if (sizestr
!= error
)