inet_ntop.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:5k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /* This is from the BIND 4.9.4 release, modified to compile by itself */
  2. /* Copyright (c) 1996 by Internet Software Consortium.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software for any
  5.  * purpose with or without fee is hereby granted, provided that the above
  6.  * copyright notice and this permission notice appear in all copies.
  7.  *
  8.  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  9.  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  10.  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  11.  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  13.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  14.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  15.  * SOFTWARE.
  16.  */
  17. #ifndef HAVE_INET_NTOP
  18. #include "config_unix.h"
  19. #include "config_win32.h"
  20. #include "inet_ntop.h"
  21. #define IN6ADDRSZ 16
  22. #define INT16SZ  2
  23. #ifndef AF_INET6
  24. #define AF_INET6 AF_MAX+1 /* just to let this compile */
  25. #endif
  26. /*
  27.  * WARNING: Don't even consider trying to compile this on a system where
  28.  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
  29.  */
  30. static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
  31. static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
  32. /* char *
  33.  * inet_ntop(af, src, dst, size)
  34.  * convert a network format address to presentation format.
  35.  * return:
  36.  * pointer to presentation format address (`dst'), or NULL (see errno).
  37.  * author:
  38.  * Paul Vixie, 1996.
  39.  */
  40. const char *
  41. inet_ntop(af, src, dst, size)
  42. int af;
  43. const void *src;
  44. char *dst;
  45. size_t size;
  46. {
  47. switch (af) {
  48. case AF_INET:
  49. return (inet_ntop4(src, dst, size));
  50. case AF_INET6:
  51. return (inet_ntop6(src, dst, size));
  52. default:
  53. errno = EAFNOSUPPORT;
  54. return (NULL);
  55. }
  56. /* NOTREACHED */
  57. }
  58. /* const char *
  59.  * inet_ntop4(src, dst, size)
  60.  * format an IPv4 address, more or less like inet_ntoa()
  61.  * return:
  62.  * `dst' (as a const)
  63.  * notes:
  64.  * (1) uses no statics
  65.  * (2) takes a u_char* not an in_addr as input
  66.  * author:
  67.  * Paul Vixie, 1996.
  68.  */
  69. static const char *
  70. inet_ntop4(src, dst, size)
  71. const u_char *src;
  72. char *dst;
  73. size_t size;
  74. {
  75. static const char fmt[] = "%u.%u.%u.%u";
  76. char tmp[sizeof "255.255.255.255"];
  77. sprintf(tmp, fmt, src[0], src[1], src[2], src[3]);
  78. if ((size_t)strlen(tmp) > size) {
  79. errno = ENOSPC;
  80. return (NULL);
  81. }
  82. strcpy(dst, tmp);
  83. return (dst);
  84. }
  85. /* const char *
  86.  * inet_ntop6(src, dst, size)
  87.  * convert IPv6 binary address into presentation (printable) format
  88.  * author:
  89.  * Paul Vixie, 1996.
  90.  */
  91. static const char *
  92. inet_ntop6(src, dst, size)
  93. const u_char *src;
  94. char *dst;
  95. size_t size;
  96. {
  97. /*
  98.  * Note that int32_t and int16_t need only be "at least" large enough
  99.  * to contain a value of the specified size.  On some systems, like
  100.  * Crays, there is no such thing as an integer variable with 16 bits.
  101.  * Keep this in mind if you think this function should have been coded
  102.  * to use pointer overlays.  All the world's not a VAX.
  103.  */
  104. char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
  105. struct { int base, len; } best, cur;
  106. uint32_t words[IN6ADDRSZ / INT16SZ];
  107. int i;
  108. /*
  109.  * Preprocess:
  110.  * Copy the input (bytewise) array into a wordwise array.
  111.  * Find the longest run of 0x00's in src[] for :: shorthanding.
  112.  */
  113. memset(words, 0, sizeof words);
  114. for (i = 0; i < IN6ADDRSZ; i++)
  115. words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
  116. best.base = -1;
  117. cur.base = -1;
  118. for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
  119. if (words[i] == 0) {
  120. if (cur.base == -1)
  121. cur.base = i, cur.len = 1;
  122. else
  123. cur.len++;
  124. } else {
  125. if (cur.base != -1) {
  126. if (best.base == -1 || cur.len > best.len)
  127. best = cur;
  128. cur.base = -1;
  129. }
  130. }
  131. }
  132. if (cur.base != -1) {
  133. if (best.base == -1 || cur.len > best.len)
  134. best = cur;
  135. }
  136. if (best.base != -1 && best.len < 2)
  137. best.base = -1;
  138. /*
  139.  * Format the result.
  140.  */
  141. tp = tmp;
  142. for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
  143. /* Are we inside the best run of 0x00's? */
  144. if (best.base != -1 && i >= best.base &&
  145.     i < (best.base + best.len)) {
  146. if (i == best.base)
  147. *tp++ = ':';
  148. continue;
  149. }
  150. /* Are we following an initial run of 0x00s or any real hex? */
  151. if (i != 0)
  152. *tp++ = ':';
  153. /* Is this address an encapsulated IPv4? */
  154. if (i == 6 && best.base == 0 &&
  155.     (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
  156. if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
  157. return (NULL);
  158. tp += strlen(tp);
  159. break;
  160. }
  161. sprintf(tp, "%x", words[i]);
  162. tp += strlen(tp);
  163. }
  164. /* Was it a trailing run of 0x00's? */
  165. if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
  166. *tp++ = ':';
  167. *tp++ = '';
  168. /*
  169.  * Check for overflow, copy, and we're done.
  170.  */
  171. if ((size_t) (tp - tmp) > size) {
  172. errno = ENOSPC;
  173. return (NULL);
  174. }
  175. strcpy(dst, tmp);
  176. return (dst);
  177. }
  178. #endif