2 * PostgreSQL type definitions for the INET and CIDR types.
4 * $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.58 2006/01/11 08:43:12 neilc 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 Datum text_network(text *src, int type);
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);
35 #define ip_family(inetptr) \
36 (((inet_struct *)VARDATA(inetptr))->family)
38 #define ip_bits(inetptr) \
39 (((inet_struct *)VARDATA(inetptr))->bits)
41 #define ip_type(inetptr) \
42 (((inet_struct *)VARDATA(inetptr))->type)
44 #define ip_addr(inetptr) \
45 (((inet_struct *)VARDATA(inetptr))->ipaddr)
47 #define ip_maxbits(inetptr) \
48 (ip_family(inetptr) == PGSQL_AF_INET ? 32 : 128)
51 * Return the number of bytes of storage needed for this data type.
54 ip_addrsize(inet *inetptr)
56 switch (ip_family(inetptr))
67 /* Common input routine */
69 network_in(char *src, int type)
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 type ? 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 type ? "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 address reader. */
119 inet_in(PG_FUNCTION_ARGS)
121 char *src = PG_GETARG_CSTRING(0);
123 PG_RETURN_INET_P(network_in(src, 0));
126 /* CIDR address reader. */
128 cidr_in(PG_FUNCTION_ARGS)
130 char *src = PG_GETARG_CSTRING(0);
132 PG_RETURN_INET_P(network_in(src, 1));
137 * INET address output function.
140 inet_out(PG_FUNCTION_ARGS)
142 inet *src = PG_GETARG_INET_P(0);
143 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
147 dst = inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src),
151 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
152 errmsg("could not format inet value: %m")));
154 /* For CIDR, add /n if not present */
155 if (ip_type(src) && strchr(tmp, '/') == NULL)
158 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
161 PG_RETURN_CSTRING(pstrdup(tmp));
165 /* share code with INET case */
167 cidr_out(PG_FUNCTION_ARGS)
169 return inet_out(fcinfo);
174 * inet_recv - converts external binary format to inet
176 * The external representation is (one byte apiece for)
177 * family, bits, type, address length, address in network byte order.
180 inet_recv(PG_FUNCTION_ARGS)
182 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
189 /* make sure any unused bits in a CIDR value are zeroed */
190 addr = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
192 ip_family(addr) = pq_getmsgbyte(buf);
193 if (ip_family(addr) != PGSQL_AF_INET &&
194 ip_family(addr) != PGSQL_AF_INET6)
196 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
197 errmsg("invalid address family in external \"inet\" value")));
198 bits = pq_getmsgbyte(buf);
199 if (bits < 0 || bits > ip_maxbits(addr))
201 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
202 errmsg("invalid bits in external \"inet\" value")));
203 ip_bits(addr) = bits;
204 ip_type(addr) = pq_getmsgbyte(buf);
205 if (ip_type(addr) != 0 && ip_type(addr) != 1)
207 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
208 errmsg("invalid type in external \"inet\" value")));
209 nb = pq_getmsgbyte(buf);
210 if (nb != ip_addrsize(addr))
212 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
213 errmsg("invalid length in external \"inet\" value")));
214 VARATT_SIZEP(addr) = VARHDRSZ
215 + ((char *) ip_addr(addr) - (char *) VARDATA(addr))
218 addrptr = (char *) ip_addr(addr);
219 for (i = 0; i < nb; i++)
220 addrptr[i] = pq_getmsgbyte(buf);
223 * Error check: CIDR values must not have any bits set beyond the masklen.
227 if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
229 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
230 errmsg("invalid external \"cidr\" value"),
231 errdetail("Value has bits set to right of mask.")));
234 PG_RETURN_INET_P(addr);
237 /* share code with INET case */
239 cidr_recv(PG_FUNCTION_ARGS)
241 return inet_recv(fcinfo);
245 * inet_send - converts inet to binary format
248 inet_send(PG_FUNCTION_ARGS)
250 inet *addr = PG_GETARG_INET_P(0);
256 pq_begintypsend(&buf);
257 pq_sendbyte(&buf, ip_family(addr));
258 pq_sendbyte(&buf, ip_bits(addr));
259 pq_sendbyte(&buf, ip_type(addr));
260 nb = ip_addrsize(addr);
263 pq_sendbyte(&buf, nb);
264 addrptr = (char *) ip_addr(addr);
265 for (i = 0; i < nb; i++)
266 pq_sendbyte(&buf, addrptr[i]);
267 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
270 /* share code with INET case */
272 cidr_send(PG_FUNCTION_ARGS)
274 return inet_send(fcinfo);
279 text_network(text *src, int type)
281 int len = VARSIZE(src) - VARHDRSZ;
283 char *str = palloc(len + 1);
285 memcpy(str, VARDATA(src), len);
288 PG_RETURN_INET_P(network_in(str, type));
293 text_cidr(PG_FUNCTION_ARGS)
295 return text_network(PG_GETARG_TEXT_P(0), 1);
299 text_inet(PG_FUNCTION_ARGS)
301 return text_network(PG_GETARG_TEXT_P(0), 0);
305 inet_set_masklen(PG_FUNCTION_ARGS)
307 inet *src = PG_GETARG_INET_P(0);
308 int bits = PG_GETARG_INT32(1);
312 bits = ip_maxbits(src);
314 if ((bits < 0) || (bits > ip_maxbits(src)))
316 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
317 errmsg("invalid mask length: %d", bits)));
319 /* clone the original data */
320 dst = (inet *) palloc(VARSIZE(src));
321 memcpy(dst, src, VARSIZE(src));
325 PG_RETURN_INET_P(dst);
329 * Basic comparison function for sorting and inet/cidr comparisons.
331 * Comparison is first on the common bits of the network part, then on
332 * the length of the network part, and then on the whole unmasked address.
333 * The effect is that the network part is the major sort key, and for
334 * equal network parts we sort on the host part. Note this is only sane
335 * for CIDR if address bits to the right of the mask are guaranteed zero;
336 * otherwise logically-equal CIDRs might compare different.
340 network_cmp_internal(inet *a1, inet *a2)
342 if (ip_family(a1) == ip_family(a2))
346 order = bitncmp(ip_addr(a1), ip_addr(a2),
347 Min(ip_bits(a1), ip_bits(a2)));
350 order = ((int) ip_bits(a1)) - ((int) ip_bits(a2));
353 return bitncmp(ip_addr(a1), ip_addr(a2), ip_maxbits(a1));
356 return ip_family(a1) - ip_family(a2);
360 network_cmp(PG_FUNCTION_ARGS)
362 inet *a1 = PG_GETARG_INET_P(0);
363 inet *a2 = PG_GETARG_INET_P(1);
365 PG_RETURN_INT32(network_cmp_internal(a1, a2));
369 * Boolean ordering tests.
372 network_lt(PG_FUNCTION_ARGS)
374 inet *a1 = PG_GETARG_INET_P(0);
375 inet *a2 = PG_GETARG_INET_P(1);
377 PG_RETURN_BOOL(network_cmp_internal(a1, a2) < 0);
381 network_le(PG_FUNCTION_ARGS)
383 inet *a1 = PG_GETARG_INET_P(0);
384 inet *a2 = PG_GETARG_INET_P(1);
386 PG_RETURN_BOOL(network_cmp_internal(a1, a2) <= 0);
390 network_eq(PG_FUNCTION_ARGS)
392 inet *a1 = PG_GETARG_INET_P(0);
393 inet *a2 = PG_GETARG_INET_P(1);
395 PG_RETURN_BOOL(network_cmp_internal(a1, a2) == 0);
399 network_ge(PG_FUNCTION_ARGS)
401 inet *a1 = PG_GETARG_INET_P(0);
402 inet *a2 = PG_GETARG_INET_P(1);
404 PG_RETURN_BOOL(network_cmp_internal(a1, a2) >= 0);
408 network_gt(PG_FUNCTION_ARGS)
410 inet *a1 = PG_GETARG_INET_P(0);
411 inet *a2 = PG_GETARG_INET_P(1);
413 PG_RETURN_BOOL(network_cmp_internal(a1, a2) > 0);
417 network_ne(PG_FUNCTION_ARGS)
419 inet *a1 = PG_GETARG_INET_P(0);
420 inet *a2 = PG_GETARG_INET_P(1);
422 PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0);
426 * Support function for hash indexes on inet/cidr.
428 * Since network_cmp considers only ip_family, ip_bits, and ip_addr,
429 * only these fields may be used in the hash; in particular don't use type.
432 hashinet(PG_FUNCTION_ARGS)
434 inet *addr = PG_GETARG_INET_P(0);
435 int addrsize = ip_addrsize(addr);
436 unsigned char key[sizeof(inet_struct)];
438 Assert(addrsize + 2 <= sizeof(key));
439 key[0] = ip_family(addr);
440 key[1] = ip_bits(addr);
441 memcpy(key + 2, ip_addr(addr), addrsize);
443 return hash_any(key, addrsize + 2);
447 * Boolean network-inclusion tests.
450 network_sub(PG_FUNCTION_ARGS)
452 inet *a1 = PG_GETARG_INET_P(0);
453 inet *a2 = PG_GETARG_INET_P(1);
455 if (ip_family(a1) == ip_family(a2))
457 PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2)
458 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
461 PG_RETURN_BOOL(false);
465 network_subeq(PG_FUNCTION_ARGS)
467 inet *a1 = PG_GETARG_INET_P(0);
468 inet *a2 = PG_GETARG_INET_P(1);
470 if (ip_family(a1) == ip_family(a2))
472 PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2)
473 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
476 PG_RETURN_BOOL(false);
480 network_sup(PG_FUNCTION_ARGS)
482 inet *a1 = PG_GETARG_INET_P(0);
483 inet *a2 = PG_GETARG_INET_P(1);
485 if (ip_family(a1) == ip_family(a2))
487 PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2)
488 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
491 PG_RETURN_BOOL(false);
495 network_supeq(PG_FUNCTION_ARGS)
497 inet *a1 = PG_GETARG_INET_P(0);
498 inet *a2 = PG_GETARG_INET_P(1);
500 if (ip_family(a1) == ip_family(a2))
502 PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2)
503 && bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
506 PG_RETURN_BOOL(false);
510 * Extract data from a network datatype.
513 network_host(PG_FUNCTION_ARGS)
515 inet *ip = PG_GETARG_INET_P(0);
519 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
521 /* force display of max bits, regardless of masklen... */
522 if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
523 tmp, sizeof(tmp)) == NULL)
525 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
526 errmsg("could not format inet value: %m")));
528 /* Suppress /n if present (shouldn't happen now) */
529 if ((ptr = strchr(tmp, '/')) != NULL)
532 /* Return string as a text datum */
534 ret = (text *) palloc(len + VARHDRSZ);
535 VARATT_SIZEP(ret) = len + VARHDRSZ;
536 memcpy(VARDATA(ret), tmp, len);
537 PG_RETURN_TEXT_P(ret);
541 network_show(PG_FUNCTION_ARGS)
543 inet *ip = PG_GETARG_INET_P(0);
546 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
548 if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
549 tmp, sizeof(tmp)) == NULL)
551 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
552 errmsg("could not format inet value: %m")));
554 /* Add /n if not present (which it won't be) */
555 if (strchr(tmp, '/') == NULL)
558 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
561 /* Return string as a text datum */
563 ret = (text *) palloc(len + VARHDRSZ);
564 VARATT_SIZEP(ret) = len + VARHDRSZ;
565 memcpy(VARDATA(ret), tmp, len);
566 PG_RETURN_TEXT_P(ret);
570 network_abbrev(PG_FUNCTION_ARGS)
572 inet *ip = PG_GETARG_INET_P(0);
576 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
579 dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip),
580 ip_bits(ip), tmp, sizeof(tmp));
582 dst = inet_net_ntop(ip_family(ip), ip_addr(ip),
583 ip_bits(ip), tmp, sizeof(tmp));
587 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
588 errmsg("could not format inet value: %m")));
590 /* Return string as a text datum */
592 ret = (text *) palloc(len + VARHDRSZ);
593 VARATT_SIZEP(ret) = len + VARHDRSZ;
594 memcpy(VARDATA(ret), tmp, len);
595 PG_RETURN_TEXT_P(ret);
599 network_masklen(PG_FUNCTION_ARGS)
601 inet *ip = PG_GETARG_INET_P(0);
603 PG_RETURN_INT32(ip_bits(ip));
607 network_family(PG_FUNCTION_ARGS)
609 inet *ip = PG_GETARG_INET_P(0);
611 switch (ip_family(ip))
626 network_broadcast(PG_FUNCTION_ARGS)
628 inet *ip = PG_GETARG_INET_P(0);
637 /* make sure any unused bits are zeroed */
638 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
640 if (ip_family(ip) == PGSQL_AF_INET)
649 for (byte = 0; byte < maxbytes; byte++)
664 b[byte] = a[byte] | mask;
667 ip_family(dst) = ip_family(ip);
668 ip_bits(dst) = ip_bits(ip);
670 VARATT_SIZEP(dst) = VARHDRSZ
671 + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
674 PG_RETURN_INET_P(dst);
678 network_network(PG_FUNCTION_ARGS)
680 inet *ip = PG_GETARG_INET_P(0);
688 /* make sure any unused bits are zeroed */
689 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
705 mask = 0xff << (8 - bits);
709 b[byte] = a[byte] & mask;
713 ip_family(dst) = ip_family(ip);
714 ip_bits(dst) = ip_bits(ip);
716 VARATT_SIZEP(dst) = VARHDRSZ
717 + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
720 PG_RETURN_INET_P(dst);
724 network_netmask(PG_FUNCTION_ARGS)
726 inet *ip = PG_GETARG_INET_P(0);
733 /* make sure any unused bits are zeroed */
734 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
749 mask = 0xff << (8 - bits);
757 ip_family(dst) = ip_family(ip);
758 ip_bits(dst) = ip_maxbits(ip);
760 VARATT_SIZEP(dst) = VARHDRSZ
761 + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
764 PG_RETURN_INET_P(dst);
768 network_hostmask(PG_FUNCTION_ARGS)
770 inet *ip = PG_GETARG_INET_P(0);
778 /* make sure any unused bits are zeroed */
779 dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
781 if (ip_family(ip) == PGSQL_AF_INET)
786 bits = ip_maxbits(ip) - ip_bits(ip);
799 mask = 0xff >> (8 - bits);
807 ip_family(dst) = ip_family(ip);
808 ip_bits(dst) = ip_maxbits(ip);
810 VARATT_SIZEP(dst) = VARHDRSZ
811 + ((char *) ip_addr(dst) - (char *) VARDATA(dst))
814 PG_RETURN_INET_P(dst);
818 * Convert a value of a network datatype to an approximate scalar value.
819 * This is used for estimating selectivities of inequality operators
820 * involving network types.
822 * Currently, inet/cidr values are simply converted to the IPv4 address;
823 * this will need more thought when IPv6 is supported too. MAC addresses
824 * are converted to their numeric equivalent as well (OK since we have a
825 * double to play in).
828 convert_network_to_scalar(Datum value, Oid typid)
835 inet *ip = DatumGetInetP(value);
841 * Note that we don't use the full address here.
843 if (ip_family(ip) == PGSQL_AF_INET)
849 for (i = 0; i < len; i++)
852 res += ip_addr(ip)[i];
860 macaddr *mac = DatumGetMacaddrP(value);
863 res = (mac->a << 16) | (mac->b << 8) | (mac->c);
864 res *= 256 * 256 * 256;
865 res += (mac->d << 16) | (mac->e << 8) | (mac->f);
871 * Can't get here unless someone tries to use scalarltsel/scalargtsel on
872 * an operator with one network and one non-network operand.
874 elog(ERROR, "unsupported type: %u", typid);
881 * compare bit masks l and r, for n bits.
883 * -1, 1, or 0 in the libc tradition.
885 * network byte order assumed. this means 192.5.5.240/28 has
886 * 0x11110000 in its fourth octet.
888 * Paul Vixie (ISC), June 1996
891 bitncmp(void *l, void *r, int n)
903 lb = ((const u_char *) l)[b];
904 rb = ((const u_char *) r)[b];
905 for (b = n % 8; b > 0; b--)
907 if (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))
909 if (IS_HIGHBIT_SET(lb))
920 addressOK(unsigned char *a, int bits, int family)
928 if (family == PGSQL_AF_INET)
938 Assert(bits <= maxbits);
949 while (byte < maxbytes)
951 if ((a[byte] & mask) != 0)
962 * These functions are used by planner to generate indexscan limits
963 * for clauses a << b and a <<= b
966 /* return the minimal value for an IP on a given network */
968 network_scan_first(Datum in)
970 return DirectFunctionCall1(network_network, in);
974 * return "last" IP on a given network. It's the broadcast address,
975 * however, masklen has to be set to its max btis, since
976 * 192.168.0.255/24 is considered less than 192.168.0.255/32
978 * inet_set_masklen() hacked to max out the masklength to 128 for IPv6
979 * and 32 for IPv4 when given '-1' as argument.
982 network_scan_last(Datum in)
984 return DirectFunctionCall2(inet_set_masklen,
985 DirectFunctionCall1(network_broadcast, in),
991 * IP address that the client is connecting from (NULL if Unix socket)
994 inet_client_addr(PG_FUNCTION_ARGS)
996 Port *port = MyProcPort;
997 char remote_host[NI_MAXHOST];
1003 switch (port->raddr.addr.ss_family)
1014 remote_host[0] = '\0';
1016 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1017 remote_host, sizeof(remote_host),
1019 NI_NUMERICHOST | NI_NUMERICSERV);
1023 PG_RETURN_INET_P(network_in(remote_host, 0));
1028 * port that the client is connecting from (NULL if Unix socket)
1031 inet_client_port(PG_FUNCTION_ARGS)
1033 Port *port = MyProcPort;
1034 char remote_port[NI_MAXSERV];
1040 switch (port->raddr.addr.ss_family)
1051 remote_port[0] = '\0';
1053 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1055 remote_port, sizeof(remote_port),
1056 NI_NUMERICHOST | NI_NUMERICSERV);
1060 PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));
1065 * IP address that the server accepted the connection on (NULL if Unix socket)
1068 inet_server_addr(PG_FUNCTION_ARGS)
1070 Port *port = MyProcPort;
1071 char local_host[NI_MAXHOST];
1077 switch (port->laddr.addr.ss_family)
1088 local_host[0] = '\0';
1090 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1091 local_host, sizeof(local_host),
1093 NI_NUMERICHOST | NI_NUMERICSERV);
1097 PG_RETURN_INET_P(network_in(local_host, 0));
1102 * port that the server accepted the connection on (NULL if Unix socket)
1105 inet_server_port(PG_FUNCTION_ARGS)
1107 Port *port = MyProcPort;
1108 char local_port[NI_MAXSERV];
1114 switch (port->laddr.addr.ss_family)
1125 local_port[0] = '\0';
1127 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1129 local_port, sizeof(local_port),
1130 NI_NUMERICHOST | NI_NUMERICSERV);
1134 PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(local_port)));