PageRenderTime 58ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/bionic/libc/netbsd/resolv/res_debug.c

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