gethostnamadr.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:11k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* gethostnamadr.c - */
  2. /* Copyright 1984-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1985, 1988 Regents of the University of California.
  6.  * All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  * This product includes software developed by the University of
  19.  * California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36. /*
  37. modification history
  38. --------------------
  39. 01d,05nov01,vvv  fixed compilation warnings
  40. 01c,04sep01,vvv  fixed to correctly query multiple servers (SPR #67238);
  41.  fixed compilation warnings
  42. 01b,11feb96,jag  Fix the formating of the hostent structure in  _gethostbyname
  43.                  when invoked with an IP address. Cleaned up warnings.
  44. 01a,13dec96,jag  Cleaned up and rename user I/F functions with the resolv
  45.  prefix.  Man pages for these functions appear in resolvLib
  46. */
  47. #include <vxWorks.h>
  48. #include <resolvLib.h>
  49. #include <semLib.h>
  50. #include <stdio.h>
  51. #include <ctype.h>
  52. #include <errno.h>
  53. #include <string.h>
  54. #include <stdlib.h>
  55. #include <inetLib.h>
  56. #define  MAX_RR_TTL  172800         /* Maximum of Two days in seconds */
  57. #if PACKETSZ > 1024
  58. #define MAXPACKET PACKETSZ
  59. #else
  60. #define MAXPACKET 1024
  61. #endif
  62. typedef union {
  63. HEADER hdr;
  64. u_char buf[MAXPACKET];
  65. } querybuf;
  66. typedef union {
  67. int32_t al;
  68. char ac;
  69. } align;
  70. static int qcomp (struct in_addr **, struct in_addr **);
  71. LOCAL struct hostent *getanswer (querybuf *, int, int, struct hostent *, 
  72.  char *, int);
  73. LOCAL struct hostent *
  74. getanswer(answer, anslen, iquery, pHost, hostbuf, bufLen)
  75. querybuf *answer;
  76. int anslen;
  77. int iquery;
  78. struct hostent   *  pHost;
  79. char *           hostbuf;
  80. int              bufLen;
  81. {
  82. register HEADER *hp;
  83. register u_char *cp;
  84. register int n;
  85. u_char *eom;
  86. char *bp, **ap;
  87. int type, class, ancount, qdcount;
  88. int haveanswer, getclass = C_ANY;
  89. char **hap;
  90. char *hostbufEnd;
  91. unsigned int rrttl; /* RR time to live field */
  92. eom = answer->buf + anslen;
  93. /*
  94.  * find first satisfactory answer
  95.  */
  96. hp = &answer->hdr;
  97. ancount = ntohs(hp->ancount);
  98. qdcount = ntohs(hp->qdcount);
  99. bp = hostbuf;
  100.         hostbufEnd = hostbuf + bufLen - 1;
  101. cp = answer->buf + sizeof(HEADER);
  102. /* Process the "questions section" of the DNS response */
  103. if (qdcount) {
  104.     /* Check if this is a Pointer query */
  105. if (iquery) {
  106. if ((n = resolvDNExpand((u_char *)answer->buf,
  107.     (u_char *)eom, (u_char *)cp, (u_char *)bp,
  108.     bufLen)) < 0) {
  109. errno = S_resolvLib_NO_RECOVERY;
  110. return ((struct hostent *) NULL);
  111. }
  112. cp += n + QFIXEDSZ;
  113. pHost->h_name = bp;
  114. n = strlen(bp) + 1;
  115. bp += n;
  116. bufLen -= n;
  117. } else
  118. cp += __dn_skipname(cp, eom) + QFIXEDSZ;
  119. while (--qdcount > 0)
  120. cp += __dn_skipname(cp, eom) + QFIXEDSZ;
  121. } else if (iquery) {
  122. if (hp->aa)
  123. errno = S_resolvLib_HOST_NOT_FOUND;
  124. else
  125. errno = S_resolvLib_TRY_AGAIN;
  126. return ((struct hostent *) NULL);
  127. }
  128. /* Set everything up to process the resource records */
  129. ap = pHost->h_aliases;
  130. *ap = NULL;
  131. hap = pHost->h_addr_list;
  132. *hap = NULL;
  133. pHost->h_ttl = MAX_RR_TTL;  /* Maximum of Two days in seconds */
  134. haveanswer = 0;
  135. while (--ancount >= 0 && cp < eom) {
  136. if ((n = resolvDNExpand((u_char *)answer->buf, (u_char *)eom,
  137.     (u_char *)cp, (u_char *)bp, bufLen)) < 0)
  138. break;
  139. cp += n;
  140. type = _getshort(cp); /* Get RR type field */
  141.   cp += sizeof(uint16_t);         /* Skip size of type field */
  142. class = _getshort(cp); /* Get RR class field */
  143.   cp += sizeof(uint16_t);         /* Skip size of class field */
  144. rrttl = _getlong(cp);         /* Get RR TTL field */
  145. cp += sizeof(uint32_t);         /* Skip size of TTL field */
  146. n = _getshort(cp); /* Get RR data length field */
  147. cp += sizeof(uint16_t); /* Skip size of length filed */
  148. if (type == T_CNAME) {
  149. cp += n;
  150. if (ap >= & pHost->h_aliases [MAXALIASES-1])
  151. continue;
  152. *ap++ = bp;
  153. n = strlen(bp) + 1;
  154. bp += n;
  155. bufLen -= n;
  156. if (rrttl < pHost->h_ttl)
  157.     pHost->h_ttl = rrttl;
  158. continue;
  159. }
  160. if (iquery && type == T_PTR) {
  161. if ((n = resolvDNExpand((u_char *)answer->buf,
  162.     (u_char *)eom, (u_char *)cp, (u_char *)bp,
  163.     bufLen)) < 0)
  164. break;
  165. cp += n;
  166. pHost->h_name = bp;
  167. if (rrttl < pHost->h_ttl)
  168.     pHost->h_ttl = rrttl;
  169. return (pHost);
  170. }
  171. if (iquery || type != T_A)  {
  172. #ifdef DEBUG
  173. if (_res.options & RES_DEBUG)
  174. printf("unexpected answer type %d, size %dn",
  175. type, n);
  176. #endif
  177. cp += n;
  178. continue;
  179. }
  180. if (haveanswer) {
  181. if (n != pHost->h_length) {
  182. cp += n;
  183. continue;
  184. }
  185. if (class != getclass) {
  186. cp += n;
  187. continue;
  188. }
  189. } else {
  190. pHost->h_length = n;
  191. getclass = class;
  192. pHost->h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
  193. if (!iquery) {
  194.     pHost->h_name = bp;
  195.     bp += strlen(bp) + 1;
  196.     if (rrttl < pHost->h_ttl)
  197. pHost->h_ttl = rrttl;
  198. }
  199. }
  200. bp += sizeof(align) - ((u_long)bp % sizeof(align));
  201. if (bp + n >= hostbufEnd) {
  202. #ifdef DEBUG
  203. if (_res.options & RES_DEBUG)
  204. printf("size (%d) too bign", n);
  205. #endif
  206. break;
  207. }
  208. bcopy(cp, *hap++ = bp, n);
  209. bp +=n;
  210. cp += n;
  211. haveanswer++;
  212. }
  213. if (haveanswer) {
  214. *ap = NULL;
  215. *hap = NULL;
  216. if (_res.nsort) {
  217. qsort(pHost->h_addr_list, haveanswer,
  218.     sizeof(struct in_addr),
  219.     (int (*)__P((const void *, const void *)))qcomp);
  220. }
  221. return (pHost);
  222. } else {
  223. errno = S_resolvLib_TRY_AGAIN;
  224. return ((struct hostent *) NULL);
  225. }
  226. }
  227. struct hostent *
  228. _gethostbyname(name, pHost, hostbuf, bufLen)
  229. const char *name;
  230. struct hostent *pHost;
  231.         char        *hostbuf;
  232.         int         bufLen;
  233. {
  234. querybuf buf;
  235. register const char *cp;
  236. int n, i;
  237. register struct hostent *hp;
  238. char lookups[MAXDNSLUS];
  239. /*
  240.  * disallow names consisting only of digits/dots, unless
  241.  * they end in a dot.
  242.  */
  243. if (isdigit((int) name[0]))
  244. for (cp = name;; ++cp) {
  245. if (!*cp) {
  246. if (*--cp == '.')
  247. break;
  248. /*
  249.  * All-numeric, no dot at the end.
  250.  * Fake up a hostent as if we'd actually
  251.  * done a lookup.
  252.  */
  253. pHost->h_addr_list[0] = hostbuf;
  254. hostbuf += sizeof(uint32_t);
  255. if (inet_aton((char *) name, 
  256.       (struct in_addr *) pHost->h_addr_list[0]) 
  257.    == ERROR) 
  258.     {
  259. errno = S_resolvLib_HOST_NOT_FOUND;
  260. return((struct hostent *) NULL);
  261.     }
  262. pHost->h_name = (char *)name;
  263. pHost->h_aliases[0] = NULL;
  264. pHost->h_addrtype = AF_INET;
  265. pHost->h_length = sizeof(uint32_t);
  266. pHost->h_addr_list [1] = NULL;
  267. /* Maximum of Two days in seconds */
  268. pHost->h_ttl = MAX_RR_TTL;
  269. return (pHost);
  270. }
  271. if (!isdigit((int) *cp) && *cp != '.') 
  272. break;
  273. }
  274. bcopy(_res.lookups, lookups, sizeof lookups);
  275. if (lookups[0] == '')
  276. strncpy(lookups, "bf", sizeof lookups);
  277. hp = (struct hostent *)NULL;
  278. for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
  279. /*
  280.  * if resolvSend has already contacted this server, lookup
  281.  * is 'd' indicating 'done'. In this case the server will
  282.  * not be contacted again and lookup is reset.
  283.  */
  284. if (_res.lookups [i] == 'd')
  285.     {
  286.     _res.lookups [i] = 'b';
  287.     continue;
  288.     }
  289. switch (lookups[i]) {
  290. case 'b':
  291. /*
  292.          * Set this server to be the active server - 
  293.  * resolvSend will start its querying from this
  294.  * server, skipping the previous servers
  295.  */
  296. _res.lookups[i] = 'a';
  297. if ((n = resSearch(name, C_IN, T_A, buf.buf,
  298.     sizeof(buf))) < 0) {
  299. #ifdef DEBUG
  300. if (_res.options & RES_DEBUG)
  301. printf("resSearch failedn");
  302. #endif
  303. break;
  304. }
  305. hp = getanswer(&buf, n, 0, pHost, hostbuf, bufLen );
  306. /* 
  307.  * Validate the address returned by the server - 
  308.  * should not be a network or broadcast address
  309.  * (SPR #67238)
  310.  */
  311. if (((hp->h_addr [3] & 0xff) == 0) ||
  312.     ((hp->h_addr [3] & 0xff) == 0xff))
  313.     {
  314.     hp = NULL;
  315.     errno = S_resolvLib_INVALID_ADDRESS;
  316.     }
  317. break;
  318. }
  319. if (_res.lookups [i] != 'f')
  320.     _res.lookups [i] = 'b'; 
  321. }
  322. return (hp);
  323. }
  324. struct hostent *
  325. _gethostbyaddr(addr, len, type, pHost, hostbuf, bufLen)
  326. const char *addr;
  327. int len, type;
  328. struct hostent *pHost;
  329. char *           hostbuf;
  330. int             bufLen;
  331. {
  332. int n, i;
  333. querybuf buf;
  334. register struct hostent *hp;
  335. char qbuf[MAXDNAME];
  336. char lookups[MAXDNSLUS];
  337. if (type != AF_INET)
  338. return ((struct hostent *) NULL);
  339. (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
  340. ((unsigned)addr[3] & 0xff),
  341. ((unsigned)addr[2] & 0xff),
  342. ((unsigned)addr[1] & 0xff),
  343. ((unsigned)addr[0] & 0xff));
  344. bcopy(_res.lookups, lookups, sizeof lookups);
  345. if (lookups[0] == '')
  346. strncpy(lookups, "bf", sizeof lookups);
  347. hp = (struct hostent *)NULL;
  348. for (i = 0; i < MAXDNSLUS && hp == NULL && lookups[i]; i++) {
  349. switch (lookups[i]) {
  350. case 'b':
  351. n = resolvQuery(qbuf, C_IN, T_PTR, (char *)&buf, 
  352. sizeof(buf));
  353. if (n == ERROR) {
  354. #ifdef DEBUG
  355. if (_res.options & RES_DEBUG)
  356. printf("resolvQuery failedn");
  357. #endif
  358. break;
  359. }
  360. hp = getanswer(&buf, n, 1, pHost, hostbuf, bufLen);
  361. if (hp == NULL)
  362. break;
  363. hp->h_addrtype = type;
  364. hp->h_length = len;
  365.              pHost->h_addr_list [1] = NULL;
  366.              bcopy (addr, (char *) &pHost->h_addr_list [2], 4);
  367.              pHost->h_addr_list [0] =  (char*) & pHost->h_addr_list [2];
  368. break;
  369. }
  370. }
  371. return (hp);
  372. }
  373. static int
  374. qcomp(a1, a2)
  375. struct in_addr **a1, **a2;
  376. {
  377. int pos1, pos2;
  378. for (pos1 = 0; pos1 < _res.nsort; pos1++)
  379. if (_res.sort_list[pos1].addr.s_addr ==
  380.     ((*a1)->s_addr & _res.sort_list[pos1].mask))
  381. break;
  382. for (pos2 = 0; pos2 < _res.nsort; pos2++)
  383. if (_res.sort_list[pos2].addr.s_addr ==
  384.     ((*a2)->s_addr & _res.sort_list[pos2].mask))
  385. break;
  386. return pos1 - pos2;
  387. }