PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
network.c
Go to the documentation of this file.
1/*
2 * PostgreSQL type definitions for the INET and CIDR types.
3 *
4 * src/backend/utils/adt/network.c
5 *
6 * Jon Postel RIP 16 Oct 1998
7 */
8
9#include "postgres.h"
10
11#include <sys/socket.h>
12#include <netinet/in.h>
13#include <arpa/inet.h>
14
15#include "access/stratnum.h"
16#include "catalog/pg_opfamily.h"
17#include "catalog/pg_type.h"
18#include "common/hashfn.h"
19#include "common/ip.h"
20#include "lib/hyperloglog.h"
21#include "libpq/libpq-be.h"
22#include "libpq/pqformat.h"
23#include "miscadmin.h"
24#include "nodes/makefuncs.h"
25#include "nodes/nodeFuncs.h"
26#include "nodes/supportnodes.h"
27#include "utils/builtins.h"
28#include "utils/fmgroids.h"
29#include "utils/guc.h"
30#include "utils/inet.h"
31#include "utils/lsyscache.h"
32#include "utils/sortsupport.h"
33
34
35/*
36 * An IPv4 netmask size is a value in the range of 0 - 32, which is
37 * represented with 6 bits in inet/cidr abbreviated keys where possible.
38 *
39 * An IPv4 inet/cidr abbreviated key can use up to 25 bits for subnet
40 * component.
41 */
42#define ABBREV_BITS_INET4_NETMASK_SIZE 6
43#define ABBREV_BITS_INET4_SUBNET 25
44
45/* sortsupport for inet/cidr */
46typedef struct
47{
48 int64 input_count; /* number of non-null values seen */
49 bool estimating; /* true if estimating cardinality */
50
51 hyperLogLogState abbr_card; /* cardinality estimator */
53
55static int network_fast_cmp(Datum x, Datum y, SortSupport ssup);
56static bool network_abbrev_abort(int memtupcount, SortSupport ssup);
57static Datum network_abbrev_convert(Datum original, SortSupport ssup);
58static List *match_network_function(Node *leftop,
59 Node *rightop,
60 int indexarg,
61 Oid funcid,
62 Oid opfamily);
63static List *match_network_subset(Node *leftop,
64 Node *rightop,
65 bool is_eq,
66 Oid opfamily);
67static bool addressOK(unsigned char *a, int bits, int family);
68static inet *internal_inetpl(inet *ip, int64 addend);
69
70
71/*
72 * Common INET/CIDR input routine
73 */
74static inet *
75network_in(char *src, bool is_cidr, Node *escontext)
76{
77 int bits;
78 inet *dst;
79
80 dst = (inet *) palloc0(sizeof(inet));
81
82 /*
83 * First, check to see if this is an IPv6 or IPv4 address. IPv6 addresses
84 * will have a : somewhere in them (several, in fact) so if there is one
85 * present, assume it's V6, otherwise assume it's V4.
86 */
87
88 if (strchr(src, ':') != NULL)
90 else
92
93 bits = pg_inet_net_pton(ip_family(dst), src, ip_addr(dst),
94 is_cidr ? ip_addrsize(dst) : -1);
95 if ((bits < 0) || (bits > ip_maxbits(dst)))
96 ereturn(escontext, NULL,
97 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
98 /* translator: first %s is inet or cidr */
99 errmsg("invalid input syntax for type %s: \"%s\"",
100 is_cidr ? "cidr" : "inet", src)));
101
102 /*
103 * Error check: CIDR values must not have any bits set beyond the masklen.
104 */
105 if (is_cidr)
106 {
107 if (!addressOK(ip_addr(dst), bits, ip_family(dst)))
108 ereturn(escontext, NULL,
109 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
110 errmsg("invalid cidr value: \"%s\"", src),
111 errdetail("Value has bits set to right of mask.")));
112 }
113
114 ip_bits(dst) = bits;
115 SET_INET_VARSIZE(dst);
116
117 return dst;
118}
119
120Datum
122{
123 char *src = PG_GETARG_CSTRING(0);
124
125 PG_RETURN_INET_P(network_in(src, false, fcinfo->context));
126}
127
128Datum
130{
131 char *src = PG_GETARG_CSTRING(0);
132
133 PG_RETURN_INET_P(network_in(src, true, fcinfo->context));
134}
135
136
137/*
138 * Common INET/CIDR output routine
139 */
140static char *
141network_out(inet *src, bool is_cidr)
142{
143 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
144 char *dst;
145 int len;
146
147 dst = pg_inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src),
148 tmp, sizeof(tmp));
149 if (dst == NULL)
151 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
152 errmsg("could not format inet value: %m")));
153
154 /* For CIDR, add /n if not present */
155 if (is_cidr && strchr(tmp, '/') == NULL)
156 {
157 len = strlen(tmp);
158 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(src));
159 }
160
161 return pstrdup(tmp);
162}
163
164Datum
166{
167 inet *src = PG_GETARG_INET_PP(0);
168
169 PG_RETURN_CSTRING(network_out(src, false));
170}
171
172Datum
174{
175 inet *src = PG_GETARG_INET_PP(0);
176
177 PG_RETURN_CSTRING(network_out(src, true));
178}
179
180
181/*
182 * network_recv - converts external binary format to inet
183 *
184 * The external representation is (one byte apiece for)
185 * family, bits, is_cidr, address length, address in network byte order.
186 *
187 * Presence of is_cidr is largely for historical reasons, though it might
188 * allow some code-sharing on the client side. We send it correctly on
189 * output, but ignore the value on input.
190 */
191static inet *
193{
194 inet *addr;
195 char *addrptr;
196 int bits;
197 int nb,
198 i;
199
200 /* make sure any unused bits in a CIDR value are zeroed */
201 addr = (inet *) palloc0(sizeof(inet));
202
203 ip_family(addr) = pq_getmsgbyte(buf);
204 if (ip_family(addr) != PGSQL_AF_INET &&
205 ip_family(addr) != PGSQL_AF_INET6)
207 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
208 /* translator: %s is inet or cidr */
209 errmsg("invalid address family in external \"%s\" value",
210 is_cidr ? "cidr" : "inet")));
211 bits = pq_getmsgbyte(buf);
212 if (bits < 0 || bits > ip_maxbits(addr))
214 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
215 /* translator: %s is inet or cidr */
216 errmsg("invalid bits in external \"%s\" value",
217 is_cidr ? "cidr" : "inet")));
218 ip_bits(addr) = bits;
219 i = pq_getmsgbyte(buf); /* ignore is_cidr */
220 nb = pq_getmsgbyte(buf);
221 if (nb != ip_addrsize(addr))
223 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
224 /* translator: %s is inet or cidr */
225 errmsg("invalid length in external \"%s\" value",
226 is_cidr ? "cidr" : "inet")));
227
228 addrptr = (char *) ip_addr(addr);
229 for (i = 0; i < nb; i++)
230 addrptr[i] = pq_getmsgbyte(buf);
231
232 /*
233 * Error check: CIDR values must not have any bits set beyond the masklen.
234 */
235 if (is_cidr)
236 {
237 if (!addressOK(ip_addr(addr), bits, ip_family(addr)))
239 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
240 errmsg("invalid external \"cidr\" value"),
241 errdetail("Value has bits set to right of mask.")));
242 }
243
244 SET_INET_VARSIZE(addr);
245
246 return addr;
247}
248
249Datum
251{
253
255}
256
257Datum
259{
261
263}
264
265
266/*
267 * network_send - converts inet to binary format
268 */
269static bytea *
270network_send(inet *addr, bool is_cidr)
271{
273 char *addrptr;
274 int nb,
275 i;
276
278 pq_sendbyte(&buf, ip_family(addr));
279 pq_sendbyte(&buf, ip_bits(addr));
280 pq_sendbyte(&buf, is_cidr);
281 nb = ip_addrsize(addr);
282 pq_sendbyte(&buf, nb);
283 addrptr = (char *) ip_addr(addr);
284 for (i = 0; i < nb; i++)
285 pq_sendbyte(&buf, addrptr[i]);
286 return pq_endtypsend(&buf);
287}
288
289Datum
291{
292 inet *addr = PG_GETARG_INET_PP(0);
293
294 PG_RETURN_BYTEA_P(network_send(addr, false));
295}
296
297Datum
299{
300 inet *addr = PG_GETARG_INET_PP(0);
301
302 PG_RETURN_BYTEA_P(network_send(addr, true));
303}
304
305
306Datum
308{
309 inet *src = PG_GETARG_INET_PP(0);
310 int bits;
311
312 bits = ip_bits(src);
313
314 /* safety check */
315 if ((bits < 0) || (bits > ip_maxbits(src)))
316 elog(ERROR, "invalid inet bit length: %d", bits);
317
319}
320
321Datum
323{
324 inet *src = PG_GETARG_INET_PP(0);
325 int bits = PG_GETARG_INT32(1);
326 inet *dst;
327
328 if (bits == -1)
329 bits = ip_maxbits(src);
330
331 if ((bits < 0) || (bits > ip_maxbits(src)))
333 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
334 errmsg("invalid mask length: %d", bits)));
335
336 /* clone the original data */
337 dst = (inet *) palloc(VARSIZE_ANY(src));
338 memcpy(dst, src, VARSIZE_ANY(src));
339
340 ip_bits(dst) = bits;
341
342 PG_RETURN_INET_P(dst);
343}
344
345Datum
347{
348 inet *src = PG_GETARG_INET_PP(0);
349 int bits = PG_GETARG_INT32(1);
350
351 if (bits == -1)
352 bits = ip_maxbits(src);
353
354 if ((bits < 0) || (bits > ip_maxbits(src)))
356 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
357 errmsg("invalid mask length: %d", bits)));
358
360}
361
362/*
363 * Copy src and set mask length to 'bits' (which must be valid for the family)
364 */
365inet *
366cidr_set_masklen_internal(const inet *src, int bits)
367{
368 inet *dst = (inet *) palloc0(sizeof(inet));
369
370 ip_family(dst) = ip_family(src);
371 ip_bits(dst) = bits;
372
373 if (bits > 0)
374 {
375 Assert(bits <= ip_maxbits(dst));
376
377 /* Clone appropriate bytes of the address, leaving the rest 0 */
378 memcpy(ip_addr(dst), ip_addr(src), (bits + 7) / 8);
379
380 /* Clear any unwanted bits in the last partial byte */
381 if (bits % 8)
382 ip_addr(dst)[bits / 8] &= ~(0xFF >> (bits % 8));
383 }
384
385 /* Set varlena header correctly */
386 SET_INET_VARSIZE(dst);
387
388 return dst;
389}
390
391/*
392 * Basic comparison function for sorting and inet/cidr comparisons.
393 *
394 * Comparison is first on the common bits of the network part, then on
395 * the length of the network part, and then on the whole unmasked address.
396 * The effect is that the network part is the major sort key, and for
397 * equal network parts we sort on the host part. Note this is only sane
398 * for CIDR if address bits to the right of the mask are guaranteed zero;
399 * otherwise logically-equal CIDRs might compare different.
400 */
401
402static int32
404{
405 if (ip_family(a1) == ip_family(a2))
406 {
407 int order;
408
409 order = bitncmp(ip_addr(a1), ip_addr(a2),
410 Min(ip_bits(a1), ip_bits(a2)));
411 if (order != 0)
412 return order;
413 order = ((int) ip_bits(a1)) - ((int) ip_bits(a2));
414 if (order != 0)
415 return order;
416 return bitncmp(ip_addr(a1), ip_addr(a2), ip_maxbits(a1));
417 }
418
419 return ip_family(a1) - ip_family(a2);
420}
421
422Datum
424{
427
429}
430
431/*
432 * SortSupport strategy routine
433 */
434Datum
436{
438
440 ssup->ssup_extra = NULL;
441
442 if (ssup->abbreviate)
443 {
445 MemoryContext oldcontext;
446
447 oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt);
448
449 uss = palloc(sizeof(network_sortsupport_state));
450 uss->input_count = 0;
451 uss->estimating = true;
452 initHyperLogLog(&uss->abbr_card, 10);
453
454 ssup->ssup_extra = uss;
455
460
461 MemoryContextSwitchTo(oldcontext);
462 }
463
465}
466
467/*
468 * SortSupport comparison func
469 */
470static int
472{
473 inet *arg1 = DatumGetInetPP(x);
474 inet *arg2 = DatumGetInetPP(y);
475
476 return network_cmp_internal(arg1, arg2);
477}
478
479/*
480 * Callback for estimating effectiveness of abbreviated key optimization.
481 *
482 * We pay no attention to the cardinality of the non-abbreviated data, because
483 * there is no equality fast-path within authoritative inet comparator.
484 */
485static bool
486network_abbrev_abort(int memtupcount, SortSupport ssup)
487{
489 double abbr_card;
490
491 if (memtupcount < 10000 || uss->input_count < 10000 || !uss->estimating)
492 return false;
493
494 abbr_card = estimateHyperLogLog(&uss->abbr_card);
495
496 /*
497 * If we have >100k distinct values, then even if we were sorting many
498 * billion rows we'd likely still break even, and the penalty of undoing
499 * that many rows of abbrevs would probably not be worth it. At this point
500 * we stop counting because we know that we're now fully committed.
501 */
502 if (abbr_card > 100000.0)
503 {
504 if (trace_sort)
505 elog(LOG,
506 "network_abbrev: estimation ends at cardinality %f"
507 " after " INT64_FORMAT " values (%d rows)",
508 abbr_card, uss->input_count, memtupcount);
509 uss->estimating = false;
510 return false;
511 }
512
513 /*
514 * Target minimum cardinality is 1 per ~2k of non-null inputs. 0.5 row
515 * fudge factor allows us to abort earlier on genuinely pathological data
516 * where we've had exactly one abbreviated value in the first 2k
517 * (non-null) rows.
518 */
519 if (abbr_card < uss->input_count / 2000.0 + 0.5)
520 {
521 if (trace_sort)
522 elog(LOG,
523 "network_abbrev: aborting abbreviation at cardinality %f"
524 " below threshold %f after " INT64_FORMAT " values (%d rows)",
525 abbr_card, uss->input_count / 2000.0 + 0.5, uss->input_count,
526 memtupcount);
527 return true;
528 }
529
530 if (trace_sort)
531 elog(LOG,
532 "network_abbrev: cardinality %f after " INT64_FORMAT
533 " values (%d rows)", abbr_card, uss->input_count, memtupcount);
534
535 return false;
536}
537
538/*
539 * SortSupport conversion routine. Converts original inet/cidr representation
540 * to abbreviated key representation that works with simple 3-way unsigned int
541 * comparisons. The network_cmp_internal() rules for sorting inet/cidr datums
542 * are followed by abbreviated comparisons by an encoding scheme that
543 * conditions keys through careful use of padding.
544 *
545 * Some background: inet values have three major components (take for example
546 * the address 1.2.3.4/24):
547 *
548 * * A network, or netmasked bits (1.2.3.0).
549 * * A netmask size (/24).
550 * * A subnet, or bits outside of the netmask (0.0.0.4).
551 *
552 * cidr values are the same except that with only the first two components --
553 * all their subnet bits *must* be zero (1.2.3.0/24).
554 *
555 * IPv4 and IPv6 are identical in this makeup, with the difference being that
556 * IPv4 addresses have a maximum of 32 bits compared to IPv6's 64 bits, so in
557 * IPv6 each part may be larger.
558 *
559 * inet/cidr types compare using these sorting rules. If inequality is detected
560 * at any step, comparison is finished. If any rule is a tie, the algorithm
561 * drops through to the next to break it:
562 *
563 * 1. IPv4 always appears before IPv6.
564 * 2. Network bits are compared.
565 * 3. Netmask size is compared.
566 * 4. All bits are compared (having made it here, we know that both
567 * netmasked bits and netmask size are equal, so we're in effect only
568 * comparing subnet bits).
569 *
570 * When generating abbreviated keys for SortSupport, we pack as much as we can
571 * into a datum while ensuring that when comparing those keys as integers,
572 * these rules will be respected. Exact contents depend on IP family and datum
573 * size.
574 *
575 * IPv4
576 * ----
577 *
578 * 4 byte datums:
579 *
580 * Start with 1 bit for the IP family (IPv4 or IPv6; this bit is present in
581 * every case below) followed by all but 1 of the netmasked bits.
582 *
583 * +----------+---------------------+
584 * | 1 bit IP | 31 bits network | (1 bit network
585 * | family | (truncated) | omitted)
586 * +----------+---------------------+
587 *
588 * 8 byte datums:
589 *
590 * We have space to store all netmasked bits, followed by the netmask size,
591 * followed by 25 bits of the subnet (25 bits is usually more than enough in
592 * practice). cidr datums always have all-zero subnet bits.
593 *
594 * +----------+-----------------------+--------------+--------------------+
595 * | 1 bit IP | 32 bits network | 6 bits | 25 bits subnet |
596 * | family | (full) | network size | (truncated) |
597 * +----------+-----------------------+--------------+--------------------+
598 *
599 * IPv6
600 * ----
601 *
602 * 4 byte datums:
603 *
604 * +----------+---------------------+
605 * | 1 bit IP | 31 bits network | (up to 97 bits
606 * | family | (truncated) | network omitted)
607 * +----------+---------------------+
608 *
609 * 8 byte datums:
610 *
611 * +----------+---------------------------------+
612 * | 1 bit IP | 63 bits network | (up to 65 bits
613 * | family | (truncated) | network omitted)
614 * +----------+---------------------------------+
615 */
616static Datum
618{
620 inet *authoritative = DatumGetInetPP(original);
621 Datum res,
622 ipaddr_datum,
623 subnet_bitmask,
624 network;
625 int subnet_size;
626
627 Assert(ip_family(authoritative) == PGSQL_AF_INET ||
628 ip_family(authoritative) == PGSQL_AF_INET6);
629
630 /*
631 * Get an unsigned integer representation of the IP address by taking its
632 * first 4 or 8 bytes. Always take all 4 bytes of an IPv4 address. Take
633 * the first 8 bytes of an IPv6 address with an 8 byte datum and 4 bytes
634 * otherwise.
635 *
636 * We're consuming an array of unsigned char, so byteswap on little endian
637 * systems (an inet's ipaddr field stores the most significant byte
638 * first).
639 */
640 if (ip_family(authoritative) == PGSQL_AF_INET)
641 {
642 uint32 ipaddr_datum32;
643
644 memcpy(&ipaddr_datum32, ip_addr(authoritative), sizeof(uint32));
645
646 /* Must byteswap on little-endian machines */
647#ifndef WORDS_BIGENDIAN
648 ipaddr_datum = pg_bswap32(ipaddr_datum32);
649#else
650 ipaddr_datum = ipaddr_datum32;
651#endif
652
653 /* Initialize result without setting ipfamily bit */
654 res = (Datum) 0;
655 }
656 else
657 {
658 memcpy(&ipaddr_datum, ip_addr(authoritative), sizeof(Datum));
659
660 /* Must byteswap on little-endian machines */
661 ipaddr_datum = DatumBigEndianToNative(ipaddr_datum);
662
663 /* Initialize result with ipfamily (most significant) bit set */
664 res = ((Datum) 1) << (SIZEOF_DATUM * BITS_PER_BYTE - 1);
665 }
666
667 /*
668 * ipaddr_datum must be "split": high order bits go in "network" component
669 * of abbreviated key (often with zeroed bits at the end due to masking),
670 * while low order bits go in "subnet" component when there is space for
671 * one. This is often accomplished by generating a temp datum subnet
672 * bitmask, which we may reuse later when generating the subnet bits
673 * themselves. (Note that subnet bits are only used with IPv4 datums on
674 * platforms where datum is 8 bytes.)
675 *
676 * The number of bits in subnet is used to generate a datum subnet
677 * bitmask. For example, with a /24 IPv4 datum there are 8 subnet bits
678 * (since 32 - 24 is 8), so the final subnet bitmask is B'1111 1111'. We
679 * need explicit handling for cases where the ipaddr bits cannot all fit
680 * in a datum, though (otherwise we'd incorrectly mask the network
681 * component with IPv6 values).
682 */
683 subnet_size = ip_maxbits(authoritative) - ip_bits(authoritative);
684 Assert(subnet_size >= 0);
685 /* subnet size must work with prefix ipaddr cases */
686 subnet_size %= SIZEOF_DATUM * BITS_PER_BYTE;
687 if (ip_bits(authoritative) == 0)
688 {
689 /* Fit as many ipaddr bits as possible into subnet */
690 subnet_bitmask = ((Datum) 0) - 1;
691 network = 0;
692 }
693 else if (ip_bits(authoritative) < SIZEOF_DATUM * BITS_PER_BYTE)
694 {
695 /* Split ipaddr bits between network and subnet */
696 subnet_bitmask = (((Datum) 1) << subnet_size) - 1;
697 network = ipaddr_datum & ~subnet_bitmask;
698 }
699 else
700 {
701 /* Fit as many ipaddr bits as possible into network */
702 subnet_bitmask = 0;
703 network = ipaddr_datum;
704 }
705
706#if SIZEOF_DATUM == 8
707 if (ip_family(authoritative) == PGSQL_AF_INET)
708 {
709 /*
710 * IPv4 with 8 byte datums: keep all 32 netmasked bits, netmask size,
711 * and most significant 25 subnet bits
712 */
713 Datum netmask_size = (Datum) ip_bits(authoritative);
714 Datum subnet;
715
716 /*
717 * Shift left 31 bits: 6 bits netmask size + 25 subnet bits.
718 *
719 * We don't make any distinction between network bits that are zero
720 * due to masking and "true"/non-masked zero bits. An abbreviated
721 * comparison that is resolved by comparing a non-masked and non-zero
722 * bit to a masked/zeroed bit is effectively resolved based on
723 * ip_bits(), even though the comparison won't reach the netmask_size
724 * bits.
725 */
726 network <<= (ABBREV_BITS_INET4_NETMASK_SIZE +
728
729 /* Shift size to make room for subnet bits at the end */
730 netmask_size <<= ABBREV_BITS_INET4_SUBNET;
731
732 /* Extract subnet bits without shifting them */
733 subnet = ipaddr_datum & subnet_bitmask;
734
735 /*
736 * If we have more than 25 subnet bits, we can't fit everything. Shift
737 * subnet down to avoid clobbering bits that are only supposed to be
738 * used for netmask_size.
739 *
740 * Discarding the least significant subnet bits like this is correct
741 * because abbreviated comparisons that are resolved at the subnet
742 * level must have had equal netmask_size/ip_bits() values in order to
743 * get that far.
744 */
745 if (subnet_size > ABBREV_BITS_INET4_SUBNET)
746 subnet >>= subnet_size - ABBREV_BITS_INET4_SUBNET;
747
748 /*
749 * Assemble the final abbreviated key without clobbering the ipfamily
750 * bit that must remain a zero.
751 */
752 res |= network | netmask_size | subnet;
753 }
754 else
755#endif
756 {
757 /*
758 * 4 byte datums, or IPv6 with 8 byte datums: Use as many of the
759 * netmasked bits as will fit in final abbreviated key. Avoid
760 * clobbering the ipfamily bit that was set earlier.
761 */
762 res |= network >> 1;
763 }
764
765 uss->input_count += 1;
766
767 /* Hash abbreviated key */
768 if (uss->estimating)
769 {
770 uint32 tmp;
771
772#if SIZEOF_DATUM == 8
773 tmp = (uint32) res ^ (uint32) ((uint64) res >> 32);
774#else /* SIZEOF_DATUM != 8 */
775 tmp = (uint32) res;
776#endif
777
779 }
780
781 return res;
782}
783
784/*
785 * Boolean ordering tests.
786 */
787Datum
789{
792
794}
795
796Datum
798{
801
803}
804
805Datum
807{
810
812}
813
814Datum
816{
819
821}
822
823Datum
825{
828
830}
831
832Datum
834{
837
839}
840
841/*
842 * MIN/MAX support functions.
843 */
844Datum
846{
849
850 if (network_cmp_internal(a1, a2) < 0)
852 else
854}
855
856Datum
858{
861
862 if (network_cmp_internal(a1, a2) > 0)
864 else
866}
867
868/*
869 * Support function for hash indexes on inet/cidr.
870 */
871Datum
873{
874 inet *addr = PG_GETARG_INET_PP(0);
875 int addrsize = ip_addrsize(addr);
876
877 /* XXX this assumes there are no pad bytes in the data structure */
878 return hash_any((unsigned char *) VARDATA_ANY(addr), addrsize + 2);
879}
880
881Datum
883{
884 inet *addr = PG_GETARG_INET_PP(0);
885 int addrsize = ip_addrsize(addr);
886
887 return hash_any_extended((unsigned char *) VARDATA_ANY(addr), addrsize + 2,
888 PG_GETARG_INT64(1));
889}
890
891/*
892 * Boolean network-inclusion tests.
893 */
894Datum
896{
899
900 if (ip_family(a1) == ip_family(a2))
901 {
903 bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
904 }
905
906 PG_RETURN_BOOL(false);
907}
908
909Datum
911{
914
915 if (ip_family(a1) == ip_family(a2))
916 {
918 bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a2)) == 0);
919 }
920
921 PG_RETURN_BOOL(false);
922}
923
924Datum
926{
929
930 if (ip_family(a1) == ip_family(a2))
931 {
933 bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
934 }
935
936 PG_RETURN_BOOL(false);
937}
938
939Datum
941{
944
945 if (ip_family(a1) == ip_family(a2))
946 {
948 bitncmp(ip_addr(a1), ip_addr(a2), ip_bits(a1)) == 0);
949 }
950
951 PG_RETURN_BOOL(false);
952}
953
954Datum
956{
959
960 if (ip_family(a1) == ip_family(a2))
961 {
963 Min(ip_bits(a1), ip_bits(a2))) == 0);
964 }
965
966 PG_RETURN_BOOL(false);
967}
968
969/*
970 * Planner support function for network subset/superset operators
971 */
972Datum
974{
975 Node *rawreq = (Node *) PG_GETARG_POINTER(0);
976 Node *ret = NULL;
977
979 {
980 /* Try to convert operator/function call to index conditions */
982
983 if (is_opclause(req->node))
984 {
985 OpExpr *clause = (OpExpr *) req->node;
986
987 Assert(list_length(clause->args) == 2);
988 ret = (Node *)
990 (Node *) lsecond(clause->args),
991 req->indexarg,
992 req->funcid,
993 req->opfamily);
994 }
995 else if (is_funcclause(req->node)) /* be paranoid */
996 {
997 FuncExpr *clause = (FuncExpr *) req->node;
998
999 Assert(list_length(clause->args) == 2);
1000 ret = (Node *)
1002 (Node *) lsecond(clause->args),
1003 req->indexarg,
1004 req->funcid,
1005 req->opfamily);
1006 }
1007 }
1008
1009 PG_RETURN_POINTER(ret);
1010}
1011
1012/*
1013 * match_network_function
1014 * Try to generate an indexqual for a network subset/superset function.
1015 *
1016 * This layer is just concerned with identifying the function and swapping
1017 * the arguments if necessary.
1018 */
1019static List *
1021 Node *rightop,
1022 int indexarg,
1023 Oid funcid,
1024 Oid opfamily)
1025{
1026 switch (funcid)
1027 {
1028 case F_NETWORK_SUB:
1029 /* indexkey must be on the left */
1030 if (indexarg != 0)
1031 return NIL;
1032 return match_network_subset(leftop, rightop, false, opfamily);
1033
1034 case F_NETWORK_SUBEQ:
1035 /* indexkey must be on the left */
1036 if (indexarg != 0)
1037 return NIL;
1038 return match_network_subset(leftop, rightop, true, opfamily);
1039
1040 case F_NETWORK_SUP:
1041 /* indexkey must be on the right */
1042 if (indexarg != 1)
1043 return NIL;
1044 return match_network_subset(rightop, leftop, false, opfamily);
1045
1046 case F_NETWORK_SUPEQ:
1047 /* indexkey must be on the right */
1048 if (indexarg != 1)
1049 return NIL;
1050 return match_network_subset(rightop, leftop, true, opfamily);
1051
1052 default:
1053
1054 /*
1055 * We'd only get here if somebody attached this support function
1056 * to an unexpected function. Maybe we should complain, but for
1057 * now, do nothing.
1058 */
1059 return NIL;
1060 }
1061}
1062
1063/*
1064 * match_network_subset
1065 * Try to generate an indexqual for a network subset function.
1066 */
1067static List *
1069 Node *rightop,
1070 bool is_eq,
1071 Oid opfamily)
1072{
1073 List *result;
1074 Datum rightopval;
1075 Oid datatype = INETOID;
1076 Oid opr1oid;
1077 Oid opr2oid;
1078 Datum opr1right;
1079 Datum opr2right;
1080 Expr *expr;
1081
1082 /*
1083 * Can't do anything with a non-constant or NULL comparison value.
1084 *
1085 * Note that since we restrict ourselves to cases with a hard constant on
1086 * the RHS, it's a-fortiori a pseudoconstant, and we don't need to worry
1087 * about verifying that.
1088 */
1089 if (!IsA(rightop, Const) ||
1090 ((Const *) rightop)->constisnull)
1091 return NIL;
1092 rightopval = ((Const *) rightop)->constvalue;
1093
1094 /*
1095 * create clause "key >= network_scan_first( rightopval )", or ">" if the
1096 * operator disallows equality.
1097 */
1098 opr1oid = get_opfamily_member_for_cmptype(opfamily, datatype, datatype, is_eq ? COMPARE_GE : COMPARE_GT);
1099 if (opr1oid == InvalidOid)
1100 return NIL;
1101
1102 opr1right = network_scan_first(rightopval);
1103
1104 expr = make_opclause(opr1oid, BOOLOID, false,
1105 (Expr *) leftop,
1106 (Expr *) makeConst(datatype, -1,
1107 InvalidOid, /* not collatable */
1108 -1, opr1right,
1109 false, false),
1111 result = list_make1(expr);
1112
1113 /* create clause "key <= network_scan_last( rightopval )" */
1114
1115 opr2oid = get_opfamily_member_for_cmptype(opfamily, datatype, datatype, COMPARE_LE);
1116 if (opr2oid == InvalidOid)
1117 return NIL;
1118
1119 opr2right = network_scan_last(rightopval);
1120
1121 expr = make_opclause(opr2oid, BOOLOID, false,
1122 (Expr *) leftop,
1123 (Expr *) makeConst(datatype, -1,
1124 InvalidOid, /* not collatable */
1125 -1, opr2right,
1126 false, false),
1128 result = lappend(result, expr);
1129
1130 return result;
1131}
1132
1133
1134/*
1135 * Extract data from a network datatype.
1136 */
1137Datum
1139{
1140 inet *ip = PG_GETARG_INET_PP(0);
1141 char *ptr;
1142 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1143
1144 /* force display of max bits, regardless of masklen... */
1145 if (pg_inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
1146 tmp, sizeof(tmp)) == NULL)
1147 ereport(ERROR,
1148 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1149 errmsg("could not format inet value: %m")));
1150
1151 /* Suppress /n if present (shouldn't happen now) */
1152 if ((ptr = strchr(tmp, '/')) != NULL)
1153 *ptr = '\0';
1154
1156}
1157
1158/*
1159 * network_show implements the inet and cidr casts to text. This is not
1160 * quite the same behavior as network_out, hence we can't drop it in favor
1161 * of CoerceViaIO.
1162 */
1163Datum
1165{
1166 inet *ip = PG_GETARG_INET_PP(0);
1167 int len;
1168 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1169
1170 if (pg_inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip),
1171 tmp, sizeof(tmp)) == NULL)
1172 ereport(ERROR,
1173 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1174 errmsg("could not format inet value: %m")));
1175
1176 /* Add /n if not present (which it won't be) */
1177 if (strchr(tmp, '/') == NULL)
1178 {
1179 len = strlen(tmp);
1180 snprintf(tmp + len, sizeof(tmp) - len, "/%u", ip_bits(ip));
1181 }
1182
1184}
1185
1186Datum
1188{
1189 inet *ip = PG_GETARG_INET_PP(0);
1190 char *dst;
1191 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1192
1193 dst = pg_inet_net_ntop(ip_family(ip), ip_addr(ip),
1194 ip_bits(ip), tmp, sizeof(tmp));
1195
1196 if (dst == NULL)
1197 ereport(ERROR,
1198 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1199 errmsg("could not format inet value: %m")));
1200
1202}
1203
1204Datum
1206{
1207 inet *ip = PG_GETARG_INET_PP(0);
1208 char *dst;
1209 char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
1210
1211 dst = pg_inet_cidr_ntop(ip_family(ip), ip_addr(ip),
1212 ip_bits(ip), tmp, sizeof(tmp));
1213
1214 if (dst == NULL)
1215 ereport(ERROR,
1216 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1217 errmsg("could not format cidr value: %m")));
1218
1220}
1221
1222Datum
1224{
1225 inet *ip = PG_GETARG_INET_PP(0);
1226
1228}
1229
1230Datum
1232{
1233 inet *ip = PG_GETARG_INET_PP(0);
1234
1235 switch (ip_family(ip))
1236 {
1237 case PGSQL_AF_INET:
1238 PG_RETURN_INT32(4);
1239 break;
1240 case PGSQL_AF_INET6:
1241 PG_RETURN_INT32(6);
1242 break;
1243 default:
1244 PG_RETURN_INT32(0);
1245 break;
1246 }
1247}
1248
1249Datum
1251{
1252 inet *ip = PG_GETARG_INET_PP(0);
1253 inet *dst;
1254 int byte;
1255 int bits;
1256 int maxbytes;
1257 unsigned char mask;
1258 unsigned char *a,
1259 *b;
1260
1261 /* make sure any unused bits are zeroed */
1262 dst = (inet *) palloc0(sizeof(inet));
1263
1264 maxbytes = ip_addrsize(ip);
1265 bits = ip_bits(ip);
1266 a = ip_addr(ip);
1267 b = ip_addr(dst);
1268
1269 for (byte = 0; byte < maxbytes; byte++)
1270 {
1271 if (bits >= 8)
1272 {
1273 mask = 0x00;
1274 bits -= 8;
1275 }
1276 else if (bits == 0)
1277 mask = 0xff;
1278 else
1279 {
1280 mask = 0xff >> bits;
1281 bits = 0;
1282 }
1283
1284 b[byte] = a[byte] | mask;
1285 }
1286
1287 ip_family(dst) = ip_family(ip);
1288 ip_bits(dst) = ip_bits(ip);
1289 SET_INET_VARSIZE(dst);
1290
1291 PG_RETURN_INET_P(dst);
1292}
1293
1294Datum
1296{
1297 inet *ip = PG_GETARG_INET_PP(0);
1298 inet *dst;
1299 int byte;
1300 int bits;
1301 unsigned char mask;
1302 unsigned char *a,
1303 *b;
1304
1305 /* make sure any unused bits are zeroed */
1306 dst = (inet *) palloc0(sizeof(inet));
1307
1308 bits = ip_bits(ip);
1309 a = ip_addr(ip);
1310 b = ip_addr(dst);
1311
1312 byte = 0;
1313
1314 while (bits)
1315 {
1316 if (bits >= 8)
1317 {
1318 mask = 0xff;
1319 bits -= 8;
1320 }
1321 else
1322 {
1323 mask = 0xff << (8 - bits);
1324 bits = 0;
1325 }
1326
1327 b[byte] = a[byte] & mask;
1328 byte++;
1329 }
1330
1331 ip_family(dst) = ip_family(ip);
1332 ip_bits(dst) = ip_bits(ip);
1333 SET_INET_VARSIZE(dst);
1334
1335 PG_RETURN_INET_P(dst);
1336}
1337
1338Datum
1340{
1341 inet *ip = PG_GETARG_INET_PP(0);
1342 inet *dst;
1343 int byte;
1344 int bits;
1345 unsigned char mask;
1346 unsigned char *b;
1347
1348 /* make sure any unused bits are zeroed */
1349 dst = (inet *) palloc0(sizeof(inet));
1350
1351 bits = ip_bits(ip);
1352 b = ip_addr(dst);
1353
1354 byte = 0;
1355
1356 while (bits)
1357 {
1358 if (bits >= 8)
1359 {
1360 mask = 0xff;
1361 bits -= 8;
1362 }
1363 else
1364 {
1365 mask = 0xff << (8 - bits);
1366 bits = 0;
1367 }
1368
1369 b[byte] = mask;
1370 byte++;
1371 }
1372
1373 ip_family(dst) = ip_family(ip);
1374 ip_bits(dst) = ip_maxbits(ip);
1375 SET_INET_VARSIZE(dst);
1376
1377 PG_RETURN_INET_P(dst);
1378}
1379
1380Datum
1382{
1383 inet *ip = PG_GETARG_INET_PP(0);
1384 inet *dst;
1385 int byte;
1386 int bits;
1387 int maxbytes;
1388 unsigned char mask;
1389 unsigned char *b;
1390
1391 /* make sure any unused bits are zeroed */
1392 dst = (inet *) palloc0(sizeof(inet));
1393
1394 maxbytes = ip_addrsize(ip);
1395 bits = ip_maxbits(ip) - ip_bits(ip);
1396 b = ip_addr(dst);
1397
1398 byte = maxbytes - 1;
1399
1400 while (bits)
1401 {
1402 if (bits >= 8)
1403 {
1404 mask = 0xff;
1405 bits -= 8;
1406 }
1407 else
1408 {
1409 mask = 0xff >> (8 - bits);
1410 bits = 0;
1411 }
1412
1413 b[byte] = mask;
1414 byte--;
1415 }
1416
1417 ip_family(dst) = ip_family(ip);
1418 ip_bits(dst) = ip_maxbits(ip);
1419 SET_INET_VARSIZE(dst);
1420
1421 PG_RETURN_INET_P(dst);
1422}
1423
1424/*
1425 * Returns true if the addresses are from the same family, or false. Used to
1426 * check that we can create a network which contains both of the networks.
1427 */
1428Datum
1430{
1433
1435}
1436
1437/*
1438 * Returns the smallest CIDR which contains both of the inputs.
1439 */
1440Datum
1442{
1444 *a2 = PG_GETARG_INET_PP(1);
1445 int commonbits;
1446
1447 if (ip_family(a1) != ip_family(a2))
1448 ereport(ERROR,
1449 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1450 errmsg("cannot merge addresses from different families")));
1451
1452 commonbits = bitncommon(ip_addr(a1), ip_addr(a2),
1453 Min(ip_bits(a1), ip_bits(a2)));
1454
1456}
1457
1458/*
1459 * Convert a value of a network datatype to an approximate scalar value.
1460 * This is used for estimating selectivities of inequality operators
1461 * involving network types.
1462 *
1463 * On failure (e.g., unsupported typid), set *failure to true;
1464 * otherwise, that variable is not changed.
1465 */
1466double
1468{
1469 switch (typid)
1470 {
1471 case INETOID:
1472 case CIDROID:
1473 {
1474 inet *ip = DatumGetInetPP(value);
1475 int len;
1476 double res;
1477 int i;
1478
1479 /*
1480 * Note that we don't use the full address for IPv6.
1481 */
1482 if (ip_family(ip) == PGSQL_AF_INET)
1483 len = 4;
1484 else
1485 len = 5;
1486
1487 res = ip_family(ip);
1488 for (i = 0; i < len; i++)
1489 {
1490 res *= 256;
1491 res += ip_addr(ip)[i];
1492 }
1493 return res;
1494 }
1495 case MACADDROID:
1496 {
1498 double res;
1499
1500 res = (mac->a << 16) | (mac->b << 8) | (mac->c);
1501 res *= 256 * 256 * 256;
1502 res += (mac->d << 16) | (mac->e << 8) | (mac->f);
1503 return res;
1504 }
1505 case MACADDR8OID:
1506 {
1508 double res;
1509
1510 res = (mac->a << 24) | (mac->b << 16) | (mac->c << 8) | (mac->d);
1511 res *= ((double) 256) * 256 * 256 * 256;
1512 res += (mac->e << 24) | (mac->f << 16) | (mac->g << 8) | (mac->h);
1513 return res;
1514 }
1515 }
1516
1517 *failure = true;
1518 return 0;
1519}
1520
1521/*
1522 * int
1523 * bitncmp(l, r, n)
1524 * compare bit masks l and r, for n bits.
1525 * return:
1526 * <0, >0, or 0 in the libc tradition.
1527 * note:
1528 * network byte order assumed. this means 192.5.5.240/28 has
1529 * 0x11110000 in its fourth octet.
1530 * author:
1531 * Paul Vixie (ISC), June 1996
1532 */
1533int
1534bitncmp(const unsigned char *l, const unsigned char *r, int n)
1535{
1536 unsigned int lb,
1537 rb;
1538 int x,
1539 b;
1540
1541 b = n / 8;
1542 x = memcmp(l, r, b);
1543 if (x || (n % 8) == 0)
1544 return x;
1545
1546 lb = l[b];
1547 rb = r[b];
1548 for (b = n % 8; b > 0; b--)
1549 {
1550 if (IS_HIGHBIT_SET(lb) != IS_HIGHBIT_SET(rb))
1551 {
1552 if (IS_HIGHBIT_SET(lb))
1553 return 1;
1554 return -1;
1555 }
1556 lb <<= 1;
1557 rb <<= 1;
1558 }
1559 return 0;
1560}
1561
1562/*
1563 * bitncommon: compare bit masks l and r, for up to n bits.
1564 *
1565 * Returns the number of leading bits that match (0 to n).
1566 */
1567int
1568bitncommon(const unsigned char *l, const unsigned char *r, int n)
1569{
1570 int byte,
1571 nbits;
1572
1573 /* number of bits to examine in last byte */
1574 nbits = n % 8;
1575
1576 /* check whole bytes */
1577 for (byte = 0; byte < n / 8; byte++)
1578 {
1579 if (l[byte] != r[byte])
1580 {
1581 /* at least one bit in the last byte is not common */
1582 nbits = 7;
1583 break;
1584 }
1585 }
1586
1587 /* check bits in last partial byte */
1588 if (nbits != 0)
1589 {
1590 /* calculate diff of first non-matching bytes */
1591 unsigned int diff = l[byte] ^ r[byte];
1592
1593 /* compare the bits from the most to the least */
1594 while ((diff >> (8 - nbits)) != 0)
1595 nbits--;
1596 }
1597
1598 return (8 * byte) + nbits;
1599}
1600
1601
1602/*
1603 * Verify a CIDR address is OK (doesn't have bits set past the masklen)
1604 */
1605static bool
1606addressOK(unsigned char *a, int bits, int family)
1607{
1608 int byte;
1609 int nbits;
1610 int maxbits;
1611 int maxbytes;
1612 unsigned char mask;
1613
1614 if (family == PGSQL_AF_INET)
1615 {
1616 maxbits = 32;
1617 maxbytes = 4;
1618 }
1619 else
1620 {
1621 maxbits = 128;
1622 maxbytes = 16;
1623 }
1624 Assert(bits <= maxbits);
1625
1626 if (bits == maxbits)
1627 return true;
1628
1629 byte = bits / 8;
1630
1631 nbits = bits % 8;
1632 mask = 0xff;
1633 if (bits != 0)
1634 mask >>= nbits;
1635
1636 while (byte < maxbytes)
1637 {
1638 if ((a[byte] & mask) != 0)
1639 return false;
1640 mask = 0xff;
1641 byte++;
1642 }
1643
1644 return true;
1645}
1646
1647
1648/*
1649 * These functions are used by planner to generate indexscan limits
1650 * for clauses a << b and a <<= b
1651 */
1652
1653/* return the minimal value for an IP on a given network */
1654Datum
1656{
1658}
1659
1660/*
1661 * return "last" IP on a given network. It's the broadcast address,
1662 * however, masklen has to be set to its max bits, since
1663 * 192.168.0.255/24 is considered less than 192.168.0.255/32
1664 *
1665 * inet_set_masklen() hacked to max out the masklength to 128 for IPv6
1666 * and 32 for IPv4 when given '-1' as argument.
1667 */
1668Datum
1670{
1673 Int32GetDatum(-1));
1674}
1675
1676
1677/*
1678 * IP address that the client is connecting from (NULL if Unix socket)
1679 */
1680Datum
1682{
1683 Port *port = MyProcPort;
1684 char remote_host[NI_MAXHOST];
1685 int ret;
1686
1687 if (port == NULL)
1689
1690 switch (port->raddr.addr.ss_family)
1691 {
1692 case AF_INET:
1693 case AF_INET6:
1694 break;
1695 default:
1697 }
1698
1699 remote_host[0] = '\0';
1700
1701 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1702 remote_host, sizeof(remote_host),
1703 NULL, 0,
1704 NI_NUMERICHOST | NI_NUMERICSERV);
1705 if (ret != 0)
1707
1708 clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);
1709
1710 PG_RETURN_INET_P(network_in(remote_host, false, NULL));
1711}
1712
1713
1714/*
1715 * port that the client is connecting from (NULL if Unix socket)
1716 */
1717Datum
1719{
1720 Port *port = MyProcPort;
1721 char remote_port[NI_MAXSERV];
1722 int ret;
1723
1724 if (port == NULL)
1726
1727 switch (port->raddr.addr.ss_family)
1728 {
1729 case AF_INET:
1730 case AF_INET6:
1731 break;
1732 default:
1734 }
1735
1736 remote_port[0] = '\0';
1737
1738 ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
1739 NULL, 0,
1740 remote_port, sizeof(remote_port),
1741 NI_NUMERICHOST | NI_NUMERICSERV);
1742 if (ret != 0)
1744
1746}
1747
1748
1749/*
1750 * IP address that the server accepted the connection on (NULL if Unix socket)
1751 */
1752Datum
1754{
1755 Port *port = MyProcPort;
1756 char local_host[NI_MAXHOST];
1757 int ret;
1758
1759 if (port == NULL)
1761
1762 switch (port->laddr.addr.ss_family)
1763 {
1764 case AF_INET:
1765 case AF_INET6:
1766 break;
1767 default:
1769 }
1770
1771 local_host[0] = '\0';
1772
1773 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1774 local_host, sizeof(local_host),
1775 NULL, 0,
1776 NI_NUMERICHOST | NI_NUMERICSERV);
1777 if (ret != 0)
1779
1780 clean_ipv6_addr(port->laddr.addr.ss_family, local_host);
1781
1782 PG_RETURN_INET_P(network_in(local_host, false, NULL));
1783}
1784
1785
1786/*
1787 * port that the server accepted the connection on (NULL if Unix socket)
1788 */
1789Datum
1791{
1792 Port *port = MyProcPort;
1793 char local_port[NI_MAXSERV];
1794 int ret;
1795
1796 if (port == NULL)
1798
1799 switch (port->laddr.addr.ss_family)
1800 {
1801 case AF_INET:
1802 case AF_INET6:
1803 break;
1804 default:
1806 }
1807
1808 local_port[0] = '\0';
1809
1810 ret = pg_getnameinfo_all(&port->laddr.addr, port->laddr.salen,
1811 NULL, 0,
1812 local_port, sizeof(local_port),
1813 NI_NUMERICHOST | NI_NUMERICSERV);
1814 if (ret != 0)
1816
1818}
1819
1820
1821Datum
1823{
1824 inet *ip = PG_GETARG_INET_PP(0);
1825 inet *dst;
1826
1827 dst = (inet *) palloc0(sizeof(inet));
1828
1829 {
1830 int nb = ip_addrsize(ip);
1831 unsigned char *pip = ip_addr(ip);
1832 unsigned char *pdst = ip_addr(dst);
1833
1834 while (--nb >= 0)
1835 pdst[nb] = ~pip[nb];
1836 }
1837 ip_bits(dst) = ip_bits(ip);
1838
1839 ip_family(dst) = ip_family(ip);
1840 SET_INET_VARSIZE(dst);
1841
1842 PG_RETURN_INET_P(dst);
1843}
1844
1845
1846Datum
1848{
1849 inet *ip = PG_GETARG_INET_PP(0);
1850 inet *ip2 = PG_GETARG_INET_PP(1);
1851 inet *dst;
1852
1853 dst = (inet *) palloc0(sizeof(inet));
1854
1855 if (ip_family(ip) != ip_family(ip2))
1856 ereport(ERROR,
1857 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1858 errmsg("cannot AND inet values of different sizes")));
1859 else
1860 {
1861 int nb = ip_addrsize(ip);
1862 unsigned char *pip = ip_addr(ip);
1863 unsigned char *pip2 = ip_addr(ip2);
1864 unsigned char *pdst = ip_addr(dst);
1865
1866 while (--nb >= 0)
1867 pdst[nb] = pip[nb] & pip2[nb];
1868 }
1869 ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1870
1871 ip_family(dst) = ip_family(ip);
1872 SET_INET_VARSIZE(dst);
1873
1874 PG_RETURN_INET_P(dst);
1875}
1876
1877
1878Datum
1880{
1881 inet *ip = PG_GETARG_INET_PP(0);
1882 inet *ip2 = PG_GETARG_INET_PP(1);
1883 inet *dst;
1884
1885 dst = (inet *) palloc0(sizeof(inet));
1886
1887 if (ip_family(ip) != ip_family(ip2))
1888 ereport(ERROR,
1889 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1890 errmsg("cannot OR inet values of different sizes")));
1891 else
1892 {
1893 int nb = ip_addrsize(ip);
1894 unsigned char *pip = ip_addr(ip);
1895 unsigned char *pip2 = ip_addr(ip2);
1896 unsigned char *pdst = ip_addr(dst);
1897
1898 while (--nb >= 0)
1899 pdst[nb] = pip[nb] | pip2[nb];
1900 }
1901 ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1902
1903 ip_family(dst) = ip_family(ip);
1904 SET_INET_VARSIZE(dst);
1905
1906 PG_RETURN_INET_P(dst);
1907}
1908
1909
1910static inet *
1912{
1913 inet *dst;
1914
1915 dst = (inet *) palloc0(sizeof(inet));
1916
1917 {
1918 int nb = ip_addrsize(ip);
1919 unsigned char *pip = ip_addr(ip);
1920 unsigned char *pdst = ip_addr(dst);
1921 int carry = 0;
1922
1923 while (--nb >= 0)
1924 {
1925 carry = pip[nb] + (int) (addend & 0xFF) + carry;
1926 pdst[nb] = (unsigned char) (carry & 0xFF);
1927 carry >>= 8;
1928
1929 /*
1930 * We have to be careful about right-shifting addend because
1931 * right-shift isn't portable for negative values, while simply
1932 * dividing by 256 doesn't work (the standard rounding is in the
1933 * wrong direction, besides which there may be machines out there
1934 * that round the wrong way). So, explicitly clear the low-order
1935 * byte to remove any doubt about the correct result of the
1936 * division, and then divide rather than shift.
1937 */
1938 addend &= ~((int64) 0xFF);
1939 addend /= 0x100;
1940 }
1941
1942 /*
1943 * At this point we should have addend and carry both zero if original
1944 * addend was >= 0, or addend -1 and carry 1 if original addend was <
1945 * 0. Anything else means overflow.
1946 */
1947 if (!((addend == 0 && carry == 0) ||
1948 (addend == -1 && carry == 1)))
1949 ereport(ERROR,
1950 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1951 errmsg("result is out of range")));
1952 }
1953
1954 ip_bits(dst) = ip_bits(ip);
1955 ip_family(dst) = ip_family(ip);
1956 SET_INET_VARSIZE(dst);
1957
1958 return dst;
1959}
1960
1961
1962Datum
1964{
1965 inet *ip = PG_GETARG_INET_PP(0);
1966 int64 addend = PG_GETARG_INT64(1);
1967
1968 PG_RETURN_INET_P(internal_inetpl(ip, addend));
1969}
1970
1971
1972Datum
1974{
1975 inet *ip = PG_GETARG_INET_PP(0);
1976 int64 addend = PG_GETARG_INT64(1);
1977
1978 PG_RETURN_INET_P(internal_inetpl(ip, -addend));
1979}
1980
1981
1982Datum
1984{
1985 inet *ip = PG_GETARG_INET_PP(0);
1986 inet *ip2 = PG_GETARG_INET_PP(1);
1987 int64 res = 0;
1988
1989 if (ip_family(ip) != ip_family(ip2))
1990 ereport(ERROR,
1991 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1992 errmsg("cannot subtract inet values of different sizes")));
1993 else
1994 {
1995 /*
1996 * We form the difference using the traditional complement, increment,
1997 * and add rule, with the increment part being handled by starting the
1998 * carry off at 1. If you don't think integer arithmetic is done in
1999 * two's complement, too bad.
2000 */
2001 int nb = ip_addrsize(ip);
2002 int byte = 0;
2003 unsigned char *pip = ip_addr(ip);
2004 unsigned char *pip2 = ip_addr(ip2);
2005 int carry = 1;
2006
2007 while (--nb >= 0)
2008 {
2009 int lobyte;
2010
2011 carry = pip[nb] + (~pip2[nb] & 0xFF) + carry;
2012 lobyte = carry & 0xFF;
2013 if (byte < sizeof(int64))
2014 {
2015 res |= ((int64) lobyte) << (byte * 8);
2016 }
2017 else
2018 {
2019 /*
2020 * Input wider than int64: check for overflow. All bytes to
2021 * the left of what will fit should be 0 or 0xFF, depending on
2022 * sign of the now-complete result.
2023 */
2024 if ((res < 0) ? (lobyte != 0xFF) : (lobyte != 0))
2025 ereport(ERROR,
2026 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2027 errmsg("result is out of range")));
2028 }
2029 carry >>= 8;
2030 byte++;
2031 }
2032
2033 /*
2034 * If input is narrower than int64, overflow is not possible, but we
2035 * have to do proper sign extension.
2036 */
2037 if (carry == 0 && byte < sizeof(int64))
2038 res |= ((uint64) (int64) -1) << (byte * 8);
2039 }
2040
2041 PG_RETURN_INT64(res);
2042}
2043
2044
2045/*
2046 * clean_ipv6_addr --- remove any '%zone' part from an IPv6 address string
2047 *
2048 * XXX This should go away someday!
2049 *
2050 * This is a kluge needed because we don't yet support zones in stored inet
2051 * values. Since the result of getnameinfo() might include a zone spec,
2052 * call this to remove it anywhere we want to feed getnameinfo's output to
2053 * network_in. Beats failing entirely.
2054 *
2055 * An alternative approach would be to let network_in ignore %-parts for
2056 * itself, but that would mean we'd silently drop zone specs in user input,
2057 * which seems not such a good idea.
2058 */
2059void
2060clean_ipv6_addr(int addr_family, char *addr)
2061{
2062 if (addr_family == AF_INET6)
2063 {
2064 char *pct = strchr(addr, '%');
2065
2066 if (pct)
2067 *pct = '\0';
2068 }
2069}
#define Min(x, y)
Definition: c.h:975
#define IS_HIGHBIT_SET(ch)
Definition: c.h:1126
#define Max(x, y)
Definition: c.h:969
#define INT64_FORMAT
Definition: c.h:520
int64_t int64
Definition: c.h:499
int32_t int32
Definition: c.h:498
uint64_t uint64
Definition: c.h:503
uint32_t uint32
Definition: c.h:502
@ COMPARE_LE
Definition: cmptype.h:35
@ COMPARE_GT
Definition: cmptype.h:38
@ COMPARE_GE
Definition: cmptype.h:37
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define LOG
Definition: elog.h:31
#define ereturn(context, dummy_value,...)
Definition: elog.h:278
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:149
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:684
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_RETURN_INT64(x)
Definition: fmgr.h:368
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:682
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
struct Port * MyProcPort
Definition: globals.c:52
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
static Datum hash_any_extended(const unsigned char *k, int keylen, uint64 seed)
Definition: hashfn.h:37
static Datum hash_any(const unsigned char *k, int keylen)
Definition: hashfn.h:31
Assert(PointerIsAligned(start, uint64))
static const FormData_pg_attribute a1
Definition: heap.c:144
static const FormData_pg_attribute a2
Definition: heap.c:157
void initHyperLogLog(hyperLogLogState *cState, uint8 bwidth)
Definition: hyperloglog.c:66
double estimateHyperLogLog(hyperLogLogState *cState)
Definition: hyperloglog.c:186
void addHyperLogLog(hyperLogLogState *cState, uint32 hash)
Definition: hyperloglog.c:167
char * pg_inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size)
int pg_inet_net_pton(int af, const char *src, void *dst, size_t size)
Definition: inet_net_pton.c:61
static struct @165 value
Datum int4in(PG_FUNCTION_ARGS)
Definition: int.c:287
int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags)
Definition: ip.c:114
int y
Definition: isn.c:76
int b
Definition: isn.c:74
int x
Definition: isn.c:75
int a
Definition: isn.c:73
int i
Definition: isn.c:77
List * lappend(List *list, void *datum)
Definition: list.c:339
Oid get_opfamily_member_for_cmptype(Oid opfamily, Oid lefttype, Oid righttype, CompareType cmptype)
Definition: lsyscache.c:196
Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)
Definition: makefuncs.c:701
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition: makefuncs.c:350
char * pstrdup(const char *in)
Definition: mcxt.c:2322
void * palloc0(Size size)
Definition: mcxt.c:1970
void * palloc(Size size)
Definition: mcxt.c:1940
Datum inet_server_addr(PG_FUNCTION_ARGS)
Definition: network.c:1753
Datum hashinet(PG_FUNCTION_ARGS)
Definition: network.c:872
static List * match_network_subset(Node *leftop, Node *rightop, bool is_eq, Oid opfamily)
Definition: network.c:1068
static int network_fast_cmp(Datum x, Datum y, SortSupport ssup)
Definition: network.c:471
Datum inet_send(PG_FUNCTION_ARGS)
Definition: network.c:290
static List * match_network_function(Node *leftop, Node *rightop, int indexarg, Oid funcid, Oid opfamily)
Definition: network.c:1020
void clean_ipv6_addr(int addr_family, char *addr)
Definition: network.c:2060
Datum cidr_out(PG_FUNCTION_ARGS)
Definition: network.c:173
Datum inet_client_addr(PG_FUNCTION_ARGS)
Definition: network.c:1681
int bitncommon(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1568
inet * cidr_set_masklen_internal(const inet *src, int bits)
Definition: network.c:366
Datum network_hostmask(PG_FUNCTION_ARGS)
Definition: network.c:1381
Datum network_scan_last(Datum in)
Definition: network.c:1669
Datum network_overlap(PG_FUNCTION_ARGS)
Definition: network.c:955
static inet * network_in(char *src, bool is_cidr, Node *escontext)
Definition: network.c:75
Datum inet_to_cidr(PG_FUNCTION_ARGS)
Definition: network.c:307
Datum inet_abbrev(PG_FUNCTION_ARGS)
Definition: network.c:1187
Datum inetand(PG_FUNCTION_ARGS)
Definition: network.c:1847
Datum network_subset_support(PG_FUNCTION_ARGS)
Definition: network.c:973
Datum network_sup(PG_FUNCTION_ARGS)
Definition: network.c:925
Datum network_host(PG_FUNCTION_ARGS)
Definition: network.c:1138
Datum network_supeq(PG_FUNCTION_ARGS)
Definition: network.c:940
Datum inetpl(PG_FUNCTION_ARGS)
Definition: network.c:1963
Datum cidr_abbrev(PG_FUNCTION_ARGS)
Definition: network.c:1205
Datum inet_server_port(PG_FUNCTION_ARGS)
Definition: network.c:1790
static bool addressOK(unsigned char *a, int bits, int family)
Definition: network.c:1606
int bitncmp(const unsigned char *l, const unsigned char *r, int n)
Definition: network.c:1534
Datum network_netmask(PG_FUNCTION_ARGS)
Definition: network.c:1339
Datum network_broadcast(PG_FUNCTION_ARGS)
Definition: network.c:1250
Datum network_smaller(PG_FUNCTION_ARGS)
Definition: network.c:845
Datum inetor(PG_FUNCTION_ARGS)
Definition: network.c:1879
Datum inet_set_masklen(PG_FUNCTION_ARGS)
Definition: network.c:322
static inet * network_recv(StringInfo buf, bool is_cidr)
Definition: network.c:192
Datum inet_in(PG_FUNCTION_ARGS)
Definition: network.c:121
Datum inetnot(PG_FUNCTION_ARGS)
Definition: network.c:1822
Datum network_ge(PG_FUNCTION_ARGS)
Definition: network.c:815
#define ABBREV_BITS_INET4_SUBNET
Definition: network.c:43
Datum inetmi_int8(PG_FUNCTION_ARGS)
Definition: network.c:1973
Datum inet_same_family(PG_FUNCTION_ARGS)
Definition: network.c:1429
double convert_network_to_scalar(Datum value, Oid typid, bool *failure)
Definition: network.c:1467
Datum hashinetextended(PG_FUNCTION_ARGS)
Definition: network.c:882
Datum cidr_send(PG_FUNCTION_ARGS)
Definition: network.c:298
Datum network_sub(PG_FUNCTION_ARGS)
Definition: network.c:895
Datum network_ne(PG_FUNCTION_ARGS)
Definition: network.c:833
#define ABBREV_BITS_INET4_NETMASK_SIZE
Definition: network.c:42
Datum network_le(PG_FUNCTION_ARGS)
Definition: network.c:797
Datum network_sortsupport(PG_FUNCTION_ARGS)
Definition: network.c:435
Datum cidr_recv(PG_FUNCTION_ARGS)
Definition: network.c:258
Datum inet_client_port(PG_FUNCTION_ARGS)
Definition: network.c:1718
static inet * internal_inetpl(inet *ip, int64 addend)
Definition: network.c:1911
Datum inetmi(PG_FUNCTION_ARGS)
Definition: network.c:1983
Datum cidr_set_masklen(PG_FUNCTION_ARGS)
Definition: network.c:346
Datum network_family(PG_FUNCTION_ARGS)
Definition: network.c:1231
Datum network_show(PG_FUNCTION_ARGS)
Definition: network.c:1164
static int32 network_cmp_internal(inet *a1, inet *a2)
Definition: network.c:403
Datum network_lt(PG_FUNCTION_ARGS)
Definition: network.c:788
static bytea * network_send(inet *addr, bool is_cidr)
Definition: network.c:270
Datum network_eq(PG_FUNCTION_ARGS)
Definition: network.c:806
static char * network_out(inet *src, bool is_cidr)
Definition: network.c:141
Datum network_subeq(PG_FUNCTION_ARGS)
Definition: network.c:910
Datum network_gt(PG_FUNCTION_ARGS)
Definition: network.c:824
Datum inet_merge(PG_FUNCTION_ARGS)
Definition: network.c:1441
Datum inet_recv(PG_FUNCTION_ARGS)
Definition: network.c:250
Datum network_cmp(PG_FUNCTION_ARGS)
Definition: network.c:423
Datum network_larger(PG_FUNCTION_ARGS)
Definition: network.c:857
Datum network_network(PG_FUNCTION_ARGS)
Definition: network.c:1295
static Datum network_abbrev_convert(Datum original, SortSupport ssup)
Definition: network.c:617
static bool network_abbrev_abort(int memtupcount, SortSupport ssup)
Definition: network.c:486
Datum network_masklen(PG_FUNCTION_ARGS)
Definition: network.c:1223
Datum network_scan_first(Datum in)
Definition: network.c:1655
Datum inet_out(PG_FUNCTION_ARGS)
Definition: network.c:165
Datum cidr_in(PG_FUNCTION_ARGS)
Definition: network.c:129
static bool is_opclause(const void *clause)
Definition: nodeFuncs.h:76
static bool is_funcclause(const void *clause)
Definition: nodeFuncs.h:69
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
static uint32 pg_bswap32(uint32 x)
Definition: pg_bswap.h:64
#define BITS_PER_BYTE
const void size_t len
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define list_make1(x1)
Definition: pg_list.h:212
#define linitial(l)
Definition: pg_list.h:178
#define lsecond(l)
Definition: pg_list.h:183
static int port
Definition: pg_regress.c:115
static char * buf
Definition: pg_test_fsync.c:72
char * pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
Definition: inet_net_ntop.c:77
#define snprintf
Definition: port.h:239
static uint32 DatumGetUInt32(Datum X)
Definition: postgres.h:227
uintptr_t Datum
Definition: postgres.h:69
#define SIZEOF_DATUM
Definition: postgres.h:86
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:399
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:160
struct SortSupportData * SortSupport
Definition: sortsupport.h:58
StringInfoData * StringInfo
Definition: stringinfo.h:54
List * args
Definition: primnodes.h:785
Definition: pg_list.h:54
Definition: nodes.h:135
List * args
Definition: primnodes.h:853
Definition: libpq-be.h:129
int(* comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:106
Datum(* abbrev_converter)(Datum original, SortSupport ssup)
Definition: sortsupport.h:172
void * ssup_extra
Definition: sortsupport.h:87
MemoryContext ssup_cxt
Definition: sortsupport.h:66
int(* abbrev_full_comparator)(Datum x, Datum y, SortSupport ssup)
Definition: sortsupport.h:191
bool(* abbrev_abort)(int memtupcount, SortSupport ssup)
Definition: sortsupport.h:182
Definition: inet.h:53
Definition: inet.h:108
unsigned char c
Definition: inet.h:111
unsigned char b
Definition: inet.h:110
unsigned char d
Definition: inet.h:112
unsigned char e
Definition: inet.h:113
unsigned char g
Definition: inet.h:115
unsigned char h
Definition: inet.h:116
unsigned char a
Definition: inet.h:109
unsigned char f
Definition: inet.h:114
Definition: inet.h:95
unsigned char e
Definition: inet.h:100
unsigned char b
Definition: inet.h:97
unsigned char f
Definition: inet.h:101
unsigned char c
Definition: inet.h:98
unsigned char a
Definition: inet.h:96
unsigned char d
Definition: inet.h:99
hyperLogLogState abbr_card
Definition: network.c:51
Definition: c.h:658
int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup)
Definition: tuplesort.c:3139
bool trace_sort
Definition: tuplesort.c:124
#define PG_RETURN_INET_P(x)
Definition: inet.h:135
static macaddr8 * DatumGetMacaddr8P(Datum X)
Definition: inet.h:163
static inet * DatumGetInetPP(Datum X)
Definition: inet.h:123
#define ip_addr(inetptr)
Definition: inet.h:77
#define SET_INET_VARSIZE(dst)
Definition: inet.h:86
#define PG_GETARG_INET_PP(n)
Definition: inet.h:134
#define ip_family(inetptr)
Definition: inet.h:71
static macaddr * DatumGetMacaddrP(Datum X)
Definition: inet.h:147
#define PGSQL_AF_INET
Definition: inet.h:39
#define PGSQL_AF_INET6
Definition: inet.h:40
#define ip_addrsize(inetptr)
Definition: inet.h:80
#define ip_maxbits(inetptr)
Definition: inet.h:83
#define ip_bits(inetptr)
Definition: inet.h:74
#define VARSIZE_ANY(PTR)
Definition: varatt.h:311
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
text * cstring_to_text(const char *s)
Definition: varlena.c:192