res_comp.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * 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.  * 3. All advertising materials mentioning features or use of this software
  14.  *   must display the following acknowledgement:
  15.  * This product includes software developed by the University of
  16.  * California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *   may be used to endorse or promote products derived from this software
  19.  *   without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. #if defined(LIBC_SCCS) && !defined(lint)
  34. /*static char *sccsid = "from: @(#)res_comp.c 6.22 (Berkeley) 3/19/91";*/
  35. static char *rcsid = "$Id$";
  36. #endif /* LIBC_SCCS and not lint */
  37. #include <pthread.h>
  38. #include <sys/param.h>
  39. #include <sys/cdefs.h>
  40. #include <netinet/in.h>
  41. #include <resolv.h>
  42. #include <stdio.h>
  43. static dn_find();
  44. /*
  45.  * Expand compressed domain name 'comp_dn' to full domain name.
  46.  * 'msg' is a pointer to the begining of the message,
  47.  * 'eomorig' points to the first location after the message,
  48.  * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
  49.  * Return size of compressed name or -1 if there was an error.
  50.  */
  51. dn_expand(msg, eomorig, comp_dn, exp_dn, length)
  52. const u_char *msg, *eomorig, *comp_dn;
  53. u_char *exp_dn;
  54. int length;
  55. {
  56. register u_char *cp, *dn;
  57. register int n, c;
  58. u_char *eom;
  59. int len = -1, checked = 0;
  60. dn = exp_dn;
  61. cp = (u_char *)comp_dn;
  62. eom = exp_dn + length;
  63. /*
  64.  * fetch next label in domain name
  65.  */
  66. while (n = *cp++) {
  67. /*
  68.  * Check for indirection
  69.  */
  70. switch (n & INDIR_MASK) {
  71.   case 0:
  72. if (dn != exp_dn) {
  73. if (dn >= eom)
  74. return (-1);
  75. *dn++ = '.';
  76. }
  77. if (dn+n >= eom)
  78. return (-1);
  79. checked += n + 1;
  80. while (--n >= 0) {
  81. if ((c = *cp++) == '.') {
  82. if (dn + n + 2 >= eom)
  83. return (-1);
  84. *dn++ = '\';
  85. }
  86. *dn++ = c;
  87. if (cp >= eomorig) /* out of range */
  88. return(-1);
  89. }
  90. break;
  91.   case INDIR_MASK:
  92. if (len < 0)
  93. len = cp - comp_dn + 1;
  94. cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
  95. if (cp < msg || cp >= eomorig) /* out of range */
  96. return(-1);
  97. checked += 2;
  98. /*
  99.  * Check for loops in the compressed name;
  100.  * if we've looked at the whole message,
  101.  * there must be a loop.
  102.  */
  103. if (checked >= eomorig - msg)
  104. return (-1);
  105. break;
  106.   default:
  107. return (-1); /* flag error */
  108. }
  109. }
  110. *dn = '';
  111. if (len < 0)
  112. len = cp - comp_dn;
  113. return (len);
  114. }
  115. /*
  116.  * Compress domain name 'exp_dn' into 'comp_dn'.
  117.  * Return the size of the compressed name or -1.
  118.  * 'length' is the size of the array pointed to by 'comp_dn'.
  119.  * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
  120.  * is a pointer to the beginning of the message. The list ends with NULL.
  121.  * 'lastdnptr' is a pointer to the end of the arrary pointed to
  122.  * by 'dnptrs'. Side effect is to update the list of pointers for
  123.  * labels inserted into the message as we compress the name.
  124.  * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
  125.  * is NULL, we don't update the list.
  126.  */
  127. dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
  128. const u_char *exp_dn;
  129. u_char *comp_dn, **dnptrs, **lastdnptr;
  130. int length;
  131. {
  132. register u_char *cp, *dn;
  133. register int c, l;
  134. u_char **cpp, **lpp, *sp, *eob;
  135. u_char *msg;
  136. dn = (u_char *)exp_dn;
  137. cp = comp_dn;
  138. eob = cp + length;
  139. if (dnptrs != NULL) {
  140. if ((msg = *dnptrs++) != NULL) {
  141. for (cpp = dnptrs; *cpp != NULL; cpp++)
  142. ;
  143. lpp = cpp; /* end of list to search */
  144. }
  145. } else
  146. msg = NULL;
  147. for (c = *dn++; c != ''; ) {
  148. /* look to see if we can use pointers */
  149. if (msg != NULL) {
  150. if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
  151. if (cp+1 >= eob)
  152. return (-1);
  153. *cp++ = (l >> 8) | INDIR_MASK;
  154. *cp++ = l % 256;
  155. return (cp - comp_dn);
  156. }
  157. /* not found, save it */
  158. if (lastdnptr != NULL && cpp < lastdnptr-1) {
  159. *cpp++ = cp;
  160. *cpp = NULL;
  161. }
  162. }
  163. sp = cp++; /* save ptr to length byte */
  164. do {
  165. if (c == '.') {
  166. c = *dn++;
  167. break;
  168. }
  169. if (c == '\') {
  170. if ((c = *dn++) == '')
  171. break;
  172. }
  173. if (cp >= eob) {
  174. if (msg != NULL)
  175. *lpp = NULL;
  176. return (-1);
  177. }
  178. *cp++ = c;
  179. } while ((c = *dn++) != '');
  180. /* catch trailing '.'s but not '..' */
  181. if ((l = cp - sp - 1) == 0 && c == '') {
  182. cp--;
  183. break;
  184. }
  185. if (l <= 0 || l > MAXLABEL) {
  186. if (msg != NULL)
  187. *lpp = NULL;
  188. return (-1);
  189. }
  190. *sp = l;
  191. }
  192. if (cp >= eob) {
  193. if (msg != NULL)
  194. *lpp = NULL;
  195. return (-1);
  196. }
  197. *cp++ = '';
  198. return (cp - comp_dn);
  199. }
  200. /*
  201.  * Skip over a compressed domain name. Return the size or -1.
  202.  */
  203. __dn_skipname(comp_dn, eom)
  204. const u_char *comp_dn, *eom;
  205. {
  206. register u_char *cp;
  207. register int n;
  208. cp = (u_char *)comp_dn;
  209. while (cp < eom && (n = *cp++)) {
  210. /*
  211.  * check for indirection
  212.  */
  213. switch (n & INDIR_MASK) {
  214.   case 0: /* normal case, n == len */
  215. cp += n;
  216. continue;
  217.   case INDIR_MASK: /* indirection */
  218. cp++;
  219. break;
  220.   default: /* illegal type */
  221. return (-1);
  222. }
  223. break;
  224. }
  225. if (cp > eom)
  226. return -1;
  227. return (cp - comp_dn);
  228. }
  229. /*
  230.  * Search for expanded name from a list of previously compressed names.
  231.  * Return the offset from msg if found or -1.
  232.  * dnptrs is the pointer to the first name on the list,
  233.  * not the pointer to the start of the message.
  234.  */
  235. static int
  236. dn_find(exp_dn, msg, dnptrs, lastdnptr)
  237. u_char *exp_dn, *msg;
  238. u_char **dnptrs, **lastdnptr;
  239. {
  240. register u_char *dn, *cp, **cpp;
  241. register int n;
  242. u_char *sp;
  243. for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
  244. dn = exp_dn;
  245. sp = cp = *cpp;
  246. while (n = *cp++) {
  247. /*
  248.  * check for indirection
  249.  */
  250. switch (n & INDIR_MASK) {
  251.   case 0: /* normal case, n == len */
  252. while (--n >= 0) {
  253. if (*dn == '.')
  254. goto next;
  255. if (*dn == '\')
  256. dn++;
  257. if (*dn++ != *cp++)
  258. goto next;
  259. }
  260. if ((n = *dn++) == '' && *cp == '')
  261. return (sp - msg);
  262. if (n == '.')
  263. continue;
  264. goto next;
  265.   default: /* illegal type */
  266. return (-1);
  267.   case INDIR_MASK: /* indirection */
  268. cp = msg + (((n & 0x3f) << 8) | *cp);
  269. }
  270. }
  271. if (*dn == '')
  272. return (sp - msg);
  273.   next: ;
  274. }
  275. return (-1);
  276. }
  277. /*
  278.  * Routines to insert/extract short/long's. Must account for byte
  279.  * order and non-alignment problems. This code at least has the
  280.  * advantage of being portable.
  281.  *
  282.  * used by sendmail.
  283.  */
  284. u_short
  285. _getshort(msgp)
  286. register const u_char *msgp;
  287. {
  288. register u_short u;
  289. GETSHORT(u, msgp);
  290. return (u);
  291. }
  292. pthread_ipaddr_type
  293. _getlong(msgp)
  294. const u_char *msgp;
  295. {
  296. pthread_ipaddr_type u;
  297. GETLONG(u, msgp);
  298. return (u);
  299. }
  300. void
  301. #ifdef __STDC__
  302. __putshort(register u_short s, register u_char *msgp)
  303. #else
  304. __putshort(s, msgp)
  305. register u_short s;
  306. register u_char *msgp;
  307. #endif
  308. {
  309. PUTSHORT(s, msgp);
  310. }
  311. void
  312. __putlong(l, msgp)
  313. register pthread_ipaddr_type l;
  314. register u_char *msgp;
  315. {
  316. PUTLONG(l, msgp);
  317. }