inet_net_ntop.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:5k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*
  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. #if defined(LIBC_SCCS) && !defined(lint)
  18. static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.6.2.1 1999/08/02 05:24:53 scrappy Exp $";
  19. #endif
  20. #include <sys/types.h>
  21. #include <sys/socket.h>
  22. #include <netinet/in.h>
  23. #include <arpa/inet.h>
  24. #include <errno.h>
  25. #include "postgres.h"
  26. #include "utils/builtins.h"
  27. #ifdef SPRINTF_CHAR
  28. #define SPRINTF(x) strlen(sprintf/**/x)
  29. #else
  30. #define SPRINTF(x) ((size_t)sprintf x)
  31. #endif
  32. static char *inet_net_ntop_ipv4(const u_char *src, int bits,
  33.    char *dst, size_t size);
  34. static char *inet_cidr_ntop_ipv4(const u_char *src, int bits,
  35. char *dst, size_t size);
  36. /*
  37.  * char *
  38.  * inet_cidr_ntop(af, src, bits, dst, size)
  39.  * convert network number from network to presentation format.
  40.  * generates CIDR style result always.
  41.  * return:
  42.  * pointer to dst, or NULL if an error occurred (check errno).
  43.  * author:
  44.  * Paul Vixie (ISC), July 1996
  45.  */
  46. char *
  47. inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
  48. {
  49. switch (af)
  50. {
  51. case AF_INET:
  52. return (inet_cidr_ntop_ipv4(src, bits, dst, size));
  53. default:
  54. errno = EAFNOSUPPORT;
  55. return (NULL);
  56. }
  57. }
  58. /*
  59.  * static char *
  60.  * inet_cidr_ntop_ipv4(src, bits, dst, size)
  61.  * convert IPv4 network number from network to presentation format.
  62.  * generates CIDR style result always.
  63.  * return:
  64.  * pointer to dst, or NULL if an error occurred (check errno).
  65.  * note:
  66.  * network byte order assumed.  this means 192.5.5.240/28 has
  67.  * 0x11110000 in its fourth octet.
  68.  * author:
  69.  * Paul Vixie (ISC), July 1996
  70.  */
  71. static char *
  72. inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
  73. {
  74. char    *odst = dst;
  75. char    *t;
  76. u_int m;
  77. int b;
  78. if (bits < 0 || bits > 32)
  79. {
  80. errno = EINVAL;
  81. return (NULL);
  82. }
  83. if (bits == 0)
  84. {
  85. if (size < sizeof "0")
  86. goto emsgsize;
  87. *dst++ = '0';
  88. *dst = '';
  89. }
  90. /* Format whole octets. */
  91. for (b = bits / 8; b > 0; b--)
  92. {
  93. if (size < sizeof "255.")
  94. goto emsgsize;
  95. t = dst;
  96. dst += SPRINTF((dst, "%u", *src++));
  97. if (b > 1)
  98. {
  99. *dst++ = '.';
  100. *dst = '';
  101. }
  102. size -= (size_t) (dst - t);
  103. }
  104. /* Format partial octet. */
  105. b = bits % 8;
  106. if (b > 0)
  107. {
  108. if (size < sizeof ".255")
  109. goto emsgsize;
  110. t = dst;
  111. if (dst != odst)
  112. *dst++ = '.';
  113. m = ((1 << b) - 1) << (8 - b);
  114. dst += SPRINTF((dst, "%u", *src & m));
  115. size -= (size_t) (dst - t);
  116. }
  117. /* Format CIDR /width. */
  118. if (size < sizeof "/32")
  119. goto emsgsize;
  120. dst += SPRINTF((dst, "/%u", bits));
  121. return (odst);
  122. emsgsize:
  123. errno = EMSGSIZE;
  124. return (NULL);
  125. }
  126. /*
  127.  * char *
  128.  * inet_net_ntop(af, src, bits, dst, size)
  129.  * convert host/network address from network to presentation format.
  130.  * "src"'s size is determined from its "af".
  131.  * return:
  132.  * pointer to dst, or NULL if an error occurred (check errno).
  133.  * note:
  134.  * 192.5.5.1/28 has a nonzero host part, which means it isn't a network
  135.  * as called for by inet_net_pton() but it can be a host address with
  136.  * an included netmask.
  137.  * author:
  138.  * Paul Vixie (ISC), October 1998
  139.  */
  140. char *
  141. inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
  142. {
  143. switch (af)
  144. {
  145. case AF_INET:
  146. return (inet_net_ntop_ipv4(src, bits, dst, size));
  147. default:
  148. errno = EAFNOSUPPORT;
  149. return (NULL);
  150. }
  151. }
  152. /*
  153.  * static char *
  154.  * inet_net_ntop_ipv4(src, bits, dst, size)
  155.  * convert IPv4 network address from network to presentation format.
  156.  * "src"'s size is determined from its "af".
  157.  * return:
  158.  * pointer to dst, or NULL if an error occurred (check errno).
  159.  * note:
  160.  * network byte order assumed.  this means 192.5.5.240/28 has
  161.  * 0b11110000 in its fourth octet.
  162.  * author:
  163.  * Paul Vixie (ISC), October 1998
  164.  */
  165. static char *
  166. inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
  167. {
  168. char    *odst = dst;
  169. char    *t;
  170. size_t len = 4;
  171. int b,
  172. tb;
  173. if (bits < 0 || bits > 32)
  174. {
  175. errno = EINVAL;
  176. return (NULL);
  177. }
  178. if (bits == 0)
  179. {
  180. if (size < sizeof "0")
  181. goto emsgsize;
  182. *dst++ = '0';
  183. size--;
  184. *dst = '';
  185. }
  186. /* Format whole octets plus nonzero trailing octets. */
  187. tb = (bits == 32) ? 31 : bits;
  188. for (b = 0; bits != 0 && (b <= (tb / 8) || (b < len && *src != 0)); b++)
  189. {
  190. if (size < sizeof "255.")
  191. goto emsgsize;
  192. t = dst;
  193. dst += SPRINTF((dst, "%u", *src++));
  194. if (b + 1 <= (tb / 8) || (b + 1 < len && *src != 0))
  195. {
  196. *dst++ = '.';
  197. *dst = '';
  198. }
  199. size -= (size_t) (dst - t);
  200. }
  201. /* don't print masklen if 32 bits */
  202. if (bits == 32)
  203. return odst;
  204. /* Format CIDR /width. */
  205. if (size < sizeof "/32")
  206. goto emsgsize;
  207. dst += SPRINTF((dst, "/%u", bits));
  208. return (odst);
  209. emsgsize:
  210. errno = EMSGSIZE;
  211. return (NULL);
  212. }