inet_pton.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:6k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* $Id: inet_pton.c,v 1.3 1999/05/13 16:35:56 karls Exp $ */
  2. #ifdef HAVE_CONFIG_H
  3. #include "autoconf.h"
  4. #endif  /* HAVE_CONFIG_H */
  5. #include "common.h"
  6. #if !HAVE_INET_PTON
  7. /* $OpenBSD: inet_pton.c,v 1.2 1997/04/13 05:08:24 deraadt Exp $ */
  8. /* Copyright (c) 1996 by Internet Software Consortium.
  9.  *
  10.  * Permission to use, copy, modify, and distribute this software for any
  11.  * purpose with or without fee is hereby granted, provided that the above
  12.  * copyright notice and this permission notice appear in all copies.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  15.  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  16.  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  17.  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  18.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  19.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  20.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23. #if defined(LIBC_SCCS) && !defined(lint)
  24. #if 0
  25. static char rcsid[] = "$From: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
  26. #else
  27. static char rcsid[] = "$OpenBSD: inet_pton.c,v 1.2 1997/04/13 05:08:24 deraadt Exp $";
  28. #endif
  29. #endif /* LIBC_SCCS and not lint */
  30. #if 0
  31. #include <sys/param.h>
  32. #include <sys/types.h>
  33. #include <sys/socket.h>
  34. #include <netinet/in.h>
  35. #include <arpa/inet.h>
  36. #include <arpa/nameser.h>
  37. #include <string.h>
  38. #include <errno.h>
  39. #endif
  40. #ifndef AF_INET6
  41. #define     AF_INET6  24     /* IPv6 */
  42. #endif /* !AF_INET6 */
  43. #ifndef INADDRSZ
  44. #define INADDRSZ        4               /* IPv4 T_A */
  45. #endif /* !INADDRSZ */
  46. #ifndef IN6ADDRSZ
  47. #define IN6ADDRSZ 16      /* IPv6 T_AAAA */
  48. #endif /* !IN6ADDRSZ */
  49. #ifndef INT16SZ
  50. #define INT16SZ     2     /* for systems without 16-bit ints */
  51. #endif /* !INT16SZ */
  52. /*
  53.  * WARNING: Don't even consider trying to compile this on a system where
  54.  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
  55.  */
  56. static int inet_pton4 __P((const char *src, u_char *dst));
  57. static int inet_pton6 __P((const char *src, u_char *dst));
  58. /* int
  59.  * inet_pton(af, src, dst)
  60.  * convert from presentation format (which usually means ASCII printable)
  61.  * to network format (which is usually some kind of binary format).
  62.  * return:
  63.  * 1 if the address was valid for the specified address family
  64.  * 0 if the address wasn't valid (`dst' is untouched in this case)
  65.  * -1 if some other error occurred (`dst' is untouched in this case, too)
  66.  * author:
  67.  * Paul Vixie, 1996.
  68.  */
  69. int
  70. inet_pton(af, src, dst)
  71. int af;
  72. const char *src;
  73. void *dst;
  74. {
  75. switch (af) {
  76. case AF_INET:
  77. return (inet_pton4(src, dst));
  78. case AF_INET6:
  79. return (inet_pton6(src, dst));
  80. default:
  81. errno = EAFNOSUPPORT;
  82. return (-1);
  83. }
  84. /* NOTREACHED */
  85. }
  86. /* int
  87.  * inet_pton4(src, dst)
  88.  * like inet_aton() but without all the hexadecimal and shorthand.
  89.  * return:
  90.  * 1 if `src' is a valid dotted quad, else 0.
  91.  * notice:
  92.  * does not touch `dst' unless it's returning 1.
  93.  * author:
  94.  * Paul Vixie, 1996.
  95.  */
  96. static int
  97. inet_pton4(src, dst)
  98. const char *src;
  99. u_char *dst;
  100. {
  101. static const char digits[] = "0123456789";
  102. int saw_digit, octets, ch;
  103. u_char tmp[INADDRSZ], *tp;
  104. saw_digit = 0;
  105. octets = 0;
  106. *(tp = tmp) = 0;
  107. while ((ch = *src++) != '') {
  108. const char *pch;
  109. if ((pch = strchr(digits, ch)) != NULL) {
  110. u_int new = *tp * 10 + (pch - digits);
  111. if (new > 255)
  112. return (0);
  113. if (! saw_digit) {
  114. if (++octets > 4)
  115. return (0);
  116. saw_digit = 1;
  117. }
  118. *tp = new;
  119. } else if (ch == '.' && saw_digit) {
  120. if (octets == 4)
  121. return (0);
  122. *++tp = 0;
  123. saw_digit = 0;
  124. } else
  125. return (0);
  126. }
  127. if (octets < 4)
  128. return (0);
  129. memcpy(dst, tmp, INADDRSZ);
  130. return (1);
  131. }
  132. /* int
  133.  * inet_pton6(src, dst)
  134.  * convert presentation level address to network order binary form.
  135.  * return:
  136.  * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
  137.  * notice:
  138.  * (1) does not touch `dst' unless it's returning 1.
  139.  * (2) :: in a full address is silently ignored.
  140.  * credit:
  141.  * inspired by Mark Andrews.
  142.  * author:
  143.  * Paul Vixie, 1996.
  144.  */
  145. static int
  146. inet_pton6(src, dst)
  147. const char *src;
  148. u_char *dst;
  149. {
  150. static const char xdigits_l[] = "0123456789abcdef",
  151.   xdigits_u[] = "0123456789ABCDEF";
  152. u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
  153. const char *xdigits, *curtok;
  154. int ch, saw_xdigit;
  155. u_int val;
  156. memset((tp = tmp), '', IN6ADDRSZ);
  157. endp = tp + IN6ADDRSZ;
  158. colonp = NULL;
  159. /* Leading :: requires some special handling. */
  160. if (*src == ':')
  161. if (*++src != ':')
  162. return (0);
  163. curtok = src;
  164. saw_xdigit = 0;
  165. val = 0;
  166. while ((ch = *src++) != '') {
  167. const char *pch;
  168. if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
  169. pch = strchr((xdigits = xdigits_u), ch);
  170. if (pch != NULL) {
  171. val <<= 4;
  172. val |= (pch - xdigits);
  173. if (val > 0xffff)
  174. return (0);
  175. saw_xdigit = 1;
  176. continue;
  177. }
  178. if (ch == ':') {
  179. curtok = src;
  180. if (!saw_xdigit) {
  181. if (colonp)
  182. return (0);
  183. colonp = tp;
  184. continue;
  185. }
  186. if (tp + INT16SZ > endp)
  187. return (0);
  188. *tp++ = (u_char) (val >> 8) & 0xff;
  189. *tp++ = (u_char) val & 0xff;
  190. saw_xdigit = 0;
  191. val = 0;
  192. continue;
  193. }
  194. if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
  195.     inet_pton4(curtok, tp) > 0) {
  196. tp += INADDRSZ;
  197. saw_xdigit = 0;
  198. break; /* '' was seen by inet_pton4(). */
  199. }
  200. return (0);
  201. }
  202. if (saw_xdigit) {
  203. if (tp + INT16SZ > endp)
  204. return (0);
  205. *tp++ = (u_char) (val >> 8) & 0xff;
  206. *tp++ = (u_char) val & 0xff;
  207. }
  208. if (colonp != NULL) {
  209. /*
  210.  * Since some memmove()'s erroneously fail to handle
  211.  * overlapping regions, we'll do the shift by hand.
  212.  */
  213. const int n = tp - colonp;
  214. int i;
  215. for (i = 1; i <= n; i++) {
  216. endp[- i] = colonp[n - i];
  217. colonp[n - i] = 0;
  218. }
  219. tp = endp;
  220. }
  221. if (tp != endp)
  222. return (0);
  223. memcpy(dst, tmp, IN6ADDRSZ);
  224. return (1);
  225. }
  226. #else
  227. static void avoid_error __P((void));
  228. static void avoid_error()
  229. {
  230. avoid_error();
  231. }
  232. #endif /* !HAVE_INET_PTON */