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

数据库系统

开发平台:

Unix_Linux

  1. /*
  2.  * PostgreSQL type definitions for the INET type. This
  3.  * is for IP V4 CIDR notation, but prepared for V6: just
  4.  * add the necessary bits where the comments indicate.
  5.  *
  6.  * $Id: network.c,v 1.10.2.1 1999/08/02 05:24:55 scrappy Exp $
  7.  * Jon Postel RIP 16 Oct 1998
  8.  */
  9. #include <sys/types.h>
  10. #include <sys/socket.h>
  11. #include <errno.h>
  12. #include <netinet/in.h>
  13. #include <arpa/inet.h>
  14. #include "postgres.h"
  15. #include "utils/builtins.h"
  16. static int v4bitncmp(unsigned int a1, unsigned int a2, int bits);
  17. /*
  18.  * Access macros. Add IPV6 support.
  19.  */
  20. #define ip_addrsize(inetptr) 
  21. (((inet_struct *)VARDATA(inetptr))->family == AF_INET ? 4 : -1)
  22. #define ip_family(inetptr) 
  23. (((inet_struct *)VARDATA(inetptr))->family)
  24. #define ip_bits(inetptr) 
  25. (((inet_struct *)VARDATA(inetptr))->bits)
  26. #define ip_type(inetptr) 
  27. (((inet_struct *)VARDATA(inetptr))->type)
  28. #define ip_v4addr(inetptr) 
  29. (((inet_struct *)VARDATA(inetptr))->addr.ipv4_addr)
  30. /* Common input routine */
  31. static inet *
  32. network_in(char *src, int type)
  33. {
  34. int bits;
  35. inet    *dst;
  36. if (!src)
  37. return NULL;
  38. dst = palloc(VARHDRSZ + sizeof(inet_struct));
  39. if (dst == NULL)
  40. elog(ERROR, "unable to allocate memory in network_in()");
  41. /* First, try for an IP V4 address: */
  42. ip_family(dst) = AF_INET;
  43. bits = inet_net_pton(ip_family(dst), src, &ip_v4addr(dst),
  44.  type ? ip_addrsize(dst) : -1);
  45. if ((bits < 0) || (bits > 32))
  46. /* Go for an IPV6 address here, before faulting out: */
  47. elog(ERROR, "could not parse "%s"", src);
  48. VARSIZE(dst) = VARHDRSZ
  49. + ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
  50. + ip_addrsize(dst);
  51. ip_bits(dst) = bits;
  52. ip_type(dst) = type;
  53. return dst;
  54. }
  55. /* INET address reader.  */
  56. inet *
  57. inet_in(char *src)
  58. {
  59. return network_in(src, 0);
  60. }
  61. /* CIDR address reader.  */
  62. inet *
  63. cidr_in(char *src)
  64. {
  65. return network_in(src, 1);
  66. }
  67. /*
  68.  * INET address output function.
  69.  */
  70. char *
  71. inet_out(inet *src)
  72. {
  73. char    *dst,
  74. tmp[sizeof("255.255.255.255/32")];
  75. if (ip_family(src) == AF_INET)
  76. {
  77. /* It's an IP V4 address: */
  78. if (ip_type(src))
  79. dst = inet_cidr_ntop(AF_INET, &ip_v4addr(src), ip_bits(src),
  80.  tmp, sizeof(tmp));
  81. else
  82. dst = inet_net_ntop(AF_INET, &ip_v4addr(src), ip_bits(src),
  83. tmp, sizeof(tmp));
  84. if (dst == NULL)
  85. elog(ERROR, "unable to print address (%s)", strerror(errno));
  86. }
  87. else
  88. /* Go for an IPV6 address here, before faulting out: */
  89. elog(ERROR, "unknown address family (%d)", ip_family(src));
  90. dst = palloc(strlen(tmp) + 1);
  91. if (dst == NULL)
  92. elog(ERROR, "unable to allocate memory in inet_out()");
  93. strcpy(dst, tmp);
  94. return dst;
  95. }
  96. /* just a stub */
  97. char *
  98. cidr_out(inet *src)
  99. {
  100. return inet_out(src);
  101. }
  102. /*
  103.  * Boolean tests for magnitude.  Add V4/V6 testing!
  104.  */
  105. bool
  106. network_lt(inet *a1, inet *a2)
  107. {
  108. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  109. return FALSE;
  110. if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
  111. {
  112. int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
  113. return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2))));
  114. }
  115. else
  116. {
  117. /* Go for an IPV6 address here, before faulting out: */
  118. elog(ERROR, "cannot compare address families %d and %d",
  119.  ip_family(a1), ip_family(a2));
  120. return FALSE;
  121. }
  122. }
  123. bool
  124. network_le(inet *a1, inet *a2)
  125. {
  126. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  127. return FALSE;
  128. return (network_lt(a1, a2) || network_eq(a1, a2));
  129. }
  130. bool
  131. network_eq(inet *a1, inet *a2)
  132. {
  133. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  134. return FALSE;
  135. if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
  136. {
  137. return ((ip_bits(a1) == ip_bits(a2))
  138.  && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
  139. }
  140. else
  141. {
  142. /* Go for an IPV6 address here, before faulting out: */
  143. elog(ERROR, "cannot compare address families %d and %d",
  144.  ip_family(a1), ip_family(a2));
  145. return FALSE;
  146. }
  147. }
  148. bool
  149. network_ge(inet *a1, inet *a2)
  150. {
  151. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  152. return FALSE;
  153. return (network_gt(a1, a2) || network_eq(a1, a2));
  154. }
  155. bool
  156. network_gt(inet *a1, inet *a2)
  157. {
  158. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  159. return FALSE;
  160. if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
  161. {
  162. int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2));
  163. return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2))));
  164. }
  165. else
  166. {
  167. /* Go for an IPV6 address here, before faulting out: */
  168. elog(ERROR, "cannot compare address families %d and %d",
  169.  ip_family(a1), ip_family(a2));
  170. return FALSE;
  171. }
  172. }
  173. bool
  174. network_ne(inet *a1, inet *a2)
  175. {
  176. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  177. return FALSE;
  178. return (!network_eq(a1, a2));
  179. }
  180. bool
  181. network_sub(inet *a1, inet *a2)
  182. {
  183. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  184. return FALSE;
  185. if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
  186. {
  187. return ((ip_bits(a1) > ip_bits(a2))
  188.  && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
  189. }
  190. else
  191. {
  192. /* Go for an IPV6 address here, before faulting out: */
  193. elog(ERROR, "cannot compare address families %d and %d",
  194.  ip_family(a1), ip_family(a2));
  195. return FALSE;
  196. }
  197. }
  198. bool
  199. network_subeq(inet *a1, inet *a2)
  200. {
  201. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  202. return FALSE;
  203. if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
  204. {
  205. return ((ip_bits(a1) >= ip_bits(a2))
  206.  && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0));
  207. }
  208. else
  209. {
  210. /* Go for an IPV6 address here, before faulting out: */
  211. elog(ERROR, "cannot compare address families %d and %d",
  212.  ip_family(a1), ip_family(a2));
  213. return FALSE;
  214. }
  215. }
  216. bool
  217. network_sup(inet *a1, inet *a2)
  218. {
  219. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  220. return FALSE;
  221. if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
  222. {
  223. return ((ip_bits(a1) < ip_bits(a2))
  224.  && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
  225. }
  226. else
  227. {
  228. /* Go for an IPV6 address here, before faulting out: */
  229. elog(ERROR, "cannot compare address families %d and %d",
  230.  ip_family(a1), ip_family(a2));
  231. return FALSE;
  232. }
  233. }
  234. bool
  235. network_supeq(inet *a1, inet *a2)
  236. {
  237. if (!PointerIsValid(a1) || !PointerIsValid(a2))
  238. return FALSE;
  239. if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET))
  240. {
  241. return ((ip_bits(a1) <= ip_bits(a2))
  242.  && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0));
  243. }
  244. else
  245. {
  246. /* Go for an IPV6 address here, before faulting out: */
  247. elog(ERROR, "cannot compare address families %d and %d",
  248.  ip_family(a1), ip_family(a2));
  249. return FALSE;
  250. }
  251. }
  252. /*
  253.  * Comparison function for sorting.  Add V4/V6 testing!
  254.  */
  255. int4
  256. network_cmp(inet *a1, inet *a2)
  257. {
  258. if (ntohl(ip_v4addr(a1)) < ntohl(ip_v4addr(a2)))
  259. return (-1);
  260. if (ntohl(ip_v4addr(a1)) > ntohl(ip_v4addr(a2)))
  261. return (1);
  262. if (ip_bits(a1) < ip_bits(a2))
  263. return (-1);
  264. if (ip_bits(a1) > ip_bits(a2))
  265. return (1);
  266. return 0;
  267. }
  268. text *
  269. network_host(inet *ip)
  270. {
  271. text    *ret;
  272. int len;
  273. char    *ptr,
  274. tmp[sizeof("255.255.255.255/32")];
  275. if (!PointerIsValid(ip))
  276. return NULL;
  277. if (ip_type(ip))
  278. elog(ERROR, "CIDR type has no host part");
  279. if (ip_family(ip) == AF_INET)
  280. {
  281. /* It's an IP V4 address: */
  282. if (inet_net_ntop(AF_INET, &ip_v4addr(ip), 32, tmp, sizeof(tmp)) == NULL)
  283. elog(ERROR, "unable to print host (%s)", strerror(errno));
  284. }
  285. else
  286. /* Go for an IPV6 address here, before faulting out: */
  287. elog(ERROR, "unknown address family (%d)", ip_family(ip));
  288. if ((ptr = strchr(tmp, '/')) != NULL)
  289. *ptr = 0;
  290. len = VARHDRSZ + strlen(tmp) + 1;
  291. ret = palloc(len);
  292. if (ret == NULL)
  293. elog(ERROR, "unable to allocate memory in network_host()");
  294. VARSIZE(ret) = len;
  295. strcpy(VARDATA(ret), tmp);
  296. return (ret);
  297. }
  298. int4
  299. network_masklen(inet *ip)
  300. {
  301. if (!PointerIsValid(ip))
  302. return 0;
  303. return ip_bits(ip);
  304. }
  305. text *
  306. network_broadcast(inet *ip)
  307. {
  308. text    *ret;
  309. int len;
  310. char    *ptr,
  311. tmp[sizeof("255.255.255.255/32")];
  312. if (!PointerIsValid(ip))
  313. return NULL;
  314. if (ip_family(ip) == AF_INET)
  315. {
  316. /* It's an IP V4 address: */
  317. int addr;
  318. unsigned long mask = 0xffffffff;
  319. if (ip_bits(ip) < 32)
  320. mask >>= ip_bits(ip);
  321. addr = htonl(ntohl(ip_v4addr(ip)) | mask);
  322. if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
  323. elog(ERROR, "unable to print address (%s)", strerror(errno));
  324. }
  325. else
  326. /* Go for an IPV6 address here, before faulting out: */
  327. elog(ERROR, "unknown address family (%d)", ip_family(ip));
  328. if ((ptr = strchr(tmp, '/')) != NULL)
  329. *ptr = 0;
  330. len = VARHDRSZ + strlen(tmp) + 1;
  331. ret = palloc(len);
  332. if (ret == NULL)
  333. elog(ERROR, "unable to allocate memory in network_broadcast()");
  334. VARSIZE(ret) = len;
  335. strcpy(VARDATA(ret), tmp);
  336. return (ret);
  337. }
  338. text *
  339. network_network(inet *ip)
  340. {
  341. text    *ret;
  342. int len;
  343. char tmp[sizeof("255.255.255.255/32")];
  344. if (!PointerIsValid(ip))
  345. return NULL;
  346. if (ip_family(ip) == AF_INET)
  347. {
  348. /* It's an IP V4 address: */
  349. int addr = htonl(ntohl(ip_v4addr(ip)) & (0xffffffff << (32 - ip_bits(ip))));
  350. if (inet_cidr_ntop(AF_INET, &addr, ip_bits(ip), tmp, sizeof(tmp)) == NULL)
  351. elog(ERROR, "unable to print network (%s)", strerror(errno));
  352. }
  353. else
  354. /* Go for an IPV6 address here, before faulting out: */
  355. elog(ERROR, "unknown address family (%d)", ip_family(ip));
  356. len = VARHDRSZ + strlen(tmp) + 1;
  357. ret = palloc(len);
  358. if (ret == NULL)
  359. elog(ERROR, "unable to allocate memory in network_network()");
  360. VARSIZE(ret) = len;
  361. strcpy(VARDATA(ret), tmp);
  362. return (ret);
  363. }
  364. text *
  365. network_netmask(inet *ip)
  366. {
  367. text    *ret;
  368. int len;
  369. char    *ptr,
  370. tmp[sizeof("255.255.255.255/32")];
  371. if (!PointerIsValid(ip))
  372. return NULL;
  373. if (ip_family(ip) == AF_INET)
  374. {
  375. /* It's an IP V4 address: */
  376. int addr = htonl((-1 << (32 - ip_bits(ip))) & 0xffffffff);
  377. if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
  378. elog(ERROR, "unable to print netmask (%s)", strerror(errno));
  379. }
  380. else
  381. /* Go for an IPV6 address here, before faulting out: */
  382. elog(ERROR, "unknown address family (%d)", ip_family(ip));
  383. if ((ptr = strchr(tmp, '/')) != NULL)
  384. *ptr = 0;
  385. len = VARHDRSZ + strlen(tmp) + 1;
  386. ret = palloc(len);
  387. if (ret == NULL)
  388. elog(ERROR, "unable to allocate memory in network_netmask()");
  389. VARSIZE(ret) = len;
  390. strcpy(VARDATA(ret), tmp);
  391. return (ret);
  392. }
  393. /*
  394.  * Bitwise comparison for V4 addresses.  Add V6 implementation!
  395.  */
  396. static int
  397. v4bitncmp(unsigned int a1, unsigned int a2, int bits)
  398. {
  399. unsigned long mask = 0;
  400. int i;
  401. for (i = 0; i < bits; i++)
  402. mask = (mask >> 1) | 0x80000000;
  403. a1 = ntohl(a1);
  404. a2 = ntohl(a2);
  405. if ((a1 & mask) < (a2 & mask))
  406. return (-1);
  407. else if ((a1 & mask) > (a2 & mask))
  408. return (1);
  409. return (0);
  410. }