PageRenderTime 25ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/avm2_env/usr/src/lib/libc/net/getnetbydns.c

https://gitlab.com/kidaa/crossbridge
C | 465 lines | 356 code | 30 blank | 79 comment | 87 complexity | 22ee8eb688f3a24ffe6c582875a17780 MD5 | raw file
Possible License(s): GPL-3.0, Apache-2.0, CC-BY-SA-3.0, LGPL-3.0, MPL-2.0-no-copyleft-exception, GPL-2.0, LGPL-2.1, AGPL-1.0, BSD-3-Clause, LGPL-2.0
  1. /*-
  2. * Copyright (c) 1985, 1988, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 4. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. * -
  29. * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  30. *
  31. * Permission to use, copy, modify, and distribute this software for any
  32. * purpose with or without fee is hereby granted, provided that the above
  33. * copyright notice and this permission notice appear in all copies, and that
  34. * the name of Digital Equipment Corporation not be used in advertising or
  35. * publicity pertaining to distribution of the document or software without
  36. * specific, written prior permission.
  37. *
  38. * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  39. * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  40. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  41. * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  42. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  43. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  44. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  45. * SOFTWARE.
  46. * -
  47. * --Copyright--
  48. */
  49. /* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
  50. * Dep. Matematica Universidade de Coimbra, Portugal, Europe
  51. *
  52. * Permission to use, copy, modify, and distribute this software for any
  53. * purpose with or without fee is hereby granted, provided that the above
  54. * copyright notice and this permission notice appear in all copies.
  55. */
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
  58. #endif /* LIBC_SCCS and not lint */
  59. #include <sys/cdefs.h>
  60. __FBSDID("$FreeBSD: src/lib/libc/net/getnetbydns.c,v 1.34.10.2.2.1 2010/12/21 17:09:25 kensmith Exp $");
  61. #include <sys/param.h>
  62. #include <sys/socket.h>
  63. #include <netinet/in.h>
  64. #include <arpa/inet.h>
  65. #include <arpa/nameser.h>
  66. #include <errno.h>
  67. #include <stdio.h>
  68. #include <stdlib.h>
  69. #include <netdb.h>
  70. #include <resolv.h>
  71. #include <ctype.h>
  72. #include <string.h>
  73. #include <unistd.h>
  74. #include <syslog.h>
  75. #include <stdarg.h>
  76. #include <nsswitch.h>
  77. #include "netdb_private.h"
  78. #include "res_config.h"
  79. #define BYADDR 0
  80. #define BYNAME 1
  81. #define MAXPACKET (64*1024)
  82. typedef union {
  83. HEADER hdr;
  84. u_char buf[MAXPACKET];
  85. } querybuf;
  86. typedef union {
  87. long al;
  88. char ac;
  89. } align;
  90. /*
  91. * Reverse the order of first four dotted entries of in.
  92. * Out must contain space for at least strlen(in) characters.
  93. * The result does not include any leading 0s of in.
  94. */
  95. static void
  96. ipreverse(char *in, char *out)
  97. {
  98. char *pos[4];
  99. int len[4];
  100. char *p, *start;
  101. int i = 0;
  102. int leading = 1;
  103. /* Fill-in element positions and lengths: pos[], len[]. */
  104. start = p = in;
  105. for (;;) {
  106. if (*p == '.' || *p == '\0') {
  107. /* Leading 0? */
  108. if (leading && p - start == 1 && *start == '0')
  109. len[i] = 0;
  110. else {
  111. len[i] = p - start;
  112. leading = 0;
  113. }
  114. pos[i] = start;
  115. start = p + 1;
  116. i++;
  117. }
  118. if (i == 4)
  119. break;
  120. if (*p == 0) {
  121. for (; i < 4; i++) {
  122. pos[i] = p;
  123. len[i] = 0;
  124. }
  125. break;
  126. }
  127. p++;
  128. }
  129. /* Copy the entries in reverse order */
  130. p = out;
  131. leading = 1;
  132. for (i = 3; i >= 0; i--) {
  133. memcpy(p, pos[i], len[i]);
  134. if (len[i])
  135. leading = 0;
  136. p += len[i];
  137. /* Need a . separator? */
  138. if (!leading && i > 0 && len[i - 1])
  139. *p++ = '.';
  140. }
  141. *p = '\0';
  142. }
  143. static int
  144. getnetanswer(querybuf *answer, int anslen, int net_i, struct netent *ne,
  145. struct netent_data *ned, res_state statp)
  146. {
  147. HEADER *hp;
  148. u_char *cp;
  149. int n;
  150. u_char *eom;
  151. int type, class, ancount, qdcount, haveanswer;
  152. char aux[MAXHOSTNAMELEN];
  153. char ans[MAXHOSTNAMELEN];
  154. char *in, *bp, *ep, **ap;
  155. /*
  156. * find first satisfactory answer
  157. *
  158. * answer --> +------------+ ( MESSAGE )
  159. * | Header |
  160. * +------------+
  161. * | Question | the question for the name server
  162. * +------------+
  163. * | Answer | RRs answering the question
  164. * +------------+
  165. * | Authority | RRs pointing toward an authority
  166. * | Additional | RRs holding additional information
  167. * +------------+
  168. */
  169. eom = answer->buf + anslen;
  170. hp = &answer->hdr;
  171. ancount = ntohs(hp->ancount); /* #/records in the answer section */
  172. qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
  173. bp = ned->netbuf;
  174. ep = ned->netbuf + sizeof(ned->netbuf);
  175. cp = answer->buf + HFIXEDSZ;
  176. if (!qdcount) {
  177. if (hp->aa)
  178. RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
  179. else
  180. RES_SET_H_ERRNO(statp, TRY_AGAIN);
  181. return (-1);
  182. }
  183. while (qdcount-- > 0)
  184. cp += __dn_skipname(cp, eom) + QFIXEDSZ;
  185. ap = ned->net_aliases;
  186. *ap = NULL;
  187. ne->n_aliases = ned->net_aliases;
  188. haveanswer = 0;
  189. while (--ancount >= 0 && cp < eom) {
  190. n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
  191. if ((n < 0) || !res_dnok(bp))
  192. break;
  193. cp += n;
  194. ans[0] = '\0';
  195. (void)strncpy(&ans[0], bp, sizeof(ans) - 1);
  196. ans[sizeof(ans) - 1] = '\0';
  197. GETSHORT(type, cp);
  198. GETSHORT(class, cp);
  199. cp += INT32SZ; /* TTL */
  200. GETSHORT(n, cp);
  201. if (class == C_IN && type == T_PTR) {
  202. n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
  203. if ((n < 0) || !res_hnok(bp)) {
  204. cp += n;
  205. return (-1);
  206. }
  207. cp += n;
  208. *ap++ = bp;
  209. n = strlen(bp) + 1;
  210. bp += n;
  211. ne->n_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
  212. haveanswer++;
  213. }
  214. }
  215. if (haveanswer) {
  216. *ap = NULL;
  217. switch (net_i) {
  218. case BYADDR:
  219. ne->n_name = *ne->n_aliases;
  220. ne->n_net = 0L;
  221. break;
  222. case BYNAME:
  223. in = *ne->n_aliases;
  224. n = strlen(ans) + 1;
  225. if (ep - bp < n) {
  226. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  227. errno = ENOBUFS;
  228. return (-1);
  229. }
  230. strlcpy(bp, ans, ep - bp);
  231. ne->n_name = bp;
  232. if (strlen(in) + 1 > sizeof(aux)) {
  233. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  234. errno = ENOBUFS;
  235. return (-1);
  236. }
  237. ipreverse(in, aux);
  238. ne->n_net = inet_network(aux);
  239. break;
  240. }
  241. ne->n_aliases++;
  242. return (0);
  243. }
  244. RES_SET_H_ERRNO(statp, TRY_AGAIN);
  245. return (-1);
  246. }
  247. int
  248. _dns_getnetbyaddr(void *rval, void *cb_data, va_list ap)
  249. {
  250. uint32_t net;
  251. int net_type;
  252. char *buffer;
  253. size_t buflen;
  254. int *errnop, *h_errnop;
  255. struct netent *nptr, ne;
  256. struct netent_data *ned;
  257. unsigned int netbr[4];
  258. int nn, anslen, error;
  259. querybuf *buf;
  260. char qbuf[MAXDNAME];
  261. uint32_t net2;
  262. res_state statp;
  263. net = va_arg(ap, uint32_t);
  264. net_type = va_arg(ap, int);
  265. nptr = va_arg(ap, struct netent *);
  266. buffer = va_arg(ap, char *);
  267. buflen = va_arg(ap, size_t);
  268. errnop = va_arg(ap, int *);
  269. h_errnop = va_arg(ap, int *);
  270. statp = __res_state();
  271. if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
  272. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  273. *h_errnop = statp->res_h_errno;
  274. return (NS_UNAVAIL);
  275. }
  276. if ((ned = __netent_data_init()) == NULL) {
  277. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  278. *h_errnop = statp->res_h_errno;
  279. return (NS_UNAVAIL);
  280. }
  281. *((struct netent **)rval) = NULL;
  282. if (net_type != AF_INET) {
  283. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  284. *h_errnop = statp->res_h_errno;
  285. return (NS_UNAVAIL);
  286. }
  287. for (nn = 4, net2 = net; net2; net2 >>= 8)
  288. netbr[--nn] = net2 & 0xff;
  289. switch (nn) {
  290. case 3: /* Class A */
  291. sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
  292. break;
  293. case 2: /* Class B */
  294. sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
  295. break;
  296. case 1: /* Class C */
  297. sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
  298. netbr[1]);
  299. break;
  300. case 0: /* Class D - E */
  301. sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
  302. netbr[1], netbr[0]);
  303. break;
  304. }
  305. if ((buf = malloc(sizeof(*buf))) == NULL) {
  306. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  307. *h_errnop = statp->res_h_errno;
  308. return (NS_NOTFOUND);
  309. }
  310. anslen = res_nquery(statp, qbuf, C_IN, T_PTR, (u_char *)buf,
  311. sizeof(*buf));
  312. if (anslen < 0) {
  313. free(buf);
  314. #ifdef DEBUG
  315. if (statp->options & RES_DEBUG)
  316. printf("res_nsearch failed\n");
  317. #endif
  318. *h_errnop = statp->res_h_errno;
  319. return (NS_UNAVAIL);
  320. } else if (anslen > sizeof(*buf)) {
  321. free(buf);
  322. #ifdef DEBUG
  323. if (statp->options & RES_DEBUG)
  324. printf("res_nsearch static buffer too small\n");
  325. #endif
  326. *h_errnop = statp->res_h_errno;
  327. return (NS_UNAVAIL);
  328. }
  329. error = getnetanswer(buf, anslen, BYADDR, &ne, ned, statp);
  330. free(buf);
  331. if (error == 0) {
  332. /* Strip trailing zeros */
  333. while ((net & 0xff) == 0 && net != 0)
  334. net >>= 8;
  335. ne.n_net = net;
  336. if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
  337. *errnop = errno;
  338. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  339. *h_errnop = statp->res_h_errno;
  340. return (NS_RETURN);
  341. }
  342. *((struct netent **)rval) = nptr;
  343. return (NS_SUCCESS);
  344. }
  345. *h_errnop = statp->res_h_errno;
  346. return (NS_NOTFOUND);
  347. }
  348. int
  349. _dns_getnetbyname(void *rval, void *cb_data, va_list ap)
  350. {
  351. const char *net;
  352. char *buffer;
  353. size_t buflen;
  354. int *errnop, *h_errnop;
  355. struct netent *nptr, ne;
  356. struct netent_data *ned;
  357. int anslen, error;
  358. querybuf *buf;
  359. char qbuf[MAXDNAME];
  360. res_state statp;
  361. net = va_arg(ap, const char *);
  362. nptr = va_arg(ap, struct netent *);
  363. buffer = va_arg(ap, char *);
  364. buflen = va_arg(ap, size_t);
  365. errnop = va_arg(ap, int *);
  366. h_errnop = va_arg(ap, int *);
  367. statp = __res_state();
  368. if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) {
  369. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  370. *h_errnop = statp->res_h_errno;
  371. return (NS_UNAVAIL);
  372. }
  373. if ((ned = __netent_data_init()) == NULL) {
  374. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  375. *h_errnop = statp->res_h_errno;
  376. return (NS_UNAVAIL);
  377. }
  378. if ((buf = malloc(sizeof(*buf))) == NULL) {
  379. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  380. *h_errnop = statp->res_h_errno;
  381. return (NS_NOTFOUND);
  382. }
  383. *((struct netent **)rval) = NULL;
  384. strncpy(qbuf, net, sizeof(qbuf) - 1);
  385. qbuf[sizeof(qbuf) - 1] = '\0';
  386. anslen = res_nsearch(statp, qbuf, C_IN, T_PTR, (u_char *)buf,
  387. sizeof(*buf));
  388. if (anslen < 0) {
  389. free(buf);
  390. #ifdef DEBUG
  391. if (statp->options & RES_DEBUG)
  392. printf("res_nsearch failed\n");
  393. #endif
  394. return (NS_UNAVAIL);
  395. } else if (anslen > sizeof(*buf)) {
  396. free(buf);
  397. #ifdef DEBUG
  398. if (statp->options & RES_DEBUG)
  399. printf("res_search static buffer too small\n");
  400. #endif
  401. return (NS_UNAVAIL);
  402. }
  403. error = getnetanswer(buf, anslen, BYNAME, &ne, ned, statp);
  404. free(buf);
  405. if (error != 0) {
  406. *h_errnop = statp->res_h_errno;
  407. return (NS_NOTFOUND);
  408. }
  409. if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
  410. *errnop = errno;
  411. RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
  412. *h_errnop = statp->res_h_errno;
  413. return (NS_RETURN);
  414. }
  415. *((struct netent **)rval) = nptr;
  416. return (NS_SUCCESS);
  417. }
  418. void
  419. _setnetdnsent(int stayopen)
  420. {
  421. res_state statp;
  422. statp = __res_state();
  423. if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1)
  424. return;
  425. if (stayopen)
  426. statp->options |= RES_STAYOPEN | RES_USEVC;
  427. }
  428. void
  429. _endnetdnsent()
  430. {
  431. res_state statp;
  432. statp = __res_state();
  433. statp->options &= ~(RES_STAYOPEN | RES_USEVC);
  434. res_nclose(statp);
  435. }