2 * PostgreSQL type definitions for the INET and CIDR types.
4 * $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.66 2006/10/04 00:29:59 momjian Exp $
6 * Jon Postel RIP 16 Oct 1998
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
15 #include "access/hash.h"
16 #include "catalog/pg_type.h"
18 #include "libpq/libpq-be.h"
19 #include "libpq/pqformat.h"
20 #include "miscadmin.h"
21 #include "utils/builtins.h"
22 #include "utils/inet.h"
25 static inet *text_network(text *src, bool is_cidr);
26 static int32 network_cmp_internal(inet *a1, inet *a2);
27 static int bitncmp(void *l, void *r, int n);
28 static bool addressOK(unsigned char *a, int bits, int family);
29 static int ip_addrsize(inet *inetptr);
30 static inet *internal_inetpl(inet *ip, int64 addend);
36 #define ip_family(inetptr) \
37 (((inet_struct *)VARDATA(inetptr))->family)
39 #define ip_bits(inetptr) \
40 (((inet_struct *)VARDATA(inetptr))->bits)
42 #define ip_addr(inetptr) \
43 (((inet_struct *)VARDATA(inetptr))->ipaddr)
45 #define ip_maxbits(inetptr) \
46 (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
49 * Return the number of bytes of storage needed for this data type.
52 ip_addrsize(inet *inetptr)
54 switch (ip_family(inetptr))
66 * Common INET/CIDR input routine
69 network_in(char *src, bool is_cidr)
74 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
77 * First, check to see if this is an IPv6 or IPv4 address. IPv6 addresses
78 * will have a : somewhere in them (several, in fact) so if there is one
79 * present, assume it's V6, otherwise assume it's V4.
82 if (strchr(src, ':') != NULL)
83 ip_family(dst) = PGSQL_AF_INET6;
85 ip_family(dst) = PGSQL_AF_INET;
87 bits = inet_net_pton(ip_family(dst), src, ip_addr(dst),
88 is_cidr ? ip_addrsize(dst) : -1);
89 if ((bits < 0) || (bits > ip_maxbits(dst)))
91 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
92 /* translator: first %s is inet or cidr */
93 errmsg("invalid input syntax for type %s: \"%s\"",
94 is_cidr ? "cidr" : "inet", src)));
97 * Error check: CIDR values must not have any bits set beyond the masklen.
101 if (!addressOK(ip_addr(dst), bits, ip_family(dst)))
103 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
104 errmsg("invalid cidr value: \"%s\"", src),
105 errdetail("Value has bits set to right of mask.")));
108 VARATT_SIZEP(dst) = VARHDRSZ +
109 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
117 inet_in(PG_FUNCTION_ARGS)
119 char *src = PG_GETARG_CSTRING(0);
121 PG_RETURN_INET_P(network_in(src, false));
125 cidr_in(PG_FUNCTION_ARGS)
127 char *src = PG_GETARG_CSTRING(0);
129 PG_RETURN_INET_P(network_in(src, true));
134 * Common INET/CIDR output routine
137 network_out(inet *src, bool is_cidr)
139 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
143 dst = inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src),
147 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
148 errmsg("could not format inet value: %m")));
150 /* For CIDR, add /n if not present */
151 if (is_cidr && strchr(tmp, '/') == NULL)
154 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
161 inet_out(PG_FUNCTION_ARGS)
163 inet *src = PG_GETARG_INET_P(0);
165 PG_RETURN_CSTRING(network_out(src, false));
169 cidr_out(PG_FUNCTION_ARGS)
171 inet *src = PG_GETARG_INET_P(0);
173 PG_RETURN_CSTRING(network_out(src, true));
178 * network_recv - converts external binary format to inet
180 * The external representation is (one byte apiece for)
181 * family, bits, is_cidr, address length, address in network byte order.
183 * Presence of is_cidr is largely for historical reasons, though it might
184 * allow some code-sharing on the client side. We send it correctly on
185 * output, but ignore the value on input.
188 network_recv(StringInfo buf, bool is_cidr)
196 /* make sure any unused bits in a CIDR value are zeroed */
197 addr = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
199 ip_family(addr) = pq_getmsgbyte(buf);
200 if (ip_family(addr) != PGSQL_AF_INET &&
201 ip_family(addr) != PGSQL_AF_INET6)
203 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
204 /* translator: %s is inet or cidr */
205 errmsg("invalid address family in external \"%s\" value",
206 is_cidr ? "cidr" : "inet")));
207 bits = pq_getmsgbyte(buf);
208 if (bits < 0 || bits > ip_maxbits(addr))
210 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
211 /* translator: %s is inet or cidr */
212 errmsg("invalid bits in external \"%s\" value",
213 is_cidr ? "cidr" : "inet")));
214 ip_bits(addr) = bits;
215 i = pq_getmsgbyte(buf); /* ignore is_cidr */
216 nb = pq_getmsgbyte(buf);
217 if (nb != ip_addrsize(addr))
219 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
220 /* translator: %s is inet or cidr */
221 errmsg("invalid length in external \"%s\" value",
222 is_cidr ? "cidr" : "inet")));
223 VARATT_SIZEP(addr) = VARHDRSZ +
224 ((char *) ip_addr(addr) - (char *) VARDATA(addr)) +
227 addrptr = (char *) ip_addr(addr);
228 for (i = 0; i < nb; i++)
229 addrptr[i] = pq_getmsgbyte(buf);
232 * Error check: CIDR values must not have any bits set beyond the masklen.
236 if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
238 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
239 errmsg("invalid external \"cidr\" value"),
240 errdetail("Value has bits set to right of mask.")));
247 inet_recv(PG_FUNCTION_ARGS)
249 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
251 PG_RETURN_INET_P(network_recv(buf, false));
255 cidr_recv(PG_FUNCTION_ARGS)
257 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
259 PG_RETURN_INET_P(network_recv(buf, true));
264 * network_send - converts inet to binary format
267 network_send(inet *addr, bool is_cidr)
274 pq_begintypsend(&buf);
275 pq_sendbyte(&buf, ip_family(addr));
276 pq_sendbyte(&buf, ip_bits(addr));
277 pq_sendbyte(&buf, is_cidr);
278 nb = ip_addrsize(addr);
281 pq_sendbyte(&buf, nb);
282 addrptr = (char *) ip_addr(addr);
283 for (i = 0; i < nb; i++)
284 pq_sendbyte(&buf, addrptr[i]);
285 return pq_endtypsend(&buf);
289 inet_send(PG_FUNCTION_ARGS)
291 inet *addr = PG_GETARG_INET_P(0);
293 PG_RETURN_BYTEA_P(network_send(addr, false));
297 cidr_send(PG_FUNCTION_ARGS)
299 inet *addr = PG_GETARG_INET_P(0);
301 PG_RETURN_BYTEA_P(network_send(addr, true));
306 text_network(text *src, bool is_cidr)
308 int len = VARSIZE(src) - VARHDRSZ;
309 char *str = palloc(len + 1);
311 memcpy(str, VARDATA(src), len);
314 return network_in(str, is_cidr);
318 text_inet(PG_FUNCTION_ARGS)
320 text *src = PG_GETARG_TEXT_P(0);
322 PG_RETURN_INET_P(text_network(src, false));
326 text_cidr(PG_FUNCTION_ARGS)
328 text *src = PG_GETARG_TEXT_P(0);
330 PG_RETURN_INET_P(text_network(src, true));
335 inet_to_cidr(PG_FUNCTION_ARGS)
337 inet *src = PG_GETARG_INET_P(0);
347 if ((bits < 0) || (bits > ip_maxbits(src)))
348 elog(ERROR, "invalid inet bit length: %d", bits);
350 /* clone the original data */
351 dst = (inet *) palloc(VARSIZE(src));
352 memcpy(dst, src, VARSIZE(src));
354 /* zero out any bits to the right of the netmask */
357 /* clear the first byte, this might be a partial byte */
360 ip_addr(dst)[byte] &= ~(0xFF >> nbits);
363 /* clear remaining bytes */
364 maxbytes = ip_addrsize(dst);
365 while (byte < maxbytes)
367 ip_addr(dst)[byte] = 0;
371 PG_RETURN_INET_P(dst);
375 inet_set_masklen(PG_FUNCTION_ARGS)
377 inet *src = PG_GETARG_INET_P(0);
378 int bits = PG_GETARG_INT32(1);
382 bits = ip_maxbits(src);
384 if ((bits < 0) || (bits > ip_maxbits(src)))
386 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
387 errmsg("invalid mask length: %d", bits)));
389 /* clone the original data */
390 dst = (inet *) palloc(VARSIZE(src));
391 memcpy(dst, src, VARSIZE(src));
395 PG_RETURN_INET_P(dst);
399 cidr_set_masklen(PG_FUNCTION_ARGS)
401 inet *src = PG_GETARG_INET_P(0);
402 int bits = PG_GETARG_INT32(1);
409 bits = ip_maxbits(src);
411 if ((bits < 0) || (bits > ip_maxbits(src)))
413 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
414 errmsg("invalid mask length: %d", bits)));
416 /* clone the original data */
417 dst = (inet *) palloc(VARSIZE(src));
418 memcpy(dst, src, VARSIZE(src));
422 /* zero out any bits to the right of the new netmask */
425 /* clear the first byte, this might be a partial byte */
428 ip_addr(dst)[byte] &= ~(0xFF >> nbits);
431 /* clear remaining bytes */
432 maxbytes = ip_addrsize(dst);
433 while (byte < maxbytes)
435 ip_addr(dst)[byte] = 0;
439 PG_RETURN_INET_P(dst);
443 * Basic comparison function for sorting and inet/cidr comparisons.
445 * Comparison is first on the common bits of the network part, then on
446 * the length of the network part, and then on the whole unmasked address.
447 * The effect is that the network part is the major sort key, and for
448 * equal network parts we sort on the host part. Note this is only sane
449 * for CIDR if address bits to the right of the mask are guaranteed zero;
450 * otherwise logically-equal CIDRs might compare different.
454 network_cmp_internal(inet *a1, inet *a2)
456 if (ip_family(a1) == ip_family(a2))
460 order = bitncmp(ip_addr(a1), ip_addr(a2),
461 Min(ip_bits(a1), ip_bits(a2)));
464 order = ((int) ip_bits(a1)) - ((int) ip_bits(a2));
467 return bitncmp(ip_addr(a1), ip_addr(a2), ip_maxbits(a1));
470 return ip_family(a1) - ip_family(a2);
474 network_cmp(PG_FUNCTION_ARGS)
476 inet *a1 = PG_GETARG_INET_P(0);
477 inet *a2 = PG_GETARG_INET_P(1);
479 PG_RETURN_INT32(network_cmp_internal(a1, a2));
483 * Boolean ordering tests.
486 network_lt(PG_FUNCTION_ARGS)
488 inet *a1 = PG_GETARG_INET_P(0);
489 inet *a2 = PG_GETARG_INET_P(1);
491 PG_RETURN_BOOL(network_cmp_internal(a1, a2) < 0);
495 network_le(PG_FUNCTION_ARGS)
497 inet *a1 = PG_GETARG_INET_P(0);
498 inet *a2 = PG_GETARG_INET_P(1);
500 PG_RETURN_BOOL(network_cmp_internal(a1, a2) <= 0);
504 network_eq(PG_FUNCTION_ARGS)
506 inet *a1 = PG_GETARG_INET_P(0);
507 inet *a2 = PG_GETARG_INET_P(1);
509 PG_RETURN_BOOL(network_cmp_internal(a1, a2) == 0);
513 network_ge(PG_FUNCTION_ARGS)
515 inet *a1 = PG_GETARG_INET_P(0);
516 inet *a2 = PG_GETARG_INET_P(1);
518 PG_RETURN_BOOL(network_cmp_internal(a1, a2) >= 0);
522 network_gt(PG_FUNCTION_ARGS)
524 inet *a1 = PG_GETARG_INET_P(0);
525 inet *a2 = PG_GETARG_INET_P(1);
527 PG_RETURN_BOOL(network_cmp_internal(a1, a2) > 0);
531 network_ne(PG_FUNCTION_ARGS)
533 inet *a1 = PG_GETARG_INET_P(0);
534 inet *a2 = PG_GETARG_INET_P(1);
536 PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
540 * Support function for hash indexes on inet/cidr.
543 hashinet(PG_FUNCTION_ARGS)
545 inet *addr = PG_GETARG_INET_P(0);
546 int addrsize = ip_addrsize(addr);
548 /* XXX this assumes there are no pad bytes in the data structure */
549 return hash_any((unsigned char *) VARDATA(addr), addrsize + 2);
553 * Boolean network-inclusion tests.
556 network_sub(PG_FUNCTION_ARGS)
558 inet *a1 = PG_GETARG_INET_P(0);
559 inet *a2 = PG_GETARG_INET_P(1);
561 if (ip_family(a1) == ip_family(a2))
563 PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2)
564 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
567 PG_RETURN_BOOL(false);
571 network_subeq(PG_FUNCTION_ARGS)
573 inet *a1 = PG_GETARG_INET_P(0);
574 inet *a2 = PG_GETARG_INET_P(1);
576 if (ip_family(a1) == ip_family(a2))
578 PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2)
579 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
582 PG_RETURN_BOOL(false);
586 network_sup(PG_FUNCTION_ARGS)
588 inet *a1 = PG_GETARG_INET_P(0);
589 inet *a2 = PG_GETARG_INET_P(1);
591 if (ip_family(a1) == ip_family(a2))
593 PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2)
594 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
597 PG_RETURN_BOOL(false);
601 network_supeq(PG_FUNCTION_ARGS)
603 inet *a1 = PG_GETARG_INET_P(0);
604 inet *a2 = PG_GETARG_INET_P(1);
606 if (ip_family(a1) == ip_family(a2))
608 PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2)
609 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
612 PG_RETURN_BOOL(false);
616 * Extract data from a network datatype.
619 network_host(PG_FUNCTION_ARGS)
621 inet *ip = PG_GETARG_INET_P(0);
625 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
627 /* force display of max bits, regardless of masklen... */
628 if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
629 tmp, sizeof(tmp)) == NULL)
631 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
632 errmsg("could not format inet value: %m")));
634 /* Suppress /n if present (shouldn't happen now) */
635 if ((ptr = strchr(tmp, '/')) != NULL)
638 /* Return string as a text datum */
640 ret = (text *) palloc(len + VARHDRSZ);
641 VARATT_SIZEP(ret) = len + VARHDRSZ;
642 memcpy(VARDATA(ret), tmp, len);
643 PG_RETURN_TEXT_P(ret);
647 network_show(PG_FUNCTION_ARGS)
649 inet *ip = PG_GETARG_INET_P(0);
652 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
654 if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
655 tmp, sizeof(tmp)) == NULL)
657 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
658 errmsg("could not format inet value: %m")));
660 /* Add /n if not present (which it won't be) */
661 if (strchr(tmp, '/') == NULL)
664 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
667 /* Return string as a text datum */
669 ret = (text *) palloc(len + VARHDRSZ);
670 VARATT_SIZEP(ret) = len + VARHDRSZ;
671 memcpy(VARDATA(ret), tmp, len);
672 PG_RETURN_TEXT_P(ret);
676 inet_abbrev(PG_FUNCTION_ARGS)
678 inet *ip = PG_GETARG_INET_P(0);
682 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
684 dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
685 ip_bits(ip), tmp, sizeof(tmp));
689 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
690 errmsg("could not format inet value: %m")));
692 /* Return string as a text datum */
694 ret = (text *) palloc(len + VARHDRSZ);
695 VARATT_SIZEP(ret) = len + VARHDRSZ;
696 memcpy(VARDATA(ret), tmp, len);
697 PG_RETURN_TEXT_P(ret);
701 cidr_abbrev(PG_FUNCTION_ARGS)
703 inet *ip = PG_GETARG_INET_P(0);
707 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
709 dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
710 ip_bits(ip), tmp, sizeof(tmp));
714 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
715 errmsg("could not format cidr value: %m")));
717 /* Return string as a text datum */
719 ret = (text *) palloc(len + VARHDRSZ);
720 VARATT_SIZEP(ret) = len + VARHDRSZ;
721 memcpy(VARDATA(ret), tmp, len);
722 PG_RETURN_TEXT_P(ret);
726 network_masklen(PG_FUNCTION_ARGS)
728 inet *ip = PG_GETARG_INET_P(0);
730 PG_RETURN_INT32(ip_bits(ip));
734 network_family(PG_FUNCTION_ARGS)
736 inet *ip = PG_GETARG_INET_P(0);
738 switch (ip_family(ip))
753 network_broadcast(PG_FUNCTION_ARGS)
755 inet *ip = PG_GETARG_INET_P(0);
764 /* make sure any unused bits are zeroed */
765 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
767 if (ip_family(ip) == PGSQL_AF_INET)
776 for (byte = 0; byte < maxbytes; byte++)
791 b[byte] = a[byte] | mask;
794 ip_family(dst) = ip_family(ip);
795 ip_bits(dst) = ip_bits(ip);
796 VARATT_SIZEP(dst) = VARHDRSZ +
797 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
800 PG_RETURN_INET_P(dst);
804 network_network(PG_FUNCTION_ARGS)
806 inet *ip = PG_GETARG_INET_P(0);
814 /* make sure any unused bits are zeroed */
815 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
831 mask = 0xff << (8 - bits);
835 b[byte] = a[byte] & mask;
839 ip_family(dst) = ip_family(ip);
840 ip_bits(dst) = ip_bits(ip);
841 VARATT_SIZEP(dst) = VARHDRSZ +
842 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
845 PG_RETURN_INET_P(dst);
849 network_netmask(PG_FUNCTION_ARGS)
851 inet *ip = PG_GETARG_INET_P(0);
858 /* make sure any unused bits are zeroed */
859 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
874 mask = 0xff << (8 - bits);
882 ip_family(dst) = ip_family(ip);
883 ip_bits(dst) = ip_maxbits(ip);
884 VARATT_SIZEP(dst) = VARHDRSZ +
885 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
888 PG_RETURN_INET_P(dst);
892 network_hostmask(PG_FUNCTION_ARGS)
894 inet *ip = PG_GETARG_INET_P(0);
902 /* make sure any unused bits are zeroed */
903 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
905 if (ip_family(ip) == PGSQL_AF_INET)
910 bits = ip_maxbits(ip) - ip_bits(ip);
923 mask = 0xff >> (8 - bits);
931 ip_family(dst) = ip_family(ip);
932 ip_bits(dst) = ip_maxbits(ip);
933 VARATT_SIZEP(dst) = VARHDRSZ +
934 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
937 PG_RETURN_INET_P(dst);
941 * Convert a value of a network datatype to an approximate scalar value.
942 * This is used for estimating selectivities of inequality operators
943 * involving network types.
946 convert_network_to_scalar(Datum value, Oid typid)
953 inet *ip = DatumGetInetP(value);
959 * Note that we don't use the full address for IPv6.
961 if (ip_family(ip) == PGSQL_AF_INET)
967 for (i = 0; i < len; i++)
970 res += ip_addr(ip)[i];
978 macaddr *mac = DatumGetMacaddrP(value);
981 res = (mac->a << 16) | (mac->b << 8) | (mac->c);
982 res *= 256 * 256 * 256;
983 res += (mac->d << 16) | (mac->e << 8) | (mac->f);
989 * Can't get here unless someone tries to use scalarltsel/scalargtsel on
990 * an operator with one network and one non-network operand.
992 elog(ERROR, "unsupported type: %u", typid);
999 * compare bit masks l and r, for n bits.
1001 * -1, 1, or 0 in the libc tradition.
1003 * network byte order assumed. this means 192.5.5.240/28 has
1004 * 0x11110000 in its fourth octet.
1006 * Paul Vixie (ISC), June 1996
1009 bitncmp(void *l, void *r, int n)
1017 x = memcmp(l, r, b);
1021 lb = ((const u_char *) l)[b];
1022 rb = ((const u_char *) r)[b];
1023 for (b = n % 8; b > 0; b--)
1025 if (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))
1027 if (IS_HIGHBIT_SET(lb))
1038 addressOK(unsigned char *a, int bits, int family)
1046 if (family == PGSQL_AF_INET)
1056 Assert(bits <= maxbits);
1058 if (bits == maxbits)
1067 while (byte < maxbytes)
1069 if ((a[byte] & mask) != 0)
1080 * These functions are used by planner to generate indexscan limits
1081 * for clauses a << b and a <<= b
1084 /* return the minimal value for an IP on a given network */
1086 network_scan_first(Datum in)
1088 return DirectFunctionCall1(network_network, in);
1092 * return "last" IP on a given network. It's the broadcast address,
1093 * however, masklen has to be set to its max btis, since
1094 * 192.168.0.255/24 is considered less than 192.168.0.255/32
1096 * inet_set_masklen() hacked to max out the masklength to 128 for IPv6
1097 * and 32 for IPv4 when given '-1' as argument.
1100 network_scan_last(Datum in)
1102 return DirectFunctionCall2(inet_set_masklen,
1103 DirectFunctionCall1(network_broadcast, in),
1109 * IP address that the client is connecting from (NULL if Unix socket)
1112 inet_client_addr(PG_FUNCTION_ARGS)
1114 Port *port = MyProcPort;
1115 char remote_host[NI_MAXHOST];
1121 switch (port->raddr.addr.ss_family)
1132 remote_host[0] = '\0';
1134 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1135 remote_host, sizeof(remote_host),
1137 NI_NUMERICHOST | NI_NUMERICSERV);
1141 PG_RETURN_INET_P(network_in(remote_host, false));
1146 * port that the client is connecting from (NULL if Unix socket)
1149 inet_client_port(PG_FUNCTION_ARGS)
1151 Port *port = MyProcPort;
1152 char remote_port[NI_MAXSERV];
1158 switch (port->raddr.addr.ss_family)
1169 remote_port[0] = '\0';
1171 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1173 remote_port, sizeof(remote_port),
1174 NI_NUMERICHOST | NI_NUMERICSERV);
1178 PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));
1183 * IP address that the server accepted the connection on (NULL if Unix socket)
1186 inet_server_addr(PG_FUNCTION_ARGS)
1188 Port *port = MyProcPort;
1189 char local_host[NI_MAXHOST];
1195 switch (port->laddr.addr.ss_family)
1206 local_host[0] = '\0';
1208 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1209 local_host, sizeof(local_host),
1211 NI_NUMERICHOST | NI_NUMERICSERV);
1215 PG_RETURN_INET_P(network_in(local_host, false));
1220 * port that the server accepted the connection on (NULL if Unix socket)
1223 inet_server_port(PG_FUNCTION_ARGS)
1225 Port *port = MyProcPort;
1226 char local_port[NI_MAXSERV];
1232 switch (port->laddr.addr.ss_family)
1243 local_port[0] = '\0';
1245 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1247 local_port, sizeof(local_port),
1248 NI_NUMERICHOST | NI_NUMERICSERV);
1252 PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(local_port)));
1257 inetnot(PG_FUNCTION_ARGS)
1259 inet *ip = PG_GETARG_INET_P(0);
1262 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1265 int nb = ip_addrsize(ip);
1266 unsigned char *pip = ip_addr(ip);
1267 unsigned char *pdst = ip_addr(dst);
1270 pdst[nb] = ~pip[nb];
1272 ip_bits(dst) = ip_bits(ip);
1274 ip_family(dst) = ip_family(ip);
1275 VARATT_SIZEP(dst) = VARHDRSZ +
1276 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1279 PG_RETURN_INET_P(dst);
1284 inetand(PG_FUNCTION_ARGS)
1286 inet *ip = PG_GETARG_INET_P(0);
1287 inet *ip2 = PG_GETARG_INET_P(1);
1290 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1292 if (ip_family(ip) != ip_family(ip2))
1294 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1295 errmsg("cannot AND inet values of different sizes")));
1298 int nb = ip_addrsize(ip);
1299 unsigned char *pip = ip_addr(ip);
1300 unsigned char *pip2 = ip_addr(ip2);
1301 unsigned char *pdst = ip_addr(dst);
1304 pdst[nb] = pip[nb] & pip2[nb];
1306 ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1308 ip_family(dst) = ip_family(ip);
1309 VARATT_SIZEP(dst) = VARHDRSZ +
1310 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1313 PG_RETURN_INET_P(dst);
1318 inetor(PG_FUNCTION_ARGS)
1320 inet *ip = PG_GETARG_INET_P(0);
1321 inet *ip2 = PG_GETARG_INET_P(1);
1324 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1326 if (ip_family(ip) != ip_family(ip2))
1328 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1329 errmsg("cannot OR inet values of different sizes")));
1332 int nb = ip_addrsize(ip);
1333 unsigned char *pip = ip_addr(ip);
1334 unsigned char *pip2 = ip_addr(ip2);
1335 unsigned char *pdst = ip_addr(dst);
1338 pdst[nb] = pip[nb] | pip2[nb];
1340 ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1342 ip_family(dst) = ip_family(ip);
1343 VARATT_SIZEP(dst) = VARHDRSZ +
1344 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1347 PG_RETURN_INET_P(dst);
1352 internal_inetpl(inet *ip, int64 addend)
1356 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1359 int nb = ip_addrsize(ip);
1360 unsigned char *pip = ip_addr(ip);
1361 unsigned char *pdst = ip_addr(dst);
1366 carry = pip[nb] + (int) (addend & 0xFF) + carry;
1367 pdst[nb] = (unsigned char) (carry & 0xFF);
1371 * We have to be careful about right-shifting addend because
1372 * right-shift isn't portable for negative values, while simply
1373 * dividing by 256 doesn't work (the standard rounding is in the
1374 * wrong direction, besides which there may be machines out there
1375 * that round the wrong way). So, explicitly clear the low-order
1376 * byte to remove any doubt about the correct result of the
1377 * division, and then divide rather than shift.
1379 addend &= ~((int64) 0xFF);
1384 * At this point we should have addend and carry both zero if original
1385 * addend was >= 0, or addend -1 and carry 1 if original addend was <
1386 * 0. Anything else means overflow.
1388 if (!((addend == 0 && carry == 0) ||
1389 (addend == -1 && carry == 1)))
1391 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1392 errmsg("result out of range")));
1394 ip_bits(dst) = ip_bits(ip);
1396 ip_family(dst) = ip_family(ip);
1397 VARATT_SIZEP(dst) = VARHDRSZ +
1398 ((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1406 inetpl(PG_FUNCTION_ARGS)
1408 inet *ip = PG_GETARG_INET_P(0);
1409 int64 addend = PG_GETARG_INT64(1);
1411 PG_RETURN_INET_P(internal_inetpl(ip, addend));
1416 inetmi_int8(PG_FUNCTION_ARGS)
1418 inet *ip = PG_GETARG_INET_P(0);
1419 int64 addend = PG_GETARG_INT64(1);
1421 PG_RETURN_INET_P(internal_inetpl(ip, -addend));
1426 inetmi(PG_FUNCTION_ARGS)
1428 inet *ip = PG_GETARG_INET_P(0);
1429 inet *ip2 = PG_GETARG_INET_P(1);
1432 if (ip_family(ip) != ip_family(ip2))
1434 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1435 errmsg("cannot subtract inet values of different sizes")));
1439 * We form the difference using the traditional complement, increment,
1440 * and add rule, with the increment part being handled by starting the
1441 * carry off at 1. If you don't think integer arithmetic is done in
1442 * two's complement, too bad.
1444 int nb = ip_addrsize(ip);
1446 unsigned char *pip = ip_addr(ip);
1447 unsigned char *pip2 = ip_addr(ip2);
1454 carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
1455 lobyte = carry & 0xFF;
1456 if (byte < sizeof(int64))
1458 res |= ((int64) lobyte) << (byte * 8);
1463 * Input wider than int64: check for overflow. All bytes to
1464 * the left of what will fit should be 0 or 0xFF, depending on
1465 * sign of the now-complete result.
1467 if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))
1469 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1470 errmsg("result out of range")));
1477 * If input is narrower than int64, overflow is not possible, but we
1478 * have to do proper sign extension.
1480 if (carry == 0 && byte < sizeof(int64))
1481 res |= ((int64) -1) << (byte * 8);
1484 PG_RETURN_INT64(res);