PageRenderTime 35ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

lib/libc/resolv/res_data.c

http://www.minix3.org/
C | 363 lines | 262 code | 50 blank | 51 comment | 54 complexity | db3873e89a71ac2109703d99e506b63e MD5 | raw file
Possible License(s): MIT, WTFPL, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.0, JSON, 0BSD
  1. /* $NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $ */
  2. /*
  3. * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
  4. * Copyright (c) 1995-1999 by Internet Software Consortium.
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  16. * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #include <sys/cdefs.h>
  19. #if defined(LIBC_SCCS) && !defined(lint)
  20. #ifdef notdef
  21. static const char rcsid[] = "Id: res_data.c,v 1.7 2008/12/11 09:59:00 marka Exp";
  22. #else
  23. __RCSID("$NetBSD: res_data.c,v 1.14 2009/10/24 05:35:37 christos Exp $");
  24. #endif
  25. #endif /* LIBC_SCCS and not lint */
  26. #include "port_before.h"
  27. #include "namespace.h"
  28. #include <sys/types.h>
  29. #include <sys/param.h>
  30. #include <sys/socket.h>
  31. #include <sys/time.h>
  32. #include <netinet/in.h>
  33. #include <arpa/inet.h>
  34. #include <arpa/nameser.h>
  35. #include <ctype.h>
  36. #include <netdb.h>
  37. #include <resolv.h>
  38. #include <res_update.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <unistd.h>
  43. #include "port_after.h"
  44. #include "res_private.h"
  45. #ifdef __weak_alias
  46. __weak_alias(res_init,_res_init)
  47. __weak_alias(res_mkquery,_res_mkquery)
  48. __weak_alias(res_query,_res_query)
  49. __weak_alias(res_search,_res_search)
  50. __weak_alias(res_send,__res_send)
  51. __weak_alias(res_close,__res_close)
  52. /* XXX: these leaked in the old bind8 libc */
  53. __weak_alias(res_querydomain,__res_querydomain)
  54. __weak_alias(res_send_setqhook,__res_send_setqhook)
  55. __weak_alias(res_send_setrhook,__res_send_setrhook)
  56. #if 0
  57. __weak_alias(p_query,__p_query)
  58. __weak_alias(fp_query,__fp_query)
  59. __weak_alias(fp_nquery,__fp_nquery)
  60. __weak_alias(res_isourserver,__res_isourserver)
  61. __weak_alias(res_opt,_res_opt)
  62. __weak_alias(hostalias,__hostalias)
  63. #endif
  64. #endif
  65. const char *_res_opcodes[] = {
  66. "QUERY",
  67. "IQUERY",
  68. "CQUERYM",
  69. "CQUERYU", /*%< experimental */
  70. "NOTIFY", /*%< experimental */
  71. "UPDATE",
  72. "6",
  73. "7",
  74. "8",
  75. "9",
  76. "10",
  77. "11",
  78. "12",
  79. "13",
  80. "ZONEINIT",
  81. "ZONEREF",
  82. };
  83. #ifdef BIND_UPDATE
  84. const char *_res_sectioncodes[] = {
  85. "ZONE",
  86. "PREREQUISITES",
  87. "UPDATE",
  88. "ADDITIONAL",
  89. };
  90. #endif
  91. #ifndef __BIND_NOSTATIC
  92. extern struct __res_state _nres;
  93. /* Proto. */
  94. int res_ourserver_p(const res_state, const struct sockaddr *);
  95. int
  96. res_init(void) {
  97. int rv;
  98. #ifdef COMPAT__RES
  99. /*
  100. * Compatibility with program that were accessing _res directly
  101. * to set options. We keep another struct res that is the same
  102. * size as the original res structure, and then copy fields to
  103. * it so that we achieve the same initialization
  104. */
  105. extern void *__res_get_old_state(void);
  106. extern void __res_put_old_state(void *);
  107. res_state ores = __res_get_old_state();
  108. if (ores->options != 0)
  109. _nres.options = ores->options;
  110. if (ores->retrans != 0)
  111. _nres.retrans = ores->retrans;
  112. if (ores->retry != 0)
  113. _nres.retry = ores->retry;
  114. #endif
  115. /*
  116. * These three fields used to be statically initialized. This made
  117. * it hard to use this code in a shared library. It is necessary,
  118. * now that we're doing dynamic initialization here, that we preserve
  119. * the old semantics: if an application modifies one of these three
  120. * fields of _res before res_init() is called, res_init() will not
  121. * alter them. Of course, if an application is setting them to
  122. * _zero_ before calling res_init(), hoping to override what used
  123. * to be the static default, we can't detect it and unexpected results
  124. * will follow. Zero for any of these fields would make no sense,
  125. * so one can safely assume that the applications were already getting
  126. * unexpected results.
  127. *
  128. * _nres.options is tricky since some apps were known to diddle the bits
  129. * before res_init() was first called. We can't replicate that semantic
  130. * with dynamic initialization (they may have turned bits off that are
  131. * set in RES_DEFAULT). Our solution is to declare such applications
  132. * "broken". They could fool us by setting RES_INIT but none do (yet).
  133. */
  134. if (!_nres.retrans)
  135. _nres.retrans = RES_TIMEOUT;
  136. if (!_nres.retry)
  137. _nres.retry = 4;
  138. if (!(_nres.options & RES_INIT))
  139. _nres.options = RES_DEFAULT;
  140. /*
  141. * This one used to initialize implicitly to zero, so unless the app
  142. * has set it to something in particular, we can randomize it now.
  143. */
  144. if (!_nres.id)
  145. _nres.id = res_nrandomid(&_nres);
  146. rv = __res_vinit(&_nres, 1);
  147. #ifdef COMPAT__RES
  148. __res_put_old_state(&_nres);
  149. #endif
  150. return rv;
  151. }
  152. void
  153. p_query(const u_char *msg) {
  154. fp_query(msg, stdout);
  155. }
  156. void
  157. fp_query(const u_char *msg, FILE *file) {
  158. fp_nquery(msg, PACKETSZ, file);
  159. }
  160. void
  161. fp_nquery(const u_char *msg, int len, FILE *file) {
  162. if ((_nres.options & RES_INIT) == 0U && res_init() == -1)
  163. return;
  164. res_pquery(&_nres, msg, len, file);
  165. }
  166. int
  167. res_mkquery(int op, /*!< opcode of query */
  168. const char *dname, /*!< domain name */
  169. int class, int type, /*!< class and type of query */
  170. const u_char *data, /*!< resource record data */
  171. int datalen, /*!< length of data */
  172. const u_char *newrr_in, /*!< new rr for modify or append */
  173. u_char *buf, /*!< buffer to put query */
  174. int buflen) /*!< size of buffer */
  175. {
  176. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  177. RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
  178. return (-1);
  179. }
  180. return (res_nmkquery(&_nres, op, dname, class, type,
  181. data, datalen,
  182. newrr_in, buf, buflen));
  183. }
  184. #ifdef _LIBRESOLV
  185. int
  186. res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
  187. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  188. RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
  189. return (-1);
  190. }
  191. return (res_nmkupdate(&_nres, rrecp_in, buf, buflen));
  192. }
  193. #endif
  194. int
  195. res_query(const char *name, /*!< domain name */
  196. int class, int type, /*!< class and type of query */
  197. u_char *answer, /*!< buffer to put answer */
  198. int anslen) /*!< size of answer buffer */
  199. {
  200. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  201. RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
  202. return (-1);
  203. }
  204. return (res_nquery(&_nres, name, class, type, answer, anslen));
  205. }
  206. void
  207. res_send_setqhook(res_send_qhook hook) {
  208. _nres.qhook = hook;
  209. }
  210. void
  211. res_send_setrhook(res_send_rhook hook) {
  212. _nres.rhook = hook;
  213. }
  214. int
  215. res_isourserver(const struct sockaddr_in *inp) {
  216. return (res_ourserver_p(&_nres, (const struct sockaddr *)(const void *)inp));
  217. }
  218. int
  219. res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
  220. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  221. /* errno should have been set by res_init() in this case. */
  222. return (-1);
  223. }
  224. return (res_nsend(&_nres, buf, buflen, ans, anssiz));
  225. }
  226. #ifdef _LIBRESOLV
  227. int
  228. res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
  229. u_char *ans, int anssiz)
  230. {
  231. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  232. /* errno should have been set by res_init() in this case. */
  233. return (-1);
  234. }
  235. return (res_nsendsigned(&_nres, buf, buflen, key, ans, anssiz));
  236. }
  237. #endif
  238. void
  239. res_close(void) {
  240. res_nclose(&_nres);
  241. }
  242. #ifdef _LIBRESOLV
  243. int
  244. res_update(ns_updrec *rrecp_in) {
  245. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  246. RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
  247. return (-1);
  248. }
  249. return (res_nupdate(&_nres, rrecp_in, NULL));
  250. }
  251. #endif
  252. int
  253. res_search(const char *name, /*!< domain name */
  254. int class, int type, /*!< class and type of query */
  255. u_char *answer, /*!< buffer to put answer */
  256. int anslen) /*!< size of answer */
  257. {
  258. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  259. RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
  260. return (-1);
  261. }
  262. return (res_nsearch(&_nres, name, class, type, answer, anslen));
  263. }
  264. int
  265. res_querydomain(const char *name,
  266. const char *domain,
  267. int class, int type, /*!< class and type of query */
  268. u_char *answer, /*!< buffer to put answer */
  269. int anslen) /*!< size of answer */
  270. {
  271. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  272. RES_SET_H_ERRNO(&_nres, NETDB_INTERNAL);
  273. return (-1);
  274. }
  275. return (res_nquerydomain(&_nres, name, domain,
  276. class, type,
  277. answer, anslen));
  278. }
  279. int
  280. res_opt(int a, u_char *b, int c, int d)
  281. {
  282. return res_nopt(&_nres, a, b, c, d);
  283. }
  284. u_int
  285. res_randomid(void) {
  286. if ((_nres.options & RES_INIT) == 0U && res_init() == -1) {
  287. RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
  288. return (u_int)-1;
  289. }
  290. return (res_nrandomid(&_nres));
  291. }
  292. const char *
  293. hostalias(const char *name) {
  294. static char abuf[MAXDNAME];
  295. return (res_hostalias(&_nres, name, abuf, sizeof abuf));
  296. }
  297. #ifdef ultrix
  298. int
  299. local_hostname_length(const char *hostname) {
  300. int len_host, len_domain;
  301. if (!*_nres.defdname)
  302. res_init();
  303. len_host = strlen(hostname);
  304. len_domain = strlen(_nres.defdname);
  305. if (len_host > len_domain &&
  306. !strcasecmp(hostname + len_host - len_domain, _nres.defdname) &&
  307. hostname[len_host - len_domain - 1] == '.')
  308. return (len_host - len_domain - 1);
  309. return (0);
  310. }
  311. #endif /*ultrix*/
  312. #endif
  313. /*! \file */